diff --git a/core/config/engine.h b/core/config/engine.h index be7cd62f663e..2aa4df1c586f 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -36,6 +36,11 @@ #include "core/templates/list.h" #include "core/templates/vector.h" +#if defined(VULKAN_ENABLED) && (defined(DEBUG_ENABLED) || defined(DEV_ENABLED)) +#define VK_TRACK_DRIVER_MEMORY +#define VK_TRACK_DEVICE_MEMORY +#endif + template class TypedArray; diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index d9a5a5094aef..99a845c412e3 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1457,6 +1457,11 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("display/window/subwindows/embed_subwindows", true); // Keep the enum values in sync with the `DisplayServer::VSyncMode` enum. custom_prop_info["display/window/vsync/vsync_mode"] = PropertyInfo(Variant::INT, "display/window/vsync/vsync_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Adaptive,Mailbox"); + + GLOBAL_DEF("display/window/frame_pacing/android/enable_frame_pacing", false); + GLOBAL_DEF("display/window/frame_pacing/android/enable_auto_swap", true); + GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/frame_pacing/android/target_frame_rate", PROPERTY_HINT_RANGE, "0.0, 90.0, 1.0"), 60); + custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); GLOBAL_DEF("physics/2d/run_on_separate_thread", false); GLOBAL_DEF("physics/3d/run_on_separate_thread", false); diff --git a/core/core_bind.cpp b/core/core_bind.cpp index f5c69b9b9802..963c39dbee03 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -42,6 +42,17 @@ #include "core/os/thread_safe.h" #include "core/variant/typed_array.h" + +#if defined(VK_TRACK_DRIVER_MEMORY) || defined(VK_TRACK_DEVICE_MEMORY) +#include "drivers/vulkan/rendering_context_driver_vulkan.h" +#endif + +// +// @ShadyTF script function to get performance report text +#include "servers/rendering/rendering_device.h" +// + + namespace core_bind { ////// ResourceLoader ////// @@ -1594,6 +1605,12 @@ int Engine::get_max_fps() const { double Engine::get_frames_per_second() const { return ::Engine::get_singleton()->get_frames_per_second(); } +// +// @ShadyTF script function to get performance report text +String Engine::get_perf_report() const { + return RenderingDevice::get_singleton()->get_perf_report(); +} +// uint64_t Engine::get_physics_frames() const { return ::Engine::get_singleton()->get_physics_frames(); @@ -1603,6 +1620,45 @@ uint64_t Engine::get_process_frames() const { return ::Engine::get_singleton()->get_process_frames(); } +#if defined(VK_TRACK_DRIVER_MEMORY) || defined(VK_TRACK_DEVICE_MEMORY) +String Engine::get_tracked_object_name(uint32_t typeIndex) const { + return RenderingContextDriverVulkan::get_tracked_object_name(typeIndex); +} +uint64_t Engine::get_tracked_object_type_count() const { + return RenderingContextDriverVulkan::get_tracked_object_type_count(); +} +#endif + +#if defined(VK_TRACK_DRIVER_MEMORY) +uint64_t Engine::get_driver_total_memory() const { + return RenderingContextDriverVulkan::get_driver_total_memory(); +} +uint64_t Engine::get_driver_allocation_count() const { + return RenderingContextDriverVulkan::get_driver_allocation_count(); +} +uint64_t Engine::get_driver_memory_by_object_type(uint32_t type) const { + return RenderingContextDriverVulkan::get_driver_memory_by_object_type(type); +} +uint64_t Engine::get_driver_allocs_by_object_type(uint32_t type) const { + return RenderingContextDriverVulkan::get_driver_allocs_by_object_type(type); +} +#endif + +#if defined(VK_TRACK_DEVICE_MEMORY) +uint64_t Engine::get_device_total_memory() const { + return RenderingContextDriverVulkan::get_device_total_memory(); +} +uint64_t Engine::get_device_allocation_count() const { + return RenderingContextDriverVulkan::get_device_allocation_count(); +} +uint64_t Engine::get_device_memory_by_object_type(uint32_t type) const { + return RenderingContextDriverVulkan::get_device_memory_by_object_type(type); +} +uint64_t Engine::get_device_allocs_by_object_type(uint32_t type) const { + return RenderingContextDriverVulkan::get_device_allocs_by_object_type(type); +} +#endif + void Engine::set_time_scale(double p_scale) { ::Engine::get_singleton()->set_time_scale(p_scale); } @@ -1748,10 +1804,34 @@ void Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("get_time_scale"), &Engine::get_time_scale); ClassDB::bind_method(D_METHOD("get_frames_drawn"), &Engine::get_frames_drawn); + // + // @ShadyTF script function to get performance report text ClassDB::bind_method(D_METHOD("get_frames_per_second"), &Engine::get_frames_per_second); + // + + ClassDB::bind_method(D_METHOD("get_perf_report"), &Engine::get_perf_report); ClassDB::bind_method(D_METHOD("get_physics_frames"), &Engine::get_physics_frames); ClassDB::bind_method(D_METHOD("get_process_frames"), &Engine::get_process_frames); +#if defined(VK_TRACK_DRIVER_MEMORY) || defined(VK_TRACK_DEVICE_MEMORY) + ClassDB::bind_method(D_METHOD("get_tracked_object_name"), &Engine::get_tracked_object_name); + ClassDB::bind_method(D_METHOD("get_tracked_object_type_count"), &Engine::get_tracked_object_type_count); +#endif + +#if defined(VK_TRACK_DRIVER_MEMORY) + ClassDB::bind_method(D_METHOD("get_driver_total_memory"), &Engine::get_driver_total_memory); + ClassDB::bind_method(D_METHOD("get_driver_allocation_count"), &Engine::get_driver_allocation_count); + ClassDB::bind_method(D_METHOD("get_driver_memory_by_object_type"), &Engine::get_driver_memory_by_object_type); + ClassDB::bind_method(D_METHOD("get_driver_allocs_by_object_type"), &Engine::get_driver_allocs_by_object_type); +#endif + +#if defined(VK_TRACK_DEVICE_MEMORY) + ClassDB::bind_method(D_METHOD("get_device_total_memory"), &Engine::get_device_total_memory); + ClassDB::bind_method(D_METHOD("get_device_allocation_count"), &Engine::get_device_allocation_count); + ClassDB::bind_method(D_METHOD("get_device_memory_by_object_type"), &Engine::get_device_memory_by_object_type); + ClassDB::bind_method(D_METHOD("get_device_allocs_by_object_type"), &Engine::get_device_allocs_by_object_type); +#endif + ClassDB::bind_method(D_METHOD("get_main_loop"), &Engine::get_main_loop); ClassDB::bind_method(D_METHOD("get_version_info"), &Engine::get_version_info); diff --git a/core/core_bind.h b/core/core_bind.h index f884426881ef..1346b4e3dab2 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -489,6 +489,29 @@ class Engine : public Object { double get_frames_per_second() const; uint64_t get_physics_frames() const; uint64_t get_process_frames() const; + // + // @ShadyTF script function to get performance report text + String get_perf_report() const; + // + +#if defined(VK_TRACK_DRIVER_MEMORY) || defined(VK_TRACK_DEVICE_MEMORY) + String get_tracked_object_name(uint32_t typeIndex) const; + uint64_t get_tracked_object_type_count() const; +#endif + +#if defined(VK_TRACK_DRIVER_MEMORY) + uint64_t get_driver_total_memory() const; + uint64_t get_driver_allocation_count() const; + uint64_t get_driver_memory_by_object_type(uint32_t type) const; + uint64_t get_driver_allocs_by_object_type(uint32_t type) const; +#endif + +#if defined(VK_TRACK_DEVICE_MEMORY) + uint64_t get_device_total_memory() const; + uint64_t get_device_allocation_count() const; + uint64_t get_device_memory_by_object_type(uint32_t type) const; + uint64_t get_device_allocs_by_object_type(uint32_t type) const; +#endif int get_frames_drawn(); diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 32c316e58e8c..9b255488d687 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -65,6 +65,32 @@ SafeNumeric Memory::max_usage; SafeNumeric Memory::alloc_count; +void *Memory::alloc_aligned_static(size_t p_bytes, size_t p_alignment) { + void *p1, *p2; + if ((p1 = (void *)malloc(p_bytes + p_alignment - 1 + sizeof(uint32_t))) == NULL) + return NULL; + + p2 = (void *)(((uintptr_t)p1 + sizeof(uint32_t) + p_alignment - 1) & ~((p_alignment)-1)); + *((uint32_t *)p2 - 1) = (uint32_t)((uintptr_t)p2 - (uintptr_t)p1); + return p2; +} + +void *Memory::realloc_aligned_static(void* p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment) { + if (p_memory == NULL) + return alloc_aligned_static(p_bytes, p_alignment); + + void *ret = alloc_aligned_static(p_bytes, p_alignment); + memcpy(ret, p_memory, p_prev_bytes); + free_aligned_static(p_memory); + return ret; +} + +void Memory::free_aligned_static(void* p_memory) { + uint32_t offset = *((uint32_t *)p_memory - 1); + void *p = (void *)((uint8_t *)p_memory - offset); + free(p); +} + void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { #ifdef DEBUG_ENABLED bool prepad = true; diff --git a/core/os/memory.h b/core/os/memory.h index 6f3f6fed399a..87d3d3a2a74f 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -62,6 +62,11 @@ class Memory { static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false); static void free_static(void *p_ptr, bool p_pad_align = false); + static void *alloc_aligned_static(size_t p_bytes, size_t p_alignment); + static void *realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment); + static void free_aligned_static(void* p_memory); + + static uint64_t get_mem_available(); static uint64_t get_mem_usage(); static uint64_t get_mem_max_usage(); diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index e9df3c6fc827..43d1fc693e1b 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -2583,6 +2583,13 @@ bool TextureStorage::render_target_is_using_hdr(RID p_render_target) const { return rt->hdr; } +int64_t TextureStorage::render_target_get_format(RID p_render_target) const { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_NULL_V(rt, false); + + return RenderingDevice::get_singleton()->framebuffer_get_format(rt->texture); +} + GLuint TextureStorage::render_target_get_color_internal_format(RID p_render_target) const { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_NULL_V(rt, GL_RGBA8); diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index ef310262c7a0..61394fd06c0b 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -635,6 +635,7 @@ class TextureStorage : public RendererTextureStorage { virtual void render_target_do_msaa_resolve(RID p_render_target) override {} virtual void render_target_set_use_hdr(RID p_render_target, bool p_use_hdr_2d) override; virtual bool render_target_is_using_hdr(RID p_render_target) const override; + virtual int64_t render_target_get_format(RID p_render_target) const override; // new void render_target_set_as_unused(RID p_render_target) override { diff --git a/drivers/vulkan/rendering_context_driver_vulkan.cpp b/drivers/vulkan/rendering_context_driver_vulkan.cpp index 6eb25743f923..e89663b6e13f 100644 --- a/drivers/vulkan/rendering_context_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_context_driver_vulkan.cpp @@ -40,21 +40,328 @@ #include "rendering_device_driver_vulkan.h" #include "vulkan_hooks.h" +#if defined(VK_TRACK_DRIVER_MEMORY) +/*************************************************/ +// Driver memory tracking +/*************************************************/ +// Total driver memory and allocation amount +SafeNumeric driver_memory_total_memory; +SafeNumeric driver_memory_total_alloc_count; +// Amount of driver memory for every object type +SafeNumeric driver_memory_tracker[RenderingContextDriverVulkan::VK_TRACKED_OBJECT_TYPE_COUNT][RenderingContextDriverVulkan::VK_TRACKED_SYSTEM_ALLOCATION_SCOPE_COUNT]; +// Amount of allocations for every object type +SafeNumeric driver_memory_allocation_count[RenderingContextDriverVulkan::VK_TRACKED_OBJECT_TYPE_COUNT][RenderingContextDriverVulkan::VK_TRACKED_SYSTEM_ALLOCATION_SCOPE_COUNT]; +#endif + +#if defined(VK_TRACK_DEVICE_MEMORY) +/*************************************************/ +// Device memory report +/*************************************************/ +// Total device memory and allocation amount +HashMap memory_report_table; +// Total memory and allocation amount +SafeNumeric memory_report_total_memory; +SafeNumeric memory_report_total_alloc_count; +// Amount of device memory for every object type +SafeNumeric memory_report_mem_usage[RenderingContextDriverVulkan::VK_TRACKED_OBJECT_TYPE_COUNT]; +// Amount of device memory allocations for every object type +SafeNumeric memory_report_allocation_count[RenderingContextDriverVulkan::VK_TRACKED_OBJECT_TYPE_COUNT]; +#endif + +#if defined(VK_TRACK_DRIVER_MEMORY) || defined(VK_TRACK_DEVICE_MEMORY) +const char *RenderingContextDriverVulkan::get_tracked_object_name(uint32_t typeIndex) { + static constexpr const char *vkTrackedObjectTypeNames[] = { "UNKNOWN", + "INSTANCE", + "PHYSICAL_DEVICE", + "DEVICE", + "QUEUE", + "SEMAPHORE", + "COMMAND_BUFFER", + "FENCE", + "DEVICE_MEMORY", + "BUFFER", + "IMAGE", + "EVENT", + "QUERY_POOL", + "BUFFER_VIEW", + "IMAGE_VIEW", + "SHADER_MODULE", + "PIPELINE_CACHE", + "PIPELINE_LAYOUT", + "RENDER_PASS", + "PIPELINE", + "DESCRIPTOR_SET_LAYOUT", + "SAMPLER", + "DESCRIPTOR_POOL", + "DESCRIPTOR_SET", + "FRAMEBUFFER", + "COMMAND_POOL", + "DESCRIPTOR_UPDATE_TEMPLATE_KHR", + "SURFACE_KHR", + "SWAPCHAIN_KHR", + "DEBUG_UTILS_MESSENGER_EXT", + "DEBUG_REPORT_CALLBACK_EXT", + "ACCELERATION_STRUCTURE", + "VMA_BUFFER_OR_IMAGE" }; + + return vkTrackedObjectTypeNames[typeIndex]; +} +uint64_t RenderingContextDriverVulkan::get_tracked_object_type_count() { + return VK_TRACKED_OBJECT_TYPE_COUNT; +} + +RenderingContextDriverVulkan::VkTrackedObjectType vk_object_to_tracked_object(VkObjectType type) { + if (type > VK_OBJECT_TYPE_COMMAND_POOL && type != (VkObjectType)RenderingContextDriverVulkan::VK_TRACKED_OBJECT_TYPE_VMA) { + switch (type) { + case VK_OBJECT_TYPE_SURFACE_KHR: + return RenderingContextDriverVulkan::VK_TRACKED_OBJECT_TYPE_SURFACE; + case VK_OBJECT_TYPE_SWAPCHAIN_KHR: + return RenderingContextDriverVulkan::VK_TRACKED_OBJECT_TYPE_SWAPCHAIN; + default: + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Unknown VkObjectType enum value " + itos((uint32_t)type) + ".Please add it to VkTrackedObjectType, switch statement in " + "vk_object_to_tracked_object and get_tracked_object_name.", + (int)type); + return (RenderingContextDriverVulkan::VkTrackedObjectType)VK_OBJECT_TYPE_UNKNOWN; + } + } + + return (RenderingContextDriverVulkan::VkTrackedObjectType)type; +} + +#endif + + + +#if defined(VK_TRACK_DEVICE_MEMORY) +uint64_t RenderingContextDriverVulkan::get_device_total_memory() { + return memory_report_total_memory.get(); +} +uint64_t RenderingContextDriverVulkan::get_device_allocation_count() { + return memory_report_total_alloc_count.get(); +} +uint64_t RenderingContextDriverVulkan::get_device_memory_by_object_type(uint32_t type) { + return memory_report_mem_usage[type].get(); +} +uint64_t RenderingContextDriverVulkan::get_device_allocs_by_object_type(uint32_t type) { + return memory_report_allocation_count[type].get(); +} +#endif + +#if defined(VK_TRACK_DRIVER_MEMORY) +uint64_t RenderingContextDriverVulkan::get_driver_total_memory() { + return driver_memory_total_memory.get(); +} +uint64_t RenderingContextDriverVulkan::get_driver_allocation_count() { + return driver_memory_total_alloc_count.get(); +} +uint64_t RenderingContextDriverVulkan::get_driver_memory_by_object_type(uint32_t type) { + uint64_t ret = 0; + for (uint32_t i = 0; i < VK_TRACKED_SYSTEM_ALLOCATION_SCOPE_COUNT; i++) { + ret += driver_memory_tracker[type][i].get(); + } + + return ret; +} +uint64_t RenderingContextDriverVulkan::get_driver_allocs_by_object_type(uint32_t type) { + uint64_t ret = 0; + for (uint32_t i = 0; i < VK_TRACKED_SYSTEM_ALLOCATION_SCOPE_COUNT; i++) { + ret += driver_memory_allocation_count[type][i].get(); + } + + return ret; +} +#endif + +#if defined(VK_TRACK_DEVICE_MEMORY) +void RenderingContextDriverVulkan::memory_report_callback(const VkDeviceMemoryReportCallbackDataEXT *p_callback_data, void *p_user_data) { + if (!p_callback_data) { + return; + } + const RenderingContextDriverVulkan::VkTrackedObjectType obj_type = vk_object_to_tracked_object(p_callback_data->objectType); + uint64_t obj_id = p_callback_data->memoryObjectId; + + if (p_callback_data->type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT) { + // Realloc, update size + if (memory_report_table.has(obj_id)) { + memory_report_total_memory.sub(memory_report_table[obj_id]); + memory_report_mem_usage[obj_type].sub(memory_report_table[obj_id]); + + memory_report_total_memory.add(p_callback_data->size); + memory_report_mem_usage[obj_type].add(p_callback_data->size); + + memory_report_table[p_callback_data->memoryObjectId] = p_callback_data->size; + } else { + memory_report_table[obj_id] = p_callback_data->size; + + memory_report_total_alloc_count.increment(); + memory_report_allocation_count[obj_type].increment(); + memory_report_mem_usage[obj_type].add(p_callback_data->size); + memory_report_total_memory.add(p_callback_data->size); + } + } else if (p_callback_data->type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT) { + if (memory_report_table.has(obj_id)) { + memory_report_total_alloc_count.decrement(); + memory_report_allocation_count[obj_type].decrement(); + memory_report_mem_usage[obj_type].sub(p_callback_data->size); + memory_report_total_memory.sub(p_callback_data->size); + + memory_report_table.remove(memory_report_table.find(obj_id)); + } + } +} +#endif + +VkAllocationCallbacks *RenderingContextDriverVulkan::get_allocation_callbacks(VkObjectType type) { + +#if !defined(VK_TRACK_DRIVER_MEMORY) + return nullptr; +#else + struct TrackedMemHeader { + size_t size; + VkSystemAllocationScope allocation_scope; + VkTrackedObjectType type; + }; + VkAllocationCallbacks tracking_callbacks = { + // Allocation function + nullptr, + []( + void *p_user_data, + size_t size, + size_t alignment, + VkSystemAllocationScope allocation_scope) -> void * { + static constexpr size_t tracking_data_size = 32; + VkTrackedObjectType type = static_cast(*reinterpret_cast(p_user_data)); + + driver_memory_total_memory.add(size); + driver_memory_total_alloc_count.increment(); + driver_memory_tracker[type][allocation_scope].add(size); + driver_memory_allocation_count[type][allocation_scope].increment(); + + alignment = MAX(alignment, tracking_data_size); + + uint8_t *ret = reinterpret_cast(Memory::alloc_aligned_static(size + alignment, alignment)); + if (ret == nullptr) { + return NULL; + } + + // Track allocation + TrackedMemHeader *header = reinterpret_cast(ret); + header->size = size; + header->allocation_scope = allocation_scope; + header->type = type; + *reinterpret_cast(ret + alignment - sizeof(size_t)) = alignment; + + // Return first available chunk of memory + return ret + alignment; + }, + + // Reallocation function + []( + void *p_user_data, + void *p_original, + size_t size, + size_t alignment, + VkSystemAllocationScope allocation_scope) -> void * { + + if (p_original == nullptr) { + VkObjectType type = static_cast(*reinterpret_cast(p_user_data)); + return get_allocation_callbacks(type)->pfnAllocation(p_user_data, size, alignment, allocation_scope); + } + + uint8_t *mem = reinterpret_cast(p_original); + // Retrieve alignment + alignment = *reinterpret_cast(mem - sizeof(size_t)); + // Retrieve allocation data + TrackedMemHeader *header = reinterpret_cast(mem - alignment); + + // Update allocation size + driver_memory_total_memory.sub(header->size); + driver_memory_total_memory.add(size); + driver_memory_tracker[header->type][header->allocation_scope].sub(header->size); + driver_memory_tracker[header->type][header->allocation_scope].add(size); + + uint8_t *ret = reinterpret_cast(Memory::realloc_aligned_static(header, size + alignment, header->size + alignment, alignment)); + if (ret == nullptr) { + return NULL; + } + // Update tracker + header = reinterpret_cast(ret); + header->size = size; + return ret + alignment; + }, + + // Free function + []( + void *p_user_data, + void *p_memory) { + if (!p_memory) { + return; + } + + uint8_t *mem = reinterpret_cast(p_memory); + size_t alignment = *reinterpret_cast(mem - sizeof(size_t)); + TrackedMemHeader *header = reinterpret_cast(mem - alignment); + + driver_memory_total_alloc_count.decrement(); + driver_memory_total_memory.sub(header->size); + driver_memory_tracker[header->type][header->allocation_scope].sub(header->size); + driver_memory_allocation_count[header->type][header->allocation_scope].decrement(); + + Memory::free_aligned_static(header); + }, + // Internal allocation / deallocation. We don't track them as they cannot really be controlled or optimized by the programmer. + []( + void *p_user_data, + size_t size, + VkInternalAllocationType allocation_type, + VkSystemAllocationScope allocation_scope) { + }, + []( + void *p_user_data, + size_t size, + VkInternalAllocationType allocation_type, + VkSystemAllocationScope allocation_scope) { + }, + }; + + // Create a callback per object type + static VkAllocationCallbacks object_callbacks[VK_TRACKED_OBJECT_TYPE_COUNT] = {}; + static uint32_t object_user_data[VK_TRACKED_OBJECT_TYPE_COUNT] = {}; + + // Only build the first time + if (!object_callbacks[0].pfnAllocation) { + for (uint32_t c = 0; c < VK_TRACKED_OBJECT_TYPE_COUNT; ++c) { + object_callbacks[c] = tracking_callbacks; + object_user_data[c] = c; + object_callbacks[c].pUserData = &object_user_data[c]; + + for (uint32_t i = 0; i < VK_TRACKED_SYSTEM_ALLOCATION_SCOPE_COUNT; i++) { + driver_memory_tracker[c][i].set(0); + driver_memory_allocation_count[c][i].set(0); + } + } + } + + uint32_t type_index = vk_object_to_tracked_object(type); + return &object_callbacks[type_index]; +#endif +} + RenderingContextDriverVulkan::RenderingContextDriverVulkan() { // Empty constructor. } RenderingContextDriverVulkan::~RenderingContextDriverVulkan() { if (debug_messenger != VK_NULL_HANDLE && functions.DestroyDebugUtilsMessengerEXT != nullptr) { - functions.DestroyDebugUtilsMessengerEXT(instance, debug_messenger, nullptr); + functions.DestroyDebugUtilsMessengerEXT(instance, debug_messenger, get_allocation_callbacks(VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT)); } if (debug_report != VK_NULL_HANDLE && functions.DestroyDebugReportCallbackEXT != nullptr) { - functions.DestroyDebugReportCallbackEXT(instance, debug_report, nullptr); + functions.DestroyDebugReportCallbackEXT(instance, debug_report, get_allocation_callbacks(VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT)); } if (instance != VK_NULL_HANDLE) { - vkDestroyInstance(instance, nullptr); + vkDestroyInstance(instance, get_allocation_callbacks(VK_OBJECT_TYPE_INSTANCE)); } } @@ -432,7 +739,7 @@ Error RenderingContextDriverVulkan::_initialize_instance() { ERR_FAIL_V_MSG(ERR_CANT_CREATE, "GetProcAddr: Failed to init VK_EXT_debug_utils\nGetProcAddr: Failure"); } - VkResult res = functions.CreateDebugUtilsMessengerEXT(instance, &debug_messenger_create_info, nullptr, &debug_messenger); + VkResult res = functions.CreateDebugUtilsMessengerEXT(instance, &debug_messenger_create_info, get_allocation_callbacks(VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT), &debug_messenger); switch (res) { case VK_SUCCESS: break; @@ -452,7 +759,7 @@ Error RenderingContextDriverVulkan::_initialize_instance() { ERR_FAIL_V_MSG(ERR_CANT_CREATE, "GetProcAddr: Failed to init VK_EXT_debug_report\nGetProcAddr: Failure"); } - VkResult res = functions.CreateDebugReportCallbackEXT(instance, &debug_report_callback_create_info, nullptr, &debug_report); + VkResult res = functions.CreateDebugReportCallbackEXT(instance, &debug_report_callback_create_info, get_allocation_callbacks(VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT), &debug_report); switch (res) { case VK_SUCCESS: break; @@ -523,7 +830,7 @@ Error RenderingContextDriverVulkan::_create_vulkan_instance(const VkInstanceCrea if (VulkanHooks::get_singleton() != nullptr) { return VulkanHooks::get_singleton()->create_vulkan_instance(p_create_info, r_instance) ? OK : ERR_CANT_CREATE; } else { - VkResult err = vkCreateInstance(p_create_info, nullptr, r_instance); + VkResult err = vkCreateInstance(p_create_info, get_allocation_callbacks(VK_OBJECT_TYPE_INSTANCE), r_instance); ERR_FAIL_COND_V_MSG(err == VK_ERROR_INCOMPATIBLE_DRIVER, ERR_CANT_CREATE, "Cannot find a compatible Vulkan installable client driver (ICD).\n\n" "vkCreateInstance Failure"); @@ -642,7 +949,7 @@ bool RenderingContextDriverVulkan::surface_get_needs_resize(SurfaceID p_surface) void RenderingContextDriverVulkan::surface_destroy(SurfaceID p_surface) { Surface *surface = (Surface *)(p_surface); - vkDestroySurfaceKHR(instance, surface->vk_surface, nullptr); + vkDestroySurfaceKHR(instance, surface->vk_surface, get_allocation_callbacks(VK_OBJECT_TYPE_SURFACE_KHR)); memdelete(surface); } diff --git a/drivers/vulkan/rendering_context_driver_vulkan.h b/drivers/vulkan/rendering_context_driver_vulkan.h index 6348f90d55e2..6d23c918c372 100644 --- a/drivers/vulkan/rendering_context_driver_vulkan.h +++ b/drivers/vulkan/rendering_context_driver_vulkan.h @@ -77,6 +77,14 @@ class RenderingContextDriverVulkan : public RenderingContextDriver { PFN_vkDebugReportMessageEXT DebugReportMessageEXT = nullptr; PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT = nullptr; + // + // @ShadyTF debug marker extensions + PFN_vkCmdDebugMarkerBeginEXT vkCmdDebugMarkerBeginEXT = nullptr; + PFN_vkCmdDebugMarkerEndEXT vkCmdDebugMarkerEndEXT = nullptr; + PFN_vkCmdDebugMarkerInsertEXT vkCmdDebugMarkerInsertEXT = nullptr; + PFN_vkDebugMarkerSetObjectNameEXT vkDebugMarkerSetObjectNameEXT = nullptr; + // + bool debug_report_functions_available() const { return CreateDebugReportCallbackEXT != nullptr && DebugReportMessageEXT != nullptr && @@ -109,6 +117,10 @@ class RenderingContextDriverVulkan : public RenderingContextDriver { // Static callbacks. static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT p_message_severity, VkDebugUtilsMessageTypeFlagsEXT p_message_type, const VkDebugUtilsMessengerCallbackDataEXT *p_callback_data, void *p_user_data); static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_report_callback(VkDebugReportFlagsEXT p_flags, VkDebugReportObjectTypeEXT p_object_type, uint64_t p_object, size_t p_location, int32_t p_message_code, const char *p_layer_prefix, const char *p_message, void *p_user_data); + // + // @ShadyTF debug marker extensions + VkDebugReportObjectTypeEXT _convert_to_debug_report_objectType(VkObjectType p_object_type); + // protected: Error _find_validation_layers(TightLocalVector &r_layer_names) const; @@ -152,6 +164,39 @@ class RenderingContextDriverVulkan : public RenderingContextDriver { bool queue_family_supports_present(VkPhysicalDevice p_physical_device, uint32_t p_queue_family_index, SurfaceID p_surface) const; const Functions &functions_get() const; + static VkAllocationCallbacks *get_allocation_callbacks(VkObjectType type); + +#if defined(VK_TRACK_DRIVER_MEMORY) || defined(VK_TRACK_DEVICE_MEMORY) + enum VkTrackedObjectType{ + VK_TRACKED_OBJECT_TYPE_SURFACE = VK_OBJECT_TYPE_COMMAND_POOL + 1, + VK_TRACKED_OBJECT_TYPE_SWAPCHAIN, + VK_TRACKED_OBJECT_TYPE_VMA, + VK_TRACKED_OBJECT_TYPE_COUNT + }; + + enum VkTrackedSystemAllocationScope{ + VK_TRACKED_SYSTEM_ALLOCATION_SCOPE_COUNT = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE + 1 + }; + + static const char *get_tracked_object_name(uint32_t typeIndex); + static uint64_t get_tracked_object_type_count(); +#endif + +#if defined(VK_TRACK_DRIVER_MEMORY) + static uint64_t get_driver_total_memory(); + static uint64_t get_driver_allocation_count(); + static uint64_t get_driver_memory_by_object_type(uint32_t type); + static uint64_t get_driver_allocs_by_object_type(uint32_t type); +#endif + +#if defined(VK_TRACK_DEVICE_MEMORY) + static uint64_t get_device_total_memory(); + static uint64_t get_device_allocation_count(); + static uint64_t get_device_memory_by_object_type(uint32_t type); + static uint64_t get_device_allocs_by_object_type(uint32_t type); + static VKAPI_ATTR void VKAPI_CALL memory_report_callback(const VkDeviceMemoryReportCallbackDataEXT *p_callback_data, void *p_user_data); +#endif + RenderingContextDriverVulkan(); virtual ~RenderingContextDriverVulkan() override; }; diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index 21cf54b4be28..14b30b4eac8a 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -35,6 +35,13 @@ #include "thirdparty/misc/smolv.h" #include "vulkan_hooks.h" +#if defined(ANDROID_ENABLED) +#include "platform/android/java_godot_wrapper.h" +#include "platform/android/os_android.h" +#include "platform/android/thread_jandroid.h" +#include "thirdparty/swappy-frame-pacing/swappyVk.h" +#endif + #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #define PRINT_NATIVE_COMMANDS 0 @@ -445,6 +452,29 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() { _register_requested_device_extension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME, true); } +#if defined(VK_TRACK_DEVICE_MEMORY) + _register_requested_device_extension(VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME, false); +#endif + _register_requested_device_extension(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, false); + + // + // @ShadyTF debug marker extensions + // Should be last element in the array + +#ifdef DEV_ENABLED + bool want_debug_markers = true; +#else + bool want_debug_markers = OS::get_singleton()->is_stdout_verbose(); +#endif + if (want_debug_markers) { + _register_requested_device_extension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME, false); + } + // + + // + // @ShadyTF ASTC decode mode extension + _register_requested_device_extension(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, false); + // uint32_t device_extension_count = 0; VkResult err = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &device_extension_count, nullptr); ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE); @@ -455,6 +485,38 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() { err = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &device_extension_count, device_extensions.ptr()); ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE); +#if defined(ANDROID_ENABLED) + if (swappy_frame_pacer_enable) { + char **swappy_required_extensions; + uint32_t swappy_required_extensions_count = 0; + // Determine number of extensions required by Swappy frame pacer + SwappyVk_determineDeviceExtensions(physical_device, device_extension_count, device_extensions.ptr(), &swappy_required_extensions_count, nullptr); + + if (swappy_required_extensions_count < device_extension_count && swappy_required_extensions_count < device_extension_count) { + // Determine the actual extensions + swappy_required_extensions = (char **)malloc(swappy_required_extensions_count * sizeof(char *)); + char *pRequiredExtensionsData = (char *)malloc(swappy_required_extensions_count * (VK_MAX_EXTENSION_NAME_SIZE + 1)); + for (uint32_t i = 0; i < swappy_required_extensions_count; i++) { + swappy_required_extensions[i] = &pRequiredExtensionsData[i * (VK_MAX_EXTENSION_NAME_SIZE + 1)]; + } + SwappyVk_determineDeviceExtensions(physical_device, device_extension_count, + device_extensions.ptr(), &swappy_required_extensions_count, swappy_required_extensions); + + // Enable extensions requested by Swappy + for (uint32_t i = 0; i < swappy_required_extensions_count; i++) { + CharString extension_name(swappy_required_extensions[i]); + if (requested_device_extensions.has(extension_name)) { + enabled_device_extension_names.insert(extension_name); + } + } + + free(pRequiredExtensionsData); + free(swappy_required_extensions); + } + } + +#endif + #ifdef DEV_ENABLED for (uint32_t i = 0; i < device_extension_count; i++) { print_verbose(String("VULKAN: Found device extension ") + String::utf8(device_extensions[i].extensionName)); @@ -688,6 +750,14 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() { if (enabled_device_extension_names.has(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) { pipeline_cache_control_support = pipeline_cache_control_features.pipelineCreationCacheControl; } + + if (enabled_device_extension_names.has(VK_EXT_DEVICE_FAULT_EXTENSION_NAME)) { + device_fault_support = true; + } + + if (enabled_device_extension_names.has(VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME)) { + device_memory_report_support = true; + } } if (functions.GetPhysicalDeviceProperties2 != nullptr) { @@ -855,6 +925,26 @@ Error RenderingDeviceDriverVulkan::_initialize_device(const LocalVectorcreate_vulkan_device(&create_info, &vk_device); ERR_FAIL_COND_V(!device_created, ERR_CANT_CREATE); } else { - VkResult err = vkCreateDevice(physical_device, &create_info, nullptr, &vk_device); + VkResult err = vkCreateDevice(physical_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DEVICE), &vk_device); ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE); } @@ -931,6 +1021,16 @@ Error RenderingDeviceDriverVulkan::_initialize_device(const LocalVector + // @ShadyTF debug marker extensions + if (enabled_device_extension_names.has(VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) { + vkCmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT)functions.GetDeviceProcAddr(vk_device, "vkCmdDebugMarkerBeginEXT"); + vkCmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT)functions.GetDeviceProcAddr(vk_device, "vkCmdDebugMarkerEndEXT"); + vkCmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT)functions.GetDeviceProcAddr(vk_device, "vkCmdDebugMarkerInsertEXT"); + vkDebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)functions.GetDeviceProcAddr(vk_device, "vkDebugMarkerSetObjectNameEXT"); + } + // } return OK; @@ -1086,17 +1186,104 @@ bool RenderingDeviceDriverVulkan::_recreate_image_semaphore(CommandQueue *p_comm VkSemaphore semaphore; VkSemaphoreCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - VkResult err = vkCreateSemaphore(vk_device, &create_info, nullptr, &semaphore); + VkResult err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore); ERR_FAIL_COND_V(err != VK_SUCCESS, false); // Indicate the semaphore is free again and destroy the previous one before storing the new one. - vkDestroySemaphore(vk_device, p_command_queue->image_semaphores[p_semaphore_index], nullptr); + vkDestroySemaphore(vk_device, p_command_queue->image_semaphores[p_semaphore_index], VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE)); p_command_queue->image_semaphores[p_semaphore_index] = semaphore; p_command_queue->free_image_semaphores.push_back(p_semaphore_index); return true; } +// +// @ShadyTF debug marker extensions +VkDebugReportObjectTypeEXT RenderingDeviceDriverVulkan::_convert_to_debug_report_objectType(VkObjectType p_object_type){ + switch (p_object_type) { + case VK_OBJECT_TYPE_UNKNOWN: + return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; + case VK_OBJECT_TYPE_INSTANCE: + return VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; + case VK_OBJECT_TYPE_PHYSICAL_DEVICE: + return VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT; + case VK_OBJECT_TYPE_DEVICE: + return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT; + case VK_OBJECT_TYPE_QUEUE: + return VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT; + case VK_OBJECT_TYPE_SEMAPHORE: + return VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT; + case VK_OBJECT_TYPE_COMMAND_BUFFER: + return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT; + case VK_OBJECT_TYPE_FENCE: + return VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT; + case VK_OBJECT_TYPE_DEVICE_MEMORY: + return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT; + case VK_OBJECT_TYPE_BUFFER: + return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT; + case VK_OBJECT_TYPE_IMAGE: + return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT; + case VK_OBJECT_TYPE_EVENT: + return VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT; + case VK_OBJECT_TYPE_QUERY_POOL: + return VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT; + case VK_OBJECT_TYPE_BUFFER_VIEW: + return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT; + case VK_OBJECT_TYPE_IMAGE_VIEW: + return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT; + case VK_OBJECT_TYPE_SHADER_MODULE: + return VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT; + case VK_OBJECT_TYPE_PIPELINE_CACHE: + return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT; + case VK_OBJECT_TYPE_PIPELINE_LAYOUT: + return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT; + case VK_OBJECT_TYPE_RENDER_PASS: + return VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT; + case VK_OBJECT_TYPE_PIPELINE: + return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT; + case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT: + return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT; + case VK_OBJECT_TYPE_SAMPLER: + return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT; + case VK_OBJECT_TYPE_DESCRIPTOR_POOL: + return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT; + case VK_OBJECT_TYPE_DESCRIPTOR_SET: + return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT; + case VK_OBJECT_TYPE_FRAMEBUFFER: + return VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT; + case VK_OBJECT_TYPE_COMMAND_POOL: + return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT; + case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION: + return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT; + case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE: + return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT; + case VK_OBJECT_TYPE_SURFACE_KHR: + return VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT; + case VK_OBJECT_TYPE_SWAPCHAIN_KHR: + return VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT; + case VK_OBJECT_TYPE_DISPLAY_KHR: + return VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT; + case VK_OBJECT_TYPE_DISPLAY_MODE_KHR: + return VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT; + case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT: + return VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT; + case VK_OBJECT_TYPE_CU_MODULE_NVX: + return VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT; + case VK_OBJECT_TYPE_CU_FUNCTION_NVX: + return VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT; + case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR: + return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT; + case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT: + return VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT; + case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV: + return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT; + default: + break; + } + + return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; +} +// void RenderingDeviceDriverVulkan::_set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name) { const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get(); @@ -1110,13 +1297,42 @@ void RenderingDeviceDriverVulkan::_set_object_name(VkObjectType p_object_type, u name_info.pObjectName = obj_data.get_data(); functions.SetDebugUtilsObjectNameEXT(vk_device, &name_info); } + // + // @ShadyTF debug marker extensions + else { + if (functions.vkDebugMarkerSetObjectNameEXT != nullptr) { + CharString obj_data = p_object_name.utf8(); + VkDebugMarkerObjectNameInfoEXT name_info; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.pNext = nullptr; + name_info.objectType = _convert_to_debug_report_objectType( p_object_type ); + name_info.object = p_object_handle; + name_info.pObjectName = obj_data.get_data(); + functions.vkDebugMarkerSetObjectNameEXT(vk_device, &name_info); + } + } + // + + } Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t p_frame_count) { context_device = context_driver->device_get(p_device_index); physical_device = context_driver->physical_device_get(p_device_index); vkGetPhysicalDeviceProperties(physical_device, &physical_device_properties); - + + // + // @ShadyTF + // Workaround a driver bug on Adreno 730 GPUs that keeps leaking memory on each call to vkResetDescriptorPool. + // Which eventually run out of memory. in such case we should not be using linear allocated pools + // Bug introduced in driver 512.597.0 and fixed in 512.671.0 + // Confirmed by Qualcomm + if (linear_descriptor_pools_enabled) { + const uint32_t reset_descriptor_pool_broken_driver_begin = VK_MAKE_VERSION( 512u, 597u, 0u ); + const uint32_t reset_descriptor_pool_fixed_driver_begin = VK_MAKE_VERSION( 512u, 671u, 0u ); + linear_descriptor_pools_enabled = physical_device_properties.driverVersion < reset_descriptor_pool_broken_driver_begin || physical_device_properties.driverVersion > reset_descriptor_pool_fixed_driver_begin; + } + // frame_count = p_frame_count; // Copy the queue family properties the context already retrieved. @@ -1149,6 +1365,13 @@ Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t ERR_FAIL_COND_V(err != OK, err); max_descriptor_sets_per_pool = GLOBAL_GET("rendering/rendering_device/vulkan/max_descriptors_per_pool"); + breadcrumb_buffer = buffer_create(sizeof(uint32_t), BufferUsageBits::BUFFER_USAGE_TRANSFER_TO_BIT, MemoryAllocationType::MEMORY_ALLOCATION_TYPE_CPU); + +#if defined(ANDROID_ENABLED) + swappy_frame_pacer_enable = GLOBAL_GET("display/window/frame_pacing/android/enable_frame_pacing"); + swappy_enable_auto_swap = GLOBAL_GET("display/window/frame_pacing/android/enable_auto_swap"); + swappy_target_framerate = GLOBAL_GET("display/window/frame_pacing/android/target_frame_rate"); +#endif return OK; } @@ -1217,11 +1440,17 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie // Looks like a readback buffer: GPU copies from VRAM, then CPU maps and reads. alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; } - alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST; alloc_create_info.requiredFlags = (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } break; case MEMORY_ALLOCATION_TYPE_GPU: { - alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + // + // @ShadyTF + // condition to use persistent memory, UMA, condition would be passed in + if (p_usage & BUFFER_USAGE_PERSISTENT_BIT ) { + alloc_create_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + } + // if (p_size <= SMALL_ALLOCATION_MAX_SIZE) { uint32_t mem_type_index = 0; vmaFindMemoryTypeIndexForBufferInfo(allocator, &create_info, &alloc_create_info, &mem_type_index); @@ -1233,16 +1462,27 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie VkBuffer vk_buffer = VK_NULL_HANDLE; VmaAllocation allocation = nullptr; VmaAllocationInfo alloc_info = {}; - VkResult err = vmaCreateBuffer(allocator, &create_info, &alloc_create_info, &vk_buffer, &allocation, &alloc_info); + + VkResult err = vkCreateBuffer(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER), &vk_buffer); ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); + err = vmaAllocateMemoryForBuffer(allocator, vk_buffer, &alloc_create_info, &allocation, &alloc_info); + ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't allocate memory for buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); + err = vmaBindBufferMemory2(allocator, allocation, 0, vk_buffer, NULL); + ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't bind memory to buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); +#if VMA_STATS_STRING_ENABLED + //allocation->InitBufferImageUsage(alloc_create_info.usage); +#endif // Bookkeep. - BufferInfo *buf_info = VersatileResource::allocate(resources_allocator); buf_info->vk_buffer = vk_buffer; buf_info->allocation.handle = allocation; buf_info->allocation.size = alloc_info.size; buf_info->size = p_size; + // + // @ShadyTF - Store persistent address + buf_info->mapped_address = (uint8_t*)alloc_info.pMappedData; + // return BufferID(buf_info); } @@ -1258,7 +1498,7 @@ bool RenderingDeviceDriverVulkan::buffer_set_texel_format(BufferID p_buffer, Dat view_create_info.format = RD_TO_VK_FORMAT[p_format]; view_create_info.range = buf_info->allocation.size; - VkResult res = vkCreateBufferView(vk_device, &view_create_info, nullptr, &buf_info->vk_view); + VkResult res = vkCreateBufferView(vk_device, &view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER_VIEW), &buf_info->vk_view); ERR_FAIL_COND_V_MSG(res, false, "Unable to create buffer view, error " + itos(res) + "."); return true; @@ -1267,9 +1507,12 @@ bool RenderingDeviceDriverVulkan::buffer_set_texel_format(BufferID p_buffer, Dat void RenderingDeviceDriverVulkan::buffer_free(BufferID p_buffer) { BufferInfo *buf_info = (BufferInfo *)p_buffer.id; if (buf_info->vk_view) { - vkDestroyBufferView(vk_device, buf_info->vk_view, nullptr); + vkDestroyBufferView(vk_device, buf_info->vk_view, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER_VIEW)); } - vmaDestroyBuffer(allocator, buf_info->vk_buffer, buf_info->allocation.handle); + + vkDestroyBuffer(vk_device, buf_info->vk_buffer, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER)); + vmaFreeMemory(allocator, buf_info->allocation.handle); + VersatileResource::free(resources_allocator, buf_info); } @@ -1291,6 +1534,15 @@ void RenderingDeviceDriverVulkan::buffer_unmap(BufferID p_buffer) { vmaUnmapMemory(allocator, buf_info->allocation.handle); } +// +// @ShadyTF : return persistent mapped adreess +uint8_t* RenderingDeviceDriverVulkan::buffer_get_persistent_address( BufferID p_buffer ) { + //VkBuffer vk_buffer = (VkBuffer)p_buffer.id; + const BufferInfo *buf_info = (const BufferInfo *)p_buffer.id; + return buf_info->mapped_address; +} +// + /*****************/ /**** TEXTURE ****/ /*****************/ @@ -1452,7 +1704,27 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat & VmaAllocationCreateInfo alloc_create_info = {}; alloc_create_info.flags = (p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT) ? VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT : 0; - alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + + + // + //@ShadyTF : lazily allocated buffers + if (p_format.usage_bits & TEXTURE_USAGE_LAZILY_ALLOCATED_BIT) { + uint32_t memoryTypeIndex = 0; + VmaAllocationCreateInfo lazy_memory_requirements = alloc_create_info; + lazy_memory_requirements.usage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED; + VkResult result = vmaFindMemoryTypeIndex(allocator, UINT32_MAX, &lazy_memory_requirements, &memoryTypeIndex); + if (VK_SUCCESS == result) { + alloc_create_info = lazy_memory_requirements; + create_info.usage |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + // VUID-VkImageCreateInfo-usage-00963 : + // If usage includes VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + // then bits other than VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + // and VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT must not be set + create_info.usage &= (VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); + } + } + // + if (image_size <= SMALL_ALLOCATION_MAX_SIZE) { uint32_t mem_type_index = 0; vmaFindMemoryTypeIndexForImageInfo(allocator, &create_info, &alloc_create_info, &mem_type_index); @@ -1464,8 +1736,16 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat & VkImage vk_image = VK_NULL_HANDLE; VmaAllocation allocation = nullptr; VmaAllocationInfo alloc_info = {}; - VkResult err = vmaCreateImage(allocator, &create_info, &alloc_create_info, &vk_image, &allocation, &alloc_info); - ERR_FAIL_COND_V_MSG(err, TextureID(), "vmaCreateImage failed with error " + itos(err) + "."); + + VkResult err = vkCreateImage(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE), &vk_image); + ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImage failed with error " + itos(err) + "."); + err = vmaAllocateMemoryForImage(allocator, vk_image, &alloc_create_info, &allocation, &alloc_info); + ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't allocate memory for image, error: " + itos(err) + "."); + err = vmaBindImageMemory2(allocator, allocation, 0, vk_image, NULL); + ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't bind memory to image, error: " + itos(err) + "."); +#if VMA_STATS_STRING_ENABLED + //allocation->InitBufferImageUsage(alloc_create_info.usage); +#endif // Create view. @@ -1486,16 +1766,33 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat & image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; } + // + // @ShadyTF ASTC decode mode extension + VkImageViewASTCDecodeModeEXT decode_mode; + if (enabled_device_extension_names.has(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME)) { + if (image_view_create_info.format >= VK_FORMAT_ASTC_4x4_UNORM_BLOCK + && image_view_create_info.format <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK ) { + create_info.extent.height = p_format.height; + decode_mode.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT; + decode_mode.pNext = nullptr; + decode_mode.decodeMode = VK_FORMAT_R8G8B8A8_UNORM; + image_view_create_info.pNext = &decode_mode; + } + } + // + VkImageView vk_image_view = VK_NULL_HANDLE; - err = vkCreateImageView(vk_device, &image_view_create_info, nullptr, &vk_image_view); + err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &vk_image_view); if (err) { - vmaDestroyImage(allocator, vk_image, allocation); + vkDestroyImage(vk_device, vk_image, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE)); + vmaFreeMemory(allocator, allocation); ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + "."); } // Bookkeep. TextureInfo *tex_info = VersatileResource::allocate(resources_allocator); + tex_info->vk_image = vk_image; tex_info->vk_view = vk_image_view; tex_info->rd_format = p_format.format; tex_info->vk_create_info = create_info; @@ -1529,7 +1826,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_from_extension(uint64 image_view_create_info.subresourceRange.aspectMask = p_depth_stencil ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; VkImageView vk_image_view = VK_NULL_HANDLE; - VkResult err = vkCreateImageView(vk_device, &image_view_create_info, nullptr, &vk_image_view); + VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &vk_image_view); if (err) { ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + "."); } @@ -1584,7 +1881,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared(TextureID p_or } VkImageView new_vk_image_view = VK_NULL_HANDLE; - VkResult err = vkCreateImageView(vk_device, &image_view_create_info, nullptr, &new_vk_image_view); + VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &new_vk_image_view); ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + "."); // Bookkeep. @@ -1637,7 +1934,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared_from_slice(Tex image_view_create_info.subresourceRange.layerCount = p_layers; VkImageView new_vk_image_view = VK_NULL_HANDLE; - VkResult err = vkCreateImageView(vk_device, &image_view_create_info, nullptr, &new_vk_image_view); + VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &new_vk_image_view); ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + "."); // Bookkeep. @@ -1657,9 +1954,10 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared_from_slice(Tex void RenderingDeviceDriverVulkan::texture_free(TextureID p_texture) { TextureInfo *tex_info = (TextureInfo *)p_texture.id; - vkDestroyImageView(vk_device, tex_info->vk_view, nullptr); + vkDestroyImageView(vk_device, tex_info->vk_view, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW)); if (tex_info->allocation.handle) { - vmaDestroyImage(allocator, tex_info->vk_view_create_info.image, tex_info->allocation.handle); + vkDestroyImage(vk_device, tex_info->vk_image, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER)); + vmaFreeMemory(allocator, tex_info->allocation.handle); } VersatileResource::free(resources_allocator, tex_info); } @@ -1738,7 +2036,7 @@ uint8_t *RenderingDeviceDriverVulkan::texture_map(TextureID p_texture, const Tex void RenderingDeviceDriverVulkan::texture_unmap(TextureID p_texture) { const TextureInfo *tex_info = (const TextureInfo *)p_texture.id; - vkUnmapMemory(vk_device, tex_info->allocation.info.deviceMemory); + vmaUnmapMemory(allocator, tex_info->allocation.handle); } BitField RenderingDeviceDriverVulkan::texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) { @@ -1814,14 +2112,14 @@ RDD::SamplerID RenderingDeviceDriverVulkan::sampler_create(const SamplerState &p sampler_create_info.unnormalizedCoordinates = p_state.unnormalized_uvw; VkSampler vk_sampler = VK_NULL_HANDLE; - VkResult res = vkCreateSampler(vk_device, &sampler_create_info, nullptr, &vk_sampler); + VkResult res = vkCreateSampler(vk_device, &sampler_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SAMPLER), &vk_sampler); ERR_FAIL_COND_V_MSG(res, SamplerID(), "vkCreateSampler failed with error " + itos(res) + "."); return SamplerID(vk_sampler); } void RenderingDeviceDriverVulkan::sampler_free(SamplerID p_sampler) { - vkDestroySampler(vk_device, (VkSampler)p_sampler.id, nullptr); + vkDestroySampler(vk_device, (VkSampler)p_sampler.id, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SAMPLER)); } bool RenderingDeviceDriverVulkan::sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_filter) { @@ -1999,7 +2297,7 @@ RDD::FenceID RenderingDeviceDriverVulkan::fence_create() { VkFence vk_fence = VK_NULL_HANDLE; VkFenceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - VkResult err = vkCreateFence(vk_device, &create_info, nullptr, &vk_fence); + VkResult err = vkCreateFence(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FENCE), &vk_fence); ERR_FAIL_COND_V(err != VK_SUCCESS, FenceID()); Fence *fence = memnew(Fence); @@ -2010,10 +2308,13 @@ RDD::FenceID RenderingDeviceDriverVulkan::fence_create() { Error RenderingDeviceDriverVulkan::fence_wait(FenceID p_fence) { Fence *fence = (Fence *)(p_fence.id); - VkResult err = vkWaitForFences(vk_device, 1, &fence->vk_fence, VK_TRUE, UINT64_MAX); - ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED); + VkResult fence_status = vkGetFenceStatus(vk_device, fence->vk_fence); + if (fence_status == VK_NOT_READY) { + VkResult err = vkWaitForFences(vk_device, 1, &fence->vk_fence, VK_TRUE, UINT64_MAX); + ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED); + } - err = vkResetFences(vk_device, 1, &fence->vk_fence); + VkResult err = vkResetFences(vk_device, 1, &fence->vk_fence); ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED); if (fence->queue_signaled_from != nullptr) { @@ -2038,7 +2339,7 @@ Error RenderingDeviceDriverVulkan::fence_wait(FenceID p_fence) { void RenderingDeviceDriverVulkan::fence_free(FenceID p_fence) { Fence *fence = (Fence *)(p_fence.id); - vkDestroyFence(vk_device, fence->vk_fence, nullptr); + vkDestroyFence(vk_device, fence->vk_fence, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FENCE)); memdelete(fence); } @@ -2050,14 +2351,14 @@ RDD::SemaphoreID RenderingDeviceDriverVulkan::semaphore_create() { VkSemaphore semaphore = VK_NULL_HANDLE; VkSemaphoreCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - VkResult err = vkCreateSemaphore(vk_device, &create_info, nullptr, &semaphore); + VkResult err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore); ERR_FAIL_COND_V(err != VK_SUCCESS, SemaphoreID()); return SemaphoreID(semaphore); } void RenderingDeviceDriverVulkan::semaphore_free(SemaphoreID p_semaphore) { - vkDestroySemaphore(vk_device, VkSemaphore(p_semaphore.id), nullptr); + vkDestroySemaphore(vk_device, VkSemaphore(p_semaphore.id), VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE)); } /******************/ @@ -2117,6 +2418,14 @@ RDD::CommandQueueID RenderingDeviceDriverVulkan::command_queue_create(CommandQue ERR_FAIL_COND_V_MSG(picked_queue_index >= queue_family.size(), CommandQueueID(), "A queue in the picked family could not be found."); +#if defined(ANDROID_ENABLED) + if (swappy_frame_pacer_enable) { + VkQueue selected_queue; + vkGetDeviceQueue(vk_device, family_index, picked_queue_index, &selected_queue); + SwappyVk_setQueueFamilyIndex(vk_device, selected_queue, family_index); + } +#endif + // Create the virtual queue. CommandQueue *command_queue = memnew(CommandQueue); command_queue->queue_family = family_index; @@ -2184,7 +2493,7 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; for (uint32_t i = 0; i < frame_count; i++) { - err = vkCreateSemaphore(vk_device, &create_info, nullptr, &semaphore); + err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore); ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED); command_queue->present_semaphores.push_back(semaphore); } @@ -2211,6 +2520,11 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu device_queue.submit_mutex.lock(); err = vkQueueSubmit(device_queue.queue, 1, &submit_info, vk_fence); device_queue.submit_mutex.unlock(); + + if (err == VK_ERROR_DEVICE_LOST) { + print_lost_device_info(); + CRASH_NOW_MSG("Vulkan device was lost."); + } ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED); if (fence != nullptr && !command_queue->pending_semaphores_for_fence.is_empty()) { @@ -2257,7 +2571,16 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu present_info.pResults = results.ptr(); device_queue.submit_mutex.lock(); +#if defined(ANDROID_ENABLED) + if (swappy_frame_pacer_enable) { + err = SwappyVk_queuePresent(device_queue.queue, &present_info); + } else { + err = device_functions.QueuePresentKHR(device_queue.queue, &present_info); + } +#else err = device_functions.QueuePresentKHR(device_queue.queue, &present_info); +#endif + device_queue.submit_mutex.unlock(); // Set the index to an invalid value. If any of the swap chains returned out of date, indicate it should be resized the next time it's acquired. @@ -2302,12 +2625,12 @@ void RenderingDeviceDriverVulkan::command_queue_free(CommandQueueID p_cmd_queue) // Erase all the semaphores used for presentation. for (VkSemaphore semaphore : command_queue->present_semaphores) { - vkDestroySemaphore(vk_device, semaphore, nullptr); + vkDestroySemaphore(vk_device, semaphore, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE)); } // Erase all the semaphores used for image acquisition. for (VkSemaphore semaphore : command_queue->image_semaphores) { - vkDestroySemaphore(vk_device, semaphore, nullptr); + vkDestroySemaphore(vk_device, semaphore, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE)); } // Retrieve the queue family corresponding to the virtual queue. @@ -2332,10 +2655,14 @@ RDD::CommandPoolID RenderingDeviceDriverVulkan::command_pool_create(CommandQueue VkCommandPoolCreateInfo cmd_pool_info = {}; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.queueFamilyIndex = family_index; - cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + + // @NicolaTF: manually reset command pool + if (!command_pool_reset_enabled) { + cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + } VkCommandPool vk_command_pool = VK_NULL_HANDLE; - VkResult res = vkCreateCommandPool(vk_device, &cmd_pool_info, nullptr, &vk_command_pool); + VkResult res = vkCreateCommandPool(vk_device, &cmd_pool_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_COMMAND_POOL), &vk_command_pool); ERR_FAIL_COND_V_MSG(res, CommandPoolID(), "vkCreateCommandPool failed with error " + itos(res) + "."); CommandPool *command_pool = memnew(CommandPool); @@ -2344,11 +2671,21 @@ RDD::CommandPoolID RenderingDeviceDriverVulkan::command_pool_create(CommandQueue return CommandPoolID(command_pool); } +bool RenderingDeviceDriverVulkan::command_pool_reset(CommandPoolID p_cmd_pool) { + DEV_ASSERT(p_cmd_pool); + + CommandPool *command_pool = (CommandPool *)(p_cmd_pool.id); + VkResult err = vkResetCommandPool(vk_device, command_pool->vk_command_pool, 0); + ERR_FAIL_COND_V_MSG(err, false, "vkResetCommandPool failed with error " + itos(err) + "."); + + return true; +} + void RenderingDeviceDriverVulkan::command_pool_free(CommandPoolID p_cmd_pool) { DEV_ASSERT(p_cmd_pool); CommandPool *command_pool = (CommandPool *)(p_cmd_pool.id); - vkDestroyCommandPool(vk_device, command_pool->vk_command_pool, nullptr); + vkDestroyCommandPool(vk_device, command_pool->vk_command_pool, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_COMMAND_POOL)); memdelete(command_pool); } @@ -2377,8 +2714,6 @@ RDD::CommandBufferID RenderingDeviceDriverVulkan::command_buffer_create(CommandP } bool RenderingDeviceDriverVulkan::command_buffer_begin(CommandBufferID p_cmd_buffer) { - // Reset is implicit (VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT). - VkCommandBufferBeginInfo cmd_buf_begin_info = {}; cmd_buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; cmd_buf_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; @@ -2390,8 +2725,6 @@ bool RenderingDeviceDriverVulkan::command_buffer_begin(CommandBufferID p_cmd_buf } bool RenderingDeviceDriverVulkan::command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) { - // Reset is implicit (VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT). - VkCommandBufferInheritanceInfo inheritance_info = {}; inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; inheritance_info.renderPass = (VkRenderPass)p_render_pass.id; @@ -2428,7 +2761,7 @@ void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) { } for (VkImageView view : swap_chain->image_views) { - vkDestroyImageView(vk_device, view, nullptr); + vkDestroyImageView(vk_device, view, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW)); } swap_chain->image_index = UINT_MAX; @@ -2437,7 +2770,12 @@ void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) { swap_chain->framebuffers.clear(); if (swap_chain->vk_swapchain != VK_NULL_HANDLE) { - device_functions.DestroySwapchainKHR(vk_device, swap_chain->vk_swapchain, nullptr); +#if defined(ANDROID_ENABLED) + if (swappy_frame_pacer_enable) { + SwappyVk_destroySwapchain(vk_device, swap_chain->vk_swapchain); + } +#endif + device_functions.DestroySwapchainKHR(vk_device, swap_chain->vk_swapchain, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SWAPCHAIN_KHR)); swap_chain->vk_swapchain = VK_NULL_HANDLE; } @@ -2519,7 +2857,7 @@ RenderingDeviceDriver::SwapChainID RenderingDeviceDriverVulkan::swap_chain_creat pass_info.pSubpasses = &subpass; VkRenderPass render_pass = VK_NULL_HANDLE; - err = _create_render_pass(vk_device, &pass_info, nullptr, &render_pass); + err = _create_render_pass(vk_device, &pass_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS), &render_pass); ERR_FAIL_COND_V(err != VK_SUCCESS, SwapChainID()); SwapChain *swap_chain = memnew(SwapChain); @@ -2553,6 +2891,20 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, VkResult err = functions.GetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface->vk_surface, &surface_capabilities); ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE); + // No swapchain yet, this is the first time we're creating it + if (!swap_chain->vk_swapchain) { + uint32_t width = surface_capabilities.currentExtent.width; + uint32_t height = surface_capabilities.currentExtent.height; + if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR || + surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { + // Swap to get identity width and height + surface_capabilities.currentExtent.height = width; + surface_capabilities.currentExtent.width = height; + } + + native_display_size = surface_capabilities.currentExtent; + } + VkExtent2D extent; if (surface_capabilities.currentExtent.width == 0xFFFFFFFF) { // The current extent is currently undefined, so the current surface width and height will be clamped to the surface's capabilities. @@ -2619,15 +2971,8 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, desired_swapchain_images = MIN(desired_swapchain_images, surface_capabilities.maxImageCount); } - // Prefer identity transform if it's supported, use the current transform otherwise. - // This behavior is intended as Godot does not supported native rotation in platforms that use these bits. // Refer to the comment in command_queue_present() for more details. - VkSurfaceTransformFlagBitsKHR surface_transform_bits; - if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { - surface_transform_bits = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - } else { - surface_transform_bits = surface_capabilities.currentTransform; - } + VkSurfaceTransformFlagBitsKHR surface_transform_bits = surface_capabilities.currentTransform; VkCompositeAlphaFlagBitsKHR composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; if (OS::get_singleton()->is_layered_allowed() || !(surface_capabilities.supportedCompositeAlpha & composite_alpha)) { @@ -2653,7 +2998,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, swap_create_info.minImageCount = desired_swapchain_images; swap_create_info.imageFormat = swap_chain->format; swap_create_info.imageColorSpace = swap_chain->color_space; - swap_create_info.imageExtent = extent; + swap_create_info.imageExtent = native_display_size; swap_create_info.imageArrayLayers = 1; swap_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swap_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; @@ -2661,9 +3006,20 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, swap_create_info.compositeAlpha = composite_alpha; swap_create_info.presentMode = present_mode; swap_create_info.clipped = true; - err = device_functions.CreateSwapchainKHR(vk_device, &swap_create_info, nullptr, &swap_chain->vk_swapchain); + err = device_functions.CreateSwapchainKHR(vk_device, &swap_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SWAPCHAIN_KHR), &swap_chain->vk_swapchain); ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE); +#if defined(ANDROID_ENABLED) + if (swappy_frame_pacer_enable) { + uint64_t refresh_duration; + SwappyVk_initAndGetRefreshCycleDuration(get_jni_env(), static_cast(OS::get_singleton())->get_godot_java()->get_activity(), physical_device, + vk_device, swap_chain->vk_swapchain, &refresh_duration); + SwappyVk_setSwapIntervalNS(vk_device, swap_chain->vk_swapchain, MAX(refresh_duration, (1.0f / swappy_target_framerate) * 1000 * 1000 * 1000)); + SwappyVk_setAutoSwapInterval(swappy_enable_auto_swap); + SwappyVk_setWindow(vk_device, swap_chain->vk_swapchain, static_cast(OS::get_singleton())->get_native_window()); + } +#endif + uint32_t image_count = 0; err = device_functions.GetSwapchainImagesKHR(vk_device, swap_chain->vk_swapchain, &image_count, nullptr); ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE); @@ -2689,7 +3045,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, VkImageView image_view; for (uint32_t i = 0; i < image_count; i++) { view_create_info.image = swap_chain->images[i]; - err = vkCreateImageView(vk_device, &view_create_info, nullptr, &image_view); + err = vkCreateImageView(vk_device, &view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &image_view); ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE); swap_chain->image_views.push_back(image_view); @@ -2708,7 +3064,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, VkFramebuffer framebuffer; for (uint32_t i = 0; i < image_count; i++) { fb_create_info.pAttachments = &swap_chain->image_views[i]; - err = vkCreateFramebuffer(vk_device, &fb_create_info, nullptr, &framebuffer); + err = vkCreateFramebuffer(vk_device, &fb_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER), &framebuffer); ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE); swap_chain->framebuffers.push_back(RDD::FramebufferID(framebuffer)); @@ -2739,7 +3095,7 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::swap_chain_acquire_framebuffer(C // Add a new semaphore if none are free. VkSemaphoreCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - err = vkCreateSemaphore(vk_device, &create_info, nullptr, &semaphore); + err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore); ERR_FAIL_COND_V(err != VK_SUCCESS, FramebufferID()); semaphore_index = command_queue->image_semaphores.size(); @@ -2811,7 +3167,7 @@ void RenderingDeviceDriverVulkan::swap_chain_free(SwapChainID p_swap_chain) { _swap_chain_release(swap_chain); if (swap_chain->render_pass.id != 0) { - vkDestroyRenderPass(vk_device, VkRenderPass(swap_chain->render_pass.id), nullptr); + vkDestroyRenderPass(vk_device, VkRenderPass(swap_chain->render_pass.id), VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS)); } memdelete(swap_chain); @@ -2837,7 +3193,7 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::framebuffer_create(RenderPassID framebuffer_create_info.layers = 1; VkFramebuffer vk_framebuffer = VK_NULL_HANDLE; - VkResult err = vkCreateFramebuffer(vk_device, &framebuffer_create_info, nullptr, &vk_framebuffer); + VkResult err = vkCreateFramebuffer(vk_device, &framebuffer_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER), &vk_framebuffer); ERR_FAIL_COND_V_MSG(err, FramebufferID(), "vkCreateFramebuffer failed with error " + itos(err) + "."); #if PRINT_NATIVE_COMMANDS @@ -2852,7 +3208,7 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::framebuffer_create(RenderPassID } void RenderingDeviceDriverVulkan::framebuffer_free(FramebufferID p_framebuffer) { - vkDestroyFramebuffer(vk_device, (VkFramebuffer)p_framebuffer.id, nullptr); + vkDestroyFramebuffer(vk_device, (VkFramebuffer)p_framebuffer.id, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER)); } /****************/ @@ -3054,8 +3410,14 @@ Vector RenderingDeviceDriverVulkan::shader_compile_binary_from_spirv(Ve return ret; } - -RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) { +// +// @ShadyTF +// adding support of immutable samplers, which can be embedded when creating the pipeline layout on the condition they remain +// valid and unchanged, so they don't need to be specified when creating uniform sets +// Was: +//RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) { +RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name, const Vector& r_immutableSamplers) { +// r_shader_desc = {}; // Driver-agnostic. ShaderInfo shader_info; // Driver-specific. @@ -3130,6 +3492,22 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec case UNIFORM_TYPE_SAMPLER: { layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; layout_binding.descriptorCount = set_ptr[j].length; +// +// @ShadyTF +// Immutable samplers : here they get set in the layoutbinding, given that they will not be changed later + int immutable_bind_index = -1; + if (immutable_samplers_enabled && r_immutableSamplers.size() > 0) { + for (int k = 0; k < r_immutableSamplers.size(); k++) { + if (r_immutableSamplers[k].binding == layout_binding.binding) { + immutable_bind_index = k; + break; + } + } + if (immutable_bind_index >= 0) { + layout_binding.pImmutableSamplers = (VkSampler*)&r_immutableSamplers[immutable_bind_index].ids[0].id; + } + } +// } break; case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE: { layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; @@ -3153,6 +3531,13 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec case UNIFORM_TYPE_UNIFORM_BUFFER: { layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; } break; +// +// @ShadyTF +// Dynamic uniform buffer + case UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC: { + layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + } break; +// case UNIFORM_TYPE_STORAGE_BUFFER: { layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; } break; @@ -3245,7 +3630,7 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec shader_module_create_info.pCode = (const uint32_t *)stages_spirv[i].ptr(); VkShaderModule vk_module = VK_NULL_HANDLE; - VkResult res = vkCreateShaderModule(vk_device, &shader_module_create_info, nullptr, &vk_module); + VkResult res = vkCreateShaderModule(vk_device, &shader_module_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SHADER_MODULE), &vk_module); if (res) { error_text = "Error (" + itos(res) + ") creating shader module for stage: " + String(SHADER_STAGE_NAMES[r_shader_desc.stages[i]]); break; @@ -3272,7 +3657,7 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec layout_create_info.pBindings = vk_set_bindings[i].ptr(); VkDescriptorSetLayout layout = VK_NULL_HANDLE; - VkResult res = vkCreateDescriptorSetLayout(vk_device, &layout_create_info, nullptr, &layout); + VkResult res = vkCreateDescriptorSetLayout(vk_device, &layout_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT), &layout); if (res) { error_text = "Error (" + itos(res) + ") creating descriptor set layout for set " + itos(i); break; @@ -3299,7 +3684,7 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec pipeline_layout_create_info.pPushConstantRanges = push_constant_range; } - VkResult err = vkCreatePipelineLayout(vk_device, &pipeline_layout_create_info, nullptr, &shader_info.vk_pipeline_layout); + VkResult err = vkCreatePipelineLayout(vk_device, &pipeline_layout_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_LAYOUT), &shader_info.vk_pipeline_layout); if (err) { error_text = "Error (" + itos(err) + ") creating pipeline layout."; } @@ -3308,10 +3693,10 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec if (!error_text.is_empty()) { // Clean up if failed. for (uint32_t i = 0; i < shader_info.vk_stages_create_info.size(); i++) { - vkDestroyShaderModule(vk_device, shader_info.vk_stages_create_info[i].module, nullptr); + vkDestroyShaderModule(vk_device, shader_info.vk_stages_create_info[i].module, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SHADER_MODULE)); } for (uint32_t i = 0; i < binary_data.set_count; i++) { - vkDestroyDescriptorSetLayout(vk_device, shader_info.vk_descriptor_set_layouts[i], nullptr); + vkDestroyDescriptorSetLayout(vk_device, shader_info.vk_descriptor_set_layouts[i], VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)); } ERR_FAIL_V_MSG(ShaderID(), error_text); @@ -3328,24 +3713,62 @@ void RenderingDeviceDriverVulkan::shader_free(ShaderID p_shader) { ShaderInfo *shader_info = (ShaderInfo *)p_shader.id; for (uint32_t i = 0; i < shader_info->vk_descriptor_set_layouts.size(); i++) { - vkDestroyDescriptorSetLayout(vk_device, shader_info->vk_descriptor_set_layouts[i], nullptr); + vkDestroyDescriptorSetLayout(vk_device, shader_info->vk_descriptor_set_layouts[i], VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)); } - vkDestroyPipelineLayout(vk_device, shader_info->vk_pipeline_layout, nullptr); + vkDestroyPipelineLayout(vk_device, shader_info->vk_pipeline_layout, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_LAYOUT)); for (uint32_t i = 0; i < shader_info->vk_stages_create_info.size(); i++) { - vkDestroyShaderModule(vk_device, shader_info->vk_stages_create_info[i].module, nullptr); - } + vkDestroyShaderModule(vk_device, shader_info->vk_stages_create_info[i].module, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SHADER_MODULE)); + } + // + // @ShadyTF unload shader modules + // Was : + //for (uint32_t i = 0; i < si.vk_stages_create_info.size(); i++) { + // if (si.vk_stages_create_info[i].module) { + // vkDestroyShaderModule(vk_device, si.vk_stages_create_info[i].module, nullptr); + // } + //} + shader_destroy_modules( p_shader ); + // VersatileResource::free(resources_allocator, shader_info); } +// +// @ShadyTF unload shader modules + + +void RenderingDeviceDriverVulkan::shader_destroy_modules(ShaderID p_shader) { + auto *E = (RBSet::Element *)p_shader.id; + ShaderInfo &si = E->get(); + + for (uint32_t i = 0; i < si.vk_stages_create_info.size(); i++) { + if (si.vk_stages_create_info[i].module) { + vkDestroyShaderModule(vk_device, si.vk_stages_create_info[i].module, nullptr); + si.vk_stages_create_info[i].module = VK_NULL_HANDLE; + } + } + si.vk_stages_create_info.clear(); +} + +// + + + /*********************/ /**** UNIFORM SET ****/ /*********************/ - -VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it) { - DescriptorSetPools::Iterator pool_sets_it = descriptor_set_pools.find(p_key); +// +// @ShadyTF : +// descriptor optimizations : linear allocation of descriptor set pools +// Was: +// VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it) { +// DescriptorSetPools::Iterator pool_sets_it = descriptor_set_pools.find(p_key); +VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it, int p_linear_pool_index) { + bool linear_pool = p_linear_pool_index >= 0; + DescriptorSetPools::Iterator pool_sets_it = linear_pool ? linear_descriptor_set_pools[p_linear_pool_index].find(p_key) : descriptor_set_pools.find(p_key); + // if (pool_sets_it) { for (KeyValue &E : pool_sets_it->value) { @@ -3412,6 +3835,17 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat curr_vk_size++; vk_sizes_count++; } +// +// @ShadyTF +// Dynamic uniform buffer + if (p_key.uniform_type[UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC]) { + *curr_vk_size = {}; + curr_vk_size->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC] * max_descriptor_sets_per_pool; + curr_vk_size++; + vk_sizes_count++; + } +// if (p_key.uniform_type[UNIFORM_TYPE_STORAGE_BUFFER]) { *curr_vk_size = {}; curr_vk_size->type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; @@ -3431,13 +3865,23 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat VkDescriptorPoolCreateInfo descriptor_set_pool_create_info = {}; descriptor_set_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - descriptor_set_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; // Can't think how somebody may NOT need this flag. + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was : + // descriptor_set_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; // Can't think how somebody may NOT need this flag. + if (linear_descriptor_pools_enabled && linear_pool) { + descriptor_set_pool_create_info.flags = 0; + } else { + descriptor_set_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; // Can't think how somebody may NOT need this flag. + } + // descriptor_set_pool_create_info.maxSets = max_descriptor_sets_per_pool; descriptor_set_pool_create_info.poolSizeCount = vk_sizes_count; descriptor_set_pool_create_info.pPoolSizes = vk_sizes; VkDescriptorPool vk_pool = VK_NULL_HANDLE; - VkResult res = vkCreateDescriptorPool(vk_device, &descriptor_set_pool_create_info, nullptr, &vk_pool); + VkResult res = vkCreateDescriptorPool(vk_device, &descriptor_set_pool_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL), &vk_pool); if (res) { ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateDescriptorPool failed with error " + itos(res) + "."); } @@ -3445,7 +3889,17 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat // Bookkeep. if (!pool_sets_it) { - pool_sets_it = descriptor_set_pools.insert(p_key, HashMap()); +// +// @ShadyTF : +// descriptor optimizations : linear allocation of descriptor set pools +// Was: +// pool_sets_it = descriptor_set_pools.insert(p_key, HashMap()); + if (linear_pool) { + pool_sets_it = linear_descriptor_set_pools[p_linear_pool_index].insert(p_key, HashMap()); + } else { + pool_sets_it = descriptor_set_pools.insert(p_key, HashMap()); + } +// } HashMap &pool_rcs = pool_sets_it->value; pool_rcs.insert(vk_pool, 0); @@ -3453,34 +3907,73 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat return vk_pool; } -void RenderingDeviceDriverVulkan::_descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool) { +// +// @ShadyTF : +// descriptor optimizations : linear allocation of descriptor set pools +// Was : +//void RenderingDeviceDriverVulkan::_descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool) { +void RenderingDeviceDriverVulkan::_descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool, int p_linear_pool_index) { +// HashMap::Iterator pool_rcs_it = p_pool_sets_it->value.find(p_vk_descriptor_pool); pool_rcs_it->value--; if (pool_rcs_it->value == 0) { - vkDestroyDescriptorPool(vk_device, p_vk_descriptor_pool, nullptr); + vkDestroyDescriptorPool(vk_device, p_vk_descriptor_pool, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL)); p_pool_sets_it->value.erase(p_vk_descriptor_pool); if (p_pool_sets_it->value.is_empty()) { - descriptor_set_pools.remove(p_pool_sets_it); + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was: descriptor_set_pools.remove(p_pool_sets_it); + if (linear_descriptor_pools_enabled && p_linear_pool_index >= 0) { + linear_descriptor_set_pools[p_linear_pool_index].remove(p_pool_sets_it); + } else { + descriptor_set_pools.remove(p_pool_sets_it); + } } } } -RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) { +// +// @ShadyTF : +// descriptor optimizations : linear allocation of descriptor set pools +// Was: +//RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) { +RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index, int p_linear_pool_index) { + if (!linear_descriptor_pools_enabled) { + p_linear_pool_index = -1; + } +// DescriptorSetPoolKey pool_key; +// +// @ShadyTF : +// immutable samplers : +// as immutable samplers will be skipped we need to track the number of vk_writes used +// Was : +// VkWriteDescriptorSet *vk_writes = ALLOCA_ARRAY(VkWriteDescriptorSet, p_uniforms.size()); +// for (uint32_t i = 0; i < p_uniforms.size(); i++) { +// const BoundUniform &uniform = p_uniforms[i]; VkWriteDescriptorSet *vk_writes = ALLOCA_ARRAY(VkWriteDescriptorSet, p_uniforms.size()); + uint32_t writes_amount = 0; for (uint32_t i = 0; i < p_uniforms.size(); i++) { const BoundUniform &uniform = p_uniforms[i]; - vk_writes[i] = {}; - vk_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - vk_writes[i].dstBinding = uniform.binding; - vk_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; // Invalid value. +// + vk_writes[writes_amount] = {}; + vk_writes[writes_amount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; uint32_t num_descriptors = 1; switch (uniform.type) { case UNIFORM_TYPE_SAMPLER: { +// +// @ShadyTF : +// immutable samplers : +// skipping immutable samplers. + if (uniform.immutable_sampler && immutable_samplers_enabled) { + continue; + } +// num_descriptors = uniform.ids.size(); VkDescriptorImageInfo *vk_img_infos = ALLOCA_ARRAY(VkDescriptorImageInfo, num_descriptors); @@ -3491,8 +3984,8 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorViewvk_view; } - vk_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - vk_writes[i].pBufferInfo = vk_buf_infos; - vk_writes[i].pTexelBufferView = vk_buf_views; + vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + vk_writes[writes_amount].pBufferInfo = vk_buf_infos; + vk_writes[writes_amount].pTexelBufferView = vk_buf_views; } break; case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER: { num_descriptors = uniform.ids.size() / 2; @@ -3570,10 +4063,10 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorViewvk_view; } - vk_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - vk_writes[i].pImageInfo = vk_img_infos; - vk_writes[i].pBufferInfo = vk_buf_infos; - vk_writes[i].pTexelBufferView = vk_buf_views; + vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + vk_writes[writes_amount].pImageInfo = vk_img_infos; + vk_writes[writes_amount].pBufferInfo = vk_buf_infos; + vk_writes[writes_amount].pTexelBufferView = vk_buf_views; } break; case UNIFORM_TYPE_IMAGE_BUFFER: { CRASH_NOW_MSG("Unimplemented!"); // TODO. @@ -3585,9 +4078,23 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorViewbuffer = buf_info->vk_buffer; vk_buf_info->range = buf_info->size; - vk_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - vk_writes[i].pBufferInfo = vk_buf_info; + vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + vk_writes[writes_amount].pBufferInfo = vk_buf_info; + } break; +// +// @ShadyTF +// Dynamic uniform buffer + case UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC: { + const BufferInfo *buf_info = (const BufferInfo *)uniform.ids[0].id; + VkDescriptorBufferInfo *vk_buf_info = ALLOCA_SINGLE(VkDescriptorBufferInfo); + *vk_buf_info = {}; + vk_buf_info->buffer = buf_info->vk_buffer; + vk_buf_info->range = buf_info->size; + + vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + vk_writes[writes_amount].pBufferInfo = vk_buf_info; } break; +// case UNIFORM_TYPE_STORAGE_BUFFER: { const BufferInfo *buf_info = (const BufferInfo *)uniform.ids[0].id; VkDescriptorBufferInfo *vk_buf_info = ALLOCA_SINGLE(VkDescriptorBufferInfo); @@ -3595,8 +4102,8 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorViewbuffer = buf_info->vk_buffer; vk_buf_info->range = buf_info->size; - vk_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - vk_writes[i].pBufferInfo = vk_buf_info; + vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + vk_writes[writes_amount].pBufferInfo = vk_buf_info; } break; case UNIFORM_TYPE_INPUT_ATTACHMENT: { num_descriptors = uniform.ids.size(); @@ -3608,24 +4115,32 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was: + // VkDescriptorPool vk_pool = _descriptor_set_pool_find_or_create(pool_key, &pool_sets_it); + VkDescriptorPool vk_pool = _descriptor_set_pool_find_or_create(pool_key, &pool_sets_it, p_linear_pool_index); + // DEV_ASSERT(vk_pool); pool_sets_it->value[vk_pool]++; @@ -3637,22 +4152,51 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorViewvk_descriptor_set_layouts[p_set_index]; VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE; + VkResult res = vkAllocateDescriptorSets(vk_device, &descriptor_set_allocate_info, &vk_descriptor_set); if (res) { - _descriptor_set_pool_unreference(pool_sets_it, vk_pool); + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was: + // _descriptor_set_pool_unreference(pool_sets_it, vk_pool); + _descriptor_set_pool_unreference(pool_sets_it, vk_pool, p_linear_pool_index); + // ERR_FAIL_V_MSG(UniformSetID(), "Cannot allocate descriptor sets, error " + itos(res) + "."); } - for (uint32_t i = 0; i < p_uniforms.size(); i++) { +// +// @ShadyTF : +// immutable samplers : +// using number of vk_writes after skipping ummutable samplers +// Was: +// for (uint32_t i = 0; i < p_uniforms.size(); i++) { +// vk_writes[i].dstSet = vk_descriptor_set; +// } +// vkUpdateDescriptorSets(vk_device, p_uniforms.size(), vk_writes, 0, nullptr); + + for (uint32_t i = 0; i < writes_amount; i++) { vk_writes[i].dstSet = vk_descriptor_set; } - vkUpdateDescriptorSets(vk_device, p_uniforms.size(), vk_writes, 0, nullptr); + vkUpdateDescriptorSets(vk_device, writes_amount, vk_writes, 0, nullptr); + // // Bookkeep. UniformSetInfo *usi = VersatileResource::allocate(resources_allocator); usi->vk_descriptor_set = vk_descriptor_set; - usi->vk_descriptor_pool = vk_pool; + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was: + // usi->vk_descriptor_pool = vk_pool; + if (p_linear_pool_index >= 0) { + usi->vk_linear_descriptor_pool = vk_pool; + } else { + usi->vk_descriptor_pool = vk_pool; + } + // + usi->pool_sets_it = pool_sets_it; return UniformSetID(usi); @@ -3660,13 +4204,43 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorViewvk_descriptor_pool, 1, &usi->vk_descriptor_set); - _descriptor_set_pool_unreference(usi->pool_sets_it, usi->vk_descriptor_pool); + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was : + // vkFreeDescriptorSets(vk_device, usi->vk_descriptor_pool, 1, &usi->vk_descriptor_set); + // _descriptor_set_pool_unreference(usi->pool_sets_it, usi->vk_descriptor_pool); + if (usi->vk_linear_descriptor_pool) { + } else { + vkFreeDescriptorSets(vk_device, usi->vk_descriptor_pool, 1, &usi->vk_descriptor_set); + _descriptor_set_pool_unreference(usi->pool_sets_it, usi->vk_descriptor_pool, -1); + } + // + + + VersatileResource::free(resources_allocator, usi); } +void RenderingDeviceDriverVulkan::linear_uniform_set_pools_reset(int p_linear_pool_index) { + if (linear_descriptor_pools_enabled) { + DescriptorSetPools& pools_to_reset = linear_descriptor_set_pools[p_linear_pool_index]; + DescriptorSetPools::Iterator curr_pool = pools_to_reset.begin(); + + while (curr_pool != pools_to_reset.end()) { + HashMap::Iterator curr_pair = curr_pool->value.begin(); + while (curr_pair != curr_pool->value.end()) { + vkResetDescriptorPool(vk_device, curr_pair->key, 0); + curr_pair->value = 0; + ++curr_pair; + } + ++curr_pool; + } + } +} + // ----- COMMANDS ----- void RenderingDeviceDriverVulkan::command_uniform_set_prepare_for_use(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) { @@ -3802,7 +4376,7 @@ void RenderingDeviceDriverVulkan::command_copy_texture_to_buffer(CommandBufferID /******************/ void RenderingDeviceDriverVulkan::pipeline_free(PipelineID p_pipeline) { - vkDestroyPipeline(vk_device, (VkPipeline)p_pipeline.id, nullptr); + vkDestroyPipeline(vk_device, (VkPipeline)p_pipeline.id, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE)); } // ----- BINDING ----- @@ -3865,7 +4439,7 @@ bool RenderingDeviceDriverVulkan::pipeline_cache_create(const Vector &p cache_info.flags = VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT; } - VkResult err = vkCreatePipelineCache(vk_device, &cache_info, nullptr, &pipelines_cache.vk_cache); + VkResult err = vkCreatePipelineCache(vk_device, &cache_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_CACHE), &pipelines_cache.vk_cache); if (err != VK_SUCCESS) { WARN_PRINT("vkCreatePipelinecache failed with error " + itos(err) + "."); return false; @@ -3878,7 +4452,7 @@ bool RenderingDeviceDriverVulkan::pipeline_cache_create(const Vector &p void RenderingDeviceDriverVulkan::pipeline_cache_free() { DEV_ASSERT(pipelines_cache.vk_cache); - vkDestroyPipelineCache(vk_device, pipelines_cache.vk_cache, nullptr); + vkDestroyPipelineCache(vk_device, pipelines_cache.vk_cache, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_CACHE)); pipelines_cache.vk_cache = VK_NULL_HANDLE; DEV_ASSERT(caching_instance_count > 0); @@ -4062,14 +4636,14 @@ RDD::RenderPassID RenderingDeviceDriverVulkan::render_pass_create(VectorViewvk_pipeline_layout, p_set_index, 1, &usi->vk_descriptor_set, 0, nullptr); } + +void RenderingDeviceDriverVulkan::command_bind_render_uniform_sets(CommandBufferID p_cmd_buffer, VectorView p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) { + if (p_set_count == 0) { + return; + } + + const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id; + VkDescriptorSet *sets = (VkDescriptorSet *)alloca(sizeof(VkDescriptorSet) * p_set_count); + + for (uint32_t i = 0; i < p_set_count; i++) { + sets[i] = ((const UniformSetInfo *)p_uniform_sets[i].id)->vk_descriptor_set; + } + + vkCmdBindDescriptorSets((VkCommandBuffer)p_cmd_buffer.id, VK_PIPELINE_BIND_POINT_GRAPHICS, shader_info->vk_pipeline_layout, p_first_set_index, p_set_count, &sets[0], 0, nullptr); +} + + +// +// @ShadyTF +// Dynamic uniform buffer +void RenderingDeviceDriverVulkan::command_bind_render_uniform_set_dynamic(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index, uint32_t p_offsets_count, const uint32_t* p_offsets) { + const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id; + const UniformSetInfo *usi = (const UniformSetInfo *)p_uniform_set.id; + vkCmdBindDescriptorSets((VkCommandBuffer)p_cmd_buffer.id, VK_PIPELINE_BIND_POINT_GRAPHICS, shader_info->vk_pipeline_layout, p_set_index, 1, &usi->vk_descriptor_set, p_offsets_count, p_offsets); +} +// + + void RenderingDeviceDriverVulkan::command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) { vkCmdDraw((VkCommandBuffer)p_cmd_buffer.id, p_vertex_count, p_instance_count, p_base_vertex, p_first_instance); } @@ -4511,6 +5113,10 @@ RDD::PipelineID RenderingDeviceDriverVulkan::render_pipeline_create( pipeline_create_info.pNext = graphics_pipeline_nextptr; pipeline_create_info.stageCount = shader_info->vk_stages_create_info.size(); + // + // @ShadyTF unload shader modules + ERR_FAIL_COND_V_MSG(pipeline_create_info.stageCount == 0, PipelineID(), "Cannot create pipeline without shader module, please make sure shader modules are destroyed only after all associated pipelines are created"); + // VkPipelineShaderStageCreateInfo *vk_pipeline_stages = ALLOCA_ARRAY(VkPipelineShaderStageCreateInfo, shader_info->vk_stages_create_info.size()); for (uint32_t i = 0; i < shader_info->vk_stages_create_info.size(); i++) { @@ -4553,7 +5159,7 @@ RDD::PipelineID RenderingDeviceDriverVulkan::render_pipeline_create( // --- VkPipeline vk_pipeline = VK_NULL_HANDLE; - VkResult err = vkCreateGraphicsPipelines(vk_device, pipelines_cache.vk_cache, 1, &pipeline_create_info, nullptr, &vk_pipeline); + VkResult err = vkCreateGraphicsPipelines(vk_device, pipelines_cache.vk_cache, 1, &pipeline_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE), &vk_pipeline); ERR_FAIL_COND_V_MSG(err, PipelineID(), "vkCreateGraphicsPipelines failed with error " + itos(err) + "."); return PipelineID(vk_pipeline); @@ -4575,6 +5181,21 @@ void RenderingDeviceDriverVulkan::command_bind_compute_uniform_set(CommandBuffer vkCmdBindDescriptorSets((VkCommandBuffer)p_cmd_buffer.id, VK_PIPELINE_BIND_POINT_COMPUTE, shader_info->vk_pipeline_layout, p_set_index, 1, &usi->vk_descriptor_set, 0, nullptr); } +void RenderingDeviceDriverVulkan::command_bind_compute_uniform_sets(CommandBufferID p_cmd_buffer, VectorView p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) { + if (p_set_count == 0) { + return; + } + + const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id; + VkDescriptorSet *sets = (VkDescriptorSet *)alloca(sizeof(VkDescriptorSet) * p_set_count); + + for (uint32_t i = 0; i < p_set_count; i++) { + sets[i] = ((const UniformSetInfo *)p_uniform_sets[i].id)->vk_descriptor_set; + } + + vkCmdBindDescriptorSets((VkCommandBuffer)p_cmd_buffer.id, VK_PIPELINE_BIND_POINT_COMPUTE, shader_info->vk_pipeline_layout, p_first_set_index, p_set_count, &sets[0], 0, nullptr); +} + void RenderingDeviceDriverVulkan::command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) { vkCmdDispatch((VkCommandBuffer)p_cmd_buffer.id, p_x_groups, p_y_groups, p_z_groups); } @@ -4614,7 +5235,7 @@ RDD::PipelineID RenderingDeviceDriverVulkan::compute_pipeline_create(ShaderID p_ } VkPipeline vk_pipeline = VK_NULL_HANDLE; - VkResult err = vkCreateComputePipelines(vk_device, pipelines_cache.vk_cache, 1, &pipeline_create_info, nullptr, &vk_pipeline); + VkResult err = vkCreateComputePipelines(vk_device, pipelines_cache.vk_cache, 1, &pipeline_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE), &vk_pipeline); ERR_FAIL_COND_V_MSG(err, PipelineID(), "vkCreateComputePipelines failed with error " + itos(err) + "."); return PipelineID(vk_pipeline); @@ -4633,12 +5254,12 @@ RDD::QueryPoolID RenderingDeviceDriverVulkan::timestamp_query_pool_create(uint32 query_pool_create_info.queryCount = p_query_count; VkQueryPool vk_query_pool = VK_NULL_HANDLE; - vkCreateQueryPool(vk_device, &query_pool_create_info, nullptr, &vk_query_pool); + vkCreateQueryPool(vk_device, &query_pool_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_QUERY_POOL), &vk_query_pool); return RDD::QueryPoolID(vk_query_pool); } void RenderingDeviceDriverVulkan::timestamp_query_pool_free(QueryPoolID p_pool_id) { - vkDestroyQueryPool(vk_device, (VkQueryPool)p_pool_id.id, nullptr); + vkDestroyQueryPool(vk_device, (VkQueryPool)p_pool_id.id, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_QUERY_POOL)); } void RenderingDeviceDriverVulkan::timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) { @@ -4693,6 +5314,23 @@ void RenderingDeviceDriverVulkan::command_timestamp_write(CommandBufferID p_cmd_ void RenderingDeviceDriverVulkan::command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) { const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get(); + // + // @ShadyTF debug marker extensions + if (!functions.CmdBeginDebugUtilsLabelEXT) { + if (functions.vkCmdDebugMarkerBeginEXT) { + VkDebugMarkerMarkerInfoEXT marker; + marker.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; + marker.pNext = nullptr; + marker.pMarkerName = p_label_name; + marker.color[0] = p_color[0]; + marker.color[1] = p_color[1]; + marker.color[2] = p_color[2]; + marker.color[3] = p_color[3]; + functions.vkCmdDebugMarkerBeginEXT((VkCommandBuffer)p_cmd_buffer.id, &marker); + } + return; + } + // VkDebugUtilsLabelEXT label; label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; label.pNext = nullptr; @@ -4706,9 +5344,134 @@ void RenderingDeviceDriverVulkan::command_begin_label(CommandBufferID p_cmd_buff void RenderingDeviceDriverVulkan::command_end_label(CommandBufferID p_cmd_buffer) { const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get(); + // + // @ShadyTF debug marker extensions + if (!functions.CmdEndDebugUtilsLabelEXT) { + if (functions.vkCmdDebugMarkerEndEXT) { + functions.vkCmdDebugMarkerEndEXT((VkCommandBuffer)p_cmd_buffer.id); + } + return; + } + // functions.CmdEndDebugUtilsLabelEXT((VkCommandBuffer)p_cmd_buffer.id); } +/****************/ +/**** DEBUG *****/ +/****************/ +void RenderingDeviceDriverVulkan::command_insert_breadcrumb(CommandBufferID p_cmd_buffer, uint32_t p_data) { + if (p_data == BreadcrumbMarker::NONE) + return; + vkCmdFillBuffer((VkCommandBuffer)p_cmd_buffer.id, ((BufferInfo*)breadcrumb_buffer.id)->vk_buffer, 0, sizeof(uint32_t), p_data); +} + +void RenderingDeviceDriverVulkan::on_device_lost() const { + VkDeviceFaultCountsEXT fault_counts = { }; + fault_counts.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT; + VkResult vkres = vkGetDeviceFaultInfoEXT(vk_device, &fault_counts, nullptr); + + if (vkres != VK_SUCCESS) { + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "vkGetDeviceFaultInfoEXT returned " + itos(vkres) + " when getting fault count, skipping VK_EXT_device_fault report..."); + return; + } + + String err_msg = ""; + VkDeviceFaultInfoEXT fault_info = { }; + fault_info.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT; + fault_info.pVendorInfos = fault_counts.vendorInfoCount + ? (VkDeviceFaultVendorInfoEXT *)memalloc(fault_counts.vendorInfoCount * sizeof(VkDeviceFaultVendorInfoEXT)) + : NULL; + fault_info.pAddressInfos = + fault_counts.addressInfoCount + ? (VkDeviceFaultAddressInfoEXT *)memalloc(fault_counts.addressInfoCount * sizeof(VkDeviceFaultAddressInfoEXT)) + : NULL; + fault_counts.vendorBinarySize = 0; + vkres = vkGetDeviceFaultInfoEXT(vk_device, &fault_counts, &fault_info); + if (vkres != VK_SUCCESS) { + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "vkGetDeviceFaultInfoEXT returned " + itos(vkres) + " when getting fault info, skipping VK_EXT_device_fault report..."); + } else { + err_msg += "** Report from VK_EXT_device_fault **\n"; + err_msg += "Description: " + String(fault_info.description) + "\n"; + err_msg += "Vendor infos\n"; + for (uint32_t vd = 0; vd < fault_counts.vendorInfoCount; ++vd) { + const VkDeviceFaultVendorInfoEXT *vendor_info = &fault_info.pVendorInfos[vd]; + err_msg += "Info " + itos(vd) + "\n"; + err_msg += " Description: " + String(vendor_info->description) + "\n"; + err_msg += " Fault code : " + itos(vendor_info->vendorFaultCode) + "\n"; + err_msg += " Fault data : " + itos(vendor_info->vendorFaultData) + "\n"; + } + + static constexpr const char *addressTypeNames[] = { + "NONE", + "READ_INVALID", + "WRITE_INVALID", + "EXECUTE_INVALID", + "INSTRUCTION_POINTER_UNKNOWN", + "INSTRUCTION_POINTER_INVALID", + "INSTRUCTION_POINTER_FAULT", + }; + err_msg += "Address infosn\n"; + for (uint32_t ad = 0; ad < fault_counts.addressInfoCount; ++ad) { + const VkDeviceFaultAddressInfoEXT *addr_info = &fault_info.pAddressInfos[ad]; + // From https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDeviceFaultAddressInfoEXT.html + const VkDeviceAddress lower = (addr_info->reportedAddress & ~(addr_info->addressPrecision - 1)); + const VkDeviceAddress upper = (addr_info->reportedAddress | (addr_info->addressPrecision - 1)); + err_msg += "Info " + itos(ad); + err_msg += " Type : " + String(addressTypeNames[addr_info->addressType]); + err_msg += " Reported address: " + itos(addr_info->reportedAddress); + err_msg += " Lower address : " + itos(lower); + err_msg += " Upper address : " + itos(upper); + err_msg += " Precision : " + itos(addr_info->addressPrecision); + } + } + + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, err_msg); + + if (fault_info.pVendorInfos) + memfree(fault_info.pVendorInfos); + if (fault_info.pAddressInfos) + memfree(fault_info.pAddressInfos); +} + +void RenderingDeviceDriverVulkan::print_lost_device_info() { + +#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED) + void *breadcrumb_ptr; + vmaFlushAllocation(allocator, ((BufferInfo *)breadcrumb_buffer.id)->allocation.handle, 0, sizeof(uint32_t)); + vmaInvalidateAllocation(allocator, ((BufferInfo *)breadcrumb_buffer.id)->allocation.handle, 0, sizeof(uint32_t)); + + vmaMapMemory(allocator, ((BufferInfo *)breadcrumb_buffer.id)->allocation.handle, &breadcrumb_ptr); + uint32_t last_breadcrumb = *(uint32_t*)breadcrumb_ptr; + vmaUnmapMemory(allocator, ((BufferInfo *)breadcrumb_buffer.id)->allocation.handle); + uint32_t phase = last_breadcrumb >> 16; + uint32_t user_data = last_breadcrumb & ((1 << 16) - 1); + String errorMsg = "Last known breadcrumb: "; + + switch (phase) { + case BreadcrumbMarker::ALPHA_PASS: errorMsg += "ALPHA_PASS"; break; + case BreadcrumbMarker::BLIT_PASS: errorMsg += "BLIT_PASS"; break; + case BreadcrumbMarker::DEBUG_PASS: errorMsg += "DEBUG_PASS"; break; + case BreadcrumbMarker::LIGHTMAPPER_PASS: errorMsg += "LIGHTMAPPER_PASS"; break; + case BreadcrumbMarker::OPAQUE_PASS: errorMsg += "OPAQUE_PASS"; break; + case BreadcrumbMarker::POST_PROCESSING_PASS: errorMsg += "POST_PROCESSING_PASS"; break; + case BreadcrumbMarker::REFLECTION_PROBES: errorMsg += "REFLECTION_PROBES"; break; + case BreadcrumbMarker::SHADOW_PASS_CUBE: errorMsg += "SHADOW_PASS_CUBE"; break; + case BreadcrumbMarker::SHADOW_PASS_DIRECTIONAL: errorMsg += "SHADOW_PASS_DIRECTIONAL"; break; + case BreadcrumbMarker::SKY_PASS: errorMsg += "SKY_PASS"; break; + case BreadcrumbMarker::TRANSPARENT_PASS: errorMsg += "TRANSPARENT_PASS"; break; + case BreadcrumbMarker::UI_PASS: errorMsg += "UI_PASS"; break; + default: errorMsg += "UNKNOWN_BREADCRUMB(" + itos((uint32_t)phase) + ')'; break; + } + + if (user_data != 0) { + errorMsg += " | User data: " + itos(user_data); + } + + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, errorMsg); +#endif + on_device_lost(); +} + /********************/ /**** SUBMISSION ****/ /********************/ @@ -4813,6 +5576,13 @@ uint64_t RenderingDeviceDriverVulkan::get_total_memory_used() { return stats.total.statistics.allocationBytes; } +// +// @ShadyTF lazily allocated memory +uint64_t RenderingDeviceDriverVulkan::get_lazily_memory_used() { + return vmaCalculateLazilyAllocatedBytes(allocator); +} +// + uint64_t RenderingDeviceDriverVulkan::limit_get(Limit p_limit) { const VkPhysicalDeviceLimits &limits = physical_device_properties.limits; switch (p_limit) { @@ -4960,17 +5730,30 @@ RenderingDeviceDriverVulkan::RenderingDeviceDriverVulkan(RenderingContextDriverV DEV_ASSERT(p_context_driver != nullptr); context_driver = p_context_driver; + max_descriptor_sets_per_pool = GLOBAL_GET("rendering/rendering_device/vulkan/max_descriptors_per_pool"); + } RenderingDeviceDriverVulkan::~RenderingDeviceDriverVulkan() { + buffer_free(breadcrumb_buffer); + while (small_allocs_pools.size()) { HashMap::Iterator E = small_allocs_pools.begin(); - vmaDestroyPool(allocator, E->value); + vmaDestroyPool(allocator, E->value); small_allocs_pools.remove(E); } vmaDestroyAllocator(allocator); + // Destroy linearly allocated descriptor pools + for (KeyValue& pool_map : linear_descriptor_set_pools) { + for (KeyValue> pools : pool_map.value) { + for (KeyValue descriptor_pool : pools.value) { + vkDestroyDescriptorPool(vk_device, descriptor_pool.key, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL)); + } + } + } + if (vk_device != VK_NULL_HANDLE) { - vkDestroyDevice(vk_device, nullptr); + vkDestroyDevice(vk_device, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DEVICE)); } } diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h index 70c4cebba5ed..d27e85202cd2 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.h +++ b/drivers/vulkan/rendering_device_driver_vulkan.h @@ -110,7 +110,18 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { PFN_vkAcquireNextImageKHR AcquireNextImageKHR = nullptr; PFN_vkQueuePresentKHR QueuePresentKHR = nullptr; PFN_vkCreateRenderPass2KHR CreateRenderPass2KHR = nullptr; + // + // @ShadyTF debug marker extensions + PFN_vkCmdDebugMarkerBeginEXT vkCmdDebugMarkerBeginEXT = nullptr; + PFN_vkCmdDebugMarkerEndEXT vkCmdDebugMarkerEndEXT = nullptr; + PFN_vkCmdDebugMarkerInsertEXT vkCmdDebugMarkerInsertEXT = nullptr; + PFN_vkDebugMarkerSetObjectNameEXT vkDebugMarkerSetObjectNameEXT = nullptr; + // }; + // + // @ShadyTF debug marker extensions + VkDebugReportObjectTypeEXT _convert_to_debug_report_objectType(VkObjectType p_object_type); + // VkDevice vk_device = VK_NULL_HANDLE; RenderingContextDriverVulkan *context_driver = nullptr; @@ -131,6 +142,14 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { ShaderCapabilities shader_capabilities; StorageBufferCapabilities storage_buffer_capabilities; bool pipeline_cache_control_support = false; + bool device_fault_support = false; + bool device_memory_report_support = false; +#if defined(ANDROID_ENABLED) + // Swappy frame pacer for Android + bool swappy_frame_pacer_enable = false; + bool swappy_enable_auto_swap = true; + uint32_t swappy_target_framerate = 60; +#endif DeviceFunctions device_functions; void _register_requested_device_extension(const CharString &p_extension_name, bool p_required); @@ -154,15 +173,18 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { /**** MEMORY ****/ /****************/ - VmaAllocator allocator = nullptr; + VmaAllocator allocator; HashMap small_allocs_pools; VmaPool _find_or_create_small_allocs_pool(uint32_t p_mem_type_index); +private: + BufferID breadcrumb_buffer; + +public: /*****************/ /**** BUFFERS ****/ /*****************/ -private: struct BufferInfo { VkBuffer vk_buffer = VK_NULL_HANDLE; struct { @@ -170,22 +192,29 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { uint64_t size = UINT64_MAX; } allocation; uint64_t size = 0; + // + // persistent mapped address + uint8_t* mapped_address = VK_NULL_HANDLE; + // VkBufferView vk_view = VK_NULL_HANDLE; // For texel buffers. }; -public: virtual BufferID buffer_create(uint64_t p_size, BitField p_usage, MemoryAllocationType p_allocation_type) override final; virtual bool buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) override final; virtual void buffer_free(BufferID p_buffer) override final; virtual uint64_t buffer_get_allocation_size(BufferID p_buffer) override final; virtual uint8_t *buffer_map(BufferID p_buffer) override final; virtual void buffer_unmap(BufferID p_buffer) override final; - + // + // @ShadyTF -- getter for persitent mapped address + virtual uint8_t* buffer_get_persistent_address(BufferID p_buffer) override final; + // /*****************/ /**** TEXTURE ****/ /*****************/ struct TextureInfo { + VkImage vk_image = VK_NULL_HANDLE; VkImageView vk_view = VK_NULL_HANDLE; DataFormat rd_format = DATA_FORMAT_MAX; VkImageCreateInfo vk_create_info = {}; @@ -304,6 +333,7 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { public: virtual CommandPoolID command_pool_create(CommandQueueFamilyID p_cmd_queue_family, CommandBufferType p_cmd_buffer_type) override final; + virtual bool command_pool_reset(CommandPoolID p_cmd_pool) override final; virtual void command_pool_free(CommandPoolID p_cmd_pool) override final; // ----- BUFFER ----- @@ -334,6 +364,7 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { }; void _swap_chain_release(SwapChain *p_swap_chain); + VkExtent2D native_display_size; public: virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override final; @@ -400,9 +431,20 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { public: virtual String shader_get_binary_cache_key() override final; virtual Vector shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) override final; - virtual ShaderID shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) override final; + // + // @ShadyTF + // adding support of immutable samplers, which can be embedded when creating the pipeline layout on the condition they remain + // valid and unchanged, so they don't need to be specified when creating uniform sets + // Was: + //virtual ShaderID shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) override final; + virtual ShaderID shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name, const Vector& r_immutableSamplers) override final; + // virtual void shader_free(ShaderID p_shader) override final; + // + // @ShadyTF unload shader modules + virtual void shader_destroy_modules(ShaderID p_shader) override final; + // /*********************/ /**** UNIFORM SET ****/ /*********************/ @@ -437,17 +479,46 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { DescriptorSetPools descriptor_set_pools; uint32_t max_descriptor_sets_per_pool = 0; - VkDescriptorPool _descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it); - void _descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool); + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was : + // VkDescriptorPool _descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it); + // void _descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool); + HashMap linear_descriptor_set_pools; + bool linear_descriptor_pools_enabled = true; + VkDescriptorPool _descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it, int p_linear_pool_index); + void _descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool, int p_linear_pool_index); + // + + // + // @ShadyTF : + // global flag to toggle usage of immutable sampler when creating pipeline layouts and for skipping when creating uniform sets + bool immutable_samplers_enabled = true; + // + + struct UniformSetInfo { VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE; VkDescriptorPool vk_descriptor_pool = VK_NULL_HANDLE; + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + VkDescriptorPool vk_linear_descriptor_pool = VK_NULL_HANDLE; + // DescriptorSetPools::Iterator pool_sets_it = {}; }; public: - virtual UniformSetID uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) override final; + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was: + // virtual UniformSetID uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) override final; + virtual UniformSetID uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index, int p_linear_pool_index) override final; + virtual void linear_uniform_set_pools_reset( int p_linear_pool_index) override final; + // virtual void uniform_set_free(UniformSetID p_uniform_set) override final; // ----- COMMANDS ----- @@ -529,7 +600,13 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { // Binding. virtual void command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) override final; virtual void command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final; + virtual void command_bind_render_uniform_sets(CommandBufferID p_cmd_buffer, VectorView p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) override final; +// +// @ShadyTF +// Dynamic uniform buffer + virtual void command_bind_render_uniform_set_dynamic(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index, uint32_t p_offsets_count, const uint32_t* p_offsets) override final; +// // Drawing. virtual void command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) override final; virtual void command_render_draw_indexed(CommandBufferID p_cmd_buffer, uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index, int32_t p_vertex_offset, uint32_t p_first_instance) override final; @@ -571,6 +648,7 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { // Binding. virtual void command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) override final; virtual void command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final; + virtual void command_bind_compute_uniform_sets(CommandBufferID p_cmd_buffer, VectorView p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) override final; // Dispatching. virtual void command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) override final; @@ -603,6 +681,13 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { virtual void command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) override final; virtual void command_end_label(CommandBufferID p_cmd_buffer) override final; + /****************/ + /**** DEBUG *****/ + /****************/ + virtual void command_insert_breadcrumb(CommandBufferID p_cmd_buffer, uint32_t p_data) override final; + void print_lost_device_info(); + void on_device_lost() const; + /********************/ /**** SUBMISSION ****/ /********************/ @@ -617,6 +702,10 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { virtual void set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) override final; virtual uint64_t get_resource_native_handle(DriverResource p_type, ID p_driver_id) override final; virtual uint64_t get_total_memory_used() override final; + // + // @ShadyTF lazily allocated memory + virtual uint64_t get_lazily_memory_used() override final; + // virtual uint64_t limit_get(Limit p_limit) override final; virtual uint64_t api_trait_get(ApiTrait p_trait) override final; virtual bool has_feature(Features p_feature) override final; @@ -646,4 +735,6 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { virtual ~RenderingDeviceDriverVulkan(); }; +using VKC = RenderingContextDriverVulkan; + #endif // RENDERING_DEVICE_DRIVER_VULKAN_H diff --git a/main/main.cpp b/main/main.cpp index c520ebecd379..eaeb3330de01 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -195,7 +195,7 @@ static bool single_threaded_scene = false; // Display static DisplayServer::WindowMode window_mode = DisplayServer::WINDOW_MODE_WINDOWED; -static DisplayServer::ScreenOrientation window_orientation = DisplayServer::SCREEN_LANDSCAPE; +static DisplayServer::ScreenOrientation window_orientation = DisplayServer::SCREEN_SENSOR; static DisplayServer::VSyncMode window_vsync_mode = DisplayServer::VSYNC_ENABLED; static uint32_t window_flags = 0; static Size2i window_size = Size2i(1152, 648); @@ -861,6 +861,7 @@ int Main::test_entrypoint(int argc, char *argv[], bool &tests_need_run) { */ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) { + Thread::make_main_thread(); set_current_thread_safe_for_nodes(true); @@ -2290,7 +2291,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } { - window_orientation = DisplayServer::ScreenOrientation(int(GLOBAL_DEF_BASIC("display/window/handheld/orientation", DisplayServer::ScreenOrientation::SCREEN_LANDSCAPE))); + window_orientation = DisplayServer::ScreenOrientation(int(GLOBAL_DEF_BASIC("display/window/handheld/orientation", DisplayServer::ScreenOrientation::SCREEN_SENSOR))); } { window_vsync_mode = DisplayServer::VSyncMode(int(GLOBAL_DEF_BASIC("display/window/vsync/vsync_mode", DisplayServer::VSyncMode::VSYNC_ENABLED))); @@ -4250,3 +4251,53 @@ void Main::cleanup(bool p_force) { OS::get_singleton()->finalize_core(); } + +// +// @ShadyTF : Thermal status support + +Main::ThermalState Main::thermal_state = Main::THERMAL_STATE_NONE; + +const char* Main::get_therrmal_state_string(Main::ThermalState p_thermalState) { + switch (p_thermalState) { + case THERMAL_STATE_NOT_SUPPORTED: return "NotSupported"; + case THERMAL_STATE_ERROR: return "Error"; + case THERMAL_STATE_NONE: return "None"; + case THERMAL_STATE_LIGHT: return "Light"; + case THERMAL_STATE_MODERATE: return "Moderate"; + case THERMAL_STATE_SEVERE: return "Severe"; + case THERMAL_STATE_CRITICAL: return "Critical"; + case THERMAL_STATE_EMERGENCY: return "Emergency"; + case THERMAL_STATE_SHUTDOWN: return "Shutdown"; + default: return "Invalid"; + } +} + +void Main::update_thermal_state(ThermalState p_thermalState) { + DEV_ASSERT(p_thermalState >= THERMAL_STATE_MIN && p_thermalState < THERMAL_STATE_MAX); + const char* state_string = get_therrmal_state_string(p_thermalState); + OS::get_singleton()->print("Thermal state changed : %s (%d)", state_string, p_thermalState); + + if ( p_thermalState > THERMAL_STATE_MODERATE ){ + const String error_msg = "Thermal state is " + String(state_string); + OS::get_singleton()->alert(error_msg ); + } + thermal_state = p_thermalState; +} + +Main::ThermalState Main::get_thermal_state() { + return thermal_state; +} + +float Main::get_thermal_headroom( int p_forecast_seconds ) { + +#if defined(ANDROID_ENABLED) + float GodotGetThermalHeadroom(int); + return GodotGetThermalHeadroom( p_forecast_seconds ); +#else + return -1.0f; +#endif + +} + + +// diff --git a/main/main.h b/main/main.h index 09cc0feae6ff..217088d8ffdf 100644 --- a/main/main.h +++ b/main/main.h @@ -69,6 +69,31 @@ class Main { static const Vector &get_forwardable_cli_arguments(CLIScope p_scope); #endif + // + // @ShadyTF : Thermal state support + enum ThermalState + { + THERMAL_STATE_MIN = -2, + THERMAL_STATE_NOT_SUPPORTED = -2, // Current platform/device/build doesn't support ThermalState queries + THERMAL_STATE_ERROR = -1, // error aqcuiring thermal state + + + THERMAL_STATE_NONE = 0, // no state (perhaps device doesn't support it) + THERMAL_STATE_LIGHT = 1, // iOS Nominal + THERMAL_STATE_MODERATE = 2, // iOS Fair + THERMAL_STATE_SEVERE = 3, // iOS Serious + THERMAL_STATE_CRITICAL = 4, // iOS Critical + THERMAL_STATE_EMERGENCY = 5, + THERMAL_STATE_SHUTDOWN = 6, + + THERMAL_STATE_MAX, + }; + static ThermalState thermal_state; + static const char* get_therrmal_state_string(ThermalState p_thermalState); + static void update_thermal_state(ThermalState p_thermalState); + static ThermalState get_thermal_state(); + static float get_thermal_headroom( int p_forecast_seconds ); + // static int test_entrypoint(int argc, char *argv[], bool &tests_need_run); static Error setup(const char *execpath, int argc, char *argv[], bool p_second_phase = true); static Error setup2(); // The thread calling setup2() will effectively become the main thread. diff --git a/modules/glslang/SCsub b/modules/glslang/SCsub index 3068377e60ab..45cc8c2f3fc0 100644 --- a/modules/glslang/SCsub +++ b/modules/glslang/SCsub @@ -1,10 +1,22 @@ #!/usr/bin/env python +import glob +import os Import("env") Import("env_modules") env_glslang = env_modules.Clone() +def get_cpp_files(directory): + print(os.getcwd()) + ret = [] + + for file in os.listdir("../../thirdparty/glslang/" + directory): + filename = os.fsdecode(file) + if filename.endswith(".cpp"): + ret += [filename] + return ret + # Thirdparty source files thirdparty_obj = [] @@ -52,6 +64,9 @@ if env["builtin_glslang"]: "SPIRV/SpvPostProcess.cpp", "SPIRV/SPVRemapper.cpp", "SPIRV/SpvTools.cpp", + "External/spirv-tools/source/util/string_utils.cpp", + "External/spirv-tools/source/util/bit_vector.cpp", + "External/spirv-tools/source/util/parse_number.cpp", ] if env["platform"] == "windows": @@ -59,21 +74,38 @@ if env["builtin_glslang"]: else: thirdparty_sources.append("glslang/OSDependent/Unix/ossource.cpp") + opt_files = [thirdparty_dir + "External/spirv-tools/source/opt/" + file for file in get_cpp_files("External/spirv-tools/source/opt/")] + val_files = [thirdparty_dir + "External/spirv-tools/source/val/" + file for file in get_cpp_files("External/spirv-tools/source/val/")] + source_files = [thirdparty_dir + "External/spirv-tools/source/" + file for file in get_cpp_files("External/spirv-tools/source/")] + thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] + thirdparty_sources += opt_files + thirdparty_sources += val_files + thirdparty_sources += source_files # Treat glslang headers as system headers to avoid raising warnings. Not supported on MSVC. # Include `#thirdparty` to workaround mismatch between location of `SPIRV` in library source # and in installed public headers. if not env.msvc: env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir("#thirdparty").path]) + env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir("#thirdparty/glslang/External/spirv-tools").path]) + env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir("#thirdparty/glslang/SPIRV-Headers/spirv/unified1").path]) + env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir("#thirdparty/glslang/SPIRV-Headers/").path]) + env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir("#thirdparty/glslang/External/spirv-tools/include").path]) else: env_glslang.Prepend(CPPPATH=[thirdparty_dir, "#thirdparty"]) + env_glslang.Prepend(CPPPATH=[thirdparty_dir, "#thirdparty/glslang/External/spirv-tools"]) + env_glslang.Prepend(CPPPATH=[thirdparty_dir, "#thirdparty/glslang/SPIRV-Headers/spirv/unified1"]) + env_glslang.Prepend(CPPPATH=[thirdparty_dir, "#thirdparty/glslang/SPIRV-Headers/"]) + env_glslang.Prepend(CPPPATH=[thirdparty_dir, "#thirdparty/glslang/External/spirv-tools/include"]) - env_glslang.Append(CPPDEFINES=["ENABLE_OPT=0"]) + env_glslang.Append(CPPDEFINES=["ENABLE_OPT=1"]) env_thirdparty = env_glslang.Clone() env_thirdparty.disable_warnings() env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) + env_thirdparty.Append(CPPDEFINES=["ENABLE_OPT=1"]) + env.Append(CPPDEFINES=["ENABLE_OPT=1"]) env.modules_sources += thirdparty_obj diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp index 09ad1d67773b..14ae48c08c7b 100644 --- a/modules/glslang/register_types.cpp +++ b/modules/glslang/register_types.cpp @@ -31,12 +31,15 @@ #include "register_types.h" #include "core/config/engine.h" +#include "core/config/project_settings.h" #include "servers/rendering/rendering_device.h" #include #include #include #include +#include +#include static Vector _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error, const RenderingDevice *p_render_device) { const RDD::Capabilities &capabilities = p_render_device->get_device_capabilities(); @@ -166,13 +169,18 @@ static Vector _compile_shader_glsl(RenderingDevice::ShaderStage p_stage std::vector SpirV; spv::SpvBuildLogger logger; - glslang::SpvOptions spvOptions; + glslang::SpvOptions spvOptions; +#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED) if (Engine::get_singleton()->is_generate_spirv_debug_info_enabled()) { spvOptions.generateDebugInfo = true; spvOptions.emitNonSemanticShaderDebugInfo = true; spvOptions.emitNonSemanticShaderDebugSource = true; } +#endif + if (GLOBAL_GET("rendering/shader_compiler/shader_compilation/optimize")) { + spvOptions.disableOptimizer = false; + } glslang::GlslangToSpv(*program.getIntermediate(stages[p_stage]), SpirV, &logger, &spvOptions); @@ -180,6 +188,7 @@ static Vector _compile_shader_glsl(RenderingDevice::ShaderStage p_stage { uint8_t *w = ret.ptrw(); memcpy(w, &SpirV[0], SpirV.size() * sizeof(uint32_t)); + char buffer[256]; } return ret; diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 5d22cb1301c3..558a62825ca6 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -707,7 +707,7 @@ void LightmapperRD::_raster_geometry(RenderingDevice *rd, Size2i atlas_size, int raster_push_constant.uv_offset[0] = -0.5f / float(atlas_size.x); raster_push_constant.uv_offset[1] = -0.5f / float(atlas_size.y); - RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors); + RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors, RDD::BreadcrumbMarker::LIGHTMAPPER_PASS); //draw opaque rd->draw_list_bind_render_pipeline(draw_list, raster_pipeline); rd->draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0); @@ -1909,7 +1909,8 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d seams_push_constant.slice = uint32_t(i * subslices + k); seams_push_constant.debug = debug; - RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors); + // Store the current subslice in the breadcrumb + RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors, RDD::BreadcrumbMarker::LIGHTMAPPER_PASS); rd->draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0); rd->draw_list_bind_uniform_set(draw_list, blendseams_raster_uniform, 1); diff --git a/platform/android/detect.py b/platform/android/detect.py index fea8ec3287c7..766850adb282 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -184,13 +184,16 @@ def configure(env: "SConsEnvironment"): if env["arch"] == "x86_32": # The NDK adds this if targeting API < 24, so we can drop it when Godot targets it at least env.Append(CCFLAGS=["-mstackrealign"]) + env.Append(LIBPATH=["../../thirdparty/swappy-frame-pacing/x86"]) elif env["arch"] == "arm32": env.Append(CCFLAGS="-march=armv7-a -mfloat-abi=softfp".split()) env.Append(CPPDEFINES=["__ARM_ARCH_7__", "__ARM_ARCH_7A__"]) env.Append(CPPDEFINES=["__ARM_NEON__"]) + env.Append(LIBPATH=["../../thirdparty/swappy-frame-pacing/armeabi-v7a"]) elif env["arch"] == "arm64": env.Append(CCFLAGS=["-mfix-cortex-a53-835769"]) env.Append(CPPDEFINES=["__ARM_ARCH_8A__"]) + env.Append(LIBPATH=["../../thirdparty/swappy-frame-pacing/arm64-v8a"]) # Link flags @@ -200,6 +203,8 @@ def configure(env: "SConsEnvironment"): env.Prepend(CPPPATH=["#platform/android"]) env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"]) env.Append(LIBS=["OpenSLES", "EGL", "android", "log", "z", "dl"]) + env.Append(LIBS=["swappy_static"]) + env.Append(LIBPATH=["java/editor/build/intermediates/stripped_native_libs/dev/out/lib/arm64-v8a"]) if env["vulkan"]: env.Append(CPPDEFINES=["VULKAN_ENABLED", "RD_ENABLED"]) diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 01ecbc7164e0..f9c427ba9b77 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -210,6 +210,14 @@ DisplayServer::ScreenOrientation DisplayServerAndroid::screen_get_orientation(in return (ScreenOrientation)orientation; } +int DisplayServerAndroid::screen_get_current_rotation(int p_screen) const { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_NULL_V(godot_io_java, SCREEN_LANDSCAPE); + + const int rotation = godot_io_java->get_current_screen_rotation(); + return rotation; +} + int DisplayServerAndroid::get_screen_count() const { return 1; } diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index c95eaddf93c6..d7fc842ac435 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -123,6 +123,7 @@ class DisplayServerAndroid : public DisplayServer { virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW) override; virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual int screen_get_current_rotation(int p_screen) const override; virtual int get_screen_count() const override; virtual int get_primary_screen() const override; diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt b/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt index e01c5481d518..b2dfe210233e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt @@ -40,6 +40,28 @@ import androidx.fragment.app.FragmentActivity import org.godotengine.godot.utils.PermissionsUtil import org.godotengine.godot.utils.ProcessPhoenix +// +// @ShadyTF : Thermal status support +import android.os.Build +import android.os.PowerManager +import androidx.annotation.RequiresApi + + + +class GodotThermalWrapper { + companion object { + public var power_manager: PowerManager? = null + @RequiresApi(Build.VERSION_CODES.R) + public fun getThermalHeadRoom(forecast: Int): Float { + if (Build.VERSION.SDK_INT >= 30) { + return power_manager!!.getThermalHeadroom(forecast); + } else { + return -1.0f; + } + } + } +} +// /** * Base abstract activity for Android apps intending to use Godot as the primary screen. * @@ -57,6 +79,13 @@ abstract class GodotActivity : FragmentActivity(), GodotHost { protected val EXTRA_NEW_LAUNCH = "new_launch_requested" } + // + // @ShadyTF : Thermal status support + private var thermalStatusMap: HashMap? = null + private val MOBILE_THERMAL_NOT_SUPPORTED = -2 + private val MOBILE_THERMAL_ERROR = -1 + private external fun nativeThermalEvent(nativeStatus: Int) + // /** * Interaction with the [Godot] object is delegated to the [GodotFragment] class. */ @@ -68,7 +97,39 @@ abstract class GodotActivity : FragmentActivity(), GodotHost { setContentView(R.layout.godot_app_layout) handleStartIntent(intent, true) + // + // @ShadyTF : Thermal status support + thermalStatusMap = java.util.HashMap() + + try { + if (Build.VERSION.SDK_INT >= 29) { + thermalStatusMap!![PowerManager.THERMAL_STATUS_NONE] = 0 // Main::ThermalState::THERMAL_STATE_NONE + thermalStatusMap!![PowerManager.THERMAL_STATUS_LIGHT] = 1 // Main::ThermalState::THERMAL_STATE_LIGHT + thermalStatusMap!![PowerManager.THERMAL_STATUS_MODERATE] = 2 // Main::ThermalState::THERMAL_STATE_MODERATE + thermalStatusMap!![PowerManager.THERMAL_STATUS_SEVERE] = 3 // Main::ThermalState::THERMAL_STATE_SEVERE + thermalStatusMap!![PowerManager.THERMAL_STATUS_CRITICAL] = 4 // Main::ThermalState::THERMAL_STATE_CRITICAL + thermalStatusMap!![PowerManager.THERMAL_STATUS_EMERGENCY] = 5 // Main::ThermalState::THERMAL_STATE_EMERGENCY + thermalStatusMap!![PowerManager.THERMAL_STATUS_SHUTDOWN] = 6 // Main::ThermalState::THERMAL_STATE_SHUTDOWN + } + } catch (e: Exception) { + Log.i(TAG, "Failed to populate mMobileThermalMap: " + e.message) + } + try { + if (Build.VERSION.SDK_INT >= 29) { + val pManager = applicationContext.getSystemService(POWER_SERVICE) as PowerManager + GodotThermalWrapper.Companion.power_manager = pManager; + pManager.addThermalStatusListener { status: Int -> + val nativeStatus = thermalStatusMap!![status] + nativeThermalEvent(nativeStatus ?: MOBILE_THERMAL_ERROR) + } + } else { + nativeThermalEvent(MOBILE_THERMAL_NOT_SUPPORTED) + } + } catch (e: java.lang.Exception) { + Log.i(TAG, "Failed to setup thermal status listener: " + e.message) + } + // val currentFragment = supportFragmentManager.findFragmentById(R.id.godot_fragment_container) if (currentFragment is GodotFragment) { Log.v(TAG, "Reusing existing Godot fragment instance.") diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index 4b51bd778d49..5d598a3b9da2 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -34,8 +34,10 @@ import android.app.Activity; import android.content.ActivityNotFoundException; +import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; import android.net.Uri; @@ -47,10 +49,15 @@ import android.util.Log; import android.view.Display; import android.view.DisplayCutout; +import android.view.Surface; import android.view.WindowInsets; +import android.view.WindowManager; +import androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; +import com.google.android.vending.expansion.downloader.Constants; + import java.io.File; import java.util.List; import java.util.Locale; @@ -287,6 +294,17 @@ public int getScreenOrientation() { } } + public int getCurrentScreenRotation() { + int rotation = ((WindowManager)ContextCompat.getSystemService(activity.getBaseContext(), WindowManager.class)).getDefaultDisplay().getRotation(); + + switch (rotation) { + case Surface.ROTATION_90: return 90; + case Surface.ROTATION_180: return 180; + case Surface.ROTATION_270: return 270; + default: return 0; + } + } + public void setEdit(GodotEditText _edit) { edit = _edit; } diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index 10716a5c79c8..ca9292277a38 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -65,6 +65,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc _hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V"); _set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V"); _get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I"); + _get_current_screen_rotation = p_env->GetMethodID(cls, "getCurrentScreenRotation", "()I"); _get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(IZ)Ljava/lang/String;"); } } @@ -249,6 +250,16 @@ int GodotIOJavaWrapper::get_screen_orientation() { } } +int GodotIOJavaWrapper::get_current_screen_rotation() { + if (_get_current_screen_rotation) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL_V(env, 0); + return env->CallIntMethod(godot_io_instance, _get_current_screen_rotation); + } else { + return 0; + } +} + String GodotIOJavaWrapper::get_system_dir(int p_dir, bool p_shared_storage) { if (_get_system_dir) { JNIEnv *env = get_jni_env(); diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index c113a13040d9..53623de0392b 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -60,6 +60,7 @@ class GodotIOJavaWrapper { jmethodID _hide_keyboard = 0; jmethodID _set_screen_orientation = 0; jmethodID _get_screen_orientation = 0; + jmethodID _get_current_screen_rotation = 0; jmethodID _get_system_dir = 0; public: @@ -86,6 +87,8 @@ class GodotIOJavaWrapper { void set_vk_height(int p_height); void set_screen_orientation(int p_orient); int get_screen_orientation(); + int get_current_screen_rotation(); + int get_native_screen_orientation(); String get_system_dir(int p_dir, bool p_shared_storage); }; diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 85d5cf279616..46eaebbea9d4 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -74,6 +74,49 @@ static Vector3 gravity; static Vector3 magnetometer; static Vector3 gyroscope; +// +// @ShadyTF : Thermal headroom support +jclass godot_thermal_wrapper_class = nullptr; +JNIEnv* godot_thermal_env = nullptr; +jmethodID godot_thermal_wrapper_thermal_headroom_methodid = nullptr; +jobject godot_thermal_wrapper_obj = nullptr; + +void GodotGetThermalHeadroom_initialize(JNIEnv *env) { + godot_thermal_env = env; + // Find the class + godot_thermal_wrapper_class = env->FindClass( "org/godotengine/godot/GodotThermalWrapper$Companion"); + if (godot_thermal_wrapper_class == nullptr) { + return; + } + // Find the method + godot_thermal_wrapper_thermal_headroom_methodid = env->GetMethodID(godot_thermal_wrapper_class, + "getThermalHeadRoom", "(I)F"); + godot_thermal_wrapper_obj = godot_thermal_env->AllocObject(godot_thermal_wrapper_class); +} + +void GodotGetThermalHeadroom_cleanup(JNIEnv *env) { + if ( godot_thermal_wrapper_obj ) { + godot_thermal_env->DeleteLocalRef(godot_thermal_wrapper_obj); + } +} + + +float GodotGetThermalHeadroom(int forecastSeconds) { + if (godot_thermal_wrapper_class == nullptr) { + return 0.0f; + } + if (godot_thermal_wrapper_thermal_headroom_methodid == nullptr) { + return 0.0f; + } + + // Call the method + jfloat result = godot_thermal_env->CallFloatMethod(godot_thermal_wrapper_obj, godot_thermal_wrapper_thermal_headroom_methodid, forecastSeconds); + return result; +} + +// + + static void _terminate(JNIEnv *env, bool p_restart = false) { step.set(-1); // Ensure no further steps are attempted and no further events are sent @@ -84,6 +127,11 @@ static void _terminate(JNIEnv *env, bool p_restart = false) { if (input_handler) { delete input_handler; } + // + // @ShadyTF : Thermal headroom support + GodotGetThermalHeadroom_cleanup( env ); + // + // Whether restarting is handled by 'Main::cleanup()' bool restart_on_cleanup = false; if (os_android) { @@ -145,6 +193,11 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline, jobject p_godot_tts) { setup_android_thread(); + // + // @ShadyTF : Thermal headroom support + GodotGetThermalHeadroom_initialize(env); + // + const char **cmdline = nullptr; jstring *j_cmdline = nullptr; int cmdlen = 0; @@ -527,3 +580,15 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererPaused(JNIE } } } + + +// +// @ShadyTF : Thermal state support +extern "C" +JNIEXPORT void JNICALL +Java_org_godotengine_godot_GodotActivity_nativeThermalEvent(JNIEnv *env, jobject thiz, + jint native_state) { + const Main::ThermalState thermal_state = (Main::ThermalState)native_state; + Main::update_thermal_state( thermal_state ); +} +// diff --git a/platform/android/rendering_context_driver_vulkan_android.cpp b/platform/android/rendering_context_driver_vulkan_android.cpp index 9232126b0475..a306a121f88c 100644 --- a/platform/android/rendering_context_driver_vulkan_android.cpp +++ b/platform/android/rendering_context_driver_vulkan_android.cpp @@ -50,7 +50,7 @@ RenderingContextDriver::SurfaceID RenderingContextDriverVulkanAndroid::surface_c create_info.window = wpd->window; VkSurfaceKHR vk_surface = VK_NULL_HANDLE; - VkResult err = vkCreateAndroidSurfaceKHR(instance_get(), &create_info, nullptr, &vk_surface); + VkResult err = vkCreateAndroidSurfaceKHR(instance_get(), &create_info, get_allocation_callbacks(VK_OBJECT_TYPE_SURFACE_KHR), &vk_surface); ERR_FAIL_COND_V(err != VK_SUCCESS, SurfaceID()); Surface *surface = memnew(Surface); diff --git a/platform/ios/rendering_context_driver_vulkan_ios.mm b/platform/ios/rendering_context_driver_vulkan_ios.mm index 6a6af1bc4191..8747bfd76abd 100644 --- a/platform/ios/rendering_context_driver_vulkan_ios.mm +++ b/platform/ios/rendering_context_driver_vulkan_ios.mm @@ -50,7 +50,7 @@ create_info.pLayer = *wpd->layer_ptr; VkSurfaceKHR vk_surface = VK_NULL_HANDLE; - VkResult err = vkCreateMetalSurfaceEXT(instance_get(), &create_info, nullptr, &vk_surface); + VkResult err = vkCreateMetalSurfaceEXT(instance_get(), &create_info, get_allocation_callbacks(VK_OBJECT_TYPE_SURFACE_KHR), &vk_surface); ERR_FAIL_COND_V(err != VK_SUCCESS, SurfaceID()); Surface *surface = memnew(Surface); diff --git a/platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp b/platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp index bf44062266d9..3f505d000c22 100644 --- a/platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp +++ b/platform/linuxbsd/x11/rendering_context_driver_vulkan_x11.cpp @@ -51,7 +51,7 @@ RenderingContextDriver::SurfaceID RenderingContextDriverVulkanX11::surface_creat create_info.window = wpd->window; VkSurfaceKHR vk_surface = VK_NULL_HANDLE; - VkResult err = vkCreateXlibSurfaceKHR(instance_get(), &create_info, nullptr, &vk_surface); + VkResult err = vkCreateXlibSurfaceKHR(instance_get(), &create_info, get_allocation_callbacks(VK_OBJECT_TYPE_SURFACE_KHR), &vk_surface); ERR_FAIL_COND_V(err != VK_SUCCESS, SurfaceID()); Surface *surface = memnew(Surface); diff --git a/platform/windows/rendering_context_driver_vulkan_windows.cpp b/platform/windows/rendering_context_driver_vulkan_windows.cpp index f968ffc1d785..445388af89fe 100644 --- a/platform/windows/rendering_context_driver_vulkan_windows.cpp +++ b/platform/windows/rendering_context_driver_vulkan_windows.cpp @@ -64,7 +64,7 @@ RenderingContextDriver::SurfaceID RenderingContextDriverVulkanWindows::surface_c create_info.hwnd = wpd->window; VkSurfaceKHR vk_surface = VK_NULL_HANDLE; - VkResult err = vkCreateWin32SurfaceKHR(instance_get(), &create_info, nullptr, &vk_surface); + VkResult err = vkCreateWin32SurfaceKHR(instance_get(), &create_info, get_allocation_callbacks(VK_OBJECT_TYPE_SURFACE_KHR), &vk_surface); ERR_FAIL_COND_V(err != VK_SUCCESS, SurfaceID()); Surface *surface = memnew(Surface); diff --git a/servers/display_server.h b/servers/display_server.h index 0f6c43ebe03f..2c4abc15314b 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -333,6 +333,7 @@ class DisplayServer : public Object { virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW); virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual int screen_get_current_rotation(int p_screen = SCREEN_OF_MAIN_WINDOW) const { return 0; } virtual void screen_set_keep_on(bool p_enable); //disable screensaver virtual bool screen_is_kept_on() const; @@ -342,6 +343,11 @@ class DisplayServer : public Object { INVALID_INDICATOR_ID = -1 }; +private: + ScreenOrientation native_orientation = ScreenOrientation::SCREEN_LANDSCAPE; + +public: + typedef int WindowID; typedef int IndicatorID; diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h index 1331ca72c251..4fe9aef41ae6 100644 --- a/servers/rendering/dummy/storage/texture_storage.h +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -180,6 +180,7 @@ class TextureStorage : public RendererTextureStorage { virtual void render_target_do_msaa_resolve(RID p_render_target) override {} virtual void render_target_set_use_hdr(RID p_render_target, bool p_use_hdr_2d) override {} virtual bool render_target_is_using_hdr(RID p_render_target) const override { return false; } + virtual int64_t render_target_get_format(RID p_render_target) const override { return 0; } virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override {} virtual bool render_target_is_clear_requested(RID p_render_target) override { return false; } diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index fd6409d6bf18..824cbbbfb665 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -47,6 +47,17 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { singleton = this; prefer_raster_effects = p_prefer_raster_effects; + uint32_t RID_size = sizeof(RID) * RD::get_singleton()->get_frame_delay(); + copy_to_fb.params_uniform_buffer = (RID *)memalloc(RID_size); + copy_to_fb.params_uniform_set = (RID *)memalloc(RID_size); + memset(copy_to_fb.params_uniform_buffer, 0, RID_size); + memset(copy_to_fb.params_uniform_set, 0, RID_size); + + copy.params_uniform_buffer = (RID *)memalloc(RID_size); + copy.params_uniform_set = (RID *)memalloc(RID_size); + memset(copy.params_uniform_buffer, 0, RID_size); + memset(copy.params_uniform_set, 0, RID_size); + if (prefer_raster_effects) { // init blur shader (on compute use copy shader) @@ -73,6 +84,23 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { } } +// +// @ShadyTF +// replace push constants with UBO +// prepare uniform set and buffer + { + uint32_t params_size = sizeof(BlurRasterPushConstant); + blur_raster.params_uniform_buffer = RD::RenderingDevice::get_singleton()->uniform_buffer_create(params_size); + Vector params_uniforms; + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(blur_raster.params_uniform_buffer); + params_uniforms.push_back(u); + blur_raster.params_uniform_set = RD::RenderingDevice::get_singleton()->uniform_set_create(params_uniforms, blur_raster.shader.version_get_shader(blur_raster.shader_version, 0), 4); + } +// + { Vector copy_modes; copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); @@ -90,8 +118,6 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { copy_modes.push_back("\n#define MODE_CUBEMAP_ARRAY_TO_PANORAMA\n"); copy.shader.initialize(copy_modes); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - copy.shader_version = copy.shader.version_create(); for (int i = 0; i < COPY_MODE_MAX; i++) { @@ -99,6 +125,15 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { copy.pipelines[i] = RD::get_singleton()->compute_pipeline_create(copy.shader.version_get_shader(copy.shader_version, i)); } } + + // + // @ShadyTF + // replace push constants with UBO + // prepare uniform set and buffer + for (uint32_t i = 0; i < RD::get_singleton()->get_frame_delay(); i++) { + copy.params_uniform_buffer[i] = RD::get_singleton()->uniform_buffer_create(sizeof(CopyPushConstant), Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT | RD::BUFFER_CREATION_LINEAR_BIT); + } + // } { @@ -128,6 +163,16 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { copy_to_fb.pipelines[i].clear(); } } + + // + // @ShadyTF + // replace push constants with UBO + // prepare uniform set and buffer + for (uint32_t i = 0; i < RD::get_singleton()->get_frame_delay(); i++) { + uint32_t params_size = sizeof(CopyToFbPushConstant); + copy_to_fb.params_uniform_buffer[i] = RD::RenderingDevice::get_singleton()->uniform_buffer_create(params_size, Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT | RD::BUFFER_CREATION_LINEAR_BIT); + } + // } { @@ -144,6 +189,20 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS; dss.enable_depth_write = true; cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0); + +// +// @ShadyTF +// prepare uniform set and buffer + uint32_t params_size = sizeof(CopyToDPPushConstant); + cube_to_dp.params_uniform_buffer = RD::RenderingDevice::get_singleton()->uniform_buffer_create( params_size ); + Vector params_uniforms; + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(cube_to_dp.params_uniform_buffer); + params_uniforms.push_back(u); + cube_to_dp.params_uniform_set = RD::RenderingDevice::get_singleton()->uniform_set_create(params_uniforms, cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0), 4); +// } { @@ -307,6 +366,16 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { CopyEffects::~CopyEffects() { if (prefer_raster_effects) { +// +// @ShadyTF +// replace push constants with UBO + if (blur_raster.params_uniform_buffer.is_valid()) { + RD::RenderingDevice::get_singleton()->free(blur_raster.params_uniform_buffer); + } + if (blur_raster.params_uniform_set.is_valid()) { + RD::RenderingDevice::get_singleton()->free(blur_raster.params_uniform_set); + } +// blur_raster.shader.version_free(blur_raster.shader_version); cubemap_downsampler.raster_shader.version_free(cubemap_downsampler.shader_version); filter.raster_shader.version_free(filter.shader_version); @@ -333,38 +402,100 @@ CopyEffects::~CopyEffects() { copy_to_fb.shader.version_free(copy_to_fb.shader_version); cube_to_dp.shader.version_free(cube_to_dp.shader_version); +// +// @ShadyTF +// replace push constants with UBO + if (cube_to_dp.params_uniform_set.is_valid()) { + RD::RenderingDevice::get_singleton()->free(cube_to_dp.params_uniform_set); + } + if (cube_to_dp.params_uniform_buffer.is_valid()) { + RD::RenderingDevice::get_singleton()->free(cube_to_dp.params_uniform_buffer); + } +// + + for (uint32_t i = 0; i < RD::get_singleton()->get_frame_delay(); i++) { + if (copy.params_uniform_buffer[i].is_valid()) + RD::get_singleton()->free(copy.params_uniform_buffer[i]); + if (copy.params_uniform_set[i].is_valid()) + RD::get_singleton()->free(copy.params_uniform_set[i]); + + if (copy_to_fb.params_uniform_buffer[i].is_valid()) + RD::get_singleton()->free(copy_to_fb.params_uniform_buffer[i]); + if (copy_to_fb.params_uniform_set[i].is_valid()) + RD::get_singleton()->free(copy_to_fb.params_uniform_set[i]); + } + + memfree(copy_to_fb.params_uniform_buffer); + memfree(copy_to_fb.params_uniform_set); + memfree(copy.params_uniform_buffer); + memfree(copy.params_uniform_set); + singleton = nullptr; } +void CopyEffects::_update_copy_to_fb_uniform_set(const CopyToFbPushConstant* p_buffer) { + uint32_t frame = RD::get_singleton()->get_current_frame_index(); + RD::get_singleton()->buffer_update(copy_to_fb.params_uniform_buffer[frame], 0, sizeof(CopyToFbPushConstant), p_buffer); + { + Vector params_uniforms; + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(copy_to_fb.params_uniform_buffer[frame]); + params_uniforms.push_back(u); + + if (copy_to_fb.params_uniform_set[frame].is_valid()) + RD::get_singleton()->free(copy_to_fb.params_uniform_set[frame]); + copy_to_fb.params_uniform_set[frame] = RD::RenderingDevice::get_singleton()->uniform_set_create(params_uniforms, copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, 0), 4, true); + } +} + +void CopyEffects::_update_copy_uniform_set(const CopyPushConstant* p_buffer) { + uint32_t frame = RD::get_singleton()->get_current_frame_index(); + RD::get_singleton()->buffer_update(copy.params_uniform_buffer[frame], 0, sizeof(CopyPushConstant), p_buffer); + { + Vector params_uniforms; + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(copy.params_uniform_buffer[frame]); + params_uniforms.push_back(u); + + if (copy.params_uniform_set[frame].is_valid()) + RD::get_singleton()->free(copy.params_uniform_set[frame]); + copy.params_uniform_set[frame] = RD::RenderingDevice::get_singleton()->uniform_set_create(params_uniforms, copy.shader.version_get_shader(copy.shader_version, 0), 4, true); + } +} + void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); + CopyPushConstant push_constant = {}; if (p_flip_y) { - copy.push_constant.flags |= COPY_FLAG_FLIP_Y; + push_constant.flags |= COPY_FLAG_FLIP_Y; } if (p_force_luminance) { - copy.push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE; + push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE; } if (p_all_source) { - copy.push_constant.flags |= COPY_FLAG_ALL_SOURCE; + push_constant.flags |= COPY_FLAG_ALL_SOURCE; } if (p_alpha_to_one) { - copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE; + push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE; } - copy.push_constant.section[0] = p_rect.position.x; - copy.push_constant.section[1] = p_rect.position.y; - copy.push_constant.section[2] = p_rect.size.width; - copy.push_constant.section[3] = p_rect.size.height; - copy.push_constant.target[0] = p_rect.position.x; - copy.push_constant.target[1] = p_rect.position.y; + push_constant.section[0] = p_rect.position.x; + push_constant.section[1] = p_rect.position.y; + push_constant.section[2] = p_rect.size.width; + push_constant.section[3] = p_rect.size.height; + push_constant.target[0] = p_rect.position.x; + push_constant.target[1] = p_rect.position.y; // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -376,11 +507,14 @@ void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, cons RID shader = copy.shader.version_get_shader(copy.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + // Update buffer and uniform set + _update_copy_uniform_set(&push_constant); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, copy.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -391,15 +525,15 @@ void CopyEffects::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panoram MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); + CopyPushConstant push_constant = {}; - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_panorama_size.width; - copy.push_constant.section[3] = p_panorama_size.height; - copy.push_constant.target[0] = 0; - copy.push_constant.target[1] = 0; - copy.push_constant.camera_z_far = p_lod; + push_constant.section[0] = 0; + push_constant.section[1] = 0; + push_constant.section[2] = p_panorama_size.width; + push_constant.section[3] = p_panorama_size.height; + push_constant.target[0] = 0; + push_constant.target[1] = 0; + push_constant.camera_z_far = p_lod; // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -411,11 +545,14 @@ void CopyEffects::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panoram RID shader = copy.shader.version_get_shader(copy.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + // Update buffer and uniform set + _update_copy_uniform_set(&push_constant); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_cube), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_panorama), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, copy.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_panorama_size.width, p_panorama_size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -426,17 +563,17 @@ void CopyEffects::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); + CopyPushConstant push_constant = {}; if (p_flip_y) { - copy.push_constant.flags |= COPY_FLAG_FLIP_Y; + push_constant.flags |= COPY_FLAG_FLIP_Y; } - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_rect.size.width; - copy.push_constant.section[3] = p_rect.size.height; - copy.push_constant.target[0] = p_rect.position.x; - copy.push_constant.target[1] = p_rect.position.y; + push_constant.section[0] = 0; + push_constant.section[1] = 0; + push_constant.section[2] = p_rect.size.width; + push_constant.section[3] = p_rect.size.height; + push_constant.target[0] = p_rect.position.x; + push_constant.target[1] = p_rect.position.y; // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -448,11 +585,14 @@ void CopyEffects::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture RID shader = copy.shader.version_get_shader(copy.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + // Update buffer and uniform set + _update_copy_uniform_set(&push_constant); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, copy.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -463,19 +603,20 @@ void CopyEffects::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); + CopyPushConstant push_constant = {}; + if (p_flip_y) { - copy.push_constant.flags |= COPY_FLAG_FLIP_Y; + push_constant.flags |= COPY_FLAG_FLIP_Y; } - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_rect.size.width; - copy.push_constant.section[3] = p_rect.size.height; - copy.push_constant.target[0] = p_rect.position.x; - copy.push_constant.target[1] = p_rect.position.y; - copy.push_constant.camera_z_far = p_z_far; - copy.push_constant.camera_z_near = p_z_near; + push_constant.section[0] = 0; + push_constant.section[1] = 0; + push_constant.section[2] = p_rect.size.width; + push_constant.section[3] = p_rect.size.height; + push_constant.target[0] = p_rect.position.x; + push_constant.target[1] = p_rect.position.y; + push_constant.camera_z_far = p_z_far; + push_constant.camera_z_near = p_z_near; // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -487,11 +628,14 @@ void CopyEffects::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID RID shader = copy.shader.version_get_shader(copy.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + // Update buffer and uniform set + _update_copy_uniform_set(&push_constant); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, copy.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -502,19 +646,19 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); + CopyToFbPushConstant push_constant = {}; - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SECTION; - copy_to_fb.push_constant.section[0] = p_uv_rect.position.x; - copy_to_fb.push_constant.section[1] = p_uv_rect.position.y; - copy_to_fb.push_constant.section[2] = p_uv_rect.size.x; - copy_to_fb.push_constant.section[3] = p_uv_rect.size.y; + push_constant.flags |= COPY_TO_FB_FLAG_USE_SECTION; + push_constant.section[0] = p_uv_rect.position.x; + push_constant.section[1] = p_uv_rect.position.y; + push_constant.section[2] = p_uv_rect.size.x; + push_constant.section[3] = p_uv_rect.size.y; if (p_flip_y) { - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y; + push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y; } - copy_to_fb.push_constant.luminance_multiplier = 1.0; + push_constant.luminance_multiplier = 1.0; // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -525,11 +669,13 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + _update_copy_to_fb_uniform_set(&push_constant); + RD::DrawListID draw_list = p_draw_list; RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, copy_to_fb.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); - RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); } @@ -539,33 +685,33 @@ void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffe MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); - copy_to_fb.push_constant.luminance_multiplier = 1.0; + CopyToFbPushConstant push_constant = {}; + push_constant.luminance_multiplier = 1.0; if (p_flip_y) { - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y; + push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y; } if (p_force_luminance) { - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FORCE_LUMINANCE; + push_constant.flags |= COPY_TO_FB_FLAG_FORCE_LUMINANCE; } if (p_alpha_to_zero) { - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ZERO; + push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ZERO; } if (p_srgb) { - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_SRGB; + push_constant.flags |= COPY_TO_FB_FLAG_SRGB; } if (p_alpha_to_one) { - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ONE; + push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ONE; } if (p_linear) { // Used for copying to a linear buffer. In the mobile renderer we divide the contents of the linear buffer // to allow for a wider effective range. - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR; - copy_to_fb.push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0; + push_constant.flags |= COPY_TO_FB_FLAG_LINEAR; + push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0; } if (p_normal) { - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_NORMAL; + push_constant.flags |= COPY_TO_FB_FLAG_NORMAL; } // setup our uniforms @@ -583,6 +729,8 @@ void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffe RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + _update_copy_to_fb_uniform_set(&push_constant); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector(), 1.0, 0, p_rect); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); @@ -591,8 +739,8 @@ void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffe RD::Uniform u_secondary(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector({ default_sampler, p_secondary })); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_secondary), 1); } + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, copy_to_fb.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); - RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); } @@ -603,14 +751,14 @@ void CopyEffects::copy_to_drawlist(RD::DrawListID p_draw_list, RD::FramebufferFo MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); - copy_to_fb.push_constant.luminance_multiplier = 1.0; + CopyToFbPushConstant push_constant = {}; + push_constant.luminance_multiplier = 1.0; if (p_linear) { // Used for copying to a linear buffer. In the mobile renderer we divide the contents of the linear buffer // to allow for a wider effective range. - copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR; - copy_to_fb.push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0; + push_constant.flags |= COPY_TO_FB_FLAG_LINEAR; + push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0; } // setup our uniforms @@ -624,10 +772,12 @@ void CopyEffects::copy_to_drawlist(RD::DrawListID p_draw_list, RD::FramebufferFo RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + _update_copy_to_fb_uniform_set(&push_constant); + RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, p_fb_format)); RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, copy_to_fb.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->draw_list_bind_index_array(p_draw_list, material_storage->get_quad_index_array()); - RD::get_singleton()->draw_list_set_push_constant(p_draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); RD::get_singleton()->draw_list_draw(p_draw_list, true); } @@ -640,6 +790,11 @@ void CopyEffects::copy_raster(RID p_source_texture, RID p_dest_framebuffer) { ERR_FAIL_NULL(material_storage); memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); +// +// @ShadyTF +// replace push constants with UBO + RD::RenderingDevice::get_singleton()->buffer_update(blur_raster.params_uniform_buffer, 0, sizeof(BlurRasterPushConstant), &blur_raster.push_constant); +// // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -654,7 +809,13 @@ void CopyEffects::copy_raster(RID p_source_texture, RID p_dest_framebuffer) { RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[BLUR_MODE_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); +// +// @ShadyTF +// replace push constants with UBO +// Was: +// RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, blur_raster.params_uniform_set, 4); +// RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); @@ -668,14 +829,14 @@ void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Re MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); + CopyPushConstant push_constant = {}; - copy.push_constant.section[0] = p_region.position.x; - copy.push_constant.section[1] = p_region.position.y; - copy.push_constant.target[0] = p_region.position.x; - copy.push_constant.target[1] = p_region.position.y; - copy.push_constant.section[2] = p_size.width; - copy.push_constant.section[3] = p_size.height; + push_constant.section[0] = p_region.position.x; + push_constant.section[1] = p_region.position.y; + push_constant.target[0] = p_region.position.x; + push_constant.target[1] = p_region.position.y; + push_constant.section[2] = p_size.width; + push_constant.section[3] = p_size.height; // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -687,12 +848,14 @@ void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Re RID shader = copy.shader.version_get_shader(copy.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + // Update buffer and uniform set + _update_copy_uniform_set(&push_constant); + RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_texture), 3); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, copy.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); @@ -716,6 +879,12 @@ void CopyEffects::gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_textu blur_raster.push_constant.pixel_size[0] = 1.0 / float(p_size.x); blur_raster.push_constant.pixel_size[1] = 1.0 / float(p_size.y); +// +// @ShadyTF +// replace push constants with UBO + RD::RenderingDevice::get_singleton()->buffer_update(blur_raster.params_uniform_buffer, 0, sizeof(BlurRasterPushConstant), &blur_raster.push_constant); +// + // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -728,7 +897,14 @@ void CopyEffects::gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_textu RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); +// +// @ShadyTF +// replace push constants with UBO +// Was: +// RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, blur_raster.params_uniform_set, 4); +// + RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u); RD::get_singleton()->draw_list_end(); @@ -742,23 +918,24 @@ void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, con MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); + CopyPushConstant push_constant = {}; CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; uint32_t base_flags = 0; - copy.push_constant.section[2] = p_size.x; - copy.push_constant.section[3] = p_size.y; + push_constant.section[2] = p_size.x; + push_constant.section[3] = p_size.y; - copy.push_constant.glow_strength = p_strength; - copy.push_constant.glow_bloom = p_bloom; - copy.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold; - copy.push_constant.glow_hdr_scale = p_hdr_bleed_scale; - copy.push_constant.glow_exposure = p_exposure; - copy.push_constant.glow_white = 0; //actually unused - copy.push_constant.glow_luminance_cap = p_luminance_cap; + push_constant.glow_strength = p_strength; + push_constant.glow_bloom = p_bloom; + push_constant.glow_hdr_threshold = p_hdr_bleed_threshold; + push_constant.glow_hdr_scale = p_hdr_bleed_scale; + push_constant.glow_exposure = p_exposure; + push_constant.glow_white = 0; //actually unused + push_constant.glow_luminance_cap = p_luminance_cap; - copy.push_constant.glow_auto_exposure_scale = p_auto_exposure_scale; //unused also + push_constant.glow_auto_exposure_scale = p_auto_exposure_scale; //unused also + push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0); // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -769,6 +946,9 @@ void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, con RID shader = copy.shader.version_get_shader(copy.shader_version, copy_mode); ERR_FAIL_COND(shader.is_null()); + // Update buffer and uniform set + _update_copy_uniform_set(&push_constant); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); @@ -777,10 +957,7 @@ void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, con RD::Uniform u_auto_exposure(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector({ default_sampler, p_auto_exposure })); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_auto_exposure), 1); } - - copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, copy.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -826,6 +1003,12 @@ void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_textu ERR_FAIL_COND(shader.is_null()); //HORIZONTAL +// +// @ShadyTF +// replace push constants with UBO + blur_raster.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0); + RD::RenderingDevice::get_singleton()->buffer_update(blur_raster.params_uniform_buffer, 0, sizeof(BlurRasterPushConstant), &blur_raster.push_constant); +// RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(half_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(half_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); @@ -833,10 +1016,14 @@ void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_textu RD::Uniform u_auto_exposure(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector({ default_sampler, p_auto_exposure })); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_auto_exposure), 1); } - - blur_raster.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); - +// +// @ShadyTF +// replace push constants with UBO +// was: +//blur_raster.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0); +//RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, blur_raster.params_uniform_set, 4); +// RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u); RD::get_singleton()->draw_list_end(); @@ -846,13 +1033,23 @@ void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_textu ERR_FAIL_COND(shader.is_null()); //VERTICAL +// +// @ShadyTF +// replace push constants with UBO + blur_raster.push_constant.flags = base_flags; + RD::RenderingDevice::get_singleton()->buffer_update(blur_raster.params_uniform_buffer, 0, sizeof(BlurRasterPushConstant), &blur_raster.push_constant); +// draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_half_texture), 0); - - blur_raster.push_constant.flags = base_flags; - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); - +// +// @ShadyTF +// replace push constants with UBO +// Was: + //blur_raster.push_constant.flags = base_flags; + //RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, blur_raster.params_uniform_set, 4); +// RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u); RD::get_singleton()->draw_list_end(); } @@ -865,12 +1062,12 @@ void CopyEffects::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); + CopyPushConstant push_constant = {}; - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_size.width; - copy.push_constant.section[3] = p_size.height; + push_constant.section[0] = 0; + push_constant.section[1] = 0; + push_constant.section[2] = p_size.width; + push_constant.section[3] = p_size.height; // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -882,11 +1079,14 @@ void CopyEffects::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const RID shader = copy.shader.version_get_shader(copy.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + // Update buffer and uniform set + _update_copy_uniform_set(&push_constant); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, copy.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -920,7 +1120,14 @@ void CopyEffects::make_mipmap_raster(RID p_source_rd_texture, RID p_dest_texture RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + // + // @ShadyTF + // replace push constants with UBO + // Was: + // RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, blur_raster.params_uniform_set, 4); + // RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); @@ -932,18 +1139,18 @@ void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); + CopyPushConstant push_constant = {}; - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_region.size.width; - copy.push_constant.section[3] = p_region.size.height; - copy.push_constant.target[0] = p_region.position.x; - copy.push_constant.target[1] = p_region.position.y; - copy.push_constant.set_color[0] = p_color.r; - copy.push_constant.set_color[1] = p_color.g; - copy.push_constant.set_color[2] = p_color.b; - copy.push_constant.set_color[3] = p_color.a; + push_constant.section[0] = 0; + push_constant.section[1] = 0; + push_constant.section[2] = p_region.size.width; + push_constant.section[3] = p_region.size.height; + push_constant.target[0] = p_region.position.x; + push_constant.target[1] = p_region.position.y; + push_constant.set_color[0] = p_color.r; + push_constant.set_color[1] = p_color.g; + push_constant.set_color[2] = p_color.b; + push_constant.set_color[3] = p_color.a; // setup our uniforms RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture); @@ -952,10 +1159,13 @@ void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect RID shader = copy.shader.version_get_shader(copy.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + // Update buffer and uniform set + _update_copy_uniform_set(&push_constant); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, copy.params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -968,12 +1178,12 @@ void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, con MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); - memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); + CopyToFbPushConstant push_constant = {}; - copy_to_fb.push_constant.set_color[0] = p_color.r; - copy_to_fb.push_constant.set_color[1] = p_color.g; - copy_to_fb.push_constant.set_color[2] = p_color.b; - copy_to_fb.push_constant.set_color[3] = p_color.a; + push_constant.set_color[0] = p_color.r; + push_constant.set_color[1] = p_color.g; + push_constant.set_color[2] = p_color.b; + push_constant.set_color[3] = p_color.a; RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture); @@ -982,10 +1192,22 @@ void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, con RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); ERR_FAIL_COND(shader.is_null()); + uint32_t frame = RD::get_singleton()->get_current_frame_index(); + RD::RenderingDevice::get_singleton()->buffer_update(copy_to_fb.params_uniform_buffer[frame], 0, sizeof(CopyToFbPushConstant), &push_constant); + { + Vector params_uniforms; + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(copy_to_fb.params_uniform_buffer[frame]); + params_uniforms.push_back(u); + copy_to_fb.params_uniform_set[frame] = RD::RenderingDevice::get_singleton()->uniform_set_create(params_uniforms, copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, 0), 4); + } + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector(), 1.0, 0, p_region); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, copy_to_fb.params_uniform_set[frame], 4); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); - RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); } @@ -1007,6 +1229,11 @@ void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuf push_constant.texel_size[1] = 1.0f / p_dst_size.y; push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign +// +// @ShadyTF +// replace push constants with UBO + RD::RenderingDevice::get_singleton()->buffer_update(cube_to_dp.params_uniform_buffer, 0, sizeof(CopyToDPPushConstant), &push_constant); +// // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -1020,7 +1247,13 @@ void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuf RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant)); +// +// @ShadyTF +// replace push constants with UBO +// Was: + //RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, cube_to_dp.params_uniform_set, 4); +// RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); } diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index d18971a67671..4dc603bfec99 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.h +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -101,6 +101,12 @@ class CopyEffects { BlurRasterShaderRD shader; RID shader_version; PipelineCacheRD pipelines[BLUR_MODE_MAX]; +// +// @ShadyTF +// replace push constants with UBO + RID params_uniform_set; + RID params_uniform_buffer; +// } blur_raster; // Copy shader @@ -159,11 +165,14 @@ class CopyEffects { }; struct Copy { - CopyPushConstant push_constant; CopyShaderRD shader; + RID shader_version; RID pipelines[COPY_MODE_MAX]; + RID *params_uniform_buffer; + RID *params_uniform_set; + } copy; // Copy to FB shader @@ -203,11 +212,17 @@ class CopyEffects { }; struct CopyToFb { - CopyToFbPushConstant push_constant; CopyToFbShaderRD shader; RID shader_version; PipelineCacheRD pipelines[COPY_TO_FB_MAX]; + // + // @ShadyTF + // replace push constants with UBO + RID *params_uniform_set; + RID *params_uniform_buffer; + // + } copy_to_fb; // Copy to DP @@ -223,6 +238,12 @@ class CopyEffects { CubeToDpShaderRD shader; RID shader_version; PipelineCacheRD pipeline; +// +// @ShadyTF +// replace push constants with UBO + RID params_uniform_set; + RID params_uniform_buffer; +// } cube_to_dp; // Cubemap effects @@ -317,6 +338,10 @@ class CopyEffects { static CopyEffects *singleton; +private: + void _update_copy_to_fb_uniform_set(const CopyToFbPushConstant *p_buffer); + void _update_copy_uniform_set(const CopyPushConstant *p_buffer); + public: static CopyEffects *get_singleton(); diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.cpp b/servers/rendering/renderer_rd/effects/tone_mapper.cpp index ee0b6adb4d6c..511b4a8c82cc 100644 --- a/servers/rendering/renderer_rd/effects/tone_mapper.cpp +++ b/servers/rendering/renderer_rd/effects/tone_mapper.cpp @@ -37,6 +37,13 @@ using namespace RendererRD; ToneMapper::ToneMapper() { { + uint32_t RID_size = sizeof(RID) * RD::get_singleton()->get_frame_delay(); + params_uniform_buffer = (RID *)memalloc(RID_size); + params_uniform_set = (RID *)memalloc(RID_size); + + memset(params_uniform_buffer, 0, RID_size); + memset(params_uniform_set, 0, RID_size); + // Initialize tonemapper Vector tonemap_modes; tonemap_modes.push_back("\n"); @@ -74,10 +81,35 @@ ToneMapper::ToneMapper() { tonemap.pipelines[i].clear(); } } + +// +// @ShadyTF +// prepare uniform set and buffer + uint32_t params_size = sizeof(TonemapPushConstant); + for (uint32_t i = 0; i < RD::get_singleton()->get_frame_delay(); i++) { + params_uniform_buffer[i] = RD::RenderingDevice::get_singleton()->uniform_buffer_create(params_size, Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT | RD::BUFFER_CREATION_LINEAR_BIT); + } +// } } ToneMapper::~ToneMapper() { +// +// @ShadyTF +// prepare uniform set and buffer + for (uint32_t i = 0; i < RD::get_singleton()->get_frame_delay(); i++) { + if (params_uniform_buffer[i].is_valid()) { + RD::RenderingDevice::get_singleton()->free(params_uniform_buffer[i]); + } + if (params_uniform_set[i].is_valid()) { + RD::RenderingDevice::get_singleton()->free(params_uniform_set[i]); + } + } + + memfree(params_uniform_set); + memfree(params_uniform_buffer); + + // tonemap.shader.version_free(tonemap.shader_version); } @@ -173,7 +205,14 @@ void ToneMapper::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Ton RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_glow_texture, u_glow_map), 2); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 3, u_color_correction_texture), 3); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &tonemap.push_constant, sizeof(TonemapPushConstant)); + +// +// @ShadyTF +// replace push constant with UBO +// was: + //RD::get_singleton()->draw_list_set_push_constant(draw_list, &tonemap.push_constant, sizeof(TonemapPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); + // RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u); RD::get_singleton()->draw_list_end(); } @@ -253,7 +292,68 @@ void ToneMapper::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_col RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 1, u_exposure_texture), 1); // should be set to a default texture, it's ignored RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 2, u_glow_texture, u_glow_map), 2); // should be set to a default texture, it's ignored RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 3, u_color_correction_texture), 3); - - RD::get_singleton()->draw_list_set_push_constant(p_subpass_draw_list, &tonemap.push_constant, sizeof(TonemapPushConstant)); + +// +// @ShadyTF +// replace push constant with UBO +// was: + //RD::get_singleton()->draw_list_set_push_constant(p_subpass_draw_list, &tonemap.push_constant, sizeof(TonemapPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, params_uniform_set[RD::get_singleton()->get_current_frame_index()], 4); + // RD::get_singleton()->draw_list_draw(p_subpass_draw_list, false, 1u, 3u); } + +// +// @ShadyTF +// replace push constant with UBO +void ToneMapper::prepare_params(const TonemapSettings& p_settings) { + + memset(&tonemap.push_constant, 0, sizeof(TonemapPushConstant)); + + tonemap.push_constant.flags |= p_settings.use_bcs ? TONEMAP_FLAG_USE_BCS : 0; + tonemap.push_constant.bcs[0] = p_settings.brightness; + tonemap.push_constant.bcs[1] = p_settings.contrast; + tonemap.push_constant.bcs[2] = p_settings.saturation; + + tonemap.push_constant.flags |= p_settings.use_glow ? TONEMAP_FLAG_USE_GLOW : 0; + tonemap.push_constant.glow_intensity = p_settings.glow_intensity; + tonemap.push_constant.glow_map_strength = p_settings.glow_map_strength; + tonemap.push_constant.glow_levels[0] = p_settings.glow_levels[0]; // clean this up to just pass by pointer or something + tonemap.push_constant.glow_levels[1] = p_settings.glow_levels[1]; + tonemap.push_constant.glow_levels[2] = p_settings.glow_levels[2]; + tonemap.push_constant.glow_levels[3] = p_settings.glow_levels[3]; + tonemap.push_constant.glow_levels[4] = p_settings.glow_levels[4]; + tonemap.push_constant.glow_levels[5] = p_settings.glow_levels[5]; + tonemap.push_constant.glow_levels[6] = p_settings.glow_levels[6]; + tonemap.push_constant.glow_texture_size[0] = p_settings.glow_texture_size.x; + tonemap.push_constant.glow_texture_size[1] = p_settings.glow_texture_size.y; + tonemap.push_constant.glow_mode = p_settings.glow_mode; + + tonemap.push_constant.tonemapper = p_settings.tonemap_mode; + tonemap.push_constant.flags |= p_settings.use_auto_exposure ? TONEMAP_FLAG_USE_AUTO_EXPOSURE : 0; + tonemap.push_constant.exposure = p_settings.exposure; + tonemap.push_constant.white = p_settings.white; + tonemap.push_constant.auto_exposure_scale = p_settings.auto_exposure_scale; + + tonemap.push_constant.flags |= p_settings.use_color_correction ? TONEMAP_FLAG_USE_COLOR_CORRECTION : 0; + + tonemap.push_constant.flags |= p_settings.use_debanding ? TONEMAP_FLAG_USE_DEBANDING : 0; + tonemap.push_constant.luminance_multiplier = p_settings.luminance_multiplier; + + tonemap.push_constant.flags |= p_settings.convert_to_srgb ? TONEMAP_FLAG_CONVERT_TO_SRGB : 0; + + uint32_t frame = RD::get_singleton()->get_current_frame_index(); + RD::RenderingDevice::get_singleton()->buffer_update(params_uniform_buffer[frame], 0, sizeof(TonemapPushConstant), &tonemap.push_constant); + + Vector params_uniforms; + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(params_uniform_buffer[frame]); + params_uniforms.push_back(u); + if (params_uniform_set[frame].is_valid()) + RD::get_singleton()->free(params_uniform_set[frame]); + params_uniform_set[frame] = RD::RenderingDevice::get_singleton()->uniform_set_create(params_uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, 0), 4, true); + +} +// diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.h b/servers/rendering/renderer_rd/effects/tone_mapper.h index a1a99f931fc3..a63a40240af2 100644 --- a/servers/rendering/renderer_rd/effects/tone_mapper.h +++ b/servers/rendering/renderer_rd/effects/tone_mapper.h @@ -81,9 +81,16 @@ class ToneMapper { float glow_intensity; // 4 - 44 float glow_map_strength; // 4 - 48 - uint32_t glow_mode; // 4 - 52 - float glow_levels[7]; // 28 - 80 - +// +// @ShadyTF +// replace push constants with UBO +// swap the members order to correct alignment of UBO +// Was: +// uint32_t glow_mode; // 4 - 52 +// float glow_levels[7]; // 28 - 80 + float glow_levels[7]; // 28 - 76 + uint32_t glow_mode; // 4 - 80 +// float exposure; // 4 - 84 float white; // 4 - 88 float auto_exposure_scale; // 4 - 92 @@ -101,6 +108,14 @@ class ToneMapper { PipelineCacheRD pipelines[TONEMAP_MODE_MAX]; } tonemap; +// +// @ShadyTF +// replacing push constants with uniform buffer +// new uniform set and uniform buffer for draw call params + RID *params_uniform_set; + RID *params_uniform_buffer; +// + public: ToneMapper(); ~ToneMapper(); @@ -152,6 +167,11 @@ class ToneMapper { void tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings); void tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_color, RD::FramebufferFormatID p_dst_format_id, const TonemapSettings &p_settings); +// +// @ShadyTF +// replace push constants with UBO + void prepare_params(const TonemapSettings &p_settings); +// }; } // namespace RendererRD diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index 78ab6f3650f1..6a5b18e7a6c8 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -198,7 +198,7 @@ void Fog::init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_lay material_storage->shader_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_shader_funcs); material_storage->material_set_data_request_function(RendererRD::MaterialStorage::SHADER_TYPE_FOG, _create_fog_material_funcs); - volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO)); + volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO), Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT); } { @@ -287,7 +287,7 @@ ALBEDO = vec3(1.0); for (int i = 0; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) { volumetric_fog.process_pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, i)); } - volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO)); + volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO), Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT); } } diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 41609dc74d31..241cdc938287 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -210,6 +210,32 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar p_array[11] = 0; } +// +// @ShadyTF +// replacing push constants with uniform buffer +void SkyRD::_render_sky_prepare_params(float p_time, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) { + + SkyPushConstant sky_push_constant; + + memset(&sky_push_constant, 0, sizeof(SkyPushConstant)); + + // We only need key components of our projection matrix + sky_push_constant.projection[0] = p_projection.columns[2][0]; + sky_push_constant.projection[1] = p_projection.columns[0][0]; + sky_push_constant.projection[2] = p_projection.columns[2][1]; + sky_push_constant.projection[3] = p_projection.columns[1][1]; + + sky_push_constant.position[0] = p_position.x; + sky_push_constant.position[1] = p_position.y; + sky_push_constant.position[2] = p_position.z; + sky_push_constant.time = p_time; + sky_push_constant.luminance_multiplier = p_luminance_multiplier; + store_transform_3x3(p_orientation, sky_push_constant.orientation); + + + RD::get_singleton()->buffer_update(sky_scene_state.params_uniform_buffer, 0, sizeof(SkyPushConstant), &sky_push_constant); +} +// void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) { SkyPushConstant sky_push_constant; @@ -248,8 +274,16 @@ void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineC RD::get_singleton()->draw_list_bind_uniform_set(draw_list, sky_scene_state.default_fog_uniform_set, SKY_SET_FOG); } } - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &sky_push_constant, sizeof(SkyPushConstant)); +// +// @ShadyTF +// replacing push constants with uniform buffer +// Was: +// RD::get_singleton()->draw_list_set_push_constant(draw_list, &sky_push_constant, sizeof(SkyPushConstant)); + if (use_push_constants) { + RD::get_singleton()->draw_list_set_push_constant(draw_list, &sky_push_constant, sizeof(SkyPushConstant)); + } +// + RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u); } @@ -733,11 +767,23 @@ void SkyRD::init() { sky_scene_state.directional_lights = memnew_arr(SkyDirectionalLightData, sky_scene_state.max_directional_lights); sky_scene_state.last_frame_directional_lights = memnew_arr(SkyDirectionalLightData, sky_scene_state.max_directional_lights); sky_scene_state.last_frame_directional_light_count = sky_scene_state.max_directional_lights + 1; - sky_scene_state.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size); + // + // @ShadyTF persistently mapped buffers + // Was: + // sky_scene_state.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size); + sky_scene_state.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size, Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT); + // String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_scene_state.max_directional_lights) + "\n"; defines += "\n#define SAMPLERS_BINDING_FIRST_INDEX " + itos(SAMPLERS_BINDING_FIRST_INDEX) + "\n"; +// +// @ShadyTF +// replacing push constants with uniform buffer + if (use_push_constants) { + defines += "\n#define USE_PUSH_CONSTANTS \n"; + } +// // Initialize sky Vector sky_modes; sky_modes.push_back(""); // Full size @@ -845,11 +891,28 @@ void sky() { SkyMaterialData *md = static_cast(material_storage->material_get_data(sky_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND); - - sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO)); + // + // @ShadyTF persistently mapped buffers + // Was: + // sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO)); + sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO), Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT); + // Vector uniforms; +// +// @ShadyTF +// replacing push constants with uniform buffer +// preparing uniform buffer in uniform set + sky_scene_state.params_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkyPushConstant)); + { + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(sky_scene_state.params_uniform_buffer); + uniforms.push_back(u); + } +// { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; @@ -1307,7 +1370,15 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers); - cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD); +// +// @ShadyTF +// replacing push constants with uniform buffer +// preparing uniform buffer in uniform set + _render_sky_prepare_params(p_time, cm, local_view, p_global_pos, p_luminance_multiplier); +// + cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_LOAD, + RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector(), 1, 0, Rect2()); + _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } @@ -1328,6 +1399,13 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd, p_render_buffers); +// +// @ShadyTF +// replacing push constants with uniform buffer +// preparing uniform buffer in uniform set + _render_sky_prepare_params(p_time, cm, local_view, p_global_pos, p_luminance_multiplier); +// + cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD); _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); @@ -1345,7 +1423,14 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd, p_render_buffers); - cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD); +// +// @ShadyTF +// replacing push constants with uniform buffer +// preparing uniform buffer in uniform set + _render_sky_prepare_params(p_time, cm, local_view, p_global_pos, p_luminance_multiplier); +// + cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector(), 1, 0, Rect2(), RDD::BreadcrumbMarker::SKY_PASS, i); + _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier); RD::get_singleton()->draw_list_end(); } @@ -1495,7 +1580,33 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers } +// +// @ShadyTF +// replacing push constants with uniform buffer +// preparing uniform buffer in uniform set +void SkyRD::draw_sky_prepare_params(RID p_env, double p_time, float p_luminance_multiplier) { + + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); + sky_transform.invert(); + + float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); + + // Camera + Projection projection = sky_scene_state.cam_projection; + if (custom_fov && sky_scene_state.view_count == 1) { + // With custom fov we don't support stereo... + float near_plane = projection.get_z_near(); + float far_plane = projection.get_z_far(); + float aspect = projection.get_aspect(); + + projection.set_perspective(custom_fov, aspect, near_plane, far_plane); + } + + sky_transform = sky_transform * sky_scene_state.cam_transform.basis; + _render_sky_prepare_params(p_time, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier); +} +// void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier) { ERR_FAIL_COND(p_render_buffers.is_null()); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index b146a416f9b8..60e5d1737267 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -133,6 +133,12 @@ class SkyRD { }; void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier); +// +// @ShadyTF +// replacing push constants with uniform buffer +// update uniform buffers + void _render_sky_prepare_params(float p_time, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier); +// public: struct SkySceneState { @@ -176,6 +182,13 @@ class SkyRD { RID fog_uniform_set; RID default_fog_uniform_set; +// +// @ShadyTF +// replacing push constants with uniform buffer + SkyPushConstant params; + RID params_uniform_buffer; +// + RID fog_shader; RID fog_material; RID fog_only_texture_uniform_set; @@ -283,6 +296,12 @@ class SkyRD { mutable RID_Owner sky_owner; int roughness_layers; +// +// @ShadyTF +// replacing push constants with uniform buffer + bool use_push_constants = true; + void draw_sky_prepare_params(RID p_env, double p_time, float p_luminance_multiplier = 1.0); +// RendererRD::MaterialStorage::ShaderData *_create_sky_shader_func(); static RendererRD::MaterialStorage::ShaderData *_create_sky_shader_funcs(); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index fa6e78750bc7..7ca8f62028fb 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -2298,6 +2298,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RENDER_TIMESTAMP("Tonemap"); + _post_process_prepare_params(p_render_data->render_buffers->get_internal_texture(), p_render_data); _render_buffers_post_process_and_tonemap(p_render_data); } @@ -2898,124 +2899,122 @@ void RenderForwardClustered::base_uniforms_changed() { void RenderForwardClustered::_update_render_base_uniform_set() { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); - if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != light_storage->lightmap_array_get_version())) { - if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { - RD::get_singleton()->free(render_base_uniform_set); - } - - lightmap_texture_array_version = light_storage->lightmap_array_get_version(); + if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { + RD::get_singleton()->free(render_base_uniform_set); + } - Vector uniforms; + lightmap_texture_array_version = light_storage->lightmap_array_get_version(); - { - RD::Uniform u; - u.binding = 2; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.append_id(scene_shader.shadow_sampler); - uniforms.push_back(u); - } + Vector uniforms; - { - RD::Uniform u; - u.binding = 3; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(RendererRD::LightStorage::get_singleton()->get_omni_light_buffer()); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 4; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(RendererRD::LightStorage::get_singleton()->get_spot_light_buffer()); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 2; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.append_id(scene_shader.shadow_sampler); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.binding = 5; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(RendererRD::LightStorage::get_singleton()->get_reflection_probe_buffer()); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 6; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.append_id(RendererRD::LightStorage::get_singleton()->get_directional_light_buffer()); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 7; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(scene_state.lightmap_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 8; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(scene_state.lightmap_capture_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 9; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture(); - u.append_id(decal_atlas); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 10; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb(); - u.append_id(decal_atlas); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 11; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(RendererRD::TextureStorage::get_singleton()->get_decal_buffer()); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 3; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(RendererRD::LightStorage::get_singleton()->get_omni_light_buffer()); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 4; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(RendererRD::LightStorage::get_singleton()->get_spot_light_buffer()); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 12; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 5; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(RendererRD::LightStorage::get_singleton()->get_reflection_probe_buffer()); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 6; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(RendererRD::LightStorage::get_singleton()->get_directional_light_buffer()); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 7; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(scene_state.lightmap_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 8; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(scene_state.lightmap_capture_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 9; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture(); + u.append_id(decal_atlas); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 10; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb(); + u.append_id(decal_atlas); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 11; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(RendererRD::TextureStorage::get_singleton()->get_decal_buffer()); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 13; - u.append_id(sdfgi_get_ubo()); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 12; + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.binding = 14; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.append_id(RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 13; + u.append_id(sdfgi_get_ubo()); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.binding = 15; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.append_id(best_fit_normal.texture); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 14; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.append_id(RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); + } - render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET); + { + RD::Uniform u; + u.binding = 15; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.append_id(best_fit_normal.texture); + uniforms.push_back(u); } + + render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET, true); } RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, bool p_use_directional_shadow_atlas, int p_index) { diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index ac93aca6bb02..ad1da7b892cd 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -303,7 +303,7 @@ bool RenderForwardMobile::_render_buffers_can_be_storage() { return false; } -RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, bool p_use_directional_shadow_atlas, int p_index) { +RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, uint32_t p_frame_idx, bool p_use_directional_shadow_atlas, int p_index) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); @@ -324,6 +324,9 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ } } + uint32_t frame = RD::get_singleton()->get_current_frame_index(); + uint32_t frame_count = RD::get_singleton()->get_frame_delay(); + // default render buffer and scene state uniform set // loaded into set 1 @@ -333,7 +336,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.append_id(scene_state.uniform_buffers[p_index]); + u.append_id(scene_state.uniform_buffers[p_index * frame_count + frame]); uniforms.push_back(u); } @@ -546,8 +549,13 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ if (render_pass_uniform_sets[p_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[p_index])) { RD::get_singleton()->free(render_pass_uniform_sets[p_index]); } - - render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET); + // + // @ShadyTF : + // descriptor optimizations : linear allocation of descriptor set pools + // Was: + // render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET); + render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET, true); + // return render_pass_uniform_sets[p_index]; } @@ -612,10 +620,11 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) { } if (p_render_data->directional_shadows.size()) { - //open the pass for directional shadows light_storage->update_directional_shadow_atlas(); - RD::get_singleton()->draw_list_begin(light_storage->direction_shadow_get_fb(), RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE); - RD::get_singleton()->draw_list_end(); + if (!RenderingDeviceCommons::render_pass_opts_enabled) { + RD::get_singleton()->draw_list_begin(light_storage->direction_shadow_get_fb(), RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE); + RD::get_singleton()->draw_list_end(); + } } } @@ -648,6 +657,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color ERR_FAIL_NULL(p_render_data); + uint32_t frame = RD::get_singleton()->get_current_frame_index(); + Ref rb = p_render_data->render_buffers; ERR_FAIL_COND(rb.is_null()); @@ -745,8 +756,15 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color // fill our render lists early so we can find out if we use various features _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR); - render_list[RENDER_LIST_OPAQUE].sort_by_key(); + if (RenderingDeviceCommons::render_pass_opts_enabled) { + render_list[RENDER_LIST_OPAQUE].sort_by_depth(); + } else { + render_list[RENDER_LIST_OPAQUE].sort_by_key(); + } + render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority(); + + _fill_instance_data(RENDER_LIST_OPAQUE); _fill_instance_data(RENDER_LIST_ALPHA); @@ -939,10 +957,13 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color } { + RDD::BreadcrumbMarker breadcrumb; if (rb_data.is_valid()) { RD::get_singleton()->draw_command_begin_label("Render 3D Pass"); + breadcrumb = RDD::BreadcrumbMarker::OPAQUE_PASS; } else { RD::get_singleton()->draw_command_begin_label("Render Reflection Probe Pass"); + breadcrumb = RDD::BreadcrumbMarker::REFLECTION_PROBES; } // opaque pass @@ -963,7 +984,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RENDER_TIMESTAMP("Render Opaque"); } - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, samplers, true); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, samplers, frame, true); // Set clear colors. Vector c; @@ -984,7 +1005,18 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color } } - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, load_color ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, c, 1.0, 0); + +// +// @ShadyTF +// replacing push constants with uniform buffer + if (draw_sky || draw_sky_fog_only) { + sky.draw_sky_prepare_params(p_render_data->environment, time, sky_energy_multiplier); + } + if (!is_reflection_probe) { + _post_process_prepare_params(p_render_data->render_buffers->get_internal_texture(), p_render_data); + } +// + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, load_color ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, c, 1.0, 0, Rect2(), breadcrumb); RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); if (copy_canvas) { @@ -1029,7 +1061,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_begin_label("Render Transparent"); - rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, samplers, true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, samplers, frame, true); RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); render_list_params.framebuffer_format = fb_format; @@ -1072,7 +1104,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); RENDER_TIMESTAMP("Render Transparent"); - rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, samplers, true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, samplers, frame, true); // this may be needed if we re-introduced steps that change info, not sure which do so in the previous implementation //_setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, false); @@ -1081,7 +1113,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color render_list_params.framebuffer_format = fb_format; render_list_params.subpass = RD::get_singleton()->draw_list_get_current_pass(); // Should now always be 0. - draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE); + draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, Vector(), 1, 0, Rect2(), breadcrumb, 0); _render_list(draw_list, fb_format, &render_list_params, 0, render_list_params.element_count); RD::get_singleton()->draw_list_end(); @@ -1268,7 +1300,7 @@ void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, i if (render_cubemap) { //rendering to cubemap - _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info, p_main_cam_transform); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, light_storage->light_get_type(base), p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info, p_main_cam_transform); if (finalize_cubemap) { _render_shadow_process(); _render_shadow_end(); @@ -1287,7 +1319,7 @@ void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, i } else { //render shadow - _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info, p_main_cam_transform); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, light_storage->light_get_type(base), p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info, p_main_cam_transform); } } @@ -1299,9 +1331,8 @@ void RenderForwardMobile::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info, const Transform3D &p_main_cam_transform) { +void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, RS::LightType p_light_type, const Plane & p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info, const Transform3D &p_main_cam_transform) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); - SceneState::ShadowPass shadow_pass; if (p_render_info) { @@ -1340,7 +1371,11 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size(); _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, true); uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from; - render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); + if (RenderingDeviceCommons::render_pass_opts_enabled) { + render_list[RENDER_LIST_SECONDARY].sort_by_depth(render_list_from, render_list_size); + } else { + render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); + } _fill_instance_data(RENDER_LIST_SECONDARY, render_list_from, render_list_size); { @@ -1363,6 +1398,7 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr shadow_pass.framebuffer = p_framebuffer; shadow_pass.initial_depth_action = p_begin ? RD::INITIAL_ACTION_CLEAR : (p_clear_region ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD); shadow_pass.rect = p_rect; + shadow_pass.light_type = p_light_type; scene_state.shadow_passes.push_back(shadow_pass); } @@ -1374,7 +1410,7 @@ void RenderForwardMobile::_render_shadow_process() { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { //render passes need to be configured after instance buffer is done, since they need the latest version SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), false, i); + shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), RD::get_singleton()->get_current_frame_index(), false, i); } RD::get_singleton()->draw_command_end_label(); @@ -1383,9 +1419,67 @@ void RenderForwardMobile::_render_shadow_process() { void RenderForwardMobile::_render_shadow_end() { RD::get_singleton()->draw_command_begin_label("Shadow Render"); - for (SceneState::ShadowPass &shadow_pass : scene_state.shadow_passes) { - RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from); - _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector(), 1.0, 0, shadow_pass.rect); + if (RenderingDeviceCommons::render_pass_opts_enabled) { + // Render all cascades in the same pass since they render on different regions + uint32_t curr_shadow_index = 0; + + while (curr_shadow_index < scene_state.shadow_passes.size()) { + uint32_t pass_amount = 0; + SceneState::ShadowPass start_shadow_pass = scene_state.shadow_passes[curr_shadow_index]; + switch (start_shadow_pass.light_type) { + case RS::LIGHT_DIRECTIONAL: { + uint32_t i = 0; + while (i < scene_state.shadow_passes.size() && scene_state.shadow_passes[i].light_type == RS::LIGHT_DIRECTIONAL) { + i++; + pass_amount++; + } + break; + } + // A cubemap is made of 6 faces + case RS::LIGHT_OMNI: + pass_amount = 6; + break; + // A spotlight requires only one pass + case RS::LIGHT_SPOT: + pass_amount = 1; + break; + } + + // Use one drawlist per face, the render target has to change + if (start_shadow_pass.light_type == RS::LIGHT_OMNI || start_shadow_pass.light_type == RS::LIGHT_SPOT) { + for (uint32_t j = 0; j < pass_amount && curr_shadow_index + j < scene_state.shadow_passes.size(); j++) { + SceneState::ShadowPass shadow_pass = scene_state.shadow_passes[curr_shadow_index + j]; + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from); + _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector(), 1.0, 0, shadow_pass.rect); + } + } else { + RID framebuffer = scene_state.shadow_passes[curr_shadow_index].framebuffer; + Size2 fb_size = RD::get_singleton()->framebuffer_get_size(framebuffer); + RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); + RD::DrawListID draw_list; + + draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, Vector(), 1.0, 0, Rect2(0, 0, fb_size.x, fb_size.y), RenderingDeviceCommons::BreadcrumbMarker::SHADOW_PASS_DIRECTIONAL); + + for (uint32_t j = 0; j < pass_amount && curr_shadow_index + j < scene_state.shadow_passes.size(); j++) { + SceneState::ShadowPass shadow_pass = scene_state.shadow_passes[curr_shadow_index + j]; + // Change viewport and scissors for the next cascade + RD::get_singleton()->draw_list_set_viewport(draw_list, shadow_pass.rect); + RD::get_singleton()->draw_list_enable_scissor(draw_list, Rect2(0, 0, shadow_pass.rect.size.x, shadow_pass.rect.size.y)); + + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from); + render_list_parameters.framebuffer_format = fb_format; + _render_list(draw_list, fb_format, &render_list_parameters, 0, render_list_parameters.element_count); + } + + RD::get_singleton()->draw_list_end(); + } + curr_shadow_index += pass_amount; + } + } else { + for (SceneState::ShadowPass &shadow_pass : scene_state.shadow_passes) { + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from); + _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector(), 1.0, 0, shadow_pass.rect); + } } RD::get_singleton()->draw_command_end_label(); @@ -1416,14 +1510,20 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c render_data.scene_data = &scene_data; render_data.instances = &p_instances; + uint32_t frame = RD::get_singleton()->get_current_frame_index(); + _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); - render_list[RENDER_LIST_SECONDARY].sort_by_key(); + if (!RenderingDeviceCommons::render_pass_opts_enabled) { + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + } else { + render_list[RENDER_LIST_SECONDARY].sort_by_depth(); + } _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), frame); RENDER_TIMESTAMP("Render 3D Material"); @@ -1449,6 +1549,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray RENDER_TIMESTAMP("Setup Rendering UV2"); RD::get_singleton()->draw_command_begin_label("Render UV2"); + uint32_t frame = RD::get_singleton()->get_current_frame_index(); _update_render_base_uniform_set(); @@ -1465,10 +1566,12 @@ void RenderForwardMobile::_render_uv2(const PagedArray PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); - render_list[RENDER_LIST_SECONDARY].sort_by_key(); + if (RenderingDeviceCommons::render_pass_opts_enabled) { + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + } _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), frame); RENDER_TIMESTAMP("Render 3D Material"); @@ -1523,6 +1626,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); + uint32_t frame = RD::get_singleton()->get_current_frame_index(); _update_render_base_uniform_set(); @@ -1547,10 +1651,12 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const PassMode pass_mode = PASS_MODE_SHADOW; _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); - render_list[RENDER_LIST_SECONDARY].sort_by_key(); + if (RenderingDeviceCommons::render_pass_opts_enabled) { + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + } _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), frame); RENDER_TIMESTAMP("Render Collider Heightfield"); @@ -1572,108 +1678,112 @@ void RenderForwardMobile::base_uniforms_changed() { void RenderForwardMobile::_update_render_base_uniform_set() { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); - if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != light_storage->lightmap_array_get_version())) { - if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { - RD::get_singleton()->free(render_base_uniform_set); - } + if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { + RD::get_singleton()->free(render_base_uniform_set); + } - lightmap_texture_array_version = light_storage->lightmap_array_get_version(); + lightmap_texture_array_version = light_storage->lightmap_array_get_version(); - Vector uniforms; + Vector uniforms; - { - RD::Uniform u; - u.binding = 2; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.append_id(scene_shader.shadow_sampler); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 2; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.append_id(scene_shader.shadow_sampler); - { - RD::Uniform u; - u.binding = 3; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(RendererRD::LightStorage::get_singleton()->get_omni_light_buffer()); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 4; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(RendererRD::LightStorage::get_singleton()->get_spot_light_buffer()); - uniforms.push_back(u); - } +// +// @ShadyTF +// immutable sampler usage case + u.immutable_sampler = true; +// + uniforms.push_back(u); + } - { - RD::Uniform u; - u.binding = 5; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(RendererRD::LightStorage::get_singleton()->get_reflection_probe_buffer()); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 6; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.append_id(RendererRD::LightStorage::get_singleton()->get_directional_light_buffer()); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 7; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(scene_state.lightmap_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 8; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(scene_state.lightmap_capture_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 9; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture(); - u.append_id(decal_atlas); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 10; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb(); - u.append_id(decal_atlas); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.binding = 11; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.append_id(RendererRD::TextureStorage::get_singleton()->get_decal_buffer()); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 3; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(RendererRD::LightStorage::get_singleton()->get_omni_light_buffer()); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 4; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(RendererRD::LightStorage::get_singleton()->get_spot_light_buffer()); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 12; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.binding = 5; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(RendererRD::LightStorage::get_singleton()->get_reflection_probe_buffer()); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 6; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(RendererRD::LightStorage::get_singleton()->get_directional_light_buffer()); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 7; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(scene_state.lightmap_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 8; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(scene_state.lightmap_capture_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 9; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture(); + u.append_id(decal_atlas); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 10; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb(); + u.append_id(decal_atlas); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 11; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.append_id(RendererRD::TextureStorage::get_singleton()->get_decal_buffer()); + uniforms.push_back(u); + } - { - RD::Uniform u; - u.binding = 13; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.append_id(RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 12; + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); + uniforms.push_back(u); + } - render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET); + { + RD::Uniform u; + u.binding = 13; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.append_id(RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); } + + render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET, true); } RID RenderForwardMobile::_render_buffers_get_normal_texture(Ref p_render_buffers) { @@ -1977,16 +2087,19 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID(); RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? RendererRD::LightStorage::get_singleton()->reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID(); + uint32_t frame_count = RD::get_singleton()->get_frame_delay(); + uint32_t frame = RD::get_singleton()->get_current_frame_index(); + // May do this earlier in RenderSceneRenderRD::render_scene - if (p_index >= (int)scene_state.uniform_buffers.size()) { + if (p_index * frame_count >= (int)scene_state.uniform_buffers.size()) { uint32_t from = scene_state.uniform_buffers.size(); - scene_state.uniform_buffers.resize(p_index + 1); + scene_state.uniform_buffers.resize(p_index * frame_count + frame_count); for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { scene_state.uniform_buffers[i] = p_render_data->scene_data->create_uniform_buffer(); } } - p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_flip_y, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers, false); + p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index * frame_count + frame], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_flip_y, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers, false); } /// RENDERING /// @@ -2045,7 +2158,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP); for (uint32_t i = p_from_element; i < p_to_element; i++) { - const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i]; + GeometryInstanceSurfaceDataCache *surf = p_params->elements[i]; const RenderElementInfo &element_info = p_params->element_info[i]; const GeometryInstanceForwardMobile *inst = surf->owner; @@ -2096,6 +2209,10 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr base_spec_constants |= 1 << SPEC_CONSTANT_DISABLE_DECALS; } + // @NicolaTF: Update spec consts in sort structure to improve further sorting + if (RenderingDeviceCommons::render_pass_opts_enabled) + surf->sort.spec_consts = base_spec_constants; + #ifdef DEBUG_ENABLED if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) { material_uniform_set = scene_shader.default_material_uniform_set; @@ -2166,9 +2283,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr } break; } - PipelineCacheRD *pipeline = nullptr; - - pipeline = &shader->pipelines[cull_variant][primitive][shader_version]; + PipelineCacheRD *pipeline = &shader->pipelines[cull_variant][primitive][shader_version]; RD::VertexFormatID vertex_format = -1; RID vertex_array_rd; @@ -2198,8 +2313,6 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe, p_params->subpass, base_spec_constants); if (pipeline_rd != prev_pipeline_rd) { - // checking with prev shader does not make so much sense, as - // the pipeline may still be different. RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, pipeline_rd); prev_pipeline_rd = pipeline_rd; } @@ -2451,19 +2564,18 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI ginstance->surface_caches = sdcache; //sortkey - - sdcache->sort.sort_key1 = 0; - sdcache->sort.sort_key2 = 0; + uint64_t format = RendererRD::MeshStorage::get_singleton()->mesh_surface_get_format(sdcache->surface); sdcache->sort.surface_index = p_surface; sdcache->sort.material_id_low = p_material_id & 0x0000FFFF; sdcache->sort.material_id_hi = p_material_id >> 16; sdcache->sort.shader_id = p_shader_id; sdcache->sort.geometry_id = p_mesh.get_local_index(); + sdcache->sort.format = format; + sdcache->sort.spec_consts = 0; // sdcache->sort.uses_forward_gi = ginstance->can_sdfgi; sdcache->sort.priority = p_material->priority; - uint64_t format = RendererRD::MeshStorage::get_singleton()->mesh_surface_get_format(sdcache->surface); if (p_material->shader_data->uses_tangent && !(format & RS::ARRAY_FORMAT_TANGENT)) { String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")"; String mesh_path = mesh_storage->mesh_get_path(p_mesh).is_empty() ? "" : "(" + mesh_storage->mesh_get_path(p_mesh) + ")"; @@ -2784,6 +2896,11 @@ RenderForwardMobile::RenderForwardMobile() { sky.set_texture_format(_render_buffers_get_color_format()); +// +// @ShadyTF +// replacing push constants with uniform buffer + sky.use_push_constants = false; +// String defines; defines += "\n#define MAX_ROUGHNESS_LOD " + itos(get_roughness_layers() - 1) + ".0\n"; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 5c022046276d..5e85f10ac143 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -180,13 +180,13 @@ class RenderForwardMobile : public RendererSceneRenderRD { void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Transform3D &p_main_cam_transform = Transform3D()); void _render_shadow_begin(); - void _render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Transform3D &p_main_cam_transform = Transform3D()); + void _render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, RS::LightType p_light_type, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Transform3D &p_main_cam_transform = Transform3D()); void _render_shadow_process(); void _render_shadow_end(); /* Render Scene */ - RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, bool p_use_directional_shadow_atlas = false, int p_index = 0); + RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, uint32_t frame_index, bool p_use_directional_shadow_atlas = false, int p_index = 0); void _pre_opaque_render(RenderDataRD *p_render_data); uint64_t lightmap_texture_array_version = 0xFFFFFFFF; @@ -277,6 +277,8 @@ class RenderForwardMobile : public RendererSceneRenderRD { RID framebuffer; RD::InitialAction initial_depth_action; Rect2i rect; + + RS::LightType light_type; }; LocalVector shadow_passes; @@ -295,7 +297,6 @@ class RenderForwardMobile : public RendererSceneRenderRD { } //should eventually be replaced by radix - struct SortByKey { _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const { return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2); @@ -318,10 +319,13 @@ class RenderForwardMobile : public RendererSceneRenderRD { } }; - void sort_by_depth() { //used for shadows + void sort_by_depth(uint32_t p_from = 0, uint32_t p_size = 0) { //used for shadows SortArray sorter; - sorter.sort(elements.ptr(), elements.size()); + if (p_from == 0 && p_size == 0) + sorter.sort(elements.ptr(), elements.size()); + else + sorter.sort(elements.ptr() + p_from, p_size); } struct SortByReverseDepthAndPriority { @@ -336,6 +340,42 @@ class RenderForwardMobile : public RendererSceneRenderRD { sorter.sort(elements.ptr(), elements.size()); } + struct SortForRendering { + _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const { + if (A->sort.shader_id == B->sort.shader_id) { + if (A->sort.format == B->sort.format) { + return (A->sort.spec_consts == B->sort.spec_consts) ? (A->owner->depth < B->owner->depth) : (A->sort.spec_consts < B->sort.spec_consts); + } else { + return A->sort.format < B->sort.format; + } + } + return (A->sort.shader_id < B->sort.shader_id); + } + }; + + void sort_for_rendering(uint32_t p_from = 0, uint32_t p_size = 0) { + + SortArray sorter; + if (p_from == 0 && p_size == 0) + sorter.sort(elements.ptr(), elements.size()); + else + sorter.sort(elements.ptr() + p_from, p_size); + } + + struct SortForShadows { + _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const { + return (A->sort.shader_id == B->sort.shader_id) ? (A->owner->depth < B->owner->depth) : (A->sort.shader_id < B->sort.shader_id); + } + }; + + void sort_for_shadows(uint32_t p_from = 0, uint32_t p_size = 0) { + SortArray sorter; + if (p_from == 0 && p_size == 0) + sorter.sort(elements.ptr(), elements.size()); + else + sorter.sort(elements.ptr() + p_from, p_size); + } + _FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) { elements.push_back(p_element); } @@ -428,6 +468,8 @@ class RenderForwardMobile : public RendererSceneRenderRD { uint64_t uses_lightmap : 4; // sort by lightmap id here, not whether its yes/no (is 4 bits enough?) uint64_t depth_layer : 4; uint64_t priority : 8; + uint64_t format; + uint64_t spec_consts : 32; // uint64_t lod_index : 8; // no need to sort on LOD // uint64_t uses_forward_gi : 1; // no GI here, remove diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 3592ee2f6d12..ad8072f7f9e0 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -424,6 +424,21 @@ SceneShaderForwardMobile::SceneShaderForwardMobile() { void SceneShaderForwardMobile::init(const String p_defines) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + +// +// @ShadyTF : +// immutable samplers : +// create the shadow sampler to be passed when creating the pipeline + { + RD::SamplerState sampler; + sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; + sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; + sampler.enable_compare = true; + sampler.compare_op = RD::COMPARE_OP_LESS; + shadow_sampler = RD::get_singleton()->sampler_create(sampler); + } +// + /* SCENE SHADER */ { @@ -439,8 +454,20 @@ void SceneShaderForwardMobile::init(const String p_defines) { shader_versions.push_back("\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_SHADOW_PASS_MULTIVIEW - shader.initialize(shader_versions, p_defines); - +// +// @ShadyTF : +// immutable samplers : +// passing in shadow sampler as immutable when initializing shaderRD +// Was: +// shader.initialize(shader_versions, p_defines); + Vector immutable_samplers; + RD::PipelineImmutableSampler immutable_shadow_sampler; + immutable_shadow_sampler.binding = 2; + immutable_shadow_sampler.append_id(shadow_sampler); + immutable_shadow_sampler.uniform_type = RenderingDeviceCommons::UNIFORM_TYPE_SAMPLER; + immutable_samplers.push_back(immutable_shadow_sampler); + shader.initialize(shader_versions, p_defines, immutable_samplers); +// if (!RendererCompositorRD::get_singleton()->is_xr_enabled()) { shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_MULTIVIEW, false); shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, false); @@ -726,14 +753,21 @@ void fragment() { default_vec4_xform_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RenderForwardMobile::TRANSFORMS_UNIFORM_SET); } - { - RD::SamplerState sampler; - sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; - sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; - sampler.enable_compare = true; - sampler.compare_op = RD::COMPARE_OP_LESS; - shadow_sampler = RD::get_singleton()->sampler_create(sampler); - } + +// +// @ShadyTF +// immutable sampler usage case +// moved to happen early before pipeline creation +// Was: +// { +// RD::SamplerState sampler; +// sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; +// sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; +// sampler.enable_compare = true; +// sampler.compare_op = RD::COMPARE_OP_LESS; +// shadow_sampler = RD::get_singleton()->sampler_create(sampler); +// } +// } void SceneShaderForwardMobile::set_default_specialization_constants(const Vector &p_constants) { diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 00604d0d4b1d..d0a4811adbb2 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1177,7 +1177,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, clear_colors); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, clear_colors, 1, 0, Rect2(), RDD::BreadcrumbMarker::UI_PASS); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, fb_uniform_set, BASE_UNIFORM_SET); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.default_transforms_uniform_set, TRANSFORMS_UNIFORM_SET); @@ -1704,6 +1704,7 @@ void RendererCanvasRenderRD::_update_shadow_atlas() { state.shadow_fb = RD::get_singleton()->framebuffer_create(fb_textures); } } + void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { CanvasLight *cl = canvas_light_owner.get_or_null(p_rid); ERR_FAIL_COND(!cl->shadow.enabled); @@ -2674,6 +2675,11 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() { for (int i = 0; i < 2; i++) { shadow_render.sdf_render_pipelines[i] = RD::get_singleton()->render_pipeline_create(shadow_render.shader.version_get_shader(shadow_render.shader_version, SHADOW_RENDER_MODE_SDF), shadow_render.sdf_framebuffer_format, shadow_render.sdf_vertex_format, i == 0 ? RD::RENDER_PRIMITIVE_TRIANGLES : RD::RENDER_PRIMITIVE_LINES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); } + // + // @ShadyTF unload shader modules + RD::get_singleton()->shader_destroy_modules(shadow_render.shader.version_get_shader(shadow_render.shader_version, SHADOW_RENDER_MODE_SHADOW)); + RD::get_singleton()->shader_destroy_modules(shadow_render.shader.version_get_shader(shadow_render.shader_version, SHADOW_RENDER_MODE_SDF)); + // } { //bindings diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index 012451a5cd63..c371f3185a75 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/io/dir_access.h" +#include "core/math/transform_3d.h" void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { Error err = RD::get_singleton()->screen_prepare_for_drawing(p_screen); @@ -40,6 +41,40 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID return; } +// +// @ShadyTF +// replace push constants with UBO + for (int i = 0; i < p_amount; i++) { + Size2 screen_size(RD::get_singleton()->screen_get_width(p_screen), RD::get_singleton()->screen_get_height(p_screen)); + // We need to invert the phone rotation + int screen_rotation_degrees = -DisplayServer::get_singleton()->screen_get_current_rotation(); + float screen_rotation = Math::deg_to_rad((float)screen_rotation_degrees); + + blit.push_constant.rotation_cos = cos(screen_rotation); + blit.push_constant.rotation_sin = sin(screen_rotation); + // Swap width and height when the orientation is not the native one + if (screen_rotation_degrees % 180 != 0) { + SWAP(screen_size.width, screen_size.height); + } + blit.push_constant.src_rect[0] = p_render_targets[i].src_rect.position.x; + blit.push_constant.src_rect[1] = p_render_targets[i].src_rect.position.y; + blit.push_constant.src_rect[2] = p_render_targets[i].src_rect.size.width; + blit.push_constant.src_rect[3] = p_render_targets[i].src_rect.size.height; + blit.push_constant.dst_rect[0] = p_render_targets[i].dst_rect.position.x / screen_size.width; + blit.push_constant.dst_rect[1] = p_render_targets[i].dst_rect.position.y / screen_size.height; + blit.push_constant.dst_rect[2] = p_render_targets[i].dst_rect.size.width / screen_size.width; + blit.push_constant.dst_rect[3] = p_render_targets[i].dst_rect.size.height / screen_size.height; + blit.push_constant.layer = p_render_targets[i].multi_view.layer; + blit.push_constant.eye_center[0] = p_render_targets[i].lens_distortion.eye_center.x; + blit.push_constant.eye_center[1] = p_render_targets[i].lens_distortion.eye_center.y; + blit.push_constant.k1 = p_render_targets[i].lens_distortion.k1; + blit.push_constant.k2 = p_render_targets[i].lens_distortion.k2; + blit.push_constant.upscale = p_render_targets[i].lens_distortion.upscale; + blit.push_constant.aspect_ratio = p_render_targets[i].lens_distortion.aspect_ratio; + blit.push_constant.convert_to_srgb = texture_storage->render_target_is_using_hdr(p_render_targets[i].render_target); + RD::RenderingDevice::get_singleton()->buffer_update(blit.params_uniform_buffer, 0, sizeof(BlitPushConstant), &blit.push_constant); + } +// RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen); ERR_FAIL_COND(draw_list == RD::INVALID_ID); @@ -66,6 +101,16 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID RD::get_singleton()->draw_list_bind_index_array(draw_list, blit.array); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_target_descriptors[rd_texture], 0); + // We need to invert the phone rotation + int screen_rotation_degrees = -DisplayServer::get_singleton()->screen_get_current_rotation(); + float screen_rotation = Math::deg_to_rad((float)screen_rotation_degrees); + + blit.push_constant.rotation_cos = cos(screen_rotation); + blit.push_constant.rotation_sin = sin(screen_rotation); + // Swap width and height when the orientation is not the native one + if (screen_rotation_degrees % 180 != 0) { + SWAP(screen_size.width, screen_size.height); + } blit.push_constant.src_rect[0] = p_render_targets[i].src_rect.position.x; blit.push_constant.src_rect[1] = p_render_targets[i].src_rect.position.y; blit.push_constant.src_rect[2] = p_render_targets[i].src_rect.size.width; @@ -83,7 +128,15 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID blit.push_constant.aspect_ratio = p_render_targets[i].lens_distortion.aspect_ratio; blit.push_constant.convert_to_srgb = texture_storage->render_target_is_using_hdr(p_render_targets[i].render_target); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant)); + +// +// @ShadyTF +// replace push constants with UBO +// Was: + //RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant)); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, blit.params_uniform_set, 4); +// + RD::get_singleton()->draw_list_draw(draw_list, true); } @@ -123,6 +176,10 @@ void RendererCompositorRD::initialize() { for (int i = 0; i < BLIT_MODE_MAX; i++) { blit.pipelines[i] = RD::get_singleton()->render_pipeline_create(blit.shader.version_get_shader(blit.shader_version, i), RD::get_singleton()->screen_get_framebuffer_format(DisplayServer::MAIN_WINDOW_ID), RD::INVALID_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), i == BLIT_MODE_NORMAL_ALPHA ? RenderingDevice::PipelineColorBlendState::create_blend() : RenderingDevice::PipelineColorBlendState::create_disabled(), 0); + // + // @ShadyTF unload shader modules + RD::get_singleton()->shader_destroy_modules(blit.shader.version_get_shader(blit.shader_version, i)); + // } //create index array for copy shader @@ -142,6 +199,19 @@ void RendererCompositorRD::initialize() { blit.array = RD::get_singleton()->index_array_create(blit.index_buffer, 0, 6); blit.sampler = RD::get_singleton()->sampler_create(RD::SamplerState()); +// +// @ShadyTF +// replace push constants with UBO + uint32_t params_size = sizeof(BlitPushConstant); + blit.params_uniform_buffer = RD::RenderingDevice::get_singleton()->uniform_buffer_create( params_size, Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT ); + Vector params_uniforms; + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.append_id(blit.params_uniform_buffer); + params_uniforms.push_back(u); + blit.params_uniform_set = RD::RenderingDevice::get_singleton()->uniform_set_create(params_uniforms, blit.shader.version_get_shader(blit.shader_version, 0), 4); +// } } @@ -217,6 +287,31 @@ void RendererCompositorRD::set_boot_image(const Ref &p_image, const Color screenrect.position /= window_size; screenrect.size /= window_size; +// +// @ShadyTF +// replace push constants with UBO + int screen_rotation_degrees = DisplayServer::get_singleton()->screen_get_current_rotation(); + float screen_rotation = Math::deg_to_rad((float)screen_rotation_degrees); + blit.push_constant.rotation_cos = cos(screen_rotation); + blit.push_constant.rotation_sin = sin(screen_rotation); + blit.push_constant.src_rect[0] = 0.0; + blit.push_constant.src_rect[1] = 0.0; + blit.push_constant.src_rect[2] = 1.0; + blit.push_constant.src_rect[3] = 1.0; + blit.push_constant.dst_rect[0] = screenrect.position.x; + blit.push_constant.dst_rect[1] = screenrect.position.y; + blit.push_constant.dst_rect[2] = screenrect.size.width; + blit.push_constant.dst_rect[3] = screenrect.size.height; + blit.push_constant.layer = 0; + blit.push_constant.eye_center[0] = 0; + blit.push_constant.eye_center[1] = 0; + blit.push_constant.k1 = 0; + blit.push_constant.k2 = 0; + blit.push_constant.upscale = 1.0; + blit.push_constant.aspect_ratio = 1.0; + blit.push_constant.convert_to_srgb = false; + RD::RenderingDevice::get_singleton()->buffer_update(blit.params_uniform_buffer, 0, sizeof(BlitPushConstant), &blit.push_constant); +// RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(DisplayServer::MAIN_WINDOW_ID, p_color); @@ -224,6 +319,11 @@ void RendererCompositorRD::set_boot_image(const Ref &p_image, const Color RD::get_singleton()->draw_list_bind_index_array(draw_list, blit.array); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uset, 0); +// +// @ShadyTF +// replace push constants with UBO +// Was: + /* blit.push_constant.src_rect[0] = 0.0; blit.push_constant.src_rect[1] = 0.0; blit.push_constant.src_rect[2] = 1.0; @@ -242,6 +342,9 @@ void RendererCompositorRD::set_boot_image(const Ref &p_image, const Color blit.push_constant.convert_to_srgb = false; RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant)); + */ + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, blit.params_uniform_set, 4); +// RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 95c2b812d94c..8da9d1b6e352 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -73,12 +73,17 @@ class RendererCompositorRD : public RendererCompositor { float src_rect[4]; float dst_rect[4]; + float rotation_sin; + float rotation_cos; + float pad[2]; + float eye_center[2]; float k1; float k2; float upscale; float aspect_ratio; + uint32_t layer; uint32_t convert_to_srgb; }; @@ -91,6 +96,12 @@ class RendererCompositorRD : public RendererCompositor { RID index_buffer; RID array; RID sampler; +// +// @ShadyTF +// replace push constants with UBO + RID params_uniform_set; + RID params_uniform_buffer; +// } blit; HashMap render_target_descriptors; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 62ecec39919e..a274117ad198 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -659,6 +659,12 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende } } + // + // @ShadyTF + // replace push constants with UBO + tone_mapper->prepare_params(tonemap); + // + tone_mapper->tonemapper(color_texture, dest_fb, tonemap); RD::get_singleton()->draw_command_end_label(); @@ -688,6 +694,63 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende texture_storage->render_target_disable_clear_request(render_target); } +// +// @ShadyTF +// replace push constants with UBO +void RendererSceneRenderRD::_post_process_prepare_params(RID p_source_texture, const RenderDataRD *p_render_data) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + + + Ref rb = p_render_data->render_buffers; + ERR_FAIL_COND(rb.is_null()); + + // FIXME: Our input it our internal_texture, shouldn't this be using internal_size ?? + // Seeing we don't support FSR in our mobile renderer right now target_size = internal_size... + Size2i target_size = rb->get_target_size(); + bool can_use_effects = target_size.x >= 8 && target_size.y >= 8; + + RendererRD::ToneMapper::TonemapSettings tonemap; + + if (p_render_data->environment.is_valid()) { + tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment); + tonemap.exposure = environment_get_exposure(p_render_data->environment); + tonemap.white = environment_get_white(p_render_data->environment); + } + + tonemap.use_glow = false; + tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); + tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); + tonemap.use_auto_exposure = false; + tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); + + tonemap.use_color_correction = false; + tonemap.use_1d_color_correction = false; + tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); + + if (can_use_effects && p_render_data->environment.is_valid()) { + tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment); + tonemap.brightness = environment_get_adjustments_brightness(p_render_data->environment); + tonemap.contrast = environment_get_adjustments_contrast(p_render_data->environment); + tonemap.saturation = environment_get_adjustments_saturation(p_render_data->environment); + if (environment_get_adjustments_enabled(p_render_data->environment) && environment_get_color_correction(p_render_data->environment).is_valid()) { + tonemap.use_color_correction = true; + tonemap.use_1d_color_correction = environment_get_use_1d_color_correction(p_render_data->environment); + tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(environment_get_color_correction(p_render_data->environment)); + } + } + + tonemap.use_debanding = rb->get_use_debanding(); + tonemap.texture_size = Vector2i(target_size.x, target_size.y); + + tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier(); + tonemap.view_count = rb->get_view_count(); + + tonemap.convert_to_srgb = !texture_storage->render_target_is_using_hdr(rb->get_render_target()); + + + tone_mapper->prepare_params(tonemap); +} +// void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); @@ -752,6 +815,11 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr tonemap.convert_to_srgb = !texture_storage->render_target_is_using_hdr(rb->get_render_target()); + // + // @ShadyTF + // replace push constants with UBO + tone_mapper->prepare_params(tonemap); + // tone_mapper->tonemapper(draw_list, p_source_texture, RD::get_singleton()->framebuffer_get_format(p_framebuffer), tonemap); RD::get_singleton()->draw_command_end_label(); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 5c5f11aba675..1d72d904a449 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -108,6 +108,11 @@ class RendererSceneRenderRD : public RendererSceneRender { void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data); void _post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data); void _disable_clear_request(const RenderDataRD *p_render_data); +// +// @ShadyTF +// replace push constants with UBO + void _post_process_prepare_params(RID p_source_texture, const RenderDataRD *p_render_data); +// // needed for a single argument calls (material and uv2) PagedArrayPool cull_argument_pool; diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 789c6c284558..0298e0dbf55a 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -306,7 +306,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) { { MutexLock lock(variant_set_mutex); - p_data->version->variants[variant] = RD::get_singleton()->shader_create_from_bytecode(shader_data, p_data->version->variants[variant]); + p_data->version->variants[variant] = RD::get_singleton()->shader_create_from_bytecode_with_samplers(shader_data, p_data->version->variants[variant], immutable_samplers); p_data->version->variant_data[variant] = shader_data; } } @@ -448,7 +448,13 @@ bool ShaderRD::_load_from_cache(Version *p_version, int p_group) { } { MutexLock lock(variant_set_mutex); - RID shader = RD::get_singleton()->shader_create_from_bytecode(p_version->variant_data[variant_id], p_version->variants[variant_id]); +// +// @ShadyTF +// use api function when creating shaders which passes immutable samplers +// Was : +// RID shader = RD::get_singleton()->shader_create_from_bytecode(p_version->variant_data[variant_id], p_version->variants[variant_id]); + RID shader = RD::get_singleton()->shader_create_from_bytecode_with_samplers(p_version->variant_data[variant_id], p_version->variants[variant_id], immutable_samplers); +// if (shader.is_null()) { for (uint32_t j = 0; j < i; j++) { int variant_free_id = group_to_variant_map[p_group][j]; @@ -715,7 +721,14 @@ ShaderRD::ShaderRD() { base_compute_defines = base_compute_define_text.ascii(); } -void ShaderRD::initialize(const Vector &p_variant_defines, const String &p_general_defines) { +// +// @ShadyTF +// optional parameter to pass immutable samplers to be used when creating pipelines +// Was : +//void ShaderRD::initialize(const Vector &p_variant_defines, const String &p_general_defines) { +void ShaderRD::initialize(const Vector &p_variant_defines, const String &p_general_defines, const Vector& r_immutable_samplers) { + immutable_samplers = r_immutable_samplers; +// ERR_FAIL_COND(variant_defines.size()); ERR_FAIL_COND(p_variant_defines.is_empty()); diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index 22a21086af9d..a4378f1d062b 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -62,6 +62,11 @@ class ShaderRD { HashMap> group_to_variant_map; Vector group_enabled; +// +// @ShadyTF : immutable samplers +// to be passed when creating shaders to render device + Vector immutable_samplers; +// struct Version { CharString uniforms; CharString vertex_globals; @@ -202,7 +207,12 @@ class ShaderRD { RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version); - void initialize(const Vector &p_variant_defines, const String &p_general_defines = ""); +// +// optional parameter to pass immutable samplers to be used when creating pipelines +// Was: +// void initialize(const Vector &p_variant_defines, const String &p_general_defines = ""); + void initialize(const Vector &p_variant_defines, const String &p_general_defines = "", const Vector& r_immutable_samplers = Vector()); +// void initialize(const Vector &p_variant_defines, const String &p_general_defines = ""); virtual ~ShaderRD(); diff --git a/servers/rendering/renderer_rd/shaders/blit.glsl b/servers/rendering/renderer_rd/shaders/blit.glsl index d451647bec66..00181ff175c1 100644 --- a/servers/rendering/renderer_rd/shaders/blit.glsl +++ b/servers/rendering/renderer_rd/shaders/blit.glsl @@ -3,10 +3,19 @@ #version 450 #VERSION_DEFINES - -layout(push_constant, std140) uniform Pos { +// +// @ShadyTF +// replace push constants with UBO +// Was: +//layout(push_constant, std140) uniform Pos { +layout(set = 4, binding = 0, std140) uniform Pos { +// vec4 src_rect; vec4 dst_rect; + + float rotation_sin; + float rotation_cos; + vec2 pad; vec2 eye_center; float k1; @@ -15,17 +24,23 @@ layout(push_constant, std140) uniform Pos { float upscale; float aspect_ratio; uint layer; - uint pad1; + bool convert_to_srgb; } data; layout(location = 0) out vec2 uv; void main() { + mat4 swapchain_transform = mat4(1.0); + swapchain_transform[0][0] = data.rotation_cos; + swapchain_transform[0][1] = -data.rotation_sin; + swapchain_transform[1][0] = data.rotation_sin; + swapchain_transform[1][1] = data.rotation_cos; + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv = data.src_rect.xy + base_arr[gl_VertexIndex] * data.src_rect.zw; vec2 vtx = data.dst_rect.xy + base_arr[gl_VertexIndex] * data.dst_rect.zw; - gl_Position = vec4(vtx * 2.0 - 1.0, 0.0, 1.0); + gl_Position = swapchain_transform * vec4(vtx * 2.0 - 1.0, 0.0, 1.0); } #[fragment] @@ -34,9 +49,19 @@ void main() { #VERSION_DEFINES -layout(push_constant, std140) uniform Pos { +// +// @ShadyTF +// replace push constants with UBO +// Was: +//layout(push_constant, std140) uniform Pos { +layout(set = 4, binding = 0, std140) uniform Pos { +// vec4 src_rect; vec4 dst_rect; + + float rotation_sin; + float rotation_cos; + vec2 pad; vec2 eye_center; float k1; @@ -101,7 +126,6 @@ void main() { #else color = texture(src_rt, uv); #endif - if (data.convert_to_srgb) { color.rgb = linear_to_srgb(color.rgb); // Regular linear -> SRGB conversion. } diff --git a/servers/rendering/renderer_rd/shaders/effects/blur_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/blur_raster_inc.glsl index 06ca198f37bf..602a04571e59 100644 --- a/servers/rendering/renderer_rd/shaders/effects/blur_raster_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/blur_raster_inc.glsl @@ -1,8 +1,13 @@ #define FLAG_HORIZONTAL (1 << 0) #define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 1) #define FLAG_GLOW_FIRST_PASS (1 << 2) - -layout(push_constant, std430) uniform Blur { +// +// @ShadyTF +// replace push constants with UBO +// Was: +//layout(push_constant, std430) uniform Blur { +layout(set = 4, binding = 0, std140) uniform Pos { +// vec2 pixel_size; // 08 - 08 uint flags; // 04 - 12 uint pad; // 04 - 16 diff --git a/servers/rendering/renderer_rd/shaders/effects/copy.glsl b/servers/rendering/renderer_rd/shaders/effects/copy.glsl index debf6b736739..b537bafcface 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy.glsl @@ -16,7 +16,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #define FLAG_COPY_ALL_SOURCE (1 << 7) #define FLAG_ALPHA_TO_ONE (1 << 8) -layout(push_constant, std430) uniform Params { +layout(set = 4, binding = 0, std140) uniform Params { ivec4 section; ivec2 target; uint flags; @@ -34,7 +34,7 @@ layout(push_constant, std430) uniform Params { // DOF. float camera_z_far; float camera_z_near; - uint pad2[2]; + ivec2 pad2; vec4 set_color; } diff --git a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl index 1b065a8dd3b6..67266cab4f96 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl @@ -28,7 +28,10 @@ layout(location = 0) out vec3 uv_interp; layout(location = 0) out vec2 uv_interp; #endif -layout(push_constant, std430) uniform Params { +// +// @ShadyTF +// replace push constants with UBO +layout(set = 4, binding = 0, std140) uniform Params { vec4 section; vec2 pixel_size; float luminance_multiplier; @@ -37,6 +40,7 @@ layout(push_constant, std430) uniform Params { vec4 color; } params; +// void main() { vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); @@ -80,7 +84,10 @@ void main() { #define FLAG_LINEAR (1 << 6) #define FLAG_NORMAL (1 << 7) -layout(push_constant, std430) uniform Params { +// +// @ShadyTF +// replace push constants with UBO +layout(set = 4, binding = 0, std140) uniform Params { vec4 section; vec2 pixel_size; float luminance_multiplier; @@ -89,6 +96,7 @@ layout(push_constant, std430) uniform Params { vec4 color; } params; +// #ifndef MODE_SET_COLOR #ifdef MULTIVIEW diff --git a/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl index e77d0de719b0..620ee0b647a4 100644 --- a/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl @@ -4,7 +4,13 @@ #VERSION_DEFINES -layout(push_constant, std430) uniform Params { +// +// @ShadyTF +// replace push constants with UBO +// Was: +//layout(push_constant, std430) uniform Params { +layout(set = 4, binding = 0, std140) uniform Params { +// float z_far; float z_near; vec2 texel_size; @@ -31,7 +37,8 @@ layout(location = 0) in vec2 uv_interp; layout(set = 0, binding = 0) uniform samplerCube source_cube; -layout(push_constant, std430) uniform Params { +layout(set = 4, binding = 0, std140) uniform Params { +//layout(push_constant, std430) uniform Params { float z_far; float z_near; vec2 texel_size; diff --git a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl index 33ec9911074b..64649c5bda36 100644 --- a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl @@ -65,7 +65,13 @@ layout(set = 3, binding = 0) uniform sampler3D source_color_correction; #define FLAG_USE_DEBANDING (1 << 5) #define FLAG_CONVERT_TO_SRGB (1 << 6) -layout(push_constant, std430) uniform Params { +// +// @ShadyTF +// replace push constants with UBO +// Was: +//layout(push_constant, std430) uniform Params { +layout(set = 4, binding = 0, std140) uniform Params { +// vec3 bcs; uint flags; @@ -77,8 +83,17 @@ layout(push_constant, std430) uniform Params { float glow_intensity; float glow_map_strength; - uint glow_mode; - float glow_levels[7]; +// +// @ShadyTF +// replace push constants with UBO +// swap these to fix alignment for UBO +// Was : +// uint glow_mode; +// float glow_levels[7]; + vec4 glow_levelsA; + vec3 glow_levelsB; + uint glow_mode; +// float exposure; float white; @@ -280,6 +295,12 @@ vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels #endif // defined(MULTIVIEW) vec3 glow = vec3(0.0f); +// +// @ShadyTF +// replace push constants with UBO +// fix aligment issues by reordering and using a vec4 and a vec3 for the 7 glow levels +// Was: +/* if (params.glow_levels[0] > 0.0001) { glow += GLOW_TEXTURE_SAMPLE(tex, uv, 0).rgb * params.glow_levels[0]; } @@ -307,7 +328,36 @@ vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels if (params.glow_levels[6] > 0.0001) { glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb * params.glow_levels[6]; } +*/ + if (params.glow_levelsA.x > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 0).rgb * params.glow_levelsA.x; + } + + if (params.glow_levelsA.y > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb * params.glow_levelsA.y; + } + + if (params.glow_levelsA.z > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb * params.glow_levelsA.z; + } + + if (params.glow_levelsA.w > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb * params.glow_levelsA.w; + } + + if (params.glow_levelsB.x > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb * params.glow_levelsB.x; + } + + if (params.glow_levelsB.y > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb * params.glow_levelsB.y; + } + + if (params.glow_levelsB.z > 0.0001) { + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb * params.glow_levelsB.z; + } +// return glow; } diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index 4e5b11aed865..242e197f6fba 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -12,7 +12,17 @@ layout(location = 0) out vec2 uv_interp; +// +// @ShadyTF +// replacing push constants with uniform buffer +// Was: +//layout(push_constant, std430) uniform Params { +#ifdef USE_PUSH_CONSTANTS layout(push_constant, std430) uniform Params { +#else +layout(set = 0, binding = 0, std140) uniform Params { +#endif +// mat3 orientation; vec4 projection; // only applicable if not multiview vec3 position; @@ -52,7 +62,17 @@ void main() { layout(location = 0) in vec2 uv_interp; +// +// @ShadyTF +// replacing push constants with uniform buffer +// Was: +//layout(push_constant, std430) uniform Params { +#ifdef USE_PUSH_CONSTANTS layout(push_constant, std430) uniform Params { +#else +layout(set = 0, binding = 0, std140) uniform Params { +#endif +// mat3 orientation; vec4 projection; // only applicable if not multiview vec3 position; @@ -282,6 +302,7 @@ void main() { frag_color.a = 0.0; } + #ifdef USE_DEBANDING frag_color.rgb += interleaved_gradient_noise(gl_FragCoord.xy) * params.luminance_multiplier; #endif diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 259edc63a0d5..398bc3ee5556 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -719,6 +719,7 @@ vec4 fog_process(vec3 vertex) { #define scene_data scene_data_block.data void main() { + #ifdef MODE_DUAL_PARABOLOID if (dp_clip > 0.0) @@ -1045,6 +1046,8 @@ void main() { vec3 specular_light = vec3(0.0, 0.0, 0.0); vec3 diffuse_light = vec3(0.0, 0.0, 0.0); vec3 ambient_light = vec3(0.0, 0.0, 0.0); + + #ifndef MODE_UNSHADED // Used in regular draw pass and when drawing SDFs for SDFGI and materials for VoxelGI. @@ -1751,6 +1754,7 @@ void main() { } #else #ifdef MODE_RENDER_DEPTH + #ifdef USE_OPAQUE_PREPASS if (alpha < scene_data.opaque_prepass_threshold) { @@ -1768,7 +1772,7 @@ void main() { #ifdef MODE_RENDER_DEPTH #ifdef MODE_RENDER_MATERIAL - + albedo_output_buffer.rgb = albedo; albedo_output_buffer.a = alpha; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 2786af65ebc1..eb585cfb8a50 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -48,6 +48,7 @@ LightStorage::LightStorage() { directional_shadow.size = GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/size"); directional_shadow.use_16_bits = GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/16_bits"); + directional_light_buffer = (RID *)memalloc(sizeof(RID) * RD::get_singleton()->get_frame_delay()); using_lightmap_array = true; // high end if (using_lightmap_array) { @@ -75,6 +76,7 @@ LightStorage::~LightStorage() { RD::get_singleton()->free(E.value.cubemap); } + memfree(directional_light_buffer); singleton = nullptr; } @@ -509,9 +511,11 @@ void LightStorage::light_instance_mark_visible(RID p_light_instance) { /* LIGHT DATA */ void LightStorage::free_light_data() { - if (directional_light_buffer.is_valid()) { - RD::get_singleton()->free(directional_light_buffer); - directional_light_buffer = RID(); + for (uint32_t i = 0; i < RD::get_singleton()->get_frame_delay(); i++) { + if (directional_light_buffer[i].is_valid()) { + RD::get_singleton()->free(directional_light_buffer[i]); + directional_light_buffer[i] = RID(); + } } if (omni_light_buffer.is_valid()) { @@ -565,13 +569,13 @@ void LightStorage::set_max_lights(const uint32_t p_max_lights) { max_directional_lights = RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; uint32_t directional_light_buffer_size = max_directional_lights * sizeof(DirectionalLightData); directional_lights = memnew_arr(DirectionalLightData, max_directional_lights); - directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size); + for (uint32_t i=0; iget_frame_delay(); i++) + directional_light_buffer[i] = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size, Vector(), RD::BUFFER_CREATION_LINEAR_BIT | RD::BUFFER_CREATION_PERSISTENT_BIT); } void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const PagedArray &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows) { ForwardIDStorage *forward_id_storage = ForwardIDStorage::get_singleton(); RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); - Transform3D inverse_transform = p_camera_transform.affine_inverse(); r_directional_light_count = 0; @@ -1004,7 +1008,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged } if (r_directional_light_count) { - RD::get_singleton()->buffer_update(directional_light_buffer, 0, sizeof(DirectionalLightData) * r_directional_light_count, directional_lights); + RD::get_singleton()->buffer_update(directional_light_buffer[RD::get_singleton()->get_current_frame_index()], 0, sizeof(DirectionalLightData) * r_directional_light_count, directional_lights); } } diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index b3d27cc6ede7..e923975e94d7 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -214,7 +214,7 @@ class LightStorage : public RendererLightStorage { uint32_t max_directional_lights; DirectionalLightData *directional_lights = nullptr; - RID directional_light_buffer; + RID* directional_light_buffer; /* REFLECTION PROBE */ @@ -766,7 +766,7 @@ class LightStorage : public RendererLightStorage { void set_max_lights(const uint32_t p_max_lights); RID get_omni_light_buffer() { return omni_light_buffer; } RID get_spot_light_buffer() { return spot_light_buffer; } - RID get_directional_light_buffer() { return directional_light_buffer; } + RID get_directional_light_buffer() { return directional_light_buffer[RD::get_singleton()->get_current_frame_index()]; } uint32_t get_max_directional_lights() { return max_directional_lights; } bool has_directional_shadows(const uint32_t p_directional_light_count) { for (uint32_t i = 0; i < p_directional_light_count; i++) { diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 1c3076b128f6..001b20e24546 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -987,25 +987,16 @@ void MaterialStorage::MaterialData::free_parameters_uniform_set(RID p_uniform_se } bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap &p_uniforms, const uint32_t *p_uniform_offsets, const Vector &p_texture_uniforms, const HashMap> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, bool p_3d_material) { - if ((uint32_t)ubo_data.size() != p_ubo_size) { - p_uniform_dirty = true; - if (uniform_buffer.is_valid()) { - RD::get_singleton()->free(uniform_buffer); - uniform_buffer = RID(); - } - - ubo_data.resize(p_ubo_size); - if (ubo_data.size()) { - uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size()); - memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear - } + p_uniform_dirty = true; + if (uniform_buffer.is_valid()) { + RD::get_singleton()->free(uniform_buffer); + uniform_buffer = RID(); + } - //clear previous uniform set - if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { - RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, nullptr, nullptr); - RD::get_singleton()->free(uniform_set); - uniform_set = RID(); - } + ubo_data.resize(p_ubo_size); + if (ubo_data.size()) { + uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size(), Vector(), RD::BUFFER_CREATION_PERSISTENT_BIT | RD::BUFFER_CREATION_LINEAR_BIT); + memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear } //check whether buffer changed @@ -1023,13 +1014,6 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap< texture_cache.resize(tex_uniform_count); render_target_cache.clear(); p_textures_dirty = true; - - //clear previous uniform set - if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { - RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, nullptr, nullptr); - RD::get_singleton()->free(uniform_set); - uniform_set = RID(); - } } if (p_textures_dirty && tex_uniform_count) { @@ -1076,7 +1060,6 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap< } uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_shader_uniform_set); - RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, MaterialStorage::_material_uniform_set_erased, &self); return true; @@ -1165,7 +1148,7 @@ MaterialStorage::MaterialStorage() { global_shader_uniforms.buffer_usage = memnew_arr(GlobalShaderUniforms::ValueUsage, global_shader_uniforms.buffer_size); global_shader_uniforms.buffer_dirty_regions = memnew_arr(bool, global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); - global_shader_uniforms.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, Vector(), 0, RD::BUFFER_CREATION_PERSISTENT_BIT); } MaterialStorage::~MaterialStorage() { diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 9d3def1246c7..b0e042fb11a5 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -1445,7 +1445,12 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS:: if (multimesh->motion_vectors_enabled) { buffer_size *= 2; } - multimesh->buffer = RD::get_singleton()->storage_buffer_create(buffer_size); + // + // @ShadyTF : persistent buffers + // was : + //multimesh->buffer = RD::get_singleton()->storage_buffer_create(buffer_size); + multimesh->buffer = RD::get_singleton()->storage_buffer_create(buffer_size, Vector(), 0, RD::BUFFER_CREATION_PERSISTENT_BIT); + // } multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH); @@ -2150,7 +2155,13 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_ if (skeleton->size) { skeleton->data.resize(skeleton->size * (skeleton->use_2d ? 8 : 12)); - skeleton->buffer = RD::get_singleton()->storage_buffer_create(skeleton->data.size() * sizeof(float)); + + // + // @ShadyTF : persistent buffers + // was: + //skeleton->buffer = RD::get_singleton()->storage_buffer_create(skeleton->data.size() * sizeof(float)); + skeleton->buffer = RD::get_singleton()->storage_buffer_create(skeleton->data.size() * sizeof(float), Vector(), 0, RD::BUFFER_CREATION_PERSISTENT_BIT); + // memset(skeleton->data.ptrw(), 0, skeleton->data.size() * sizeof(float)); _skeleton_make_dirty(skeleton); diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index a854e78f536f..680cd7f1ba15 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -1083,6 +1083,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta } uniforms.push_back(u); } + p_particles->collision_textures_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, particles_shader.default_shader_rd, 2); p_particles->collision_heightmap_texture = collision_heightmap_texture; } @@ -1459,7 +1460,13 @@ void ParticlesStorage::update_particles() { if (particles->frame_params_buffer.is_valid()) { RD::get_singleton()->free(particles->frame_params_buffer); } - particles->frame_params_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ParticlesFrameParams) * trail_steps); + + // + // @ShadyTF : persistent buffers + // was: + //particles->frame_params_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ParticlesFrameParams) * trail_steps); + particles->frame_params_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ParticlesFrameParams) * trail_steps, Vector(), 0, RD::BUFFER_CREATION_PERSISTENT_BIT); + // } if (particles->trail_bind_poses.size() > 1 && particles->trail_bind_pose_buffer.is_null()) { @@ -1615,7 +1622,7 @@ void ParticlesStorage::update_particles() { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->trail_bind_pose_uniform_set, 2); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, total_amount, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, (uint32_t)ceil((float)total_amount / 64.0), 1, 1); RD::get_singleton()->compute_list_end(); } diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp index 8dc74820e228..02d2ef81f0a8 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp @@ -173,6 +173,10 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; } + // + //@ShadyTF : lazily allocated buffers + usage_bits |= RD::TEXTURE_USAGE_LAZILY_ALLOCATED_BIT; + // create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR, base_data_format, usage_bits); } @@ -191,6 +195,10 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | (can_be_storage ? RD::TEXTURE_USAGE_STORAGE_BIT : 0); } + // + //@ShadyTF : lazily allocated buffers + usage_bits |= RD::TEXTURE_USAGE_LAZILY_ALLOCATED_BIT; + // create_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH, format, usage_bits); } @@ -210,8 +218,16 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co texture_samples = ts[msaa_3d]; + // + //@ShadyTF : lazily allocated buffers + usage_bits |= RD::TEXTURE_USAGE_LAZILY_ALLOCATED_BIT; + // create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, format, usage_bits, texture_samples); + // + //@ShadyTF : lazily allocated buffers + usage_bits |= RD::TEXTURE_USAGE_LAZILY_ALLOCATED_BIT; + // usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; format = RD::get_singleton()->texture_is_format_supported_for_usage(preferred_format[0], usage_bits) ? preferred_format[0] : preferred_format[1]; diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp index dc1e64ddcc21..550814d8111d 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp @@ -62,7 +62,16 @@ Projection RenderSceneDataRD::get_view_projection(uint32_t p_view) const { } RID RenderSceneDataRD::create_uniform_buffer() { - return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA)); + // + // @ShadyTF : persistent buffers + // Was: + //return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA)); + if (OS::get_singleton()->get_current_rendering_method() == "forward_mobile") { + return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA), Vector(), RD::BUFFER_CREATION_LINEAR_BIT | RD::BUFFER_CREATION_PERSISTENT_BIT); + } else { + return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA)); + } + // } void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers, bool p_apply_alpha_multiplier) { diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index dd94982f1aab..46d4b84be3bc 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -3408,6 +3408,13 @@ bool TextureStorage::render_target_is_using_hdr(RID p_render_target) const { return rt->use_hdr; } +int64_t TextureStorage::render_target_get_format(RID p_render_target) const { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_NULL_V(rt, 0); + + return RenderingDevice::get_singleton()->framebuffer_get_format(rt->get_framebuffer()); +} + RID TextureStorage::render_target_get_rd_framebuffer(RID p_render_target) { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_NULL_V(rt, RID()); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 1304b284d507..0acf72239936 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -724,6 +724,7 @@ class TextureStorage : public RendererTextureStorage { virtual void render_target_do_msaa_resolve(RID p_render_target) override; virtual void render_target_set_use_hdr(RID p_render_target, bool p_use_hdr) override; virtual bool render_target_is_using_hdr(RID p_render_target) const override; + virtual int64_t render_target_get_format(RID p_render_target) const override; void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps); void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index e1709fdb00e7..3974441b20c9 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -28,6 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ +#pragma optimize("", off) + #include "rendering_device.h" #include "rendering_device.compat.inc" @@ -224,6 +226,13 @@ RenderingDevice::Buffer *RenderingDevice::_get_buffer_from_owner(RID p_buffer) { buffer = vertex_buffer_owner.get_or_null(p_buffer); } else if (index_buffer_owner.owns(p_buffer)) { buffer = index_buffer_owner.get_or_null(p_buffer); + // + // @ShadyTF linear buffers + } else if (linear_buffer_owner.owns(p_buffer)) { + LinearBuffer* linear_buffer = linear_buffer_owner.get_or_null(p_buffer); + DEV_ASSERT(linear_buffer->usage_index != -1); + buffer = linear_buffer->buffers.ptrw() + linear_buffer->usage_index; + // } else if (uniform_buffer_owner.owns(p_buffer)) { buffer = uniform_buffer_owner.get_or_null(p_buffer); } else if (texture_buffer_owner.owns(p_buffer)) { @@ -500,10 +509,10 @@ Error RenderingDevice::buffer_copy(RID p_src_buffer, RID p_dst_buffer, uint32_t Error RenderingDevice::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data) { _THREAD_SAFE_METHOD_ - ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER, - "Updating buffers is forbidden during creation of a draw list"); - ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER, - "Updating buffers is forbidden during creation of a compute list"); + // + // @ShadyTF + linear_uniform_buffer_advance(p_buffer); + // Buffer *buffer = _get_buffer_from_owner(p_buffer); if (!buffer) { @@ -513,9 +522,83 @@ Error RenderingDevice::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p ERR_FAIL_COND_V_MSG(p_offset + p_size > buffer->size, ERR_INVALID_PARAMETER, "Attempted to write buffer (" + itos((p_offset + p_size) - buffer->size) + " bytes) past the end."); + // + // @ShadyTF - if persistent UMA is available, copy and skip the barrier + copy_bytes_count += p_size; + uint8_t *persistent_data_ptr = driver->buffer_get_persistent_address(buffer->driver_id); + if (persistent_data_ptr ) { + memcpy(persistent_data_ptr + p_offset, p_data, p_size); + direct_copy_count++; + return OK; + } + + ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER, + "Updating buffers is forbidden during creation of a draw list"); + ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER, + "Updating buffers is forbidden during creation of a compute list"); + + gpu_copy_count++; + // return _buffer_update(buffer, p_buffer, p_offset, (uint8_t *)p_data, p_size, true); } + +// +// @ShadyTF +String RenderingDevice::get_perf_report() const { + return perf_report_text; + +} +void RenderingDevice::linear_uniform_buffer_advance(RID p_buffer) { + LinearBuffer *linear_buffer = linear_buffer_owner.get_or_null(p_buffer); + if (linear_buffer) { + if (linear_buffer->buffers.size() <= (linear_buffer->usage_index + 1)) { + Buffer buffer; + buffer.size = linear_buffer->size; + buffer.usage = linear_buffer->usage; + buffer.driver_id = driver->buffer_create(buffer.size, buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU); + buffer_memory += buffer.size; + linear_buffer->buffers.append(buffer); + } + + if (linear_buffer->usage_index == -1) + linear_buffer->usage_frame = frame; + + linear_buffer->usage_index++; + } +} + +void RenderingDevice::linear_uniform_buffers_reset() { + List owned; + linear_buffer_owner.get_owned_list(&owned); + + for (const RID& curr : owned) { + LinearBuffer* curr_linear_buffer = linear_buffer_owner.get_or_null(curr); + if (curr_linear_buffer->usage_frame == frame) + curr_linear_buffer->usage_index = -1; + } +} + +void RenderingDevice::update_perf_report() { + perf_report_text = ""; + perf_report_text += "Persistent buffers "; + if (persistent_buffer_enabled) { + perf_report_text +="Enabled "; + } else { + perf_report_text += "Disabled"; + } + perf_report_text += " gpu:" + String::num_int64(gpu_copy_count); + perf_report_text += " direct:" + String::num_int64(direct_copy_count); + perf_report_text += " bytes:" + String::num_int64(copy_bytes_count); + + perf_report_text += " lazily alloc:" + String::num_int64(driver->get_lazily_memory_used()); + + gpu_copy_count = 0; + direct_copy_count = 0; + copy_bytes_count = 0; + +} +// Error RenderingDevice::buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size) { _THREAD_SAFE_METHOD_ @@ -589,7 +672,7 @@ Vector RenderingDevice::buffer_get_data(RID p_buffer, uint32_t p_offset return buffer_data; } -RID RenderingDevice::storage_buffer_create(uint32_t p_size_bytes, const Vector &p_data, BitField p_usage) { +RID RenderingDevice::storage_buffer_create(uint32_t p_size_bytes, const Vector &p_data, BitField p_usage, BitField p_creation_bits ) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID()); @@ -600,6 +683,13 @@ RID RenderingDevice::storage_buffer_create(uint32_t p_size_bytes, const Vectorbuffer_create(buffer.size, buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU); ERR_FAIL_COND_V(!buffer.driver_id, RID()); @@ -620,6 +710,7 @@ RID RenderingDevice::storage_buffer_create(uint32_t p_size_bytes, const Vector &p_data) { _THREAD_SAFE_METHOD_ @@ -2095,6 +2186,15 @@ RenderingDevice::FramebufferFormatID RenderingDevice::framebuffer_get_format(RID return framebuffer->format_id; } +Size2 RenderingDevice::framebuffer_get_size(RID p_framebuffer) { + _THREAD_SAFE_METHOD_ + + Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_framebuffer); + ERR_FAIL_NULL_V(framebuffer, Size2(0,0)); + + return framebuffer->size; +} + bool RenderingDevice::framebuffer_is_valid(RID p_framebuffer) const { _THREAD_SAFE_METHOD_ @@ -2157,6 +2257,13 @@ RID RenderingDevice::vertex_buffer_create(uint32_t p_size_bytes, const Vector + // @ShadyTF persistently mapped buffers + if (persistent_buffer_enabled) { + buffer.usage.set_flag(RDD::BUFFER_USAGE_PERSISTENT_BIT); + } + // + buffer.driver_id = driver->buffer_create(buffer.size, buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU); ERR_FAIL_COND_V(!buffer.driver_id, RID()); @@ -2167,7 +2274,18 @@ RID RenderingDevice::vertex_buffer_create(uint32_t p_size_bytes, const Vector + // @ShadyTF - if persistent UMA is available, copy and skip the barrier + uint8_t *persistent_data_ptr = driver->buffer_get_persistent_address(buffer.driver_id); + if (persistent_data_ptr ) { + memcpy(persistent_data_ptr, p_data.ptr(), p_data.size()); + } else { + // _buffer_update(&buffer, RID(), 0, p_data.ptr(), p_data.size()); + // + // @ShadyTF + } + // } buffer_memory += buffer.size; @@ -2321,6 +2439,13 @@ RID RenderingDevice::index_buffer_create(uint32_t p_index_count, IndexBufferForm #endif index_buffer.size = size_bytes; index_buffer.usage = (RDD::BUFFER_USAGE_TRANSFER_FROM_BIT | RDD::BUFFER_USAGE_TRANSFER_TO_BIT | RDD::BUFFER_USAGE_INDEX_BIT); + // + // @ShadyTF persistently mapped buffers + if (persistent_buffer_enabled) { + index_buffer.usage.set_flag(RDD::BUFFER_USAGE_PERSISTENT_BIT); + } + // + index_buffer.driver_id = driver->buffer_create(index_buffer.size, index_buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU); ERR_FAIL_COND_V(!index_buffer.driver_id, RID()); @@ -2331,7 +2456,18 @@ RID RenderingDevice::index_buffer_create(uint32_t p_index_count, IndexBufferForm } if (p_data.size()) { + // + // @ShadyTF - if persistent UMA is available, copy and skip the barrier + uint8_t *persistent_data_ptr = driver->buffer_get_persistent_address(index_buffer.driver_id); + if (persistent_data_ptr ) { + memcpy(persistent_data_ptr, p_data.ptr(), p_data.size()); + } else { + // _buffer_update(&index_buffer, RID(), 0, p_data.ptr(), p_data.size()); + // + // @ShadyTF + } + // } buffer_memory += index_buffer.size; @@ -2372,7 +2508,13 @@ RID RenderingDevice::index_array_create(RID p_index_buffer, uint32_t p_index_off /****************/ static const char *SHADER_UNIFORM_NAMES[RenderingDevice::UNIFORM_TYPE_MAX] = { - "Sampler", "CombinedSampler", "Texture", "Image", "TextureBuffer", "SamplerTextureBuffer", "ImageBuffer", "UniformBuffer", "StorageBuffer", "InputAttachment" +// +// @ShadyTF +// Dynamic uniform buffer +// Was: +// "Sampler", "CombinedSampler", "Texture", "Image", "TextureBuffer", "SamplerTextureBuffer", "ImageBuffer", "UniformBuffer", "StorageBuffer", "InputAttachment" + "Sampler", "CombinedSampler", "Texture", "Image", "TextureBuffer", "SamplerTextureBuffer", "ImageBuffer", "UniformBuffer", "StorageBuffer", "InputAttachment", "UniformBufferDynamic" +// }; String RenderingDevice::_shader_uniform_debug(RID p_shader, int p_set) { @@ -2403,11 +2545,44 @@ Vector RenderingDevice::shader_compile_binary_from_spirv(const Vector &p_shader_binary, RID p_placeholder) { +// +// @ShadyTF +// immutable samplers : +// expanding api when creating shader to allow passing optionally a set of immutable samplers +// keeping existing api but extending it by sending an empty set + Vector immutable_samplers; + return shader_create_from_bytecode_with_samplers(p_shader_binary, p_placeholder, immutable_samplers); +} + +RID RenderingDevice::shader_create_from_bytecode_with_samplers(const Vector &p_shader_binary, RID p_placeholder, const Vector& r_immutable_samplers) { +// _THREAD_SAFE_METHOD_ ShaderDescription shader_desc; String name; - RDD::ShaderID shader_id = driver->shader_create_from_bytecode(p_shader_binary, shader_desc, name); + +// +// @ShadyTF +// immutable samplers +// passing them to device driver +// Was: +// RDD::ShaderID shader_id = driver->shader_create_from_bytecode(p_shader_binary, shader_desc, name, driver_immutable_samplers); + Vector driver_immutable_samplers; + for (int i = 0; i < r_immutable_samplers.size(); i++) { + const PipelineImmutableSampler& source_sampler = r_immutable_samplers[i]; + RDD::ImmutableSampler driver_sampler; + driver_sampler.type = source_sampler.uniform_type; + driver_sampler.binding = source_sampler.binding; + + for (uint32_t j = 0; j < source_sampler.get_id_count(); j++) { + RDD::SamplerID *sampler_driver_id = sampler_owner.get_or_null(source_sampler.get_id(j)); + driver_sampler.ids.push_back(*sampler_driver_id); + } + + driver_immutable_samplers.append(driver_sampler); + } + RDD::ShaderID shader_id = driver->shader_create_from_bytecode(p_shader_binary, shader_desc, name, driver_immutable_samplers); +// ERR_FAIL_COND_V(!shader_id, RID()); // All good, let's create modules. @@ -2478,6 +2653,26 @@ RID RenderingDevice::shader_create_from_bytecode(const Vector &p_shader return id; } +// +// @ShadyTF unload shader modules +void RenderingDevice::shader_destroy_modules(RID p_shader) { + Shader *shader = shader_owner.get_or_null(p_shader); + ERR_FAIL_NULL(shader); + driver->shader_destroy_modules(shader->driver_id); +} + +void RenderingDevice::_destroy_all_shader_modules() { + List remaining; + shader_owner.get_owned_list(&remaining); + if (remaining.size()) { + while (remaining.size()) { + shader_destroy_modules(remaining.front()->get()); + remaining.pop_front(); + } + } +} +// + RID RenderingDevice::shader_create_placeholder() { Shader shader; return shader_owner.make_rid(shader); @@ -2495,7 +2690,7 @@ uint64_t RenderingDevice::shader_get_vertex_input_attribute_mask(RID p_shader) { /**** UNIFORMS ****/ /******************/ -RID RenderingDevice::uniform_buffer_create(uint32_t p_size_bytes, const Vector &p_data) { +RID RenderingDevice::uniform_buffer_create(uint32_t p_size_bytes, const Vector &p_data, BitField p_creation_bits) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID()); @@ -2503,6 +2698,18 @@ RID RenderingDevice::uniform_buffer_create(uint32_t p_size_bytes, const Vector + // @ShadyTF persistently mapped buffers + // all uniform buffers are persistent + if (persistent_buffer_enabled && p_creation_bits.has_flag(BUFFER_CREATION_PERSISTENT_BIT) ){ + buffer.usage.set_flag(RDD::BUFFER_USAGE_PERSISTENT_BIT); + + if (p_creation_bits.has_flag(BUFFER_CREATION_LINEAR_BIT)) { + return linear_buffer_create(p_size_bytes, false); + } + } + // buffer.driver_id = driver->buffer_create(buffer.size, buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU); ERR_FAIL_COND_V(!buffer.driver_id, RID()); @@ -2524,8 +2731,42 @@ RID RenderingDevice::uniform_buffer_create(uint32_t p_size_bytes, const Vector -RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p_shader, uint32_t p_shader_set) { +// @ShadyTF : linear buffers +RID RenderingDevice::linear_buffer_create(uint32_t p_size_bytes, bool p_storage, BitField p_usage) { + _THREAD_SAFE_METHOD_ + LinearBuffer linear_buffer; + if (p_storage) { + linear_buffer.usage = (RDD::BUFFER_USAGE_TRANSFER_FROM_BIT | RDD::BUFFER_USAGE_TRANSFER_TO_BIT | RDD::BUFFER_USAGE_STORAGE_BIT| RDD::BUFFER_USAGE_PERSISTENT_BIT); + if (p_usage.has_flag(STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT)) { + linear_buffer.usage.set_flag(RDD::BUFFER_USAGE_INDIRECT_BIT); + } + } else { + linear_buffer.usage = (RDD::BUFFER_USAGE_TRANSFER_TO_BIT | RDD::BUFFER_USAGE_UNIFORM_BIT | RDD::BUFFER_USAGE_PERSISTENT_BIT); + } + + Buffer buffer; + buffer.size = p_size_bytes; + buffer.usage = linear_buffer.usage; + buffer.driver_id = driver->buffer_create(buffer.size, buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU); + ERR_FAIL_COND_V(!buffer.driver_id, RID()); + buffer_memory += buffer.size; + + linear_buffer.buffers.append(buffer); + linear_buffer.usage_index = -1; + linear_buffer.size = p_size_bytes; + + RID id = linear_buffer_owner.make_rid(linear_buffer); + return id; +} +// +// @ShadyTF : +// descriptor optimizations : allow the option to have linearly allocated uniform set pools for frame allocated uniform sets +// Was: +//RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p_shader, uint32_t p_shader_set) { +RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool) { +// _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_uniforms.is_empty(), RID()); @@ -2560,6 +2801,7 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p for (int j = 0; j < (int)uniform_count; j++) { if (uniforms[j].binding == set_uniform.binding) { uniform_idx = j; + break; } } ERR_FAIL_COND_V_MSG(uniform_idx == -1, RID(), @@ -2574,6 +2816,13 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p driver_uniform.type = uniform.uniform_type; driver_uniform.binding = uniform.binding; +// +// @ShadyTF +// immutable samplers +// mark immutable samplers to be skipped when creating uniform set + driver_uniform.immutable_sampler = uniform.immutable_sampler; +// + switch (uniform.uniform_type) { case UNIFORM_TYPE_SAMPLER: { if (uniform.get_id_count() != (uint32_t)set_uniform.length) { @@ -2771,12 +3020,24 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p case UNIFORM_TYPE_IMAGE_BUFFER: { // Todo. } break; - case UNIFORM_TYPE_UNIFORM_BUFFER: { + +// Was: +// case UNIFORM_TYPE_UNIFORM_BUFFER: { + case UNIFORM_TYPE_UNIFORM_BUFFER: + case UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC:{ +// ERR_FAIL_COND_V_MSG(uniform.get_id_count() != 1, RID(), "Uniform buffer supplied (binding: " + itos(uniform.binding) + ") must provide one ID (" + itos(uniform.get_id_count()) + " provided)."); RID buffer_id = uniform.get_id(0); Buffer *buffer = uniform_buffer_owner.get_or_null(buffer_id); + // + // @ShadyTF linear buffers + if (buffer == nullptr) { + LinearBuffer *linear_buffer = linear_buffer_owner.get_or_null(uniform.get_id(0)); + buffer = linear_buffer->buffers.ptrw() + MAX(0, linear_buffer->usage_index); + } + // ERR_FAIL_NULL_V_MSG(buffer, RID(), "Uniform buffer supplied (binding: " + itos(uniform.binding) + ") is invalid."); ERR_FAIL_COND_V_MSG(buffer->size < (uint32_t)set_uniform.length, RID(), @@ -2861,7 +3122,13 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p } } - RDD::UniformSetID driver_uniform_set = driver->uniform_set_create(driver_uniforms, shader->driver_id, p_shader_set); +// +// @ShadyTF : +// descriptor optimizations : allow the option to have linearly allocated uniform set pools for frame allocated uniform sets +// Was: +// RDD::UniformSetID driver_uniform_set = driver->uniform_set_create(driver_uniforms, shader->driver_id, p_shader_set); + RDD::UniformSetID driver_uniform_set = driver->uniform_set_create(driver_uniforms, shader->driver_id, p_shader_set, p_linear_pool ? frame : -1 ); +// ERR_FAIL_COND_V(!driver_uniform_set, RID()); UniformSet uniform_set; @@ -3164,6 +3431,23 @@ Error RenderingDevice::screen_create(DisplayServer::WindowID p_screen) { Error RenderingDevice::screen_prepare_for_drawing(DisplayServer::WindowID p_screen) { _THREAD_SAFE_METHOD_ + // @NicolaTF: Submit offscreen rendering and swap the command buffers + if (separate_queue_submissions && !screen_prepared) { + screen_prepared = true; + + _end_frame(); + _execute_frame(false, true); + + SWAP(frames[frame].draw_command_buffer, frames[frame].blit_draw_command_buffer); + SWAP(frames[frame].setup_command_buffer, frames[frame].blit_setup_command_buffer); + + // Reset the graph. + draw_graph.begin(); + } else if (!separate_queue_submissions) { + screen_prepared = true; + } + + // After submitting work, acquire the swapchain image(s) HashMap::ConstIterator it = screen_swap_chains.find(p_screen); ERR_FAIL_COND_V_MSG(it == screen_swap_chains.end(), ERR_CANT_CREATE, "A swap chain was not created for the screen."); @@ -3185,7 +3469,11 @@ Error RenderingDevice::screen_prepare_for_drawing(DisplayServer::WindowID p_scre RDD::FramebufferID framebuffer = driver->swap_chain_acquire_framebuffer(main_queue, it->value, resize_required); if (resize_required) { // Flush everything so nothing can be using the swap chain before resizing it. - _flush_and_stall_for_all_frames(); + if (!separate_queue_submissions) { + _flush_and_stall_for_all_frames(); + } else { + _stall_for_previous_frames(); + } Error err = driver->swap_chain_resize(main_queue, it->value, _get_swap_chain_desired_count()); if (err != OK) { @@ -3284,7 +3572,7 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin_for_screen(DisplayS clear_value.color = p_clear_color; RDD::RenderPassID render_pass = driver->swap_chain_get_render_pass(sc_it->value); - draw_graph.add_draw_list_begin(render_pass, fb_it->value, viewport, clear_value, true, false); + draw_graph.add_draw_list_begin(render_pass, fb_it->value, viewport, clear_value, true, false, RDD::BreadcrumbMarker::BLIT_PASS << 16); _draw_list_set_viewport(viewport); _draw_list_set_scissor(viewport); @@ -3333,14 +3621,12 @@ Error RenderingDevice::_draw_list_setup_framebuffer(Framebuffer *p_framebuffer, return OK; } -Error RenderingDevice::_draw_list_render_pass_begin(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i p_viewport_offset, Point2i p_viewport_size, RDD::FramebufferID p_framebuffer_driver_id, RDD::RenderPassID p_render_pass) { +Error RenderingDevice::_draw_list_render_pass_begin(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i p_viewport_offset, Point2i p_viewport_size, RDD::FramebufferID p_framebuffer_driver_id, RDD::RenderPassID p_render_pass, uint32_t p_breadcrumb) { LocalVector clear_values; LocalVector resource_trackers; LocalVector resource_usages; bool uses_color = false; bool uses_depth = false; - clear_values.resize(p_framebuffer->texture_ids.size()); - int clear_values_count = 0; { int color_index = 0; for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) { @@ -3370,11 +3656,14 @@ Error RenderingDevice::_draw_list_render_pass_begin(Framebuffer *p_framebuffer, uses_depth = true; } - clear_values[clear_values_count++] = clear_value; + if (p_initial_color_action == INITIAL_ACTION_CLEAR || p_initial_color_action == INITIAL_ACTION_CLEAR_REGION || p_initial_color_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE || + p_initial_depth_action == INITIAL_ACTION_CLEAR || p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION || p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + clear_values.push_back(clear_value); + } } } - - draw_graph.add_draw_list_begin(p_render_pass, p_framebuffer_driver_id, Rect2i(p_viewport_offset, p_viewport_size), clear_values, uses_color, uses_depth); + + draw_graph.add_draw_list_begin(p_render_pass, p_framebuffer_driver_id, Rect2i(p_viewport_offset, p_viewport_size), clear_values, uses_color, uses_depth, p_breadcrumb); draw_graph.add_draw_list_usages(resource_trackers, resource_usages); // Mark textures as bound. @@ -3436,7 +3725,7 @@ void RenderingDevice::_draw_list_insert_clear_region(DrawList *p_draw_list, Fram draw_graph.add_draw_list_clear_attachments(clear_attachments, rect); } -RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) { +RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, RDD::BreadcrumbMarker p_phase, uint32_t p_breadcrumb_data) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); @@ -3482,7 +3771,8 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer, Error err = _draw_list_setup_framebuffer(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, &fb_driver_id, &render_pass, &draw_list_subpass_count); ERR_FAIL_COND_V(err != OK, INVALID_ID); - err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, fb_driver_id, render_pass); + uint32_t breadcrumb = (p_phase << 16) | (p_breadcrumb_data & ((1 << 16) - 1)); + err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, fb_driver_id, render_pass, breadcrumb); if (err != OK) { return INVALID_ID; @@ -3655,6 +3945,55 @@ void RenderingDevice::draw_list_bind_uniform_set(DrawListID p_list, RID p_unifor } #endif } +// +// @ShadyTF +// Dynamic uniform buffer +void RenderingDevice::draw_list_bind_uniform_set_dynamic(DrawListID p_list, RID p_uniform_set, uint32_t p_index, uint32_t p_offsets_count, const uint32_t* p_offsets) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_MSG(p_index >= driver->limit_get(LIMIT_MAX_BOUND_UNIFORM_SETS) || p_index >= MAX_UNIFORM_SETS, + "Attempting to bind a descriptor set (" + itos(p_index) + ") greater than what the hardware supports (" + itos(driver->limit_get(LIMIT_MAX_BOUND_UNIFORM_SETS)) + ")."); +#endif + DrawList *dl = _get_draw_list_ptr(p_list); + ERR_FAIL_NULL(dl); + +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); +#endif + +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_MSG(!p_offsets, "offsets ,ust be provided for dynamic uniform set."); +#endif + + const UniformSet *uniform_set = uniform_set_owner.get_or_null(p_uniform_set); + ERR_FAIL_NULL(uniform_set); + + if (p_index > dl->state.set_count) { + dl->state.set_count = p_index; + } + + dl->state.sets[p_index].uniform_set_driver_id = uniform_set->driver_id; // Update set pointer. + dl->state.sets[p_index].bound = false; // Needs rebind. + dl->state.sets[p_index].uniform_set_format = uniform_set->format; + dl->state.sets[p_index].uniform_set = p_uniform_set; + dl->state.sets[p_index].offsets = p_offsets; + dl->state.sets[p_index].offsets_count = p_offsets_count; + +#ifdef DEBUG_ENABLED + { // Validate that textures bound are not attached as framebuffer bindings. + uint32_t attachable_count = uniform_set->attachable_textures.size(); + const UniformSet::AttachableTexture *attachable_ptr = uniform_set->attachable_textures.ptr(); + uint32_t bound_count = draw_list_bound_textures.size(); + const RID *bound_ptr = draw_list_bound_textures.ptr(); + for (uint32_t i = 0; i < attachable_count; i++) { + for (uint32_t j = 0; j < bound_count; j++) { + ERR_FAIL_COND_MSG(attachable_ptr[i].texture == bound_ptr[j], + "Attempted to use the same texture in framebuffer attachment and a uniform (set: " + itos(p_index) + ", binding: " + itos(attachable_ptr[i].bind) + "), this is not allowed."); + } + } + } +#endif +} +// void RenderingDevice::draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) { DrawList *dl = _get_draw_list_ptr(p_list); @@ -3773,7 +4112,12 @@ void RenderingDevice::draw_list_draw(DrawListID p_list, bool p_use_indices, uint #endif - // Bind descriptor sets. + // Get valid descriptor sets + RDD::UniformSetID *valid_descriptor_ids = (RDD::UniformSetID *)alloca(dl->state.set_count * sizeof(RDD::UniformSetID)); + uint32_t valid_set_count = 0; + uint32_t first_set_index = 0; + uint32_t last_set_index = 0; + bool found_first_set = false; for (uint32_t i = 0; i < dl->state.set_count; i++) { if (dl->state.sets[i].pipeline_expected_format == 0) { @@ -3791,23 +4135,52 @@ void RenderingDevice::draw_list_draw(DrawListID p_list, bool p_use_indices, uint } } #endif + if (!dl->state.sets[i].bound && !found_first_set) { + first_set_index = i; + found_first_set = true; + } draw_graph.add_draw_list_uniform_set_prepare_for_use(dl->state.pipeline_shader_driver_id, dl->state.sets[i].uniform_set_driver_id, i); } - for (uint32_t i = 0; i < dl->state.set_count; i++) { + + for (uint32_t i = first_set_index; i < dl->state.set_count; i++) { if (dl->state.sets[i].pipeline_expected_format == 0) { continue; // Nothing expected by this pipeline. } + if (!dl->state.sets[i].bound) { - // All good, see if this requires re-binding. - draw_graph.add_draw_list_bind_uniform_set(dl->state.pipeline_shader_driver_id, dl->state.sets[i].uniform_set_driver_id, i); + // @NicolaTF: batch contiguous descriptor sets in a single call + if (descriptor_set_batching) { + // All good, see if this requires re-binding. + if (i - last_set_index > 1) { + // If the descriptor sets are not contiguous, bind the previous ones and start a new batch + draw_graph.add_draw_list_bind_uniform_sets(dl->state.pipeline_shader_driver_id, VectorView(valid_descriptor_ids, valid_set_count), first_set_index, valid_set_count); + + first_set_index = i; + valid_set_count = 1; + valid_descriptor_ids[0] = dl->state.sets[i].uniform_set_driver_id; + } else { + // Otherwise, keep storing in the current batch + valid_descriptor_ids[valid_set_count] = dl->state.sets[i].uniform_set_driver_id; + valid_set_count++; + } - UniformSet *uniform_set = uniform_set_owner.get_or_null(dl->state.sets[i].uniform_set); - draw_graph.add_draw_list_usages(uniform_set->draw_trackers, uniform_set->draw_trackers_usage); + UniformSet *uniform_set = uniform_set_owner.get_or_null(dl->state.sets[i].uniform_set); + draw_graph.add_draw_list_usages(uniform_set->draw_trackers, uniform_set->draw_trackers_usage); + dl->state.sets[i].bound = true; - dl->state.sets[i].bound = true; + last_set_index = i; + } + else { + draw_graph.add_draw_list_bind_uniform_set(dl->state.pipeline_shader_driver_id, dl->state.sets[i].uniform_set_driver_id, i); + } } } + // Bind the remaining batch + if (descriptor_set_batching && valid_set_count > 0) { + draw_graph.add_draw_list_bind_uniform_sets(dl->state.pipeline_shader_driver_id, VectorView(valid_descriptor_ids, valid_set_count), first_set_index, valid_set_count); + } + if (p_use_indices) { #ifdef DEBUG_ENABLED ERR_FAIL_COND_MSG(p_procedural_vertices > 0, @@ -3859,6 +4232,22 @@ void RenderingDevice::draw_list_draw(DrawListID p_list, bool p_use_indices, uint } } +void RenderingDevice::draw_list_set_viewport(DrawListID p_list, const Rect2 &p_rect) { + DrawList *dl = _get_draw_list_ptr(p_list); + + ERR_FAIL_NULL(dl); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); +#endif + + if (p_rect.get_area() == 0) { + return; + } + + dl->viewport = p_rect; + _draw_list_set_viewport(p_rect); +} + void RenderingDevice::draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect) { DrawList *dl = _get_draw_list_ptr(p_list); @@ -4164,7 +4553,12 @@ void RenderingDevice::compute_list_dispatch(ComputeListID p_list, uint32_t p_x_g #endif - // Bind descriptor sets. + // Get valid descriptor sets + RDD::UniformSetID *valid_descriptor_ids = (RDD::UniformSetID *)alloca(cl->state.set_count * sizeof(RDD::UniformSetID)); + uint32_t valid_set_count = 0; + uint32_t first_set_index = 0; + uint32_t last_set_index = 0; + bool found_first_set = false; for (uint32_t i = 0; i < cl->state.set_count; i++) { if (cl->state.sets[i].pipeline_expected_format == 0) { @@ -4182,23 +4576,51 @@ void RenderingDevice::compute_list_dispatch(ComputeListID p_list, uint32_t p_x_g } } #endif + + if (!cl->state.sets[i].bound && !found_first_set) { + first_set_index = i; + found_first_set = true; + } + draw_graph.add_compute_list_uniform_set_prepare_for_use(cl->state.pipeline_shader_driver_id, cl->state.sets[i].uniform_set_driver_id, i); } - for (uint32_t i = 0; i < cl->state.set_count; i++) { + + for (uint32_t i = first_set_index; i < cl->state.set_count; i++) { if (cl->state.sets[i].pipeline_expected_format == 0) { continue; // Nothing expected by this pipeline. } + if (!cl->state.sets[i].bound) { - // All good, see if this requires re-binding. - draw_graph.add_compute_list_bind_uniform_set(cl->state.pipeline_shader_driver_id, cl->state.sets[i].uniform_set_driver_id, i); + // @NicolaTF: descriptor set batching + if (descriptor_set_batching) { + // All good, see if this requires re-binding. + if (i - last_set_index > 1) { + // If the descriptor sets are not contiguous, bind the previous ones and start a new batch + draw_graph.add_compute_list_bind_uniform_sets(cl->state.pipeline_shader_driver_id, VectorView(valid_descriptor_ids, valid_set_count), first_set_index, valid_set_count); + + first_set_index = i; + valid_set_count = 1; + valid_descriptor_ids[0] = cl->state.sets[i].uniform_set_driver_id; + } else { + // Otherwise, keep storing in the current batch + valid_descriptor_ids[valid_set_count] = cl->state.sets[i].uniform_set_driver_id; + valid_set_count++; + } + last_set_index = i; + } + else { + draw_graph.add_compute_list_bind_uniform_set(cl->state.pipeline_shader_driver_id, cl->state.sets[i].uniform_set_driver_id, i); + } UniformSet *uniform_set = uniform_set_owner.get_or_null(cl->state.sets[i].uniform_set); draw_graph.add_compute_list_usages(uniform_set->draw_trackers, uniform_set->draw_trackers_usage); - cl->state.sets[i].bound = true; } } + // Bind the remaining batch + if (valid_set_count > 0) + draw_graph.add_compute_list_bind_uniform_sets(cl->state.pipeline_shader_driver_id, VectorView(valid_descriptor_ids, valid_set_count), first_set_index, valid_set_count); draw_graph.add_compute_list_dispatch(p_x_groups, p_y_groups, p_z_groups); } @@ -4258,6 +4680,11 @@ void RenderingDevice::compute_list_dispatch_indirect(ComputeListID p_list, RID p #endif // Bind descriptor sets. + RDD::UniformSetID *valid_descriptor_ids = (RDD::UniformSetID *)alloca(cl->state.set_count * sizeof(RDD::UniformSetID)); + uint32_t valid_set_count = 0; + uint32_t first_set_index = 0; + uint32_t last_set_index = 0; + bool found_first_set = false; for (uint32_t i = 0; i < cl->state.set_count; i++) { if (cl->state.sets[i].pipeline_expected_format == 0) { @@ -4275,23 +4702,46 @@ void RenderingDevice::compute_list_dispatch_indirect(ComputeListID p_list, RID p } } #endif + if (!cl->state.sets[i].bound && !found_first_set) { + first_set_index = i; + found_first_set = true; + } + draw_graph.add_compute_list_uniform_set_prepare_for_use(cl->state.pipeline_shader_driver_id, cl->state.sets[i].uniform_set_driver_id, i); } - for (uint32_t i = 0; i < cl->state.set_count; i++) { + + for (uint32_t i = first_set_index; i < cl->state.set_count; i++) { if (cl->state.sets[i].pipeline_expected_format == 0) { continue; // Nothing expected by this pipeline. } + if (!cl->state.sets[i].bound) { // All good, see if this requires re-binding. - draw_graph.add_compute_list_bind_uniform_set(cl->state.pipeline_shader_driver_id, cl->state.sets[i].uniform_set_driver_id, i); + if (i - last_set_index > 1) { + // If the descriptor sets are not contiguous, bind the previous ones and start a new batch + draw_graph.add_compute_list_bind_uniform_sets(cl->state.pipeline_shader_driver_id, VectorView(valid_descriptor_ids, valid_set_count), first_set_index, valid_set_count); + + first_set_index = i; + valid_set_count = 1; + valid_descriptor_ids[0] = cl->state.sets[i].uniform_set_driver_id; + } else { + // Otherwise, keep storing in the current batch + valid_descriptor_ids[valid_set_count] = cl->state.sets[i].uniform_set_driver_id; + valid_set_count++; + } + + last_set_index = i; UniformSet *uniform_set = uniform_set_owner.get_or_null(cl->state.sets[i].uniform_set); draw_graph.add_compute_list_usages(uniform_set->draw_trackers, uniform_set->draw_trackers_usage); - cl->state.sets[i].bound = true; } } + // Bind the remaining batch + if (valid_set_count > 0) + draw_graph.add_compute_list_bind_uniform_sets(cl->state.pipeline_shader_driver_id, VectorView(valid_descriptor_ids, valid_set_count), first_set_index, valid_set_count); + draw_graph.add_compute_list_dispatch_indirect(buffer->driver_id, p_offset); if (buffer->draw_tracker != nullptr) { @@ -4576,6 +5026,15 @@ void RenderingDevice::_free_internal(RID p_id) { RDG::resource_tracker_free(uniform_buffer->draw_tracker); frames[frame].buffers_to_dispose_of.push_back(*uniform_buffer); uniform_buffer_owner.free(p_id); + // + // @ShadyTF linear buffers + } else if (linear_buffer_owner.owns(p_id)) { + LinearBuffer *linear_uniform_buffer = linear_buffer_owner.get_or_null(p_id); + for (const Buffer &buffer : linear_uniform_buffer->buffers) { + frames[frame].buffers_to_dispose_of.push_back(buffer); + } + linear_buffer_owner.free(p_id); + // } else if (texture_buffer_owner.owns(p_id)) { Buffer *texture_buffer = texture_buffer_owner.get_or_null(p_id); RDG::resource_tracker_free(texture_buffer->draw_tracker); @@ -4635,7 +5094,7 @@ void RenderingDevice::set_resource_name(RID p_id, const String &p_name) { } else if (uniform_buffer_owner.owns(p_id)) { Buffer *uniform_buffer = uniform_buffer_owner.get_or_null(p_id); driver->set_object_name(RDD::OBJECT_TYPE_BUFFER, uniform_buffer->driver_id, p_name); - } else if (texture_buffer_owner.owns(p_id)) { + } else if (texture_buffer_owner.owns(p_id)) { Buffer *texture_buffer = texture_buffer_owner.get_or_null(p_id); driver->set_object_name(RDD::OBJECT_TYPE_BUFFER, texture_buffer->driver_id, p_name); } else if (storage_buffer_owner.owns(p_id)) { @@ -4663,7 +5122,7 @@ void RenderingDevice::draw_command_begin_label(String p_label_name, const Color if (!context->is_debug_utils_enabled()) { return; } - + draw_graph.begin_label(p_label_name, p_color); } @@ -4705,22 +5164,29 @@ void RenderingDevice::swap_buffers() { _THREAD_SAFE_METHOD_ _end_frame(); - _execute_frame(true); + _execute_frame(true, true); + + // @NicolaTF: restore command buffers + if (separate_queue_submissions) { + SWAP(frames[frame].draw_command_buffer, frames[frame].blit_draw_command_buffer); + SWAP(frames[frame].setup_command_buffer, frames[frame].blit_setup_command_buffer); + } // Advance to the next frame and begin recording again. frame = (frame + 1) % frames.size(); - _begin_frame(); + + _begin_frame(true); } void RenderingDevice::submit() { _THREAD_SAFE_METHOD_ _end_frame(); - _execute_frame(false); + _execute_frame(false, false); } void RenderingDevice::sync() { _THREAD_SAFE_METHOD_ - _begin_frame(); + _begin_frame(true); } void RenderingDevice::_free_pending_resources(int p_frame) { @@ -4809,6 +5275,10 @@ uint32_t RenderingDevice::get_frame_delay() const { return frames.size(); } +uint32_t RenderingDevice::get_current_frame_index() const { + return frame; +} + uint64_t RenderingDevice::get_memory_usage(MemoryType p_type) const { switch (p_type) { case MEMORY_BUFFERS: { @@ -4827,18 +5297,40 @@ uint64_t RenderingDevice::get_memory_usage(MemoryType p_type) const { } } -void RenderingDevice::_begin_frame() { +void RenderingDevice::_begin_frame(bool presented) { + screen_prepared = false; + // Before beginning this frame, wait on the fence if it was signaled to make sure its work is finished. if (frames[frame].draw_fence_signaled) { driver->fence_wait(frames[frame].draw_fence); frames[frame].draw_fence_signaled = false; } + // @NicolaTF: manually reset command pool + if (command_pool_reset_enabled) { + bool reset = driver->command_pool_reset(frames[frame].command_pool); + ERR_FAIL_COND(!reset); + } + + if (presented) { + // + // @ShadyTF linear buffers + // reset linear uniform + linear_uniform_buffers_reset(); + update_perf_report(); + // reset linear descriptor sets + driver->linear_uniform_set_pools_reset(frame); + // + } + // Begin recording on the frame's command buffers. driver->begin_segment(frame, frames_drawn++); driver->command_buffer_begin(frames[frame].setup_command_buffer); driver->command_buffer_begin(frames[frame].draw_command_buffer); - + if (separate_queue_submissions) { + driver->command_buffer_begin(frames[frame].blit_setup_command_buffer); + driver->command_buffer_begin(frames[frame].blit_draw_command_buffer); + } // Reset the graph. draw_graph.begin(); @@ -4875,25 +5367,62 @@ void RenderingDevice::_end_frame() { draw_graph.end(frames[frame].draw_command_buffer, RENDER_GRAPH_REORDER, RENDER_GRAPH_FULL_BARRIERS); driver->command_buffer_end(frames[frame].setup_command_buffer); driver->command_buffer_end(frames[frame].draw_command_buffer); + // @NicolaTF: when merging, remove this if statement completely + if (!screen_prepared && !command_pool_reset_enabled && separate_queue_submissions) { + driver->command_buffer_end(frames[frame].blit_setup_command_buffer); + driver->command_buffer_end(frames[frame].blit_draw_command_buffer); + } driver->end_segment(); } -void RenderingDevice::_execute_frame(bool p_present) { - const bool frame_can_present = p_present && !frames[frame].swap_chains_to_present.is_empty(); - const bool separate_present_queue = main_queue != present_queue; - const VectorView execute_draw_semaphore = frame_can_present && separate_present_queue ? frames[frame].draw_semaphore : VectorView(); - const VectorView execute_draw_swap_chains = frame_can_present && !separate_present_queue ? frames[frame].swap_chains_to_present : VectorView(); - driver->command_queue_execute_and_present(main_queue, {}, frames[frame].setup_command_buffer, frames[frame].setup_semaphore, {}, {}); - driver->command_queue_execute_and_present(main_queue, frames[frame].setup_semaphore, frames[frame].draw_command_buffer, execute_draw_semaphore, frames[frame].draw_fence, execute_draw_swap_chains); - frames[frame].draw_fence_signaled = true; +void RenderingDevice::_execute_frame(bool p_present, bool p_swap) { + if (!separate_queue_submissions) { + const bool frame_can_present = p_present && !frames[frame].swap_chains_to_present.is_empty(); + const bool separate_present_queue = main_queue != present_queue; + const VectorView execute_draw_semaphore = frame_can_present && separate_present_queue ? frames[frame].draw_semaphore : VectorView(); + const VectorView execute_draw_swap_chains = frame_can_present && !separate_present_queue ? frames[frame].swap_chains_to_present : VectorView(); + driver->command_queue_execute_and_present(main_queue, {}, frames[frame].setup_command_buffer, frames[frame].setup_semaphore, {}, {}); + driver->command_queue_execute_and_present(main_queue, frames[frame].setup_semaphore, frames[frame].draw_command_buffer, execute_draw_semaphore, frames[frame].draw_fence, execute_draw_swap_chains); + frames[frame].draw_fence_signaled = true; + + if (frame_can_present) { + if (separate_present_queue) { + // Issue the presentation separately if the presentation queue is different from the main queue. + driver->command_queue_execute_and_present(present_queue, frames[frame].draw_semaphore, {}, {}, {}, frames[frame].swap_chains_to_present); + } - if (frame_can_present) { - if (separate_present_queue) { - // Issue the presentation separately if the presentation queue is different from the main queue. - driver->command_queue_execute_and_present(present_queue, frames[frame].draw_semaphore, {}, {}, {}, frames[frame].swap_chains_to_present); + frames[frame].swap_chains_to_present.clear(); } - frames[frame].swap_chains_to_present.clear(); + return; + } + + // Command flushing, don't present and continue immediately + if (!p_swap) { + driver->command_queue_execute_and_present(main_queue, {}, frames[frame].setup_command_buffer, frames[frame].setup_semaphore, {}, {}); + driver->command_queue_execute_and_present(main_queue, frames[frame].setup_semaphore, frames[frame].draw_command_buffer, VectorView(), frames[frame].draw_fence, VectorView()); + frames[frame].draw_fence_signaled = true; + } + // Submit offscreen rendering + else { + const bool frame_can_present = p_present && !frames[frame].swap_chains_to_present.is_empty(); + const bool separate_present_queue = main_queue != present_queue; + const VectorView signal_draw_semaphore = frame_can_present && separate_present_queue ? frames[frame].blit_semaphore : (frame_can_present ? VectorView() : frames[frame].draw_semaphore); + const VectorView draw_swap_chains = frame_can_present && !separate_present_queue ? frames[frame].swap_chains_to_present : VectorView(); + const RDD::FenceID fence = frame_can_present ? frames[frame].draw_fence : RDD::FenceID{}; + + driver->command_queue_execute_and_present(main_queue, frame_can_present ? frames[frame].draw_semaphore : VectorView(), frames[frame].setup_command_buffer, frames[frame].setup_semaphore, {}, {}); + driver->command_queue_execute_and_present(main_queue, frames[frame].setup_semaphore, frames[frame].draw_command_buffer, signal_draw_semaphore, fence, draw_swap_chains); + + if (frame_can_present) { + if (separate_present_queue) { + // Issue the presentation separately if the presentation queue is different from the main queue. + driver->command_queue_execute_and_present(present_queue, frames[frame].blit_semaphore, {}, {}, {}, frames[frame].swap_chains_to_present); + } + + frames[frame].draw_fence_signaled = true; + frames[frame].swap_chains_to_present.clear(); + } } } @@ -4909,7 +5438,7 @@ void RenderingDevice::_stall_for_previous_frames() { void RenderingDevice::_flush_and_stall_for_all_frames() { _stall_for_previous_frames(); _end_frame(); - _execute_frame(false); + _execute_frame(false, false); _begin_frame(); } @@ -4959,6 +5488,7 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ frame = 0; frames.resize(frame_count); + max_timestamp_query_elements = 256; device = context->device_get(device_index); @@ -5018,14 +5548,22 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ // Create command pool, command buffers, semaphores and fences. frames[i].command_pool = driver->command_pool_create(main_queue_family, RDD::COMMAND_BUFFER_TYPE_PRIMARY); ERR_FAIL_COND_V(!frames[i].command_pool, FAILED); + frames[i].setup_command_buffer = driver->command_buffer_create(frames[i].command_pool); ERR_FAIL_COND_V(!frames[i].setup_command_buffer, FAILED); frames[i].draw_command_buffer = driver->command_buffer_create(frames[i].command_pool); - ERR_FAIL_COND_V(!frames[i].draw_command_buffer, FAILED); + ERR_FAIL_COND_V(!frames[i].setup_command_buffer, FAILED); + frames[i].blit_setup_command_buffer = driver->command_buffer_create(frames[i].command_pool); + ERR_FAIL_COND_V(!frames[i].blit_setup_command_buffer, FAILED); + frames[i].blit_draw_command_buffer = driver->command_buffer_create(frames[i].command_pool); + ERR_FAIL_COND_V(!frames[i].blit_draw_command_buffer, FAILED); + frames[i].setup_semaphore = driver->semaphore_create(); ERR_FAIL_COND_V(!frames[i].setup_semaphore, FAILED); frames[i].draw_semaphore = driver->semaphore_create(); ERR_FAIL_COND_V(!frames[i].draw_semaphore, FAILED); + frames[i].blit_semaphore = driver->semaphore_create(); + ERR_FAIL_COND_V(!frames[i].draw_semaphore, FAILED); frames[i].draw_fence = driver->fence_create(); ERR_FAIL_COND_V(!frames[i].draw_fence, FAILED); frames[i].draw_fence_signaled = false; @@ -5048,6 +5586,8 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ driver->begin_segment(frame, frames_drawn++); driver->command_buffer_begin(frames[0].setup_command_buffer); driver->command_buffer_begin(frames[0].draw_command_buffer); + driver->command_buffer_begin(frames[0].blit_setup_command_buffer); + driver->command_buffer_begin(frames[0].blit_draw_command_buffer); // Create draw graph and start it initialized as well. draw_graph.initialize(driver, frames.size(), main_queue_family, SECONDARY_COMMAND_BUFFERS_PER_FRAME); @@ -5254,6 +5794,12 @@ uint64_t RenderingDevice::get_driver_resource(DriverResource p_resource, RID p_r buffer = index_buffer_owner.get_or_null(p_rid); } else if (uniform_buffer_owner.owns(p_rid)) { buffer = uniform_buffer_owner.get_or_null(p_rid); + // + // @ShadyTF linear buffers + } else if (linear_buffer_owner.owns(p_rid)) { + LinearBuffer* linear_buffer = linear_buffer_owner.get_or_null(p_rid); + buffer = linear_buffer->buffers.ptrw() + linear_buffer->usage_index; + // } else if (texture_buffer_owner.owns(p_rid)) { buffer = texture_buffer_owner.get_or_null(p_rid); } else if (storage_buffer_owner.owns(p_rid)) { @@ -5377,6 +5923,7 @@ void RenderingDevice::finalize() { driver->timestamp_query_pool_free(frames[i].timestamp_pool); driver->semaphore_free(frames[i].setup_semaphore); driver->semaphore_free(frames[i].draw_semaphore); + driver->semaphore_free(frames[i].blit_semaphore); driver->fence_free(frames[i].draw_fence); } diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index ce7128d56476..f9bd68502063 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -181,6 +181,30 @@ class RenderingDevice : public RenderingDeviceCommons { Buffer *_get_buffer_from_owner(RID p_buffer); Error _buffer_update(Buffer *p_buffer, RID p_buffer_id, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_queue = false, uint32_t p_required_align = 32); + // + // @ShadyTF persistently mapped buffers + struct LinearBuffer { + uint32_t size; + BitField usage; + int usage_index; + uint32_t usage_frame; + Vector buffers; + }; + RID_Owner linear_buffer_owner; + void linear_uniform_buffer_advance(RID p_buffer); + void linear_uniform_buffers_reset(); + void update_perf_report(); + // flag for using persistent buffers; + bool persistent_buffer_enabled = true; + // flag for batching descriptor sets + bool descriptor_set_batching = true; + // flag for separate queue submissions + bool separate_queue_submissions = true; + uint32_t gpu_copy_count = 0; + uint32_t direct_copy_count = 0; + uint32_t copy_bytes_count = 0; + String perf_report_text; + // RID_Owner uniform_buffer_owner; RID_Owner storage_buffer_owner; RID_Owner texture_buffer_owner; @@ -547,6 +571,7 @@ class RenderingDevice : public RenderingDeviceCommons { void framebuffer_set_invalidation_callback(RID p_framebuffer, InvalidationCallback p_callback, void *p_userdata); FramebufferFormatID framebuffer_get_format(RID p_framebuffer); + Size2 framebuffer_get_size(RID p_framebuffer); /*****************/ /**** SAMPLER ****/ @@ -815,6 +840,11 @@ class RenderingDevice : public RenderingDeviceCommons { RID shader_create_from_spirv(const Vector &p_spirv, const String &p_shader_name = ""); RID shader_create_from_bytecode(const Vector &p_shader_binary, RID p_placeholder = RID()); RID shader_create_placeholder(); + // + // @ShadyTF unload shader modules + void shader_destroy_modules(RID p_shaderRID); + void _destroy_all_shader_modules(); + // uint64_t shader_get_vertex_input_attribute_mask(RID p_shader); @@ -826,14 +856,40 @@ class RenderingDevice : public RenderingDeviceCommons { STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT = 1, }; - RID uniform_buffer_create(uint32_t p_size_bytes, const Vector &p_data = Vector()); - RID storage_buffer_create(uint32_t p_size, const Vector &p_data = Vector(), BitField p_usage = 0); + // + // @ShadyTF + // was + // + //RID uniform_buffer_create(uint32_t p_size_bytes, const Vector &p_data = Vector()); + //RID storage_buffer_create(uint32_t p_size, const Vector &p_data = Vector()); + + String get_perf_report() const; + /*****************/ + /**** BUFFERS ****/ + /*****************/ + + enum BufferCreationBits { + BUFFER_CREATION_PERSISTENT_BIT = (1 << 0), + BUFFER_CREATION_LINEAR_BIT = (1 << 1) + }; + + RID linear_buffer_create(uint32_t p_size_bytes, bool p_storage, BitField p_usage = 0); + RID uniform_buffer_create(uint32_t p_size_bytes, const Vector &p_data = Vector(), BitField p_creation_bits = 0); + RID storage_buffer_create(uint32_t p_size, const Vector &p_data = Vector(), BitField p_usage = 0, BitField p_creation_bits = 0); + + // + RID texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector &p_data = Vector()); struct Uniform { UniformType uniform_type = UNIFORM_TYPE_IMAGE; uint32_t binding = 0; // Binding index as specified in shader. +// +// @ShadyTF +// immutable samplers, this flag specifies that this is an immutable sampler to be set when creating pipeline layout + bool immutable_sampler = false; +// private: // In most cases only one ID is provided per binding, so avoid allocating memory unnecessarily for performance. RID id; // If only one is provided, this is used. @@ -893,6 +949,13 @@ class RenderingDevice : public RenderingDeviceCommons { _FORCE_INLINE_ Uniform() = default; }; +// +// @ShadyTF +// immutable samplers +// alternate method to create shader from bytecode with immutable samplers provided in + typedef Uniform PipelineImmutableSampler; + RID shader_create_from_bytecode_with_samplers(const Vector &p_shader_binary, RID p_placeholder = RID(), const Vector& r_immutable_samplers = Vector()); +// private: static const uint32_t MAX_UNIFORM_SETS = 16; static const uint32_t MAX_PUSH_CONSTANT_SIZE = 128; @@ -926,7 +989,13 @@ class RenderingDevice : public RenderingDeviceCommons { RID_Owner uniform_set_owner; public: - RID uniform_set_create(const Vector &p_uniforms, RID p_shader, uint32_t p_shader_set); + // + // @ShadyTF : + // descriptor optimizations : allow the option to have linearly allocated uniform set pools for frame allocated uniform sets + // Was: + //RID uniform_set_create(const Vector &p_uniforms, RID p_shader, uint32_t p_shader_set); + RID uniform_set_create(const Vector &p_uniforms, RID p_shader, uint32_t p_shader_set, bool p_linear_pool = false); + // bool uniform_set_is_valid(RID p_uniform_set); void uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata); @@ -1036,6 +1105,12 @@ class RenderingDevice : public RenderingDeviceCommons { RDD::UniformSetID uniform_set_driver_id; RID uniform_set; bool bound = false; +// +// @ShadyTF +// Dynamic uniform buffer + uint32_t offsets_count = 0; + const uint32_t* offsets = nullptr; +// }; struct State { @@ -1095,7 +1170,7 @@ class RenderingDevice : public RenderingDeviceCommons { void _draw_list_insert_clear_region(DrawList *p_draw_list, Framebuffer *p_framebuffer, Point2i p_viewport_offset, Point2i p_viewport_size, bool p_clear_color, const Vector &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil); Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, RDD::FramebufferID *r_framebuffer, RDD::RenderPassID *r_render_pass, uint32_t *r_subpass_count); - Error _draw_list_render_pass_begin(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i p_viewport_offset, Point2i p_viewport_size, RDD::FramebufferID p_framebuffer_driver_id, RDD::RenderPassID p_render_pass); + Error _draw_list_render_pass_begin(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i p_viewport_offset, Point2i p_viewport_size, RDD::FramebufferID p_framebuffer_driver_id, RDD::RenderPassID p_render_pass, uint32_t p_breadcrumb); void _draw_list_set_viewport(Rect2i p_rect); void _draw_list_set_scissor(Rect2i p_rect); _FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id); @@ -1104,11 +1179,16 @@ class RenderingDevice : public RenderingDeviceCommons { public: DrawListID draw_list_begin_for_screen(DisplayServer::WindowID p_screen = 0, const Color &p_clear_color = Color()); - DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_color_values = Vector(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); + DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_color_values = Vector(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), RDD::BreadcrumbMarker p_phase = RDD::BreadcrumbMarker::NONE, uint32_t p_breadcrumb_data = 0); void draw_list_set_blend_constants(DrawListID p_list, const Color &p_color); void draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline); void draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index); +// +// @ShadyTF +// Dynamic uniform buffer + void draw_list_bind_uniform_set_dynamic(DrawListID p_list, RID p_uniform_set, uint32_t p_index, uint32_t p_offsets_count, const uint32_t* p_offsets); +// void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array); void draw_list_bind_index_array(DrawListID p_list, RID p_index_array); void draw_list_set_line_width(DrawListID p_list, float p_width); @@ -1116,6 +1196,7 @@ class RenderingDevice : public RenderingDeviceCommons { void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0); + void draw_list_set_viewport(DrawListID p_list, const Rect2 &p_rect); void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect); void draw_list_disable_scissor(DrawListID p_list); @@ -1235,8 +1316,6 @@ class RenderingDevice : public RenderingDeviceCommons { List compute_pipelines_to_dispose_of; RDD::CommandPoolID command_pool; - - // Used at the beginning of every frame for set-up. // Used for filling up newly created buffers with data provided on creation. // Primarily intended to be accessed by worker threads. // Ideally this command buffer should use an async transfer queue. @@ -1246,12 +1325,21 @@ class RenderingDevice : public RenderingDeviceCommons { // Primarily intended to be used by the main thread to do most stuff. RDD::CommandBufferID draw_command_buffer; + // Used at the end of every frame for set-up of on screen rendering + RDD::CommandBufferID blit_setup_command_buffer; + + // Used at the end of every frame to blit on the swapchain + RDD::CommandBufferID blit_draw_command_buffer; + // Signaled by the setup submission. Draw must wait on this semaphore. RDD::SemaphoreID setup_semaphore; - // Signaled by the draw submission. Present must wait on this semaphore. + // Signaled by the draw submission. Blit draw must wait on this semaphore. RDD::SemaphoreID draw_semaphore; + // Signaled by the blit submission. Present must wait on this semaphore. + RDD::SemaphoreID blit_semaphore; + // Signaled by the draw submission. Must wait on this fence before beginning // command recording for the frame. RDD::FenceID draw_fence; @@ -1282,6 +1370,8 @@ class RenderingDevice : public RenderingDeviceCommons { int frame = 0; TightLocalVector frames; uint64_t frames_drawn = 0; + bool screen_prepared = false; + RID local_device; void _free_pending_resources(int p_frame); @@ -1289,9 +1379,9 @@ class RenderingDevice : public RenderingDeviceCommons { uint64_t buffer_memory = 0; void _free_internal(RID p_id); - void _begin_frame(); + void _begin_frame(bool presented = false); void _end_frame(); - void _execute_frame(bool p_present); + void _execute_frame(bool p_present, bool p_swap); void _stall_for_previous_frames(); void _flush_and_stall_for_all_frames(); @@ -1328,6 +1418,7 @@ class RenderingDevice : public RenderingDeviceCommons { void swap_buffers(); uint32_t get_frame_delay() const; + uint32_t get_current_frame_index() const; void submit(); void sync(); @@ -1428,11 +1519,19 @@ VARIANT_ENUM_CAST(RenderingDevice::FinalAction) VARIANT_ENUM_CAST(RenderingDevice::Limit) VARIANT_ENUM_CAST(RenderingDevice::MemoryType) VARIANT_ENUM_CAST(RenderingDevice::Features) +VARIANT_ENUM_CAST(RenderingDevice::BreadcrumbMarker) + #ifndef DISABLE_DEPRECATED VARIANT_BITFIELD_CAST(RenderingDevice::BarrierMask); #endif +// +// @ShadyTF +VARIANT_BITFIELD_CAST(RenderingDevice::BufferCreationBits); +// + + typedef RenderingDevice RD; #endif // RENDERING_DEVICE_H diff --git a/servers/rendering/rendering_device_commons.h b/servers/rendering/rendering_device_commons.h index 688a6441a7b0..56934e5a3542 100644 --- a/servers/rendering/rendering_device_commons.h +++ b/servers/rendering/rendering_device_commons.h @@ -43,6 +43,9 @@ class RenderingDeviceCommons : public Object { // with RenderingDeviceDriver. //////////////////////////////////////////// public: + static const bool command_pool_reset_enabled = true; + static const bool render_pass_opts_enabled = true; + /*****************/ /**** GENERIC ****/ /*****************/ @@ -271,6 +274,28 @@ class RenderingDeviceCommons : public Object { DATA_FORMAT_MAX, }; + enum BreadcrumbMarker { + NONE = 0, + // Environment + REFLECTION_PROBES, + SKY_PASS, + // Light mapping + LIGHTMAPPER_PASS, + // Shadows + SHADOW_PASS_DIRECTIONAL, + SHADOW_PASS_CUBE, + // Geometry passes + OPAQUE_PASS, + ALPHA_PASS, + TRANSPARENT_PASS, + // Screen effects + POST_PROCESSING_PASS, + BLIT_PASS, + UI_PASS, + // Other + DEBUG_PASS + }; + enum CompareOperator { COMPARE_OP_NEVER, COMPARE_OP_LESS, @@ -321,6 +346,10 @@ class RenderingDeviceCommons : public Object { TEXTURE_USAGE_CAN_COPY_TO_BIT = (1 << 8), TEXTURE_USAGE_INPUT_ATTACHMENT_BIT = (1 << 9), TEXTURE_USAGE_VRS_ATTACHMENT_BIT = (1 << 10), + // + //@ShadyTF : lazily allocated buffers + TEXTURE_USAGE_LAZILY_ALLOCATED_BIT = (1 << 11), + // }; struct TextureFormat { @@ -496,6 +525,11 @@ class RenderingDeviceCommons : public Object { UNIFORM_TYPE_UNIFORM_BUFFER, // Regular uniform buffer (or UBO). UNIFORM_TYPE_STORAGE_BUFFER, // Storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly. UNIFORM_TYPE_INPUT_ATTACHMENT, // Used for sub-pass read/write, for mobile mostly. +// +// @ShadyTF +// Dynamic uniform buffer + UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC, // Dynamic uniform buffer (or Dynamic UBO). +// UNIFORM_TYPE_MAX }; diff --git a/servers/rendering/rendering_device_driver.cpp b/servers/rendering/rendering_device_driver.cpp index 9e05a6a133c4..e11e8a188b7a 100644 --- a/servers/rendering/rendering_device_driver.cpp +++ b/servers/rendering/rendering_device_driver.cpp @@ -115,7 +115,19 @@ Error RenderingDeviceDriver::_reflect_spirv(VectorView p_s may_be_writable = true; } break; case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: { - uniform.type = UNIFORM_TYPE_UNIFORM_BUFFER; +// +// @ShadyTF +// Dynamic uniform buffer +// a uniform buffer with a typename ending with "_dynamic" will be treated as dynamic +// Was : +// uniform.type = UNIFORM_TYPE_UNIFORM_BUFFER; + String type_name = binding.type_description->type_name; + if (type_name.ends_with("_dynamic")) { + uniform.type = UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC; + } else { + uniform.type = UNIFORM_TYPE_UNIFORM_BUFFER; + } +// need_block_size = true; } break; case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: { diff --git a/servers/rendering/rendering_device_driver.h b/servers/rendering/rendering_device_driver.h index 9706d3219a7e..3b5360a1ac4b 100644 --- a/servers/rendering/rendering_device_driver.h +++ b/servers/rendering/rendering_device_driver.h @@ -192,6 +192,10 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { BUFFER_USAGE_INDEX_BIT = (1 << 6), BUFFER_USAGE_VERTEX_BIT = (1 << 7), BUFFER_USAGE_INDIRECT_BIT = (1 << 8), + // + // @ShadyTF : bit for persistenly mapped buffers + BUFFER_USAGE_PERSISTENT_BIT = (1 << 9) + // }; enum { @@ -205,6 +209,11 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { virtual uint64_t buffer_get_allocation_size(BufferID p_buffer) = 0; virtual uint8_t *buffer_map(BufferID p_buffer) = 0; virtual void buffer_unmap(BufferID p_buffer) = 0; + // + // @ShadyTF + // adding UMA feature, when possible a valid persistent address is returned and can be used directly + virtual uint8_t* buffer_get_persistent_address(BufferID p_buffer) = 0; + // /*****************/ /**** TEXTURE ****/ @@ -411,7 +420,7 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { virtual Error command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView p_wait_semaphores, VectorView p_cmd_buffers, VectorView p_cmd_semaphores, FenceID p_cmd_fence, VectorView p_swap_chains) = 0; virtual void command_queue_free(CommandQueueID p_cmd_queue) = 0; - // ----- POOL ----- + // ----- BUFFER ----- enum CommandBufferType { COMMAND_BUFFER_TYPE_PRIMARY, @@ -419,6 +428,7 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { }; virtual CommandPoolID command_pool_create(CommandQueueFamilyID p_cmd_queue_family, CommandBufferType p_cmd_buffer_type) = 0; + virtual bool command_pool_reset(CommandPoolID p_cmd_pool) = 0; virtual void command_pool_free(CommandPoolID p_cmd_pool) = 0; // ----- BUFFER ----- @@ -464,10 +474,26 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { virtual String shader_get_binary_cache_key() = 0; virtual Vector shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) = 0; - virtual ShaderID shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) = 0; + // + // @ShadyTF + // adding support of immutable samplers, which can be embedded when creating the pipeline layout on the condition they remain + // valid and unchanged, so they don't need to be specified when creating uniform sets + // Was: + //virtual ShaderID shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) = 0; + struct ImmutableSampler { + UniformType type = UNIFORM_TYPE_MAX; + uint32_t binding = 0xffffffff; // Binding index as specified in shader. + LocalVector ids; + }; + virtual ShaderID shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name, const Vector& r_immutableSamplers) = 0; + // // Only meaningful if API_TRAIT_SHADER_CHANGE_INVALIDATION is SHADER_CHANGE_INVALIDATION_ALL_OR_NONE_ACCORDING_TO_LAYOUT_HASH. virtual uint32_t shader_get_layout_hash(ShaderID p_shader) { return 0; } virtual void shader_free(ShaderID p_shader) = 0; + // + // @ShadyTF unload shader modules + virtual void shader_destroy_modules(ShaderID p_shader) = 0; + // protected: // An optional service to implementations. @@ -482,9 +508,22 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { UniformType type = UNIFORM_TYPE_MAX; uint32_t binding = 0xffffffff; // Binding index as specified in shader. LocalVector ids; - }; - - virtual UniformSetID uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) = 0; + // + // @ShadyTF + // flag to indicate that this is an immutable sampler so it is skipped when creating uniform sets, as it would be set previously + // when creating the pipeline layout + bool immutable_sampler = false; + // + }; + +// +// @ShadyTF : +// descriptor optimizations : allow the option to have linearly allocated uniform set pools for frame allocated uniform sets +// Was: +// virtual UniformSetID uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) = 0; + virtual UniformSetID uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index, int p_linear_pool_index) = 0; + virtual void linear_uniform_set_pools_reset(int p_linear_pool_index) = 0; +// virtual void uniform_set_free(UniformSetID p_uniform_set) = 0; // ----- COMMANDS ----- @@ -627,6 +666,12 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { // Binding. virtual void command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) = 0; virtual void command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) = 0; + virtual void command_bind_render_uniform_sets(CommandBufferID p_cmd_buffer, VectorView p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) = 0; +// +// @ShadyTF +// Dynamic uniform buffer + virtual void command_bind_render_uniform_set_dynamic(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index, uint32_t p_offsets_count, const uint32_t* p_offsets) = 0; +// // Drawing. virtual void command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) = 0; @@ -669,6 +714,7 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { // Binding. virtual void command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) = 0; virtual void command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) = 0; + virtual void command_bind_compute_uniform_sets(CommandBufferID p_cmd_buffer, VectorView p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) = 0; // Dispatching. virtual void command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0; @@ -701,6 +747,11 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { virtual void command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) = 0; virtual void command_end_label(CommandBufferID p_cmd_buffer) = 0; + /****************/ + /**** DEBUG *****/ + /****************/ + virtual void command_insert_breadcrumb(CommandBufferID p_cmd_buffer, uint32_t p_data) = 0; + /********************/ /**** SUBMISSION ****/ /********************/ @@ -760,6 +811,10 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { virtual void set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) = 0; virtual uint64_t get_resource_native_handle(DriverResource p_type, ID p_driver_id) = 0; virtual uint64_t get_total_memory_used() = 0; + // + // @ShadyTF lazily allocated memory + virtual uint64_t get_lazily_memory_used() = 0; + // virtual uint64_t limit_get(Limit p_limit) = 0; virtual uint64_t api_trait_get(ApiTrait p_trait); virtual bool has_feature(Features p_feature) = 0; diff --git a/servers/rendering/rendering_device_graph.cpp b/servers/rendering/rendering_device_graph.cpp index 4b85d1c2bfef..9fc3ac401560 100644 --- a/servers/rendering/rendering_device_graph.cpp +++ b/servers/rendering/rendering_device_graph.cpp @@ -605,10 +605,10 @@ void RenderingDeviceGraph::_run_compute_list_command(RDD::CommandBufferID p_comm driver->command_bind_compute_pipeline(p_command_buffer, bind_pipeline_instruction->pipeline); instruction_data_cursor += sizeof(ComputeListBindPipelineInstruction); } break; - case ComputeListInstruction::TYPE_BIND_UNIFORM_SET: { - const ComputeListBindUniformSetInstruction *bind_uniform_set_instruction = reinterpret_cast(instruction); - driver->command_bind_compute_uniform_set(p_command_buffer, bind_uniform_set_instruction->uniform_set, bind_uniform_set_instruction->shader, bind_uniform_set_instruction->set_index); - instruction_data_cursor += sizeof(ComputeListBindUniformSetInstruction); + case ComputeListInstruction::TYPE_BIND_UNIFORM_SETS: { + const ComputeListBindUniformSetsInstruction *bind_uniform_sets_instruction = reinterpret_cast(instruction); + driver->command_bind_compute_uniform_sets(p_command_buffer, VectorView(bind_uniform_sets_instruction->uniform_set_ids(), bind_uniform_sets_instruction->set_count), bind_uniform_sets_instruction->shader, bind_uniform_sets_instruction->first_set_index, bind_uniform_sets_instruction->set_count); + instruction_data_cursor += sizeof(ComputeListBindUniformSetsInstruction) + sizeof(RDD::UniformSetID) * bind_uniform_sets_instruction->set_count; } break; case ComputeListInstruction::TYPE_DISPATCH: { const ComputeListDispatchInstruction *dispatch_instruction = reinterpret_cast(instruction); @@ -656,11 +656,20 @@ void RenderingDeviceGraph::_run_draw_list_command(RDD::CommandBufferID p_command driver->command_bind_render_pipeline(p_command_buffer, bind_pipeline_instruction->pipeline); instruction_data_cursor += sizeof(DrawListBindPipelineInstruction); } break; - case DrawListInstruction::TYPE_BIND_UNIFORM_SET: { - const DrawListBindUniformSetInstruction *bind_uniform_set_instruction = reinterpret_cast(instruction); - driver->command_bind_render_uniform_set(p_command_buffer, bind_uniform_set_instruction->uniform_set, bind_uniform_set_instruction->shader, bind_uniform_set_instruction->set_index); - instruction_data_cursor += sizeof(DrawListBindUniformSetInstruction); + case DrawListInstruction::TYPE_BIND_UNIFORM_SETS: { + const DrawListBindUniformSetsInstruction *bind_uniform_sets_instruction = reinterpret_cast(instruction); + driver->command_bind_render_uniform_sets(p_command_buffer, VectorView(bind_uniform_sets_instruction->uniform_set_ids(), bind_uniform_sets_instruction->set_count), bind_uniform_sets_instruction->shader, bind_uniform_sets_instruction->first_set_index, bind_uniform_sets_instruction->set_count); + instruction_data_cursor += sizeof(DrawListBindUniformSetsInstruction) + sizeof(RDD::UniformSetID) * bind_uniform_sets_instruction->set_count; } break; +// +// @ShadyTF +// Dynamic uniform buffer + case DrawListInstruction::TYPE_BIND_UNIFORM_SET_DYNAMIC: { + const DrawListBindUniformSetsInstruction *bind_uniform_sets_instruction = reinterpret_cast(instruction); + driver->command_bind_render_uniform_set_dynamic(p_command_buffer, bind_uniform_sets_instruction->uniform_set_ids()[0], bind_uniform_sets_instruction->shader, bind_uniform_sets_instruction->first_set_index, bind_uniform_sets_instruction->offsets_count, bind_uniform_sets_instruction->offsets); + instruction_data_cursor += sizeof(DrawListBindUniformSetsInstruction); + } break; +// case DrawListInstruction::TYPE_BIND_VERTEX_BUFFERS: { const DrawListBindVertexBuffersInstruction *bind_vertex_buffers_instruction = reinterpret_cast(instruction); driver->command_render_bind_vertex_buffers(p_command_buffer, bind_vertex_buffers_instruction->vertex_buffers_count, bind_vertex_buffers_instruction->vertex_buffers(), bind_vertex_buffers_instruction->vertex_buffer_offsets()); @@ -786,6 +795,9 @@ void RenderingDeviceGraph::_run_render_commands(RDD::CommandBufferID p_command_b case RecordedCommand::TYPE_DRAW_LIST: { const RecordedDrawListCommand *draw_list_command = reinterpret_cast(command); const VectorView clear_values(draw_list_command->clear_values(), draw_list_command->clear_values_count); +#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED) + driver->command_insert_breadcrumb(p_command_buffer, draw_list_command->breadcrumb); +#endif driver->command_begin_render_pass(p_command_buffer, draw_list_command->render_pass, draw_list_command->framebuffer, draw_list_command->command_buffer_type, draw_list_command->region, clear_values); _run_draw_list_command(p_command_buffer, draw_list_command->instruction_data(), draw_list_command->instruction_data_size); driver->command_end_render_pass(p_command_buffer); @@ -1108,10 +1120,13 @@ void RenderingDeviceGraph::_print_draw_list(const uint8_t *p_instruction_data, u print_line("\tBIND PIPELINE ID", itos(bind_pipeline_instruction->pipeline.id)); instruction_data_cursor += sizeof(DrawListBindPipelineInstruction); } break; - case DrawListInstruction::TYPE_BIND_UNIFORM_SET: { - const DrawListBindUniformSetInstruction *bind_uniform_set_instruction = reinterpret_cast(instruction); - print_line("\tBIND UNIFORM SET ID", itos(bind_uniform_set_instruction->uniform_set.id), "SET INDEX", bind_uniform_set_instruction->set_index); - instruction_data_cursor += sizeof(DrawListBindUniformSetInstruction); + case DrawListInstruction::TYPE_BIND_UNIFORM_SETS: { + const DrawListBindUniformSetsInstruction *bind_uniform_sets_instruction = reinterpret_cast(instruction); + print_line("\tBIND UNIFORM SETS COUNT", bind_uniform_sets_instruction->set_count); + for (uint32_t i = 0; i < bind_uniform_sets_instruction->set_count; i++) { + print_line("\tBIND UNIFORM SET ID", itos(bind_uniform_sets_instruction->uniform_set_ids()[i]), "START INDEX", bind_uniform_sets_instruction->first_set_index); + } + instruction_data_cursor += sizeof(DrawListBindUniformSetsInstruction) + sizeof(RDD::UniformSetID) * bind_uniform_sets_instruction->set_count; } break; case DrawListInstruction::TYPE_BIND_VERTEX_BUFFERS: { const DrawListBindVertexBuffersInstruction *bind_vertex_buffers_instruction = reinterpret_cast(instruction); @@ -1195,10 +1210,13 @@ void RenderingDeviceGraph::_print_compute_list(const uint8_t *p_instruction_data print_line("\tBIND PIPELINE ID", itos(bind_pipeline_instruction->pipeline.id)); instruction_data_cursor += sizeof(ComputeListBindPipelineInstruction); } break; - case ComputeListInstruction::TYPE_BIND_UNIFORM_SET: { - const ComputeListBindUniformSetInstruction *bind_uniform_set_instruction = reinterpret_cast(instruction); - print_line("\tBIND UNIFORM SET ID", itos(bind_uniform_set_instruction->uniform_set.id), "SHADER ID", itos(bind_uniform_set_instruction->shader.id)); - instruction_data_cursor += sizeof(ComputeListBindUniformSetInstruction); + case ComputeListInstruction::TYPE_BIND_UNIFORM_SETS: { + const ComputeListBindUniformSetsInstruction *bind_uniform_sets_instruction = reinterpret_cast(instruction); + print_line("\tBIND UNIFORM SETS COUNT", bind_uniform_sets_instruction->set_count); + for (uint32_t i = 0; i < bind_uniform_sets_instruction->set_count; i++) { + print_line("\tBIND UNIFORM SET ID", itos(bind_uniform_sets_instruction->uniform_set_ids()[i]), "START INDEX", bind_uniform_sets_instruction->first_set_index); + } + instruction_data_cursor += sizeof(ComputeListBindUniformSetsInstruction) + sizeof(RDD::UniformSetID) * bind_uniform_sets_instruction->set_count; } break; case ComputeListInstruction::TYPE_DISPATCH: { const ComputeListDispatchInstruction *dispatch_instruction = reinterpret_cast(instruction); @@ -1261,6 +1279,11 @@ void RenderingDeviceGraph::finalize() { } void RenderingDeviceGraph::begin() { + reset(); + tracking_frame++; +} + +void RenderingDeviceGraph::reset() { command_data.clear(); command_data_offsets.clear(); command_normalization_barriers.clear(); @@ -1281,7 +1304,6 @@ void RenderingDeviceGraph::begin() { frames[frame].secondary_command_buffers_used = 0; draw_instruction_list.index = 0; compute_instruction_list.index = 0; - tracking_frame++; #ifdef DEV_ENABLED write_dependency_counters.clear(); @@ -1359,8 +1381,10 @@ void RenderingDeviceGraph::add_buffer_update(RDD::BufferID p_dst, ResourceTracke _add_command_to_graph(&p_dst_tracker, &buffer_usage, 1, command_index, command); } -void RenderingDeviceGraph::add_compute_list_begin() { +void RenderingDeviceGraph::add_compute_list_begin(RDD::BreadcrumbMarker p_phase, uint32_t p_breadcrumb_data) { compute_instruction_list.clear(); + compute_instruction_list.has_dispatches = false; + compute_instruction_list.breadcrumb = (p_phase << 16) | (p_breadcrumb_data & ((1 << 16) - 1)); compute_instruction_list.index++; } @@ -1372,11 +1396,21 @@ void RenderingDeviceGraph::add_compute_list_bind_pipeline(RDD::PipelineID p_pipe } void RenderingDeviceGraph::add_compute_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index) { - ComputeListBindUniformSetInstruction *instruction = reinterpret_cast(_allocate_compute_list_instruction(sizeof(ComputeListBindUniformSetInstruction))); - instruction->type = ComputeListInstruction::TYPE_BIND_UNIFORM_SET; + add_compute_list_bind_uniform_sets(p_shader, VectorView(&p_uniform_set, 1), set_index, 1); +} + +void RenderingDeviceGraph::add_compute_list_bind_uniform_sets(RDD::ShaderID p_shader, VectorView p_uniform_sets, uint32_t first_set_index, uint32_t set_count) { + uint32_t instruction_size = sizeof(ComputeListBindUniformSetsInstruction) + sizeof(RDD::UniformSetID) * set_count; + ComputeListBindUniformSetsInstruction *instruction = reinterpret_cast(_allocate_compute_list_instruction(instruction_size)); + instruction->type = ComputeListInstruction::TYPE_BIND_UNIFORM_SETS; instruction->shader = p_shader; - instruction->uniform_set = p_uniform_set; - instruction->set_index = set_index; + instruction->first_set_index = first_set_index; + instruction->set_count = set_count; + + RDD::UniformSetID *ids = instruction->uniform_set_ids(); + for (uint32_t i = 0; i < p_uniform_sets.size(); i++) { + ids[i] = p_uniform_sets[i]; + } } void RenderingDeviceGraph::add_compute_list_dispatch(uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) { @@ -1385,6 +1419,8 @@ void RenderingDeviceGraph::add_compute_list_dispatch(uint32_t p_x_groups, uint32 instruction->x_groups = p_x_groups; instruction->y_groups = p_y_groups; instruction->z_groups = p_z_groups; + + compute_instruction_list.has_dispatches = true; } void RenderingDeviceGraph::add_compute_list_dispatch_indirect(RDD::BufferID p_buffer, uint32_t p_offset) { @@ -1393,6 +1429,8 @@ void RenderingDeviceGraph::add_compute_list_dispatch_indirect(RDD::BufferID p_bu instruction->buffer = p_buffer; instruction->offset = p_offset; compute_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_DRAW_INDIRECT_BIT); + + compute_instruction_list.has_dispatches = true; } void RenderingDeviceGraph::add_compute_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size) { @@ -1439,6 +1477,9 @@ void RenderingDeviceGraph::add_compute_list_usages(VectorView } void RenderingDeviceGraph::add_compute_list_end() { + if (RenderingDeviceCommons::render_pass_opts_enabled && !compute_instruction_list.has_dispatches) + return; + int32_t command_index; uint32_t instruction_data_size = compute_instruction_list.data.size(); uint32_t command_size = sizeof(RecordedComputeListCommand) + instruction_data_size; @@ -1450,12 +1491,15 @@ void RenderingDeviceGraph::add_compute_list_end() { _add_command_to_graph(compute_instruction_list.command_trackers.ptr(), compute_instruction_list.command_tracker_usages.ptr(), compute_instruction_list.command_trackers.size(), command_index, command); } -void RenderingDeviceGraph::add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView p_clear_values, bool p_uses_color, bool p_uses_depth) { +void RenderingDeviceGraph::add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView p_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb) { draw_instruction_list.clear(); + // We are forced to start the render pass if a clear operation is requested + draw_instruction_list.has_draws = p_clear_values.size() > 0; draw_instruction_list.index++; draw_instruction_list.render_pass = p_render_pass; draw_instruction_list.framebuffer = p_framebuffer; draw_instruction_list.region = p_region; + draw_instruction_list.breadcrumb = p_breadcrumb; draw_instruction_list.clear_values.resize(p_clear_values.size()); for (uint32_t i = 0; i < p_clear_values.size(); i++) { draw_instruction_list.clear_values[i] = p_clear_values[i]; @@ -1491,13 +1535,35 @@ void RenderingDeviceGraph::add_draw_list_bind_pipeline(RDD::PipelineID p_pipelin } void RenderingDeviceGraph::add_draw_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index) { - DrawListBindUniformSetInstruction *instruction = reinterpret_cast(_allocate_draw_list_instruction(sizeof(DrawListBindUniformSetInstruction))); - instruction->type = DrawListInstruction::TYPE_BIND_UNIFORM_SET; - instruction->shader = p_shader; - instruction->uniform_set = p_uniform_set; - instruction->set_index = set_index; + add_draw_list_bind_uniform_sets(p_shader, VectorView(&p_uniform_set, 1), set_index, 1); } +void RenderingDeviceGraph::add_draw_list_bind_uniform_sets(RDD::ShaderID p_shader, VectorView p_uniform_sets, uint32_t first_set_index, uint32_t set_count) { + uint32_t instruction_size = sizeof(DrawListBindUniformSetsInstruction) + sizeof(RDD::UniformSetID) * set_count; + DrawListBindUniformSetsInstruction *instruction = reinterpret_cast(_allocate_draw_list_instruction(instruction_size)); + instruction->type = DrawListInstruction::TYPE_BIND_UNIFORM_SETS; + instruction->shader = p_shader; + instruction->first_set_index = first_set_index; + instruction->set_count = set_count; + + for (uint32_t i = 0; i < p_uniform_sets.size(); i++) { + instruction->uniform_set_ids()[i] = p_uniform_sets[i]; + } +} +// +// @ShadyTF +// Dynamic uniform buffer +void RenderingDeviceGraph::add_draw_list_bind_uniform_set_dynamic(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index, uint32_t p_offsets_count, const uint32_t* p_offsets) { + DrawListBindUniformSetsInstruction *instruction = reinterpret_cast(_allocate_draw_list_instruction(sizeof(DrawListBindUniformSetsInstruction))); + instruction->type = DrawListInstruction::TYPE_BIND_UNIFORM_SET_DYNAMIC; + instruction->shader = p_shader; + instruction->first_set_index = 0; + instruction->set_count = 1; + instruction->uniform_set_ids()[0] = p_uniform_set; + instruction->offsets = p_offsets; + instruction->offsets_count = p_offsets_count; +} +// void RenderingDeviceGraph::add_draw_list_bind_vertex_buffers(VectorView p_vertex_buffers, VectorView p_vertex_buffer_offsets) { DEV_ASSERT(p_vertex_buffers.size() == p_vertex_buffer_offsets.size()); @@ -1534,6 +1600,8 @@ void RenderingDeviceGraph::add_draw_list_clear_attachments(VectorViewattachments_clear_rect_count; i++) { attachments_clear_rect[i] = p_attachments_clear_rect[i]; } + + draw_instruction_list.has_draws = true; } void RenderingDeviceGraph::add_draw_list_draw(uint32_t p_vertex_count, uint32_t p_instance_count) { @@ -1541,6 +1609,8 @@ void RenderingDeviceGraph::add_draw_list_draw(uint32_t p_vertex_count, uint32_t instruction->type = DrawListInstruction::TYPE_DRAW; instruction->vertex_count = p_vertex_count; instruction->instance_count = p_instance_count; + + draw_instruction_list.has_draws = true; } void RenderingDeviceGraph::add_draw_list_draw_indexed(uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index) { @@ -1549,12 +1619,16 @@ void RenderingDeviceGraph::add_draw_list_draw_indexed(uint32_t p_index_count, ui instruction->index_count = p_index_count; instruction->instance_count = p_instance_count; instruction->first_index = p_first_index; + + draw_instruction_list.has_draws = true; } void RenderingDeviceGraph::add_draw_list_execute_commands(RDD::CommandBufferID p_command_buffer) { DrawListExecuteCommandsInstruction *instruction = reinterpret_cast(_allocate_draw_list_instruction(sizeof(DrawListExecuteCommandsInstruction))); instruction->type = DrawListInstruction::TYPE_EXECUTE_COMMANDS; instruction->command_buffer = p_command_buffer; + + draw_instruction_list.has_draws = true; } void RenderingDeviceGraph::add_draw_list_next_subpass(RDD::CommandBufferType p_command_buffer_type) { @@ -1628,7 +1702,12 @@ void RenderingDeviceGraph::add_draw_list_usages(VectorView p_ } } + void RenderingDeviceGraph::add_draw_list_end() { + if (RenderingDeviceCommons::render_pass_opts_enabled && !draw_instruction_list.has_draws) { + return; + } + // Arbitrary size threshold to evaluate if it'd be best to record the draw list on the background as a secondary buffer. const uint32_t instruction_data_threshold_for_secondary = 16384; RDD::CommandBufferType command_buffer_type; @@ -1666,6 +1745,7 @@ void RenderingDeviceGraph::add_draw_list_end() { command->framebuffer = draw_instruction_list.framebuffer; command->command_buffer_type = command_buffer_type; command->region = draw_instruction_list.region; + command->breadcrumb = draw_instruction_list.breadcrumb; command->clear_values_count = draw_instruction_list.clear_values.size(); RDD::RenderPassClearValue *clear_values = command->clear_values(); @@ -1880,6 +1960,7 @@ void RenderingDeviceGraph::end(RDD::CommandBufferID p_command_buffer, bool p_reo 2, // TYPE_TEXTURE_GET_DATA 2, // TYPE_TEXTURE_RESOLVE 2, // TYPE_TEXTURE_UPDATE + 2, // TYPE_INSERT_BREADCRUMB }; commands_sorted.clear(); diff --git a/servers/rendering/rendering_device_graph.h b/servers/rendering/rendering_device_graph.h index 3bc63bb2977f..76709f0c8fe8 100644 --- a/servers/rendering/rendering_device_graph.h +++ b/servers/rendering/rendering_device_graph.h @@ -49,7 +49,7 @@ class RenderingDeviceGraph { enum Type { TYPE_NONE, TYPE_BIND_PIPELINE, - TYPE_BIND_UNIFORM_SET, + TYPE_BIND_UNIFORM_SETS, TYPE_DISPATCH, TYPE_DISPATCH_INDIRECT, TYPE_SET_PUSH_CONSTANT, @@ -64,7 +64,12 @@ class RenderingDeviceGraph { TYPE_NONE, TYPE_BIND_INDEX_BUFFER, TYPE_BIND_PIPELINE, - TYPE_BIND_UNIFORM_SET, + TYPE_BIND_UNIFORM_SETS, +// +// @ShadyTF +// Dynamic uniform buffer + TYPE_BIND_UNIFORM_SET_DYNAMIC, +// TYPE_BIND_VERTEX_BUFFERS, TYPE_CLEAR_ATTACHMENTS, TYPE_DRAW, @@ -201,14 +206,17 @@ class RenderingDeviceGraph { }; struct ComputeInstructionList : InstructionList { - // No extra contents. + bool has_dispatches = false; + uint32_t breadcrumb; }; struct DrawInstructionList : InstructionList { RDD::RenderPassID render_pass; RDD::FramebufferID framebuffer; Rect2i region; + uint32_t breadcrumb; LocalVector clear_values; + bool has_draws = false; }; struct RecordedCommandSort { @@ -279,6 +287,7 @@ class RenderingDeviceGraph { struct RecordedComputeListCommand : RecordedCommand { uint32_t instruction_data_size = 0; + uint32_t breadcrumb = 0; _FORCE_INLINE_ uint8_t *instruction_data() { return reinterpret_cast(&this[1]); @@ -295,6 +304,7 @@ class RenderingDeviceGraph { RDD::FramebufferID framebuffer; RDD::CommandBufferType command_buffer_type; Rect2i region; + uint32_t breadcrumb = 0; uint32_t clear_values_count = 0; _FORCE_INLINE_ RDD::RenderPassClearValue *clear_values() { @@ -377,10 +387,24 @@ class RenderingDeviceGraph { RDD::PipelineID pipeline; }; - struct DrawListBindUniformSetInstruction : DrawListInstruction { - RDD::UniformSetID uniform_set; + struct DrawListBindUniformSetsInstruction : DrawListInstruction { RDD::ShaderID shader; - uint32_t set_index = 0; + uint32_t first_set_index = 0; + uint32_t set_count = 0; + + _FORCE_INLINE_ RDD::UniformSetID *uniform_set_ids() { + return reinterpret_cast(&this[1]); + } + + _FORCE_INLINE_ const RDD::UniformSetID *uniform_set_ids() const { + return reinterpret_cast(&this[1]); + } +// +// @ShadyTF +// Dynamic uniform buffer + uint32_t offsets_count = 0; + const uint32_t* offsets = nullptr; +// }; struct DrawListBindVertexBuffersInstruction : DrawListInstruction { @@ -486,10 +510,18 @@ class RenderingDeviceGraph { RDD::PipelineID pipeline; }; - struct ComputeListBindUniformSetInstruction : ComputeListInstruction { - RDD::UniformSetID uniform_set; + struct ComputeListBindUniformSetsInstruction : ComputeListInstruction { RDD::ShaderID shader; - uint32_t set_index = 0; + uint32_t first_set_index = 0; + uint32_t set_count = 0; + + _FORCE_INLINE_ RDD::UniformSetID *uniform_set_ids() { + return reinterpret_cast(&this[1]); + } + + _FORCE_INLINE_ const RDD::UniformSetID *uniform_set_ids() const { + return reinterpret_cast(&this[1]); + } }; struct ComputeListDispatchInstruction : ComputeListInstruction { @@ -622,13 +654,15 @@ class RenderingDeviceGraph { void initialize(RDD *p_driver, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame); void finalize(); void begin(); + void reset(); void add_buffer_clear(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_offset, uint32_t p_size); void add_buffer_copy(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, RDD::BufferCopyRegion p_region); void add_buffer_get_data(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, RDD::BufferCopyRegion p_region); void add_buffer_update(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, VectorView p_buffer_copies); - void add_compute_list_begin(); + void add_compute_list_begin(RDD::BreadcrumbMarker p_phase = RDD::BreadcrumbMarker::NONE, uint32_t p_breadcrumb_data = 0); void add_compute_list_bind_pipeline(RDD::PipelineID p_pipeline); void add_compute_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index); + void add_compute_list_bind_uniform_sets(RDD::ShaderID p_shader, VectorView p_uniform_set, uint32_t first_set_index, uint32_t set_count); void add_compute_list_dispatch(uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups); void add_compute_list_dispatch_indirect(RDD::BufferID p_buffer, uint32_t p_offset); void add_compute_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size); @@ -636,10 +670,16 @@ class RenderingDeviceGraph { void add_compute_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage); void add_compute_list_usages(VectorView p_trackers, VectorView p_usages); void add_compute_list_end(); - void add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView p_clear_values, bool p_uses_color, bool p_uses_depth); + void add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView p_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb = 0); void add_draw_list_bind_index_buffer(RDD::BufferID p_buffer, RDD::IndexBufferFormat p_format, uint32_t p_offset); void add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline, BitField p_pipeline_stage_bits); void add_draw_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index); + void add_draw_list_bind_uniform_sets(RDD::ShaderID p_shader, VectorView p_uniform_set, uint32_t first_index, uint32_t set_count); +// +// @ShadyTF +// Dynamic uniform buffer + void add_draw_list_bind_uniform_set_dynamic(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index, uint32_t p_offsets_count, const uint32_t* p_offsets); +// void add_draw_list_bind_vertex_buffers(VectorView p_vertex_buffers, VectorView p_vertex_buffer_offsets); void add_draw_list_clear_attachments(VectorView p_attachments_clear, VectorView p_attachments_clear_rect); void add_draw_list_draw(uint32_t p_vertex_count, uint32_t p_instance_count); diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h index cf37fbfb4a05..e53cf5cada33 100644 --- a/servers/rendering/storage/texture_storage.h +++ b/servers/rendering/storage/texture_storage.h @@ -156,6 +156,7 @@ class RendererTextureStorage { virtual void render_target_do_msaa_resolve(RID p_render_target) = 0; virtual void render_target_set_use_hdr(RID p_render_target, bool p_use_hdr) = 0; virtual bool render_target_is_using_hdr(RID p_render_target) const = 0; + virtual int64_t render_target_get_format(RID p_render_target) const = 0; virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0; virtual bool render_target_is_clear_requested(RID p_render_target) = 0; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 6e9b525f31cf..fd83ab177430 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -3521,6 +3521,7 @@ void RenderingServer::init() { // Number of commands that can be drawn per frame. GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/gl_compatibility/item_buffer_size", PROPERTY_HINT_RANGE, "128,1048576,1"), 16384); + GLOBAL_DEF_RST("rendering/shader_compiler/shader_compilation/optimize", false); GLOBAL_DEF("rendering/shader_compiler/shader_cache/enabled", true); GLOBAL_DEF("rendering/shader_compiler/shader_cache/compress", true); diff --git a/thirdparty/glslang/External/spirv-tools/include/NonSemanticShaderDebugInfo100.h b/thirdparty/glslang/External/spirv-tools/include/NonSemanticShaderDebugInfo100.h new file mode 100644 index 000000000000..b276b560cbc8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/include/NonSemanticShaderDebugInfo100.h @@ -0,0 +1,171 @@ +// Copyright (c) 2018-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +#ifndef SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ +#define SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticShaderDebugInfo100Version = 100, + NonSemanticShaderDebugInfo100Version_BitWidthPadding = 0x7fffffff +}; +enum { + NonSemanticShaderDebugInfo100Revision = 6, + NonSemanticShaderDebugInfo100Revision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100Instructions { + NonSemanticShaderDebugInfo100DebugInfoNone = 0, + NonSemanticShaderDebugInfo100DebugCompilationUnit = 1, + NonSemanticShaderDebugInfo100DebugTypeBasic = 2, + NonSemanticShaderDebugInfo100DebugTypePointer = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifier = 4, + NonSemanticShaderDebugInfo100DebugTypeArray = 5, + NonSemanticShaderDebugInfo100DebugTypeVector = 6, + NonSemanticShaderDebugInfo100DebugTypedef = 7, + NonSemanticShaderDebugInfo100DebugTypeFunction = 8, + NonSemanticShaderDebugInfo100DebugTypeEnum = 9, + NonSemanticShaderDebugInfo100DebugTypeComposite = 10, + NonSemanticShaderDebugInfo100DebugTypeMember = 11, + NonSemanticShaderDebugInfo100DebugTypeInheritance = 12, + NonSemanticShaderDebugInfo100DebugTypePtrToMember = 13, + NonSemanticShaderDebugInfo100DebugTypeTemplate = 14, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameter = 15, + NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter = 16, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack = 17, + NonSemanticShaderDebugInfo100DebugGlobalVariable = 18, + NonSemanticShaderDebugInfo100DebugFunctionDeclaration = 19, + NonSemanticShaderDebugInfo100DebugFunction = 20, + NonSemanticShaderDebugInfo100DebugLexicalBlock = 21, + NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator = 22, + NonSemanticShaderDebugInfo100DebugScope = 23, + NonSemanticShaderDebugInfo100DebugNoScope = 24, + NonSemanticShaderDebugInfo100DebugInlinedAt = 25, + NonSemanticShaderDebugInfo100DebugLocalVariable = 26, + NonSemanticShaderDebugInfo100DebugInlinedVariable = 27, + NonSemanticShaderDebugInfo100DebugDeclare = 28, + NonSemanticShaderDebugInfo100DebugValue = 29, + NonSemanticShaderDebugInfo100DebugOperation = 30, + NonSemanticShaderDebugInfo100DebugExpression = 31, + NonSemanticShaderDebugInfo100DebugMacroDef = 32, + NonSemanticShaderDebugInfo100DebugMacroUndef = 33, + NonSemanticShaderDebugInfo100DebugImportedEntity = 34, + NonSemanticShaderDebugInfo100DebugSource = 35, + NonSemanticShaderDebugInfo100DebugFunctionDefinition = 101, + NonSemanticShaderDebugInfo100DebugSourceContinued = 102, + NonSemanticShaderDebugInfo100DebugLine = 103, + NonSemanticShaderDebugInfo100DebugNoLine = 104, + NonSemanticShaderDebugInfo100DebugBuildIdentifier = 105, + NonSemanticShaderDebugInfo100DebugStoragePath = 106, + NonSemanticShaderDebugInfo100DebugEntryPoint = 107, + NonSemanticShaderDebugInfo100DebugTypeMatrix = 108, + NonSemanticShaderDebugInfo100InstructionsMax = 0x7fffffff +}; + + +enum NonSemanticShaderDebugInfo100DebugInfoFlags { + NonSemanticShaderDebugInfo100None = 0x0000, + NonSemanticShaderDebugInfo100FlagIsProtected = 0x01, + NonSemanticShaderDebugInfo100FlagIsPrivate = 0x02, + NonSemanticShaderDebugInfo100FlagIsPublic = 0x03, + NonSemanticShaderDebugInfo100FlagIsLocal = 0x04, + NonSemanticShaderDebugInfo100FlagIsDefinition = 0x08, + NonSemanticShaderDebugInfo100FlagFwdDecl = 0x10, + NonSemanticShaderDebugInfo100FlagArtificial = 0x20, + NonSemanticShaderDebugInfo100FlagExplicit = 0x40, + NonSemanticShaderDebugInfo100FlagPrototyped = 0x80, + NonSemanticShaderDebugInfo100FlagObjectPointer = 0x100, + NonSemanticShaderDebugInfo100FlagStaticMember = 0x200, + NonSemanticShaderDebugInfo100FlagIndirectVariable = 0x400, + NonSemanticShaderDebugInfo100FlagLValueReference = 0x800, + NonSemanticShaderDebugInfo100FlagRValueReference = 0x1000, + NonSemanticShaderDebugInfo100FlagIsOptimized = 0x2000, + NonSemanticShaderDebugInfo100FlagIsEnumClass = 0x4000, + NonSemanticShaderDebugInfo100FlagTypePassByValue = 0x8000, + NonSemanticShaderDebugInfo100FlagTypePassByReference = 0x10000, + NonSemanticShaderDebugInfo100FlagUnknownPhysicalLayout = 0x20000, + NonSemanticShaderDebugInfo100DebugInfoFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100BuildIdentifierFlags { + NonSemanticShaderDebugInfo100IdentifierPossibleDuplicates = 0x01, + NonSemanticShaderDebugInfo100BuildIdentifierFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncoding { + NonSemanticShaderDebugInfo100Unspecified = 0, + NonSemanticShaderDebugInfo100Address = 1, + NonSemanticShaderDebugInfo100Boolean = 2, + NonSemanticShaderDebugInfo100Float = 3, + NonSemanticShaderDebugInfo100Signed = 4, + NonSemanticShaderDebugInfo100SignedChar = 5, + NonSemanticShaderDebugInfo100Unsigned = 6, + NonSemanticShaderDebugInfo100UnsignedChar = 7, + NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugCompositeType { + NonSemanticShaderDebugInfo100Class = 0, + NonSemanticShaderDebugInfo100Structure = 1, + NonSemanticShaderDebugInfo100Union = 2, + NonSemanticShaderDebugInfo100DebugCompositeTypeMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugTypeQualifier { + NonSemanticShaderDebugInfo100ConstType = 0, + NonSemanticShaderDebugInfo100VolatileType = 1, + NonSemanticShaderDebugInfo100RestrictType = 2, + NonSemanticShaderDebugInfo100AtomicType = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifierMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugOperation { + NonSemanticShaderDebugInfo100Deref = 0, + NonSemanticShaderDebugInfo100Plus = 1, + NonSemanticShaderDebugInfo100Minus = 2, + NonSemanticShaderDebugInfo100PlusUconst = 3, + NonSemanticShaderDebugInfo100BitPiece = 4, + NonSemanticShaderDebugInfo100Swap = 5, + NonSemanticShaderDebugInfo100Xderef = 6, + NonSemanticShaderDebugInfo100StackValue = 7, + NonSemanticShaderDebugInfo100Constu = 8, + NonSemanticShaderDebugInfo100Fragment = 9, + NonSemanticShaderDebugInfo100DebugOperationMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugImportedEntity { + NonSemanticShaderDebugInfo100ImportedModule = 0, + NonSemanticShaderDebugInfo100ImportedDeclaration = 1, + NonSemanticShaderDebugInfo100DebugImportedEntityMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ diff --git a/thirdparty/glslang/External/spirv-tools/include/spirv-tools/instrument.hpp b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/instrument.hpp new file mode 100644 index 000000000000..0a6e6306ec5a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/instrument.hpp @@ -0,0 +1,86 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_ +#define INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_ + +// Shader Instrumentation Interface +// +// This file provides an external interface for applications that wish to +// communicate with shaders instrumented by passes created by: +// +// CreateInstBindlessCheckPass +// CreateInstBuffAddrCheckPass +// CreateInstDebugPrintfPass +// +// More detailed documentation of these routines can be found in optimizer.hpp + +namespace spvtools { + +// Stream Output Buffer Offsets +// +// The following values provide offsets into the output buffer struct +// generated by InstrumentPass::GenDebugStreamWrite. This method is utilized +// by InstBindlessCheckPass, InstBuffAddrCheckPass, and InstDebugPrintfPass. +// +// The 1st member of the debug output buffer contains a set of flags +// controlling the behavior of instrumentation code. +static const int kDebugOutputFlagsOffset = 0; + +// Values stored at kDebugOutputFlagsOffset +enum kInstFlags : unsigned int { + kInstBufferOOBEnable = 0x1, +}; + +// The 2nd member of the debug output buffer contains the next available word +// in the data stream to be written. Shaders will atomically read and update +// this value so as not to overwrite each others records. This value must be +// initialized to zero +static const int kDebugOutputSizeOffset = 1; + +// The 3rd member of the output buffer is the start of the stream of records +// written by the instrumented shaders. Each record represents a validation +// error. The format of the records is documented below. +static const int kDebugOutputDataOffset = 2; + +// Common Stream Record Offsets +// +// The following are offsets to fields which are common to all records written +// to the output stream. +// +// Each record first contains the size of the record in 32-bit words, including +// the size word. +static const int kInstCommonOutSize = 0; + +// This is the shader id passed by the layer when the instrumentation pass is +// created. +static const int kInstCommonOutShaderId = 1; + +// This is the ordinal position of the instruction within the SPIR-V shader +// which generated the validation error. +static const int kInstCommonOutInstructionIdx = 2; + +// Debug Buffer Bindings +// +// These are the bindings for the different buffers which are +// read or written by the instrumentation passes. +// +// This is the output buffer written by InstDebugPrintfPass. +static const int kDebugOutputPrintfStream = 3; + +} // namespace spvtools + +#endif // INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_ diff --git a/thirdparty/glslang/External/spirv-tools/include/spirv-tools/libspirv.h b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/libspirv.h new file mode 100644 index 000000000000..abdfc15d4fe6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/libspirv.h @@ -0,0 +1,1003 @@ +// Copyright (c) 2015-2020 The Khronos Group Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_LIBSPIRV_H_ +#define INCLUDE_SPIRV_TOOLS_LIBSPIRV_H_ + +#ifdef __cplusplus +extern "C" { +#else +#include +#endif + +#include +#include + +#if defined(SPIRV_TOOLS_SHAREDLIB) +#if defined(_WIN32) +#if defined(SPIRV_TOOLS_IMPLEMENTATION) +#define SPIRV_TOOLS_EXPORT __declspec(dllexport) +#else +#define SPIRV_TOOLS_EXPORT __declspec(dllimport) +#endif +#else +#if defined(SPIRV_TOOLS_IMPLEMENTATION) +#define SPIRV_TOOLS_EXPORT __attribute__((visibility("default"))) +#else +#define SPIRV_TOOLS_EXPORT +#endif +#endif +#else +#define SPIRV_TOOLS_EXPORT +#endif + +// Helpers + +#define SPV_BIT(shift) (1 << (shift)) + +#define SPV_FORCE_16_BIT_ENUM(name) SPV_FORCE_16BIT_##name = 0x7fff +#define SPV_FORCE_32_BIT_ENUM(name) SPV_FORCE_32BIT_##name = 0x7fffffff + +// Enumerations + +typedef enum spv_result_t { + SPV_SUCCESS = 0, + SPV_UNSUPPORTED = 1, + SPV_END_OF_STREAM = 2, + SPV_WARNING = 3, + SPV_FAILED_MATCH = 4, + SPV_REQUESTED_TERMINATION = 5, // Success, but signals early termination. + SPV_ERROR_INTERNAL = -1, + SPV_ERROR_OUT_OF_MEMORY = -2, + SPV_ERROR_INVALID_POINTER = -3, + SPV_ERROR_INVALID_BINARY = -4, + SPV_ERROR_INVALID_TEXT = -5, + SPV_ERROR_INVALID_TABLE = -6, + SPV_ERROR_INVALID_VALUE = -7, + SPV_ERROR_INVALID_DIAGNOSTIC = -8, + SPV_ERROR_INVALID_LOOKUP = -9, + SPV_ERROR_INVALID_ID = -10, + SPV_ERROR_INVALID_CFG = -11, + SPV_ERROR_INVALID_LAYOUT = -12, + SPV_ERROR_INVALID_CAPABILITY = -13, + SPV_ERROR_INVALID_DATA = -14, // Indicates data rules validation failure. + SPV_ERROR_MISSING_EXTENSION = -15, + SPV_ERROR_WRONG_VERSION = -16, // Indicates wrong SPIR-V version + SPV_FORCE_32_BIT_ENUM(spv_result_t) +} spv_result_t; + +// Severity levels of messages communicated to the consumer. +typedef enum spv_message_level_t { + SPV_MSG_FATAL, // Unrecoverable error due to environment. + // Will exit the program immediately. E.g., + // out of memory. + SPV_MSG_INTERNAL_ERROR, // Unrecoverable error due to SPIRV-Tools + // internals. + // Will exit the program immediately. E.g., + // unimplemented feature. + SPV_MSG_ERROR, // Normal error due to user input. + SPV_MSG_WARNING, // Warning information. + SPV_MSG_INFO, // General information. + SPV_MSG_DEBUG, // Debug information. +} spv_message_level_t; + +typedef enum spv_endianness_t { + SPV_ENDIANNESS_LITTLE, + SPV_ENDIANNESS_BIG, + SPV_FORCE_32_BIT_ENUM(spv_endianness_t) +} spv_endianness_t; + +// The kinds of operands that an instruction may have. +// +// Some operand types are "concrete". The binary parser uses a concrete +// operand type to describe an operand of a parsed instruction. +// +// The assembler uses all operand types. In addition to determining what +// kind of value an operand may be, non-concrete operand types capture the +// fact that an operand might be optional (may be absent, or present exactly +// once), or might occur zero or more times. +// +// Sometimes we also need to be able to express the fact that an operand +// is a member of an optional tuple of values. In that case the first member +// would be optional, and the subsequent members would be required. +// +// NOTE: Although we don't promise binary compatibility, as a courtesy, please +// add new enum values at the end. +typedef enum spv_operand_type_t { + // A sentinel value. + SPV_OPERAND_TYPE_NONE = 0, + + // Set 1: Operands that are IDs. + SPV_OPERAND_TYPE_ID, + SPV_OPERAND_TYPE_TYPE_ID, + SPV_OPERAND_TYPE_RESULT_ID, + SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, // SPIR-V Sec 3.25 + SPV_OPERAND_TYPE_SCOPE_ID, // SPIR-V Sec 3.27 + + // Set 2: Operands that are literal numbers. + SPV_OPERAND_TYPE_LITERAL_INTEGER, // Always unsigned 32-bits. + // The Instruction argument to OpExtInst. It's an unsigned 32-bit literal + // number indicating which instruction to use from an extended instruction + // set. + SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + // The Opcode argument to OpSpecConstantOp. It determines the operation + // to be performed on constant operands to compute a specialization constant + // result. + SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, + // A literal number whose format and size are determined by a previous operand + // in the same instruction. It's a signed integer, an unsigned integer, or a + // floating point number. It also has a specified bit width. The width + // may be larger than 32, which would require such a typed literal value to + // occupy multiple SPIR-V words. + SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, + SPV_OPERAND_TYPE_LITERAL_FLOAT, // Always 32-bit float. + + // Set 3: The literal string operand type. + SPV_OPERAND_TYPE_LITERAL_STRING, + + // Set 4: Operands that are a single word enumerated value. + SPV_OPERAND_TYPE_SOURCE_LANGUAGE, // SPIR-V Sec 3.2 + SPV_OPERAND_TYPE_EXECUTION_MODEL, // SPIR-V Sec 3.3 + SPV_OPERAND_TYPE_ADDRESSING_MODEL, // SPIR-V Sec 3.4 + SPV_OPERAND_TYPE_MEMORY_MODEL, // SPIR-V Sec 3.5 + SPV_OPERAND_TYPE_EXECUTION_MODE, // SPIR-V Sec 3.6 + SPV_OPERAND_TYPE_STORAGE_CLASS, // SPIR-V Sec 3.7 + SPV_OPERAND_TYPE_DIMENSIONALITY, // SPIR-V Sec 3.8 + SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, // SPIR-V Sec 3.9 + SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, // SPIR-V Sec 3.10 + SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, // SPIR-V Sec 3.11 + SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, // SPIR-V Sec 3.12 + SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, // SPIR-V Sec 3.13 + SPV_OPERAND_TYPE_FP_ROUNDING_MODE, // SPIR-V Sec 3.16 + SPV_OPERAND_TYPE_LINKAGE_TYPE, // SPIR-V Sec 3.17 + SPV_OPERAND_TYPE_ACCESS_QUALIFIER, // SPIR-V Sec 3.18 + SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE, // SPIR-V Sec 3.19 + SPV_OPERAND_TYPE_DECORATION, // SPIR-V Sec 3.20 + SPV_OPERAND_TYPE_BUILT_IN, // SPIR-V Sec 3.21 + SPV_OPERAND_TYPE_GROUP_OPERATION, // SPIR-V Sec 3.28 + SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS, // SPIR-V Sec 3.29 + SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, // SPIR-V Sec 3.30 + SPV_OPERAND_TYPE_CAPABILITY, // SPIR-V Sec 3.31 + + // NOTE: New concrete enum values should be added at the end. + + // Set 5: Operands that are a single word bitmask. + // Sometimes a set bit indicates the instruction requires still more operands. + SPV_OPERAND_TYPE_IMAGE, // SPIR-V Sec 3.14 + SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, // SPIR-V Sec 3.15 + SPV_OPERAND_TYPE_SELECTION_CONTROL, // SPIR-V Sec 3.22 + SPV_OPERAND_TYPE_LOOP_CONTROL, // SPIR-V Sec 3.23 + SPV_OPERAND_TYPE_FUNCTION_CONTROL, // SPIR-V Sec 3.24 + SPV_OPERAND_TYPE_MEMORY_ACCESS, // SPIR-V Sec 3.26 + SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, // SPIR-V Sec 3.FSR + +// NOTE: New concrete enum values should be added at the end. + +// The "optional" and "variable" operand types are only used internally by +// the assembler and the binary parser. +// There are two categories: +// Optional : expands to 0 or 1 operand, like ? in regular expressions. +// Variable : expands to 0, 1 or many operands or pairs of operands. +// This is similar to * in regular expressions. + +// NOTE: These FIRST_* and LAST_* enum values are DEPRECATED. +// The concept of "optional" and "variable" operand types are only intended +// for use as an implementation detail of parsing SPIR-V, either in text or +// binary form. Instead of using enum ranges, use characteristic function +// spvOperandIsConcrete. +// The use of enum value ranges in a public API makes it difficult to insert +// new values into a range without also breaking binary compatibility. +// +// Macros for defining bounds on optional and variable operand types. +// Any variable operand type is also optional. +// TODO(dneto): Remove SPV_OPERAND_TYPE_FIRST_* and SPV_OPERAND_TYPE_LAST_* +#define FIRST_OPTIONAL(ENUM) ENUM, SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE = ENUM +#define FIRST_VARIABLE(ENUM) ENUM, SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE = ENUM +#define LAST_VARIABLE(ENUM) \ + ENUM, SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE = ENUM, \ + SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE = ENUM + + // An optional operand represents zero or one logical operands. + // In an instruction definition, this may only appear at the end of the + // operand types. + FIRST_OPTIONAL(SPV_OPERAND_TYPE_OPTIONAL_ID), + // An optional image operand type. + SPV_OPERAND_TYPE_OPTIONAL_IMAGE, + // An optional memory access type. + SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, + // An optional literal integer. + SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, + // An optional literal number, which may be either integer or floating point. + SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER, + // Like SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, but optional, and integral. + SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER, + // An optional literal string. + SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING, + // An optional access qualifier + SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, + // An optional context-independent value, or CIV. CIVs are tokens that we can + // assemble regardless of where they occur -- literals, IDs, immediate + // integers, etc. + SPV_OPERAND_TYPE_OPTIONAL_CIV, + + // A variable operand represents zero or more logical operands. + // In an instruction definition, this may only appear at the end of the + // operand types. + FIRST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID), + SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER, + // A sequence of zero or more pairs of (typed literal integer, Id). + // Expands to zero or more: + // (SPV_OPERAND_TYPE_TYPED_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID) + // where the literal number must always be an integer of some sort. + SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID, + // A sequence of zero or more pairs of (Id, Literal integer) + LAST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER), + + // The following are concrete enum types from the DebugInfo extended + // instruction set. + SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, // DebugInfo Sec 3.2. A mask. + SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, // DebugInfo Sec 3.3 + SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, // DebugInfo Sec 3.4 + SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, // DebugInfo Sec 3.5 + SPV_OPERAND_TYPE_DEBUG_OPERATION, // DebugInfo Sec 3.6 + + // The following are concrete enum types from the OpenCL.DebugInfo.100 + // extended instruction set. + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, // Sec 3.2. A Mask + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, // Sec 3.3 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE, // Sec 3.4 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER, // Sec 3.5 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, // Sec 3.6 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, // Sec 3.7 + + // The following are concrete enum types from SPV_INTEL_float_controls2 + // https://github.com/intel/llvm/blob/39fa9b0cbfbae88327118990a05c5b387b56d2ef/sycl/doc/extensions/SPIRV/SPV_INTEL_float_controls2.asciidoc + SPV_OPERAND_TYPE_FPDENORM_MODE, // Sec 3.17 FP Denorm Mode + SPV_OPERAND_TYPE_FPOPERATION_MODE, // Sec 3.18 FP Operation Mode + // A value enum from https://github.com/KhronosGroup/SPIRV-Headers/pull/177 + SPV_OPERAND_TYPE_QUANTIZATION_MODES, + // A value enum from https://github.com/KhronosGroup/SPIRV-Headers/pull/177 + SPV_OPERAND_TYPE_OVERFLOW_MODES, + + // Concrete operand types for the provisional Vulkan ray tracing feature. + SPV_OPERAND_TYPE_RAY_FLAGS, // SPIR-V Sec 3.RF + SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION, // SPIR-V Sec 3.RQIntersection + SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE, // SPIR-V Sec + // 3.RQCommitted + SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE, // SPIR-V Sec + // 3.RQCandidate + + // Concrete operand types for integer dot product. + // Packed vector format + SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT, // SPIR-V Sec 3.x + // An optional packed vector format + SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT, + + // Concrete operand types for cooperative matrix. + SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, + // An optional cooperative matrix operands + SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS, + SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT, + SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE, + + // Enum type from SPV_INTEL_global_variable_fpga_decorations + SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER, + // Enum type from SPV_INTEL_global_variable_host_access + SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER, + // Enum type from SPV_INTEL_cache_controls + SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL, + // Enum type from SPV_INTEL_cache_controls + SPV_OPERAND_TYPE_STORE_CACHE_CONTROL, + + // This is a sentinel value, and does not represent an operand type. + // It should come last. + SPV_OPERAND_TYPE_NUM_OPERAND_TYPES, + + SPV_FORCE_32_BIT_ENUM(spv_operand_type_t) +} spv_operand_type_t; + +// Returns true if the given type is concrete. +bool spvOperandIsConcrete(spv_operand_type_t type); + +// Returns true if the given type is concrete and also a mask. +bool spvOperandIsConcreteMask(spv_operand_type_t type); + +typedef enum spv_ext_inst_type_t { + SPV_EXT_INST_TYPE_NONE = 0, + SPV_EXT_INST_TYPE_GLSL_STD_450, + SPV_EXT_INST_TYPE_OPENCL_STD, + SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER, + SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX, + SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER, + SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT, + SPV_EXT_INST_TYPE_DEBUGINFO, + SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100, + SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION, + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100, + + // Multiple distinct extended instruction set types could return this + // value, if they are prefixed with NonSemantic. and are otherwise + // unrecognised + SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN, + + SPV_FORCE_32_BIT_ENUM(spv_ext_inst_type_t) +} spv_ext_inst_type_t; + +// This determines at a high level the kind of a binary-encoded literal +// number, but not the bit width. +// In principle, these could probably be folded into new entries in +// spv_operand_type_t. But then we'd have some special case differences +// between the assembler and disassembler. +typedef enum spv_number_kind_t { + SPV_NUMBER_NONE = 0, // The default for value initialization. + SPV_NUMBER_UNSIGNED_INT, + SPV_NUMBER_SIGNED_INT, + SPV_NUMBER_FLOATING, +} spv_number_kind_t; + +typedef enum spv_text_to_binary_options_t { + SPV_TEXT_TO_BINARY_OPTION_NONE = SPV_BIT(0), + // Numeric IDs in the binary will have the same values as in the source. + // Non-numeric IDs are allocated by filling in the gaps, starting with 1 + // and going up. + SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS = SPV_BIT(1), + SPV_FORCE_32_BIT_ENUM(spv_text_to_binary_options_t) +} spv_text_to_binary_options_t; + +typedef enum spv_binary_to_text_options_t { + SPV_BINARY_TO_TEXT_OPTION_NONE = SPV_BIT(0), + SPV_BINARY_TO_TEXT_OPTION_PRINT = SPV_BIT(1), + SPV_BINARY_TO_TEXT_OPTION_COLOR = SPV_BIT(2), + SPV_BINARY_TO_TEXT_OPTION_INDENT = SPV_BIT(3), + SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET = SPV_BIT(4), + // Do not output the module header as leading comments in the assembly. + SPV_BINARY_TO_TEXT_OPTION_NO_HEADER = SPV_BIT(5), + // Use friendly names where possible. The heuristic may expand over + // time, but will use common names for scalar types, and debug names from + // OpName instructions. + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES = SPV_BIT(6), + // Add some comments to the generated assembly + SPV_BINARY_TO_TEXT_OPTION_COMMENT = SPV_BIT(7), + SPV_FORCE_32_BIT_ENUM(spv_binary_to_text_options_t) +} spv_binary_to_text_options_t; + +// Constants + +// The default id bound is to the minimum value for the id limit +// in the spir-v specification under the section "Universal Limits". +const uint32_t kDefaultMaxIdBound = 0x3FFFFF; + +// Structures + +// Information about an operand parsed from a binary SPIR-V module. +// Note that the values are not included. You still need access to the binary +// to extract the values. +typedef struct spv_parsed_operand_t { + // Location of the operand, in words from the start of the instruction. + uint16_t offset; + // Number of words occupied by this operand. + uint16_t num_words; + // The "concrete" operand type. See the definition of spv_operand_type_t + // for details. + spv_operand_type_t type; + // If type is a literal number type, then number_kind says whether it's + // a signed integer, an unsigned integer, or a floating point number. + spv_number_kind_t number_kind; + // The number of bits for a literal number type. + uint32_t number_bit_width; +} spv_parsed_operand_t; + +// An instruction parsed from a binary SPIR-V module. +typedef struct spv_parsed_instruction_t { + // An array of words for this instruction, in native endianness. + const uint32_t* words; + // The number of words in this instruction. + uint16_t num_words; + uint16_t opcode; + // The extended instruction type, if opcode is OpExtInst. Otherwise + // this is the "none" value. + spv_ext_inst_type_t ext_inst_type; + // The type id, or 0 if this instruction doesn't have one. + uint32_t type_id; + // The result id, or 0 if this instruction doesn't have one. + uint32_t result_id; + // The array of parsed operands. + const spv_parsed_operand_t* operands; + uint16_t num_operands; +} spv_parsed_instruction_t; + +typedef struct spv_parsed_header_t { + // The magic number of the SPIR-V module. + uint32_t magic; + // Version number. + uint32_t version; + // Generator's magic number. + uint32_t generator; + // IDs bound for this module (0 < id < bound). + uint32_t bound; + // reserved. + uint32_t reserved; +} spv_parsed_header_t; + +typedef struct spv_const_binary_t { + const uint32_t* code; + const size_t wordCount; +} spv_const_binary_t; + +typedef struct spv_binary_t { + uint32_t* code; + size_t wordCount; +} spv_binary_t; + +typedef struct spv_text_t { + const char* str; + size_t length; +} spv_text_t; + +typedef struct spv_position_t { + size_t line; + size_t column; + size_t index; +} spv_position_t; + +typedef struct spv_diagnostic_t { + spv_position_t position; + char* error; + bool isTextSource; +} spv_diagnostic_t; + +// Opaque struct containing the context used to operate on a SPIR-V module. +// Its object is used by various translation API functions. +typedef struct spv_context_t spv_context_t; + +typedef struct spv_validator_options_t spv_validator_options_t; + +typedef struct spv_optimizer_options_t spv_optimizer_options_t; + +typedef struct spv_reducer_options_t spv_reducer_options_t; + +typedef struct spv_fuzzer_options_t spv_fuzzer_options_t; + +typedef struct spv_optimizer_t spv_optimizer_t; + +// Type Definitions + +typedef spv_const_binary_t* spv_const_binary; +typedef spv_binary_t* spv_binary; +typedef spv_text_t* spv_text; +typedef spv_position_t* spv_position; +typedef spv_diagnostic_t* spv_diagnostic; +typedef const spv_context_t* spv_const_context; +typedef spv_context_t* spv_context; +typedef spv_validator_options_t* spv_validator_options; +typedef const spv_validator_options_t* spv_const_validator_options; +typedef spv_optimizer_options_t* spv_optimizer_options; +typedef const spv_optimizer_options_t* spv_const_optimizer_options; +typedef spv_reducer_options_t* spv_reducer_options; +typedef const spv_reducer_options_t* spv_const_reducer_options; +typedef spv_fuzzer_options_t* spv_fuzzer_options; +typedef const spv_fuzzer_options_t* spv_const_fuzzer_options; + +// Platform API + +// Returns the SPIRV-Tools software version as a null-terminated string. +// The contents of the underlying storage is valid for the remainder of +// the process. +SPIRV_TOOLS_EXPORT const char* spvSoftwareVersionString(void); +// Returns a null-terminated string containing the name of the project, +// the software version string, and commit details. +// The contents of the underlying storage is valid for the remainder of +// the process. +SPIRV_TOOLS_EXPORT const char* spvSoftwareVersionDetailsString(void); + +// Certain target environments impose additional restrictions on SPIR-V, so it's +// often necessary to specify which one applies. SPV_ENV_UNIVERSAL_* implies an +// environment-agnostic SPIR-V. +// +// When an API method needs to derive a SPIR-V version from a target environment +// (from the spv_context object), the method will choose the highest version of +// SPIR-V supported by the target environment. Examples: +// SPV_ENV_VULKAN_1_0 -> SPIR-V 1.0 +// SPV_ENV_VULKAN_1_1 -> SPIR-V 1.3 +// SPV_ENV_VULKAN_1_1_SPIRV_1_4 -> SPIR-V 1.4 +// SPV_ENV_VULKAN_1_2 -> SPIR-V 1.5 +// SPV_ENV_VULKAN_1_3 -> SPIR-V 1.6 +// Consult the description of API entry points for specific rules. +typedef enum { + SPV_ENV_UNIVERSAL_1_0, // SPIR-V 1.0 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_0, // Vulkan 1.0 latest revision. + SPV_ENV_UNIVERSAL_1_1, // SPIR-V 1.1 latest revision, no other restrictions. + SPV_ENV_OPENCL_2_1, // OpenCL Full Profile 2.1 latest revision. + SPV_ENV_OPENCL_2_2, // OpenCL Full Profile 2.2 latest revision. + SPV_ENV_OPENGL_4_0, // OpenGL 4.0 plus GL_ARB_gl_spirv, latest revisions. + SPV_ENV_OPENGL_4_1, // OpenGL 4.1 plus GL_ARB_gl_spirv, latest revisions. + SPV_ENV_OPENGL_4_2, // OpenGL 4.2 plus GL_ARB_gl_spirv, latest revisions. + SPV_ENV_OPENGL_4_3, // OpenGL 4.3 plus GL_ARB_gl_spirv, latest revisions. + // There is no variant for OpenGL 4.4. + SPV_ENV_OPENGL_4_5, // OpenGL 4.5 plus GL_ARB_gl_spirv, latest revisions. + SPV_ENV_UNIVERSAL_1_2, // SPIR-V 1.2, latest revision, no other restrictions. + SPV_ENV_OPENCL_1_2, // OpenCL Full Profile 1.2 plus cl_khr_il_program, + // latest revision. + SPV_ENV_OPENCL_EMBEDDED_1_2, // OpenCL Embedded Profile 1.2 plus + // cl_khr_il_program, latest revision. + SPV_ENV_OPENCL_2_0, // OpenCL Full Profile 2.0 plus cl_khr_il_program, + // latest revision. + SPV_ENV_OPENCL_EMBEDDED_2_0, // OpenCL Embedded Profile 2.0 plus + // cl_khr_il_program, latest revision. + SPV_ENV_OPENCL_EMBEDDED_2_1, // OpenCL Embedded Profile 2.1 latest revision. + SPV_ENV_OPENCL_EMBEDDED_2_2, // OpenCL Embedded Profile 2.2 latest revision. + SPV_ENV_UNIVERSAL_1_3, // SPIR-V 1.3 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_1, // Vulkan 1.1 latest revision. + SPV_ENV_WEBGPU_0, // DEPRECATED, may be removed in the future. + SPV_ENV_UNIVERSAL_1_4, // SPIR-V 1.4 latest revision, no other restrictions. + + // Vulkan 1.1 with VK_KHR_spirv_1_4, i.e. SPIR-V 1.4 binary. + SPV_ENV_VULKAN_1_1_SPIRV_1_4, + + SPV_ENV_UNIVERSAL_1_5, // SPIR-V 1.5 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_2, // Vulkan 1.2 latest revision. + + SPV_ENV_UNIVERSAL_1_6, // SPIR-V 1.6 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_3, // Vulkan 1.3 latest revision. + + SPV_ENV_MAX // Keep this as the last enum value. +} spv_target_env; + +// SPIR-V Validator can be parameterized with the following Universal Limits. +typedef enum { + spv_validator_limit_max_struct_members, + spv_validator_limit_max_struct_depth, + spv_validator_limit_max_local_variables, + spv_validator_limit_max_global_variables, + spv_validator_limit_max_switch_branches, + spv_validator_limit_max_function_args, + spv_validator_limit_max_control_flow_nesting_depth, + spv_validator_limit_max_access_chain_indexes, + spv_validator_limit_max_id_bound, +} spv_validator_limit; + +// Returns a string describing the given SPIR-V target environment. +SPIRV_TOOLS_EXPORT const char* spvTargetEnvDescription(spv_target_env env); + +// Parses s into *env and returns true if successful. If unparsable, returns +// false and sets *env to SPV_ENV_UNIVERSAL_1_0. +SPIRV_TOOLS_EXPORT bool spvParseTargetEnv(const char* s, spv_target_env* env); + +// Determines the target env value with the least features but which enables +// the given Vulkan and SPIR-V versions. If such a target is supported, returns +// true and writes the value to |env|, otherwise returns false. +// +// The Vulkan version is given as an unsigned 32-bit number as specified in +// Vulkan section "29.2.1 Version Numbers": the major version number appears +// in bits 22 to 21, and the minor version is in bits 12 to 21. The SPIR-V +// version is given in the SPIR-V version header word: major version in bits +// 16 to 23, and minor version in bits 8 to 15. +SPIRV_TOOLS_EXPORT bool spvParseVulkanEnv(uint32_t vulkan_ver, + uint32_t spirv_ver, + spv_target_env* env); + +// Creates a context object for most of the SPIRV-Tools API. +// Returns null if env is invalid. +// +// See specific API calls for how the target environment is interpreted +// (particularly assembly and validation). +SPIRV_TOOLS_EXPORT spv_context spvContextCreate(spv_target_env env); + +// Destroys the given context object. +SPIRV_TOOLS_EXPORT void spvContextDestroy(spv_context context); + +// Creates a Validator options object with default options. Returns a valid +// options object. The object remains valid until it is passed into +// spvValidatorOptionsDestroy. +SPIRV_TOOLS_EXPORT spv_validator_options spvValidatorOptionsCreate(void); + +// Destroys the given Validator options object. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsDestroy( + spv_validator_options options); + +// Records the maximum Universal Limit that is considered valid in the given +// Validator options object. argument must be a valid options object. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetUniversalLimit( + spv_validator_options options, spv_validator_limit limit_type, + uint32_t limit); + +// Record whether or not the validator should relax the rules on types for +// stores to structs. When relaxed, it will allow a type mismatch as long as +// the types are structs with the same layout. Two structs have the same layout +// if +// +// 1) the members of the structs are either the same type or are structs with +// same layout, and +// +// 2) the decorations that affect the memory layout are identical for both +// types. Other decorations are not relevant. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetRelaxStoreStruct( + spv_validator_options options, bool val); + +// Records whether or not the validator should relax the rules on pointer usage +// in logical addressing mode. +// +// When relaxed, it will allow the following usage cases of pointers: +// 1) OpVariable allocating an object whose type is a pointer type +// 2) OpReturnValue returning a pointer value +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetRelaxLogicalPointer( + spv_validator_options options, bool val); + +// Records whether or not the validator should relax the rules because it is +// expected that the optimizations will make the code legal. +// +// When relaxed, it will allow the following: +// 1) It will allow relaxed logical pointers. Setting this option will also +// set that option. +// 2) Pointers that are pass as parameters to function calls do not have to +// match the storage class of the formal parameter. +// 3) Pointers that are actual parameters on function calls do not have to point +// to the same type pointed as the formal parameter. The types just need to +// logically match. +// 4) GLSLstd450 Interpolate* instructions can have a load of an interpolant +// for a first argument. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetBeforeHlslLegalization( + spv_validator_options options, bool val); + +// Records whether the validator should use "relaxed" block layout rules. +// Relaxed layout rules are described by Vulkan extension +// VK_KHR_relaxed_block_layout, and they affect uniform blocks, storage blocks, +// and push constants. +// +// This is enabled by default when targeting Vulkan 1.1 or later. +// Relaxed layout is more permissive than the default rules in Vulkan 1.0. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetRelaxBlockLayout( + spv_validator_options options, bool val); + +// Records whether the validator should use standard block layout rules for +// uniform blocks. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetUniformBufferStandardLayout( + spv_validator_options options, bool val); + +// Records whether the validator should use "scalar" block layout rules. +// Scalar layout rules are more permissive than relaxed block layout. +// +// See Vulkan extension VK_EXT_scalar_block_layout. The scalar alignment is +// defined as follows: +// - scalar alignment of a scalar is the scalar size +// - scalar alignment of a vector is the scalar alignment of its component +// - scalar alignment of a matrix is the scalar alignment of its component +// - scalar alignment of an array is the scalar alignment of its element +// - scalar alignment of a struct is the max scalar alignment among its +// members +// +// For a struct in Uniform, StorageClass, or PushConstant: +// - a member Offset must be a multiple of the member's scalar alignment +// - ArrayStride or MatrixStride must be a multiple of the array or matrix +// scalar alignment +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetScalarBlockLayout( + spv_validator_options options, bool val); + +// Records whether the validator should use "scalar" block layout +// rules (as defined above) for Workgroup blocks. See Vulkan +// extension VK_KHR_workgroup_memory_explicit_layout. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetWorkgroupScalarBlockLayout( + spv_validator_options options, bool val); + +// Records whether or not the validator should skip validating standard +// uniform/storage block layout. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetSkipBlockLayout( + spv_validator_options options, bool val); + +// Records whether or not the validator should allow the LocalSizeId +// decoration where the environment otherwise would not allow it. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowLocalSizeId( + spv_validator_options options, bool val); + +// Whether friendly names should be used in validation error messages. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetFriendlyNames( + spv_validator_options options, bool val); + +// Creates an optimizer options object with default options. Returns a valid +// options object. The object remains valid until it is passed into +// |spvOptimizerOptionsDestroy|. +SPIRV_TOOLS_EXPORT spv_optimizer_options spvOptimizerOptionsCreate(void); + +// Destroys the given optimizer options object. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsDestroy( + spv_optimizer_options options); + +// Records whether or not the optimizer should run the validator before +// optimizing. If |val| is true, the validator will be run. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetRunValidator( + spv_optimizer_options options, bool val); + +// Records the validator options that should be passed to the validator if it is +// run. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetValidatorOptions( + spv_optimizer_options options, spv_validator_options val); + +// Records the maximum possible value for the id bound. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetMaxIdBound( + spv_optimizer_options options, uint32_t val); + +// Records whether all bindings within the module should be preserved. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetPreserveBindings( + spv_optimizer_options options, bool val); + +// Records whether all specialization constants within the module +// should be preserved. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetPreserveSpecConstants( + spv_optimizer_options options, bool val); + +// Creates a reducer options object with default options. Returns a valid +// options object. The object remains valid until it is passed into +// |spvReducerOptionsDestroy|. +SPIRV_TOOLS_EXPORT spv_reducer_options spvReducerOptionsCreate(void); + +// Destroys the given reducer options object. +SPIRV_TOOLS_EXPORT void spvReducerOptionsDestroy(spv_reducer_options options); + +// Sets the maximum number of reduction steps that should run before the reducer +// gives up. +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetStepLimit( + spv_reducer_options options, uint32_t step_limit); + +// Sets the fail-on-validation-error option; if true, the reducer will return +// kStateInvalid if a reduction step yields a state that fails SPIR-V +// validation. Otherwise, an invalid state is treated as uninteresting and the +// reduction backtracks and continues. +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetFailOnValidationError( + spv_reducer_options options, bool fail_on_validation_error); + +// Sets the function that the reducer should target. If set to zero the reducer +// will target all functions as well as parts of the module that lie outside +// functions. Otherwise the reducer will restrict reduction to the function +// with result id |target_function|, which is required to exist. +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetTargetFunction( + spv_reducer_options options, uint32_t target_function); + +// Creates a fuzzer options object with default options. Returns a valid +// options object. The object remains valid until it is passed into +// |spvFuzzerOptionsDestroy|. +SPIRV_TOOLS_EXPORT spv_fuzzer_options spvFuzzerOptionsCreate(void); + +// Destroys the given fuzzer options object. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsDestroy(spv_fuzzer_options options); + +// Enables running the validator after every transformation is applied during +// a replay. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableReplayValidation( + spv_fuzzer_options options); + +// Sets the seed with which the random number generator used by the fuzzer +// should be initialized. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetRandomSeed( + spv_fuzzer_options options, uint32_t seed); + +// Sets the range of transformations that should be applied during replay: 0 +// means all transformations, +N means the first N transformations, -N means all +// except the final N transformations. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetReplayRange( + spv_fuzzer_options options, int32_t replay_range); + +// Sets the maximum number of steps that the shrinker should take before giving +// up. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetShrinkerStepLimit( + spv_fuzzer_options options, uint32_t shrinker_step_limit); + +// Enables running the validator after every pass is applied during a fuzzing +// run. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableFuzzerPassValidation( + spv_fuzzer_options options); + +// Enables all fuzzer passes during a fuzzing run (instead of a random subset +// of passes). +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableAllPasses( + spv_fuzzer_options options); + +// Encodes the given SPIR-V assembly text to its binary representation. The +// length parameter specifies the number of bytes for text. Encoded binary will +// be stored into *binary. Any error will be written into *diagnostic if +// diagnostic is non-null, otherwise the context's message consumer will be +// used. The generated binary is independent of the context and may outlive it. +// The SPIR-V binary version is set to the highest version of SPIR-V supported +// by the context's target environment. +SPIRV_TOOLS_EXPORT spv_result_t spvTextToBinary(const spv_const_context context, + const char* text, + const size_t length, + spv_binary* binary, + spv_diagnostic* diagnostic); + +// Encodes the given SPIR-V assembly text to its binary representation. Same as +// spvTextToBinary but with options. The options parameter is a bit field of +// spv_text_to_binary_options_t. +SPIRV_TOOLS_EXPORT spv_result_t spvTextToBinaryWithOptions( + const spv_const_context context, const char* text, const size_t length, + const uint32_t options, spv_binary* binary, spv_diagnostic* diagnostic); + +// Frees an allocated text stream. This is a no-op if the text parameter +// is a null pointer. +SPIRV_TOOLS_EXPORT void spvTextDestroy(spv_text text); + +// Decodes the given SPIR-V binary representation to its assembly text. The +// word_count parameter specifies the number of words for binary. The options +// parameter is a bit field of spv_binary_to_text_options_t. Decoded text will +// be stored into *text. Any error will be written into *diagnostic if +// diagnostic is non-null, otherwise the context's message consumer will be +// used. +SPIRV_TOOLS_EXPORT spv_result_t spvBinaryToText(const spv_const_context context, + const uint32_t* binary, + const size_t word_count, + const uint32_t options, + spv_text* text, + spv_diagnostic* diagnostic); + +// Frees a binary stream from memory. This is a no-op if binary is a null +// pointer. +SPIRV_TOOLS_EXPORT void spvBinaryDestroy(spv_binary binary); + +// Validates a SPIR-V binary for correctness. Any errors will be written into +// *diagnostic if diagnostic is non-null, otherwise the context's message +// consumer will be used. +// +// Validate for SPIR-V spec rules for the SPIR-V version named in the +// binary's header (at word offset 1). Additionally, if the context target +// environment is a client API (such as Vulkan 1.1), then validate for that +// client API version, to the extent that it is verifiable from data in the +// binary itself. +SPIRV_TOOLS_EXPORT spv_result_t spvValidate(const spv_const_context context, + const spv_const_binary binary, + spv_diagnostic* diagnostic); + +// Validates a SPIR-V binary for correctness. Uses the provided Validator +// options. Any errors will be written into *diagnostic if diagnostic is +// non-null, otherwise the context's message consumer will be used. +// +// Validate for SPIR-V spec rules for the SPIR-V version named in the +// binary's header (at word offset 1). Additionally, if the context target +// environment is a client API (such as Vulkan 1.1), then validate for that +// client API version, to the extent that it is verifiable from data in the +// binary itself, or in the validator options. +SPIRV_TOOLS_EXPORT spv_result_t spvValidateWithOptions( + const spv_const_context context, const spv_const_validator_options options, + const spv_const_binary binary, spv_diagnostic* diagnostic); + +// Validates a raw SPIR-V binary for correctness. Any errors will be written +// into *diagnostic if diagnostic is non-null, otherwise the context's message +// consumer will be used. +SPIRV_TOOLS_EXPORT spv_result_t +spvValidateBinary(const spv_const_context context, const uint32_t* words, + const size_t num_words, spv_diagnostic* diagnostic); + +// Creates a diagnostic object. The position parameter specifies the location in +// the text/binary stream. The message parameter, copied into the diagnostic +// object, contains the error message to display. +SPIRV_TOOLS_EXPORT spv_diagnostic +spvDiagnosticCreate(const spv_position position, const char* message); + +// Destroys a diagnostic object. This is a no-op if diagnostic is a null +// pointer. +SPIRV_TOOLS_EXPORT void spvDiagnosticDestroy(spv_diagnostic diagnostic); + +// Prints the diagnostic to stderr. +SPIRV_TOOLS_EXPORT spv_result_t +spvDiagnosticPrint(const spv_diagnostic diagnostic); + +// Gets the name of an instruction, without the "Op" prefix. +SPIRV_TOOLS_EXPORT const char* spvOpcodeString(const uint32_t opcode); + +// The binary parser interface. + +// A pointer to a function that accepts a parsed SPIR-V header. +// The integer arguments are the 32-bit words from the header, as specified +// in SPIR-V 1.0 Section 2.3 Table 1. +// The function should return SPV_SUCCESS if parsing should continue. +typedef spv_result_t (*spv_parsed_header_fn_t)( + void* user_data, spv_endianness_t endian, uint32_t magic, uint32_t version, + uint32_t generator, uint32_t id_bound, uint32_t reserved); + +// A pointer to a function that accepts a parsed SPIR-V instruction. +// The parsed_instruction value is transient: it may be overwritten +// or released immediately after the function has returned. That also +// applies to the words array member of the parsed instruction. The +// function should return SPV_SUCCESS if and only if parsing should +// continue. +typedef spv_result_t (*spv_parsed_instruction_fn_t)( + void* user_data, const spv_parsed_instruction_t* parsed_instruction); + +// Parses a SPIR-V binary, specified as counted sequence of 32-bit words. +// Parsing feedback is provided via two callbacks provided as function +// pointers. Each callback function pointer can be a null pointer, in +// which case it is never called. Otherwise, in a valid parse the +// parsed-header callback is called once, and then the parsed-instruction +// callback once for each instruction in the stream. The user_data parameter +// is supplied as context to the callbacks. Returns SPV_SUCCESS on successful +// parse where the callbacks always return SPV_SUCCESS. For an invalid parse, +// returns a status code other than SPV_SUCCESS, and if diagnostic is non-null +// also emits a diagnostic. If diagnostic is null the context's message consumer +// will be used to emit any errors. If a callback returns anything other than +// SPV_SUCCESS, then that status code is returned, no further callbacks are +// issued, and no additional diagnostics are emitted. +SPIRV_TOOLS_EXPORT spv_result_t spvBinaryParse( + const spv_const_context context, void* user_data, const uint32_t* words, + const size_t num_words, spv_parsed_header_fn_t parse_header, + spv_parsed_instruction_fn_t parse_instruction, spv_diagnostic* diagnostic); + +// The optimizer interface. + +// A pointer to a function that accepts a log message from an optimizer. +typedef void (*spv_message_consumer)( + spv_message_level_t, const char*, const spv_position_t*, const char*); + +// Creates and returns an optimizer object. This object must be passed to +// optimizer APIs below and is valid until passed to spvOptimizerDestroy. +SPIRV_TOOLS_EXPORT spv_optimizer_t* spvOptimizerCreate(spv_target_env env); + +// Destroys the given optimizer object. +SPIRV_TOOLS_EXPORT void spvOptimizerDestroy(spv_optimizer_t* optimizer); + +// Sets an spv_message_consumer on an optimizer object. +SPIRV_TOOLS_EXPORT void spvOptimizerSetMessageConsumer( + spv_optimizer_t* optimizer, spv_message_consumer consumer); + +// Registers passes that attempt to legalize the generated code. +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterLegalizationPasses( + spv_optimizer_t* optimizer); + +// Registers passes that attempt to improve performance of generated code. +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterPerformancePasses( + spv_optimizer_t* optimizer); + +// Registers passes that attempt to improve the size of generated code. +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterSizePasses( + spv_optimizer_t* optimizer); + +// Registers a pass specified by a flag in an optimizer object. +SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag( + spv_optimizer_t* optimizer, const char* flag); + +// Registers passes specified by length number of flags in an optimizer object. +// Passes may remove interface variables that are unused. +SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags( + spv_optimizer_t* optimizer, const char** flags, const size_t flag_count); + +// Registers passes specified by length number of flags in an optimizer object. +// Passes will not remove interface variables. +SPIRV_TOOLS_EXPORT bool +spvOptimizerRegisterPassesFromFlagsWhilePreservingTheInterface( + spv_optimizer_t* optimizer, const char** flags, const size_t flag_count); + +// Optimizes the SPIR-V code of size |word_count| pointed to by |binary| and +// returns an optimized spv_binary in |optimized_binary|. +// +// Returns SPV_SUCCESS on successful optimization, whether or not the module is +// modified. Returns an SPV_ERROR_* if the module fails to validate or if +// errors occur when processing using any of the registered passes. In that +// case, no further passes are executed and the |optimized_binary| contents may +// be invalid. +// +// By default, the binary is validated before any transforms are performed, +// and optionally after each transform. Validation uses SPIR-V spec rules +// for the SPIR-V version named in the binary's header (at word offset 1). +// Additionally, if the target environment is a client API (such as +// Vulkan 1.1), then validate for that client API version, to the extent +// that it is verifiable from data in the binary itself, or from the +// validator options set on the optimizer options. +SPIRV_TOOLS_EXPORT spv_result_t spvOptimizerRun( + spv_optimizer_t* optimizer, const uint32_t* binary, const size_t word_count, + spv_binary* optimized_binary, const spv_optimizer_options options); + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDE_SPIRV_TOOLS_LIBSPIRV_H_ diff --git a/thirdparty/glslang/External/spirv-tools/include/spirv-tools/libspirv.hpp b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/libspirv.hpp new file mode 100644 index 000000000000..ee6c8469a03c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/libspirv.hpp @@ -0,0 +1,397 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ +#define INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ + +#include +#include +#include +#include + +#include "spirv-tools/libspirv.h" + +namespace spvtools { + +// Message consumer. The C strings for source and message are only alive for the +// specific invocation. +using MessageConsumer = std::function; + +using HeaderParser = std::function; +using InstructionParser = + std::function; + +// C++ RAII wrapper around the C context object spv_context. +class Context { + public: + // Constructs a context targeting the given environment |env|. + // + // See specific API calls for how the target environment is interpreted + // (particularly assembly and validation). + // + // The constructed instance will have an empty message consumer, which just + // ignores all messages from the library. Use SetMessageConsumer() to supply + // one if messages are of concern. + explicit Context(spv_target_env env); + + // Enables move constructor/assignment operations. + Context(Context&& other); + Context& operator=(Context&& other); + + // Disables copy constructor/assignment operations. + Context(const Context&) = delete; + Context& operator=(const Context&) = delete; + + // Destructs this instance. + ~Context(); + + // Sets the message consumer to the given |consumer|. The |consumer| will be + // invoked once for each message communicated from the library. + void SetMessageConsumer(MessageConsumer consumer); + + // Returns the underlying spv_context. + spv_context& CContext(); + const spv_context& CContext() const; + + private: + spv_context context_; +}; + +// A RAII wrapper around a validator options object. +class ValidatorOptions { + public: + ValidatorOptions() : options_(spvValidatorOptionsCreate()) {} + ~ValidatorOptions() { spvValidatorOptionsDestroy(options_); } + // Allow implicit conversion to the underlying object. + operator spv_validator_options() const { return options_; } + + // Sets a limit. + void SetUniversalLimit(spv_validator_limit limit_type, uint32_t limit) { + spvValidatorOptionsSetUniversalLimit(options_, limit_type, limit); + } + + void SetRelaxStructStore(bool val) { + spvValidatorOptionsSetRelaxStoreStruct(options_, val); + } + + // Enables VK_KHR_relaxed_block_layout when validating standard + // uniform/storage buffer/push-constant layout. If true, disables + // scalar block layout rules. + void SetRelaxBlockLayout(bool val) { + spvValidatorOptionsSetRelaxBlockLayout(options_, val); + } + + // Enables VK_KHR_uniform_buffer_standard_layout when validating standard + // uniform layout. If true, disables scalar block layout rules. + void SetUniformBufferStandardLayout(bool val) { + spvValidatorOptionsSetUniformBufferStandardLayout(options_, val); + } + + // Enables VK_EXT_scalar_block_layout when validating standard + // uniform/storage buffer/push-constant layout. If true, disables + // relaxed block layout rules. + void SetScalarBlockLayout(bool val) { + spvValidatorOptionsSetScalarBlockLayout(options_, val); + } + + // Enables scalar layout when validating Workgroup blocks. See + // VK_KHR_workgroup_memory_explicit_layout. + void SetWorkgroupScalarBlockLayout(bool val) { + spvValidatorOptionsSetWorkgroupScalarBlockLayout(options_, val); + } + + // Skips validating standard uniform/storage buffer/push-constant layout. + void SetSkipBlockLayout(bool val) { + spvValidatorOptionsSetSkipBlockLayout(options_, val); + } + + // Enables LocalSizeId decorations where the environment would not otherwise + // allow them. + void SetAllowLocalSizeId(bool val) { + spvValidatorOptionsSetAllowLocalSizeId(options_, val); + } + + // Records whether or not the validator should relax the rules on pointer + // usage in logical addressing mode. + // + // When relaxed, it will allow the following usage cases of pointers: + // 1) OpVariable allocating an object whose type is a pointer type + // 2) OpReturnValue returning a pointer value + void SetRelaxLogicalPointer(bool val) { + spvValidatorOptionsSetRelaxLogicalPointer(options_, val); + } + + // Records whether or not the validator should relax the rules because it is + // expected that the optimizations will make the code legal. + // + // When relaxed, it will allow the following: + // 1) It will allow relaxed logical pointers. Setting this option will also + // set that option. + // 2) Pointers that are pass as parameters to function calls do not have to + // match the storage class of the formal parameter. + // 3) Pointers that are actual parameters on function calls do not have to + // point to the same type pointed as the formal parameter. The types just + // need to logically match. + // 4) GLSLstd450 Interpolate* instructions can have a load of an interpolant + // for a first argument. + void SetBeforeHlslLegalization(bool val) { + spvValidatorOptionsSetBeforeHlslLegalization(options_, val); + } + + // Whether friendly names should be used in validation error messages. + void SetFriendlyNames(bool val) { + spvValidatorOptionsSetFriendlyNames(options_, val); + } + + private: + spv_validator_options options_; +}; + +// A C++ wrapper around an optimization options object. +class OptimizerOptions { + public: + OptimizerOptions() : options_(spvOptimizerOptionsCreate()) {} + ~OptimizerOptions() { spvOptimizerOptionsDestroy(options_); } + + // Allow implicit conversion to the underlying object. + operator spv_optimizer_options() const { return options_; } + + // Records whether or not the optimizer should run the validator before + // optimizing. If |run| is true, the validator will be run. + void set_run_validator(bool run) { + spvOptimizerOptionsSetRunValidator(options_, run); + } + + // Records the validator options that should be passed to the validator if it + // is run. + void set_validator_options(const ValidatorOptions& val_options) { + spvOptimizerOptionsSetValidatorOptions(options_, val_options); + } + + // Records the maximum possible value for the id bound. + void set_max_id_bound(uint32_t new_bound) { + spvOptimizerOptionsSetMaxIdBound(options_, new_bound); + } + + // Records whether all bindings within the module should be preserved. + void set_preserve_bindings(bool preserve_bindings) { + spvOptimizerOptionsSetPreserveBindings(options_, preserve_bindings); + } + + // Records whether all specialization constants within the module + // should be preserved. + void set_preserve_spec_constants(bool preserve_spec_constants) { + spvOptimizerOptionsSetPreserveSpecConstants(options_, + preserve_spec_constants); + } + + private: + spv_optimizer_options options_; +}; + +// A C++ wrapper around a reducer options object. +class ReducerOptions { + public: + ReducerOptions() : options_(spvReducerOptionsCreate()) {} + ~ReducerOptions() { spvReducerOptionsDestroy(options_); } + + // Allow implicit conversion to the underlying object. + operator spv_reducer_options() const { // NOLINT(google-explicit-constructor) + return options_; + } + + // See spvReducerOptionsSetStepLimit. + void set_step_limit(uint32_t step_limit) { + spvReducerOptionsSetStepLimit(options_, step_limit); + } + + // See spvReducerOptionsSetFailOnValidationError. + void set_fail_on_validation_error(bool fail_on_validation_error) { + spvReducerOptionsSetFailOnValidationError(options_, + fail_on_validation_error); + } + + // See spvReducerOptionsSetTargetFunction. + void set_target_function(uint32_t target_function) { + spvReducerOptionsSetTargetFunction(options_, target_function); + } + + private: + spv_reducer_options options_; +}; + +// A C++ wrapper around a fuzzer options object. +class FuzzerOptions { + public: + FuzzerOptions() : options_(spvFuzzerOptionsCreate()) {} + ~FuzzerOptions() { spvFuzzerOptionsDestroy(options_); } + + // Allow implicit conversion to the underlying object. + operator spv_fuzzer_options() const { // NOLINT(google-explicit-constructor) + return options_; + } + + // See spvFuzzerOptionsEnableReplayValidation. + void enable_replay_validation() { + spvFuzzerOptionsEnableReplayValidation(options_); + } + + // See spvFuzzerOptionsSetRandomSeed. + void set_random_seed(uint32_t seed) { + spvFuzzerOptionsSetRandomSeed(options_, seed); + } + + // See spvFuzzerOptionsSetReplayRange. + void set_replay_range(int32_t replay_range) { + spvFuzzerOptionsSetReplayRange(options_, replay_range); + } + + // See spvFuzzerOptionsSetShrinkerStepLimit. + void set_shrinker_step_limit(uint32_t shrinker_step_limit) { + spvFuzzerOptionsSetShrinkerStepLimit(options_, shrinker_step_limit); + } + + // See spvFuzzerOptionsEnableFuzzerPassValidation. + void enable_fuzzer_pass_validation() { + spvFuzzerOptionsEnableFuzzerPassValidation(options_); + } + + // See spvFuzzerOptionsEnableAllPasses. + void enable_all_passes() { spvFuzzerOptionsEnableAllPasses(options_); } + + private: + spv_fuzzer_options options_; +}; + +// C++ interface for SPIRV-Tools functionalities. It wraps the context +// (including target environment and the corresponding SPIR-V grammar) and +// provides methods for assembling, disassembling, and validating. +// +// Instances of this class provide basic thread-safety guarantee. +class SpirvTools { + public: + enum { + // Default assembling option used by assemble(): + kDefaultAssembleOption = SPV_TEXT_TO_BINARY_OPTION_NONE, + + // Default disassembling option used by Disassemble(): + // * Avoid prefix comments from decoding the SPIR-V module header, and + // * Use friendly names for variables. + kDefaultDisassembleOption = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER | + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES + }; + + // Constructs an instance targeting the given environment |env|. + // + // The constructed instance will have an empty message consumer, which just + // ignores all messages from the library. Use SetMessageConsumer() to supply + // one if messages are of concern. + explicit SpirvTools(spv_target_env env); + + // Disables copy/move constructor/assignment operations. + SpirvTools(const SpirvTools&) = delete; + SpirvTools(SpirvTools&&) = delete; + SpirvTools& operator=(const SpirvTools&) = delete; + SpirvTools& operator=(SpirvTools&&) = delete; + + // Destructs this instance. + ~SpirvTools(); + + // Sets the message consumer to the given |consumer|. The |consumer| will be + // invoked once for each message communicated from the library. + void SetMessageConsumer(MessageConsumer consumer); + + // Assembles the given assembly |text| and writes the result to |binary|. + // Returns true on successful assembling. |binary| will be kept untouched if + // assembling is unsuccessful. + // The SPIR-V binary version is set to the highest version of SPIR-V supported + // by the target environment with which this SpirvTools object was created. + bool Assemble(const std::string& text, std::vector* binary, + uint32_t options = kDefaultAssembleOption) const; + // |text_size| specifies the number of bytes in |text|. A terminating null + // character is not required to present in |text| as long as |text| is valid. + // The SPIR-V binary version is set to the highest version of SPIR-V supported + // by the target environment with which this SpirvTools object was created. + bool Assemble(const char* text, size_t text_size, + std::vector* binary, + uint32_t options = kDefaultAssembleOption) const; + + // Disassembles the given SPIR-V |binary| with the given |options| and writes + // the assembly to |text|. Returns true on successful disassembling. |text| + // will be kept untouched if diassembling is unsuccessful. + bool Disassemble(const std::vector& binary, std::string* text, + uint32_t options = kDefaultDisassembleOption) const; + // |binary_size| specifies the number of words in |binary|. + bool Disassemble(const uint32_t* binary, size_t binary_size, + std::string* text, + uint32_t options = kDefaultDisassembleOption) const; + + // Parses a SPIR-V binary, specified as counted sequence of 32-bit words. + // Parsing feedback is provided via two callbacks provided as std::function. + // In a valid parse the parsed-header callback is called once, and + // then the parsed-instruction callback is called once for each instruction + // in the stream. + // Returns true on successful parsing. + // If diagnostic is non-null, a diagnostic is emitted on failed parsing. + // If diagnostic is null the context's message consumer + // will be used to emit any errors. If a callback returns anything other than + // SPV_SUCCESS, then that status code is returned, no further callbacks are + // issued, and no additional diagnostics are emitted. + // This is a wrapper around the C API spvBinaryParse. + bool Parse(const std::vector& binary, + const HeaderParser& header_parser, + const InstructionParser& instruction_parser, + spv_diagnostic* diagnostic = nullptr); + + // Validates the given SPIR-V |binary|. Returns true if no issues are found. + // Otherwise, returns false and communicates issues via the message consumer + // registered. + // Validates for SPIR-V spec rules for the SPIR-V version named in the + // binary's header (at word offset 1). Additionally, if the target + // environment is a client API (such as Vulkan 1.1), then validate for that + // client API version, to the extent that it is verifiable from data in the + // binary itself. + bool Validate(const std::vector& binary) const; + // Like the previous overload, but provides the binary as a pointer and size: + // |binary_size| specifies the number of words in |binary|. + // Validates for SPIR-V spec rules for the SPIR-V version named in the + // binary's header (at word offset 1). Additionally, if the target + // environment is a client API (such as Vulkan 1.1), then validate for that + // client API version, to the extent that it is verifiable from data in the + // binary itself. + bool Validate(const uint32_t* binary, size_t binary_size) const; + // Like the previous overload, but takes an options object. + // Validates for SPIR-V spec rules for the SPIR-V version named in the + // binary's header (at word offset 1). Additionally, if the target + // environment is a client API (such as Vulkan 1.1), then validate for that + // client API version, to the extent that it is verifiable from data in the + // binary itself, or in the validator options. + bool Validate(const uint32_t* binary, size_t binary_size, + spv_validator_options options) const; + + // Was this object successfully constructed. + bool IsValid() const; + + private: + struct Impl; // Opaque struct for holding the data fields used by this class. + std::unique_ptr impl_; // Unique pointer to implementation data. +}; + +} // namespace spvtools + +#endif // INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ diff --git a/thirdparty/glslang/External/spirv-tools/include/spirv-tools/linker.hpp b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/linker.hpp new file mode 100644 index 000000000000..5b60cb9f9593 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/linker.hpp @@ -0,0 +1,98 @@ +// Copyright (c) 2017 Pierre Moreau +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_LINKER_HPP_ +#define INCLUDE_SPIRV_TOOLS_LINKER_HPP_ + +#include + +#include +#include + +#include "libspirv.hpp" + +namespace spvtools { + +class LinkerOptions { + public: + // Returns whether a library or an executable should be produced by the + // linking phase. + // + // All exported symbols are kept when creating a library, whereas they will + // be removed when creating an executable. + // The returned value will be true if creating a library, and false if + // creating an executable. + bool GetCreateLibrary() const { return create_library_; } + + // Sets whether a library or an executable should be produced. + void SetCreateLibrary(bool create_library) { + create_library_ = create_library; + } + + // Returns whether to verify the uniqueness of the unique ids in the merged + // context. + bool GetVerifyIds() const { return verify_ids_; } + + // Sets whether to verify the uniqueness of the unique ids in the merged + // context. + void SetVerifyIds(bool verify_ids) { verify_ids_ = verify_ids; } + + // Returns whether to allow for imported symbols to have no corresponding + // exported symbols + bool GetAllowPartialLinkage() const { return allow_partial_linkage_; } + + // Sets whether to allow for imported symbols to have no corresponding + // exported symbols + void SetAllowPartialLinkage(bool allow_partial_linkage) { + allow_partial_linkage_ = allow_partial_linkage; + } + + bool GetUseHighestVersion() const { return use_highest_version_; } + void SetUseHighestVersion(bool use_highest_vers) { + use_highest_version_ = use_highest_vers; + } + + private: + bool create_library_{false}; + bool verify_ids_{false}; + bool allow_partial_linkage_{false}; + bool use_highest_version_{false}; +}; + +// Links one or more SPIR-V modules into a new SPIR-V module. That is, combine +// several SPIR-V modules into one, resolving link dependencies between them. +// +// At least one binary has to be provided in |binaries|. Those binaries do not +// have to be valid, but they should be at least parseable. +// The functions can fail due to the following: +// * The given context was not initialised using `spvContextCreate()`; +// * No input modules were given; +// * One or more of those modules were not parseable; +// * The input modules used different addressing or memory models; +// * The ID or global variable number limit were exceeded; +// * Some entry points were defined multiple times; +// * Some imported symbols did not have an exported counterpart; +// * Possibly other reasons. +spv_result_t Link(const Context& context, + const std::vector>& binaries, + std::vector* linked_binary, + const LinkerOptions& options = LinkerOptions()); +spv_result_t Link(const Context& context, const uint32_t* const* binaries, + const size_t* binary_sizes, size_t num_binaries, + std::vector* linked_binary, + const LinkerOptions& options = LinkerOptions()); + +} // namespace spvtools + +#endif // INCLUDE_SPIRV_TOOLS_LINKER_HPP_ diff --git a/thirdparty/glslang/External/spirv-tools/include/spirv-tools/linter.hpp b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/linter.hpp new file mode 100644 index 000000000000..52ed5a467287 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/linter.hpp @@ -0,0 +1,48 @@ +// Copyright (c) 2021 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_LINTER_HPP_ +#define INCLUDE_SPIRV_TOOLS_LINTER_HPP_ + +#include "libspirv.hpp" + +namespace spvtools { + +// C++ interface for SPIR-V linting functionalities. It wraps the context +// (including target environment and the corresponding SPIR-V grammar) and +// provides a method for linting. +// +// Instances of this class provides basic thread-safety guarantee. +class Linter { + public: + explicit Linter(spv_target_env env); + + ~Linter(); + + // Sets the message consumer to the given |consumer|. The |consumer| will be + // invoked once for each message communicated from the library. + void SetMessageConsumer(MessageConsumer consumer); + + // Returns a reference to the registered message consumer. + const MessageConsumer& Consumer() const; + + bool Run(const uint32_t* binary, size_t binary_size); + + private: + struct Impl; + std::unique_ptr impl_; +}; +} // namespace spvtools + +#endif // INCLUDE_SPIRV_TOOLS_LINTER_HPP_ diff --git a/thirdparty/glslang/External/spirv-tools/include/spirv-tools/optimizer.hpp b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/optimizer.hpp new file mode 100644 index 000000000000..926e438fe2ff --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/include/spirv-tools/optimizer.hpp @@ -0,0 +1,1012 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ +#define INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ + +#include +#include +#include +#include +#include +#include +#include + +#include "libspirv.hpp" + +namespace spvtools { + +namespace opt { +class Pass; +struct DescriptorSetAndBinding; +} // namespace opt + +// C++ interface for SPIR-V optimization functionalities. It wraps the context +// (including target environment and the corresponding SPIR-V grammar) and +// provides methods for registering optimization passes and optimizing. +// +// Instances of this class provides basic thread-safety guarantee. +class Optimizer { + public: + // The token for an optimization pass. It is returned via one of the + // Create*Pass() standalone functions at the end of this header file and + // consumed by the RegisterPass() method. Tokens are one-time objects that + // only support move; copying is not allowed. + struct PassToken { + struct Impl; // Opaque struct for holding internal data. + + PassToken(std::unique_ptr); + + // Tokens for built-in passes should be created using Create*Pass functions + // below; for out-of-tree passes, use this constructor instead. + // Note that this API isn't guaranteed to be stable and may change without + // preserving source or binary compatibility in the future. + PassToken(std::unique_ptr&& pass); + + // Tokens can only be moved. Copying is disabled. + PassToken(const PassToken&) = delete; + PassToken(PassToken&&); + PassToken& operator=(const PassToken&) = delete; + PassToken& operator=(PassToken&&); + + ~PassToken(); + + std::unique_ptr impl_; // Unique pointer to internal data. + }; + + // Constructs an instance with the given target |env|, which is used to decode + // the binaries to be optimized later. + // + // The instance will have an empty message consumer, which ignores all + // messages from the library. Use SetMessageConsumer() to supply a consumer + // if messages are of concern. + explicit Optimizer(spv_target_env env); + + // Disables copy/move constructor/assignment operations. + Optimizer(const Optimizer&) = delete; + Optimizer(Optimizer&&) = delete; + Optimizer& operator=(const Optimizer&) = delete; + Optimizer& operator=(Optimizer&&) = delete; + + // Destructs this instance. + ~Optimizer(); + + // Sets the message consumer to the given |consumer|. The |consumer| will be + // invoked once for each message communicated from the library. + void SetMessageConsumer(MessageConsumer consumer); + + // Returns a reference to the registered message consumer. + const MessageConsumer& consumer() const; + + // Registers the given |pass| to this optimizer. Passes will be run in the + // exact order of registration. The token passed in will be consumed by this + // method. + Optimizer& RegisterPass(PassToken&& pass); + + // Registers passes that attempt to improve performance of generated code. + // This sequence of passes is subject to constant review and will change + // from time to time. + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + Optimizer& RegisterPerformancePasses(); + Optimizer& RegisterPerformancePasses(bool preserve_interface); + + // Registers passes that attempt to improve the size of generated code. + // This sequence of passes is subject to constant review and will change + // from time to time. + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + Optimizer& RegisterSizePasses(); + Optimizer& RegisterSizePasses(bool preserve_interface); + + // Registers passes that attempt to legalize the generated code. + // + // Note: this recipe is specially designed for legalizing SPIR-V. It should be + // used by compilers after translating HLSL source code literally. It should + // *not* be used by general workloads for performance or size improvement. + // + // This sequence of passes is subject to constant review and will change + // from time to time. + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + Optimizer& RegisterLegalizationPasses(); + Optimizer& RegisterLegalizationPasses(bool preserve_interface); + + // Register passes specified in the list of |flags|. Each flag must be a + // string of a form accepted by Optimizer::FlagHasValidForm(). + // + // If the list of flags contains an invalid entry, it returns false and an + // error message is emitted to the MessageConsumer object (use + // Optimizer::SetMessageConsumer to define a message consumer, if needed). + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + // + // If all the passes are registered successfully, it returns true. + bool RegisterPassesFromFlags(const std::vector& flags); + bool RegisterPassesFromFlags(const std::vector& flags, + bool preserve_interface); + + // Registers the optimization pass associated with |flag|. This only accepts + // |flag| values of the form "--pass_name[=pass_args]". If no such pass + // exists, it returns false. Otherwise, the pass is registered and it returns + // true. + // + // The following flags have special meaning: + // + // -O: Registers all performance optimization passes + // (Optimizer::RegisterPerformancePasses) + // + // -Os: Registers all size optimization passes + // (Optimizer::RegisterSizePasses). + // + // --legalize-hlsl: Registers all passes that legalize SPIR-V generated by an + // HLSL front-end. + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + bool RegisterPassFromFlag(const std::string& flag); + bool RegisterPassFromFlag(const std::string& flag, bool preserve_interface); + + // Validates that |flag| has a valid format. Strings accepted: + // + // --pass_name[=pass_args] + // -O + // -Os + // + // If |flag| takes one of the forms above, it returns true. Otherwise, it + // returns false. + bool FlagHasValidForm(const std::string& flag) const; + + // Allows changing, after creation time, the target environment to be + // optimized for and validated. Should be called before calling Run(). + void SetTargetEnv(const spv_target_env env); + + // Optimizes the given SPIR-V module |original_binary| and writes the + // optimized binary into |optimized_binary|. The optimized binary uses + // the same SPIR-V version as the original binary. + // + // Returns true on successful optimization, whether or not the module is + // modified. Returns false if |original_binary| fails to validate or if errors + // occur when processing |original_binary| using any of the registered passes. + // In that case, no further passes are executed and the contents in + // |optimized_binary| may be invalid. + // + // By default, the binary is validated before any transforms are performed, + // and optionally after each transform. Validation uses SPIR-V spec rules + // for the SPIR-V version named in the binary's header (at word offset 1). + // Additionally, if the target environment is a client API (such as + // Vulkan 1.1), then validate for that client API version, to the extent + // that it is verifiable from data in the binary itself. + // + // It's allowed to alias |original_binary| to the start of |optimized_binary|. + bool Run(const uint32_t* original_binary, size_t original_binary_size, + std::vector* optimized_binary) const; + + // DEPRECATED: Same as above, except passes |options| to the validator when + // trying to validate the binary. If |skip_validation| is true, then the + // caller is guaranteeing that |original_binary| is valid, and the validator + // will not be run. The |max_id_bound| is the limit on the max id in the + // module. + bool Run(const uint32_t* original_binary, const size_t original_binary_size, + std::vector* optimized_binary, + const ValidatorOptions& options, bool skip_validation) const; + + // Same as above, except it takes an options object. See the documentation + // for |OptimizerOptions| to see which options can be set. + // + // By default, the binary is validated before any transforms are performed, + // and optionally after each transform. Validation uses SPIR-V spec rules + // for the SPIR-V version named in the binary's header (at word offset 1). + // Additionally, if the target environment is a client API (such as + // Vulkan 1.1), then validate for that client API version, to the extent + // that it is verifiable from data in the binary itself, or from the + // validator options set on the optimizer options. + bool Run(const uint32_t* original_binary, const size_t original_binary_size, + std::vector* optimized_binary, + const spv_optimizer_options opt_options) const; + + // Returns a vector of strings with all the pass names added to this + // optimizer's pass manager. These strings are valid until the associated + // pass manager is destroyed. + std::vector GetPassNames() const; + + // Sets the option to print the disassembly before each pass and after the + // last pass. If |out| is null, then no output is generated. Otherwise, + // output is sent to the |out| output stream. + Optimizer& SetPrintAll(std::ostream* out); + + // Sets the option to print the resource utilization of each pass. If |out| + // is null, then no output is generated. Otherwise, output is sent to the + // |out| output stream. + Optimizer& SetTimeReport(std::ostream* out); + + // Sets the option to validate the module after each pass. + Optimizer& SetValidateAfterAll(bool validate); + + private: + struct Impl; // Opaque struct for holding internal data. + std::unique_ptr impl_; // Unique pointer to internal data. +}; + +// Creates a null pass. +// A null pass does nothing to the SPIR-V module to be optimized. +Optimizer::PassToken CreateNullPass(); + +// Creates a strip-debug-info pass. +// A strip-debug-info pass removes all debug instructions (as documented in +// Section 3.42.2 of the SPIR-V spec) of the SPIR-V module to be optimized. +Optimizer::PassToken CreateStripDebugInfoPass(); + +// [Deprecated] This will create a strip-nonsemantic-info pass. See below. +Optimizer::PassToken CreateStripReflectInfoPass(); + +// Creates a strip-nonsemantic-info pass. +// A strip-nonsemantic-info pass removes all reflections and explicitly +// non-semantic instructions. +Optimizer::PassToken CreateStripNonSemanticInfoPass(); + +// Creates an eliminate-dead-functions pass. +// An eliminate-dead-functions pass will remove all functions that are not in +// the call trees rooted at entry points and exported functions. These +// functions are not needed because they will never be called. +Optimizer::PassToken CreateEliminateDeadFunctionsPass(); + +// Creates an eliminate-dead-members pass. +// An eliminate-dead-members pass will remove all unused members of structures. +// This will not affect the data layout of the remaining members. +Optimizer::PassToken CreateEliminateDeadMembersPass(); + +// Creates a set-spec-constant-default-value pass from a mapping from spec-ids +// to the default values in the form of string. +// A set-spec-constant-default-value pass sets the default values for the +// spec constants that have SpecId decorations (i.e., those defined by +// OpSpecConstant{|True|False} instructions). +Optimizer::PassToken CreateSetSpecConstantDefaultValuePass( + const std::unordered_map& id_value_map); + +// Creates a set-spec-constant-default-value pass from a mapping from spec-ids +// to the default values in the form of bit pattern. +// A set-spec-constant-default-value pass sets the default values for the +// spec constants that have SpecId decorations (i.e., those defined by +// OpSpecConstant{|True|False} instructions). +Optimizer::PassToken CreateSetSpecConstantDefaultValuePass( + const std::unordered_map>& id_value_map); + +// Creates a flatten-decoration pass. +// A flatten-decoration pass replaces grouped decorations with equivalent +// ungrouped decorations. That is, it replaces each OpDecorationGroup +// instruction and associated OpGroupDecorate and OpGroupMemberDecorate +// instructions with equivalent OpDecorate and OpMemberDecorate instructions. +// The pass does not attempt to preserve debug information for instructions +// it removes. +Optimizer::PassToken CreateFlattenDecorationPass(); + +// Creates a freeze-spec-constant-value pass. +// A freeze-spec-constant pass specializes the value of spec constants to +// their default values. This pass only processes the spec constants that have +// SpecId decorations (defined by OpSpecConstant, OpSpecConstantTrue, or +// OpSpecConstantFalse instructions) and replaces them with their normal +// counterparts (OpConstant, OpConstantTrue, or OpConstantFalse). The +// corresponding SpecId annotation instructions will also be removed. This +// pass does not fold the newly added normal constants and does not process +// other spec constants defined by OpSpecConstantComposite or +// OpSpecConstantOp. +Optimizer::PassToken CreateFreezeSpecConstantValuePass(); + +// Creates a fold-spec-constant-op-and-composite pass. +// A fold-spec-constant-op-and-composite pass folds spec constants defined by +// OpSpecConstantOp or OpSpecConstantComposite instruction, to normal Constants +// defined by OpConstantTrue, OpConstantFalse, OpConstant, OpConstantNull, or +// OpConstantComposite instructions. Note that spec constants defined with +// OpSpecConstant, OpSpecConstantTrue, or OpSpecConstantFalse instructions are +// not handled, as these instructions indicate their value are not determined +// and can be changed in future. A spec constant is foldable if all of its +// value(s) can be determined from the module. E.g., an integer spec constant +// defined with OpSpecConstantOp instruction can be folded if its value won't +// change later. This pass will replace the original OpSpecConstantOp +// instruction with an OpConstant instruction. When folding composite spec +// constants, new instructions may be inserted to define the components of the +// composite constant first, then the original spec constants will be replaced +// by OpConstantComposite instructions. +// +// There are some operations not supported yet: +// OpSConvert, OpFConvert, OpQuantizeToF16 and +// all the operations under Kernel capability. +// TODO(qining): Add support for the operations listed above. +Optimizer::PassToken CreateFoldSpecConstantOpAndCompositePass(); + +// Creates a unify-constant pass. +// A unify-constant pass de-duplicates the constants. Constants with the exact +// same value and identical form will be unified and only one constant will +// be kept for each unique pair of type and value. +// There are several cases not handled by this pass: +// 1) Constants defined by OpConstantNull instructions (null constants) and +// constants defined by OpConstantFalse, OpConstant or OpConstantComposite +// with value 0 (zero-valued normal constants) are not considered equivalent. +// So null constants won't be used to replace zero-valued normal constants, +// vice versa. +// 2) Whenever there are decorations to the constant's result id id, the +// constant won't be handled, which means, it won't be used to replace any +// other constants, neither can other constants replace it. +// 3) NaN in float point format with different bit patterns are not unified. +Optimizer::PassToken CreateUnifyConstantPass(); + +// Creates a eliminate-dead-constant pass. +// A eliminate-dead-constant pass removes dead constants, including normal +// constants defined by OpConstant, OpConstantComposite, OpConstantTrue, or +// OpConstantFalse and spec constants defined by OpSpecConstant, +// OpSpecConstantComposite, OpSpecConstantTrue, OpSpecConstantFalse or +// OpSpecConstantOp. +Optimizer::PassToken CreateEliminateDeadConstantPass(); + +// Creates a strength-reduction pass. +// A strength-reduction pass will look for opportunities to replace an +// instruction with an equivalent and less expensive one. For example, +// multiplying by a power of 2 can be replaced by a bit shift. +Optimizer::PassToken CreateStrengthReductionPass(); + +// Creates a block merge pass. +// This pass searches for blocks with a single Branch to a block with no +// other predecessors and merges the blocks into a single block. Continue +// blocks and Merge blocks are not candidates for the second block. +// +// The pass is most useful after Dead Branch Elimination, which can leave +// such sequences of blocks. Merging them makes subsequent passes more +// effective, such as single block local store-load elimination. +// +// While this pass reduces the number of occurrences of this sequence, at +// this time it does not guarantee all such sequences are eliminated. +// +// Presence of phi instructions can inhibit this optimization. Handling +// these is left for future improvements. +Optimizer::PassToken CreateBlockMergePass(); + +// Creates an exhaustive inline pass. +// An exhaustive inline pass attempts to exhaustively inline all function +// calls in all functions in an entry point call tree. The intent is to enable, +// albeit through brute force, analysis and optimization across function +// calls by subsequent optimization passes. As the inlining is exhaustive, +// there is no attempt to optimize for size or runtime performance. Functions +// that are not in the call tree of an entry point are not changed. +Optimizer::PassToken CreateInlineExhaustivePass(); + +// Creates an opaque inline pass. +// An opaque inline pass inlines all function calls in all functions in all +// entry point call trees where the called function contains an opaque type +// in either its parameter types or return type. An opaque type is currently +// defined as Image, Sampler or SampledImage. The intent is to enable, albeit +// through brute force, analysis and optimization across these function calls +// by subsequent passes in order to remove the storing of opaque types which is +// not legal in Vulkan. Functions that are not in the call tree of an entry +// point are not changed. +Optimizer::PassToken CreateInlineOpaquePass(); + +// Creates a single-block local variable load/store elimination pass. +// For every entry point function, do single block memory optimization of +// function variables referenced only with non-access-chain loads and stores. +// For each targeted variable load, if previous store to that variable in the +// block, replace the load's result id with the value id of the store. +// If previous load within the block, replace the current load's result id +// with the previous load's result id. In either case, delete the current +// load. Finally, check if any remaining stores are useless, and delete store +// and variable if possible. +// +// The presence of access chain references and function calls can inhibit +// the above optimization. +// +// Only modules with relaxed logical addressing (see opt/instruction.h) are +// currently processed. +// +// This pass is most effective if preceded by Inlining and +// LocalAccessChainConvert. This pass will reduce the work needed to be done +// by LocalSingleStoreElim and LocalMultiStoreElim. +// +// Only functions in the call tree of an entry point are processed. +Optimizer::PassToken CreateLocalSingleBlockLoadStoreElimPass(); + +// Create dead branch elimination pass. +// For each entry point function, this pass will look for SelectionMerge +// BranchConditionals with constant condition and convert to a Branch to +// the indicated label. It will delete resulting dead blocks. +// +// For all phi functions in merge block, replace all uses with the id +// corresponding to the living predecessor. +// +// Note that some branches and blocks may be left to avoid creating invalid +// control flow. Improving this is left to future work. +// +// This pass is most effective when preceded by passes which eliminate +// local loads and stores, effectively propagating constant values where +// possible. +Optimizer::PassToken CreateDeadBranchElimPass(); + +// Creates an SSA local variable load/store elimination pass. +// For every entry point function, eliminate all loads and stores of function +// scope variables only referenced with non-access-chain loads and stores. +// Eliminate the variables as well. +// +// The presence of access chain references and function calls can inhibit +// the above optimization. +// +// Only shader modules with relaxed logical addressing (see opt/instruction.h) +// are currently processed. Currently modules with any extensions enabled are +// not processed. This is left for future work. +// +// This pass is most effective if preceded by Inlining and +// LocalAccessChainConvert. LocalSingleStoreElim and LocalSingleBlockElim +// will reduce the work that this pass has to do. +Optimizer::PassToken CreateLocalMultiStoreElimPass(); + +// Creates a local access chain conversion pass. +// A local access chain conversion pass identifies all function scope +// variables which are accessed only with loads, stores and access chains +// with constant indices. It then converts all loads and stores of such +// variables into equivalent sequences of loads, stores, extracts and inserts. +// +// This pass only processes entry point functions. It currently only converts +// non-nested, non-ptr access chains. It does not process modules with +// non-32-bit integer types present. Optional memory access options on loads +// and stores are ignored as we are only processing function scope variables. +// +// This pass unifies access to these variables to a single mode and simplifies +// subsequent analysis and elimination of these variables along with their +// loads and stores allowing values to propagate to their points of use where +// possible. +Optimizer::PassToken CreateLocalAccessChainConvertPass(); + +// Creates a local single store elimination pass. +// For each entry point function, this pass eliminates loads and stores for +// function scope variable that are stored to only once, where possible. Only +// whole variable loads and stores are eliminated; access-chain references are +// not optimized. Replace all loads of such variables with the value that is +// stored and eliminate any resulting dead code. +// +// Currently, the presence of access chains and function calls can inhibit this +// pass, however the Inlining and LocalAccessChainConvert passes can make it +// more effective. In additional, many non-load/store memory operations are +// not supported and will prohibit optimization of a function. Support of +// these operations are future work. +// +// Only shader modules with relaxed logical addressing (see opt/instruction.h) +// are currently processed. +// +// This pass will reduce the work needed to be done by LocalSingleBlockElim +// and LocalMultiStoreElim and can improve the effectiveness of other passes +// such as DeadBranchElimination which depend on values for their analysis. +Optimizer::PassToken CreateLocalSingleStoreElimPass(); + +// Creates an insert/extract elimination pass. +// This pass processes each entry point function in the module, searching for +// extracts on a sequence of inserts. It further searches the sequence for an +// insert with indices identical to the extract. If such an insert can be +// found before hitting a conflicting insert, the extract's result id is +// replaced with the id of the values from the insert. +// +// Besides removing extracts this pass enables subsequent dead code elimination +// passes to delete the inserts. This pass performs best after access chains are +// converted to inserts and extracts and local loads and stores are eliminated. +Optimizer::PassToken CreateInsertExtractElimPass(); + +// Creates a dead insert elimination pass. +// This pass processes each entry point function in the module, searching for +// unreferenced inserts into composite types. These are most often unused +// stores to vector components. They are unused because they are never +// referenced, or because there is another insert to the same component between +// the insert and the reference. After removing the inserts, dead code +// elimination is attempted on the inserted values. +// +// This pass performs best after access chains are converted to inserts and +// extracts and local loads and stores are eliminated. While executing this +// pass can be advantageous on its own, it is also advantageous to execute +// this pass after CreateInsertExtractPass() as it will remove any unused +// inserts created by that pass. +Optimizer::PassToken CreateDeadInsertElimPass(); + +// Create aggressive dead code elimination pass +// This pass eliminates unused code from the module. In addition, +// it detects and eliminates code which may have spurious uses but which do +// not contribute to the output of the function. The most common cause of +// such code sequences is summations in loops whose result is no longer used +// due to dead code elimination. This optimization has additional compile +// time cost over standard dead code elimination. +// +// This pass only processes entry point functions. It also only processes +// shaders with relaxed logical addressing (see opt/instruction.h). It +// currently will not process functions with function calls. Unreachable +// functions are deleted. +// +// This pass will be made more effective by first running passes that remove +// dead control flow and inlines function calls. +// +// This pass can be especially useful after running Local Access Chain +// Conversion, which tends to cause cycles of dead code to be left after +// Store/Load elimination passes are completed. These cycles cannot be +// eliminated with standard dead code elimination. +// +// If |preserve_interface| is true, all non-io variables in the entry point +// interface are considered live and are not eliminated. This mode is needed +// by GPU-Assisted validation instrumentation, where a change in the interface +// is not allowed. +// +// If |remove_outputs| is true, allow outputs to be removed from the interface. +// This is only safe if the caller knows that there is no corresponding input +// variable in the following shader. It is false by default. +Optimizer::PassToken CreateAggressiveDCEPass(); +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface); +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface, + bool remove_outputs); + +// Creates a remove-unused-interface-variables pass. +// Removes variables referenced on the |OpEntryPoint| instruction that are not +// referenced in the entry point function or any function in its call tree. Note +// that this could cause the shader interface to no longer match other shader +// stages. +Optimizer::PassToken CreateRemoveUnusedInterfaceVariablesPass(); + +// Creates an empty pass. +// This is deprecated and will be removed. +// TODO(jaebaek): remove this pass after handling glslang's broken unit tests. +// https://github.com/KhronosGroup/glslang/pull/2440 +Optimizer::PassToken CreatePropagateLineInfoPass(); + +// Creates an empty pass. +// This is deprecated and will be removed. +// TODO(jaebaek): remove this pass after handling glslang's broken unit tests. +// https://github.com/KhronosGroup/glslang/pull/2440 +Optimizer::PassToken CreateRedundantLineInfoElimPass(); + +// Creates a compact ids pass. +// The pass remaps result ids to a compact and gapless range starting from %1. +Optimizer::PassToken CreateCompactIdsPass(); + +// Creates a remove duplicate pass. +// This pass removes various duplicates: +// * duplicate capabilities; +// * duplicate extended instruction imports; +// * duplicate types; +// * duplicate decorations. +Optimizer::PassToken CreateRemoveDuplicatesPass(); + +// Creates a CFG cleanup pass. +// This pass removes cruft from the control flow graph of functions that are +// reachable from entry points and exported functions. It currently includes the +// following functionality: +// +// - Removal of unreachable basic blocks. +Optimizer::PassToken CreateCFGCleanupPass(); + +// Create dead variable elimination pass. +// This pass will delete module scope variables, along with their decorations, +// that are not referenced. +Optimizer::PassToken CreateDeadVariableEliminationPass(); + +// create merge return pass. +// changes functions that have multiple return statements so they have a single +// return statement. +// +// for structured control flow it is assumed that the only unreachable blocks in +// the function are trivial merge and continue blocks. +// +// a trivial merge block contains the label and an opunreachable instructions, +// nothing else. a trivial continue block contain a label and an opbranch to +// the header, nothing else. +// +// these conditions are guaranteed to be met after running dead-branch +// elimination. +Optimizer::PassToken CreateMergeReturnPass(); + +// Create value numbering pass. +// This pass will look for instructions in the same basic block that compute the +// same value, and remove the redundant ones. +Optimizer::PassToken CreateLocalRedundancyEliminationPass(); + +// Create LICM pass. +// This pass will look for invariant instructions inside loops and hoist them to +// the loops preheader. +Optimizer::PassToken CreateLoopInvariantCodeMotionPass(); + +// Creates a loop fission pass. +// This pass will split all top level loops whose register pressure exceedes the +// given |threshold|. +Optimizer::PassToken CreateLoopFissionPass(size_t threshold); + +// Creates a loop fusion pass. +// This pass will look for adjacent loops that are compatible and legal to be +// fused. The fuse all such loops as long as the register usage for the fused +// loop stays under the threshold defined by |max_registers_per_loop|. +Optimizer::PassToken CreateLoopFusionPass(size_t max_registers_per_loop); + +// Creates a loop peeling pass. +// This pass will look for conditions inside a loop that are true or false only +// for the N first or last iteration. For loop with such condition, those N +// iterations of the loop will be executed outside of the main loop. +// To limit code size explosion, the loop peeling can only happen if the code +// size growth for each loop is under |code_growth_threshold|. +Optimizer::PassToken CreateLoopPeelingPass(); + +// Creates a loop unswitch pass. +// This pass will look for loop independent branch conditions and move the +// condition out of the loop and version the loop based on the taken branch. +// Works best after LICM and local multi store elimination pass. +Optimizer::PassToken CreateLoopUnswitchPass(); + +// Create global value numbering pass. +// This pass will look for instructions where the same value is computed on all +// paths leading to the instruction. Those instructions are deleted. +Optimizer::PassToken CreateRedundancyEliminationPass(); + +// Create scalar replacement pass. +// This pass replaces composite function scope variables with variables for each +// element if those elements are accessed individually. The parameter is a +// limit on the number of members in the composite variable that the pass will +// consider replacing. +Optimizer::PassToken CreateScalarReplacementPass(uint32_t size_limit = 100); + +// Create a private to local pass. +// This pass looks for variables declared in the private storage class that are +// used in only one function. Those variables are moved to the function storage +// class in the function that they are used. +Optimizer::PassToken CreatePrivateToLocalPass(); + +// Creates a conditional constant propagation (CCP) pass. +// This pass implements the SSA-CCP algorithm in +// +// Constant propagation with conditional branches, +// Wegman and Zadeck, ACM TOPLAS 13(2):181-210. +// +// Constant values in expressions and conditional jumps are folded and +// simplified. This may reduce code size by removing never executed jump targets +// and computations with constant operands. +Optimizer::PassToken CreateCCPPass(); + +// Creates a workaround driver bugs pass. This pass attempts to work around +// a known driver bug (issue #1209) by identifying the bad code sequences and +// rewriting them. +// +// Current workaround: Avoid OpUnreachable instructions in loops. +Optimizer::PassToken CreateWorkaround1209Pass(); + +// Creates a pass that converts if-then-else like assignments into OpSelect. +Optimizer::PassToken CreateIfConversionPass(); + +// Creates a pass that will replace instructions that are not valid for the +// current shader stage by constants. Has no effect on non-shader modules. +Optimizer::PassToken CreateReplaceInvalidOpcodePass(); + +// Creates a pass that simplifies instructions using the instruction folder. +Optimizer::PassToken CreateSimplificationPass(); + +// Create loop unroller pass. +// Creates a pass to unroll loops which have the "Unroll" loop control +// mask set. The loops must meet a specific criteria in order to be unrolled +// safely this criteria is checked before doing the unroll by the +// LoopUtils::CanPerformUnroll method. Any loop that does not meet the criteria +// won't be unrolled. See CanPerformUnroll LoopUtils.h for more information. +Optimizer::PassToken CreateLoopUnrollPass(bool fully_unroll, int factor = 0); + +// Create the SSA rewrite pass. +// This pass converts load/store operations on function local variables into +// operations on SSA IDs. This allows SSA optimizers to act on these variables. +// Only variables that are local to the function and of supported types are +// processed (see IsSSATargetVar for details). +Optimizer::PassToken CreateSSARewritePass(); + +// Create pass to convert relaxed precision instructions to half precision. +// This pass converts as many relaxed float32 arithmetic operations to half as +// possible. It converts any float32 operands to half if needed. It converts +// any resulting half precision values back to float32 as needed. No variables +// are changed. No image operations are changed. +// +// Best if run after function scope store/load and composite operation +// eliminations are run. Also best if followed by instruction simplification, +// redundancy elimination and DCE. +Optimizer::PassToken CreateConvertRelaxedToHalfPass(); + +// Create relax float ops pass. +// This pass decorates all float32 result instructions with RelaxedPrecision +// if not already so decorated. +Optimizer::PassToken CreateRelaxFloatOpsPass(); + +// Create copy propagate arrays pass. +// This pass looks to copy propagate memory references for arrays. It looks +// for specific code patterns to recognize array copies. +Optimizer::PassToken CreateCopyPropagateArraysPass(); + +// Create a vector dce pass. +// This pass looks for components of vectors that are unused, and removes them +// from the vector. Note this would still leave around lots of dead code that +// a pass of ADCE will be able to remove. +Optimizer::PassToken CreateVectorDCEPass(); + +// Create a pass to reduce the size of loads. +// This pass looks for loads of structures where only a few of its members are +// used. It replaces the loads feeding an OpExtract with an OpAccessChain and +// a load of the specific elements. The parameter is a threshold to determine +// whether we have to replace the load or not. If the ratio of the used +// components of the load is less than the threshold, we replace the load. +Optimizer::PassToken CreateReduceLoadSizePass( + double load_replacement_threshold = 0.9); + +// Create a pass to combine chained access chains. +// This pass looks for access chains fed by other access chains and combines +// them into a single instruction where possible. +Optimizer::PassToken CreateCombineAccessChainsPass(); + +// Create a pass to instrument bindless descriptor checking +// This pass instruments all bindless references to check that descriptor +// array indices are inbounds, and if the descriptor indexing extension is +// enabled, that the descriptor has been initialized. If the reference is +// invalid, a record is written to the debug output buffer (if space allows) +// and a null value is returned. This pass is designed to support bindless +// validation in the Vulkan validation layers. +// +// TODO(greg-lunarg): Add support for buffer references. Currently only does +// checking for image references. +// +// Dead code elimination should be run after this pass as the original, +// potentially invalid code is not removed and could cause undefined behavior, +// including crashes. It may also be beneficial to run Simplification +// (ie Constant Propagation), DeadBranchElim and BlockMerge after this pass to +// optimize instrument code involving the testing of compile-time constants. +// It is also generally recommended that this pass (and all +// instrumentation passes) be run after any legalization and optimization +// passes. This will give better analysis for the instrumentation and avoid +// potentially de-optimizing the instrument code, for example, inlining +// the debug record output function throughout the module. +// +// The instrumentation will write |shader_id| in each output record +// to identify the shader module which generated the record. +Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id); + +// Create a pass to instrument physical buffer address checking +// This pass instruments all physical buffer address references to check that +// all referenced bytes fall in a valid buffer. If the reference is +// invalid, a record is written to the debug output buffer (if space allows) +// and a null value is returned. This pass is designed to support buffer +// address validation in the Vulkan validation layers. +// +// Dead code elimination should be run after this pass as the original, +// potentially invalid code is not removed and could cause undefined behavior, +// including crashes. Instruction simplification would likely also be +// beneficial. It is also generally recommended that this pass (and all +// instrumentation passes) be run after any legalization and optimization +// passes. This will give better analysis for the instrumentation and avoid +// potentially de-optimizing the instrument code, for example, inlining +// the debug record output function throughout the module. +// +// The instrumentation will read and write buffers in debug +// descriptor set |desc_set|. It will write |shader_id| in each output record +// to identify the shader module which generated the record. +Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id); + +// Create a pass to instrument OpDebugPrintf instructions. +// This pass replaces all OpDebugPrintf instructions with instructions to write +// a record containing the string id and the all specified values into a special +// printf output buffer (if space allows). This pass is designed to support +// the printf validation in the Vulkan validation layers. +// +// The instrumentation will write buffers in debug descriptor set |desc_set|. +// It will write |shader_id| in each output record to identify the shader +// module which generated the record. +Optimizer::PassToken CreateInstDebugPrintfPass(uint32_t desc_set, + uint32_t shader_id); + +// Create a pass to upgrade to the VulkanKHR memory model. +// This pass upgrades the Logical GLSL450 memory model to Logical VulkanKHR. +// Additionally, it modifies memory, image, atomic and barrier operations to +// conform to that model's requirements. +Optimizer::PassToken CreateUpgradeMemoryModelPass(); + +// Create a pass to do code sinking. Code sinking is a transformation +// where an instruction is moved into a more deeply nested construct. +Optimizer::PassToken CreateCodeSinkingPass(); + +// Create a pass to fix incorrect storage classes. In order to make code +// generation simpler, DXC may generate code where the storage classes do not +// match up correctly. This pass will fix the errors that it can. +Optimizer::PassToken CreateFixStorageClassPass(); + +// Creates a graphics robust access pass. +// +// This pass injects code to clamp indexed accesses to buffers and internal +// arrays, providing guarantees satisfying Vulkan's robustBufferAccess rules. +// +// TODO(dneto): Clamps coordinates and sample index for pointer calculations +// into storage images (OpImageTexelPointer). For an cube array image, it +// assumes the maximum layer count times 6 is at most 0xffffffff. +// +// NOTE: This pass will fail with a message if: +// - The module is not a Shader module. +// - The module declares VariablePointers, VariablePointersStorageBuffer, or +// RuntimeDescriptorArrayEXT capabilities. +// - The module uses an addressing model other than Logical +// - Access chain indices are wider than 64 bits. +// - Access chain index for a struct is not an OpConstant integer or is out +// of range. (The module is already invalid if that is the case.) +// - TODO(dneto): The OpImageTexelPointer coordinate component is not 32-bits +// wide. +// +// NOTE: Access chain indices are always treated as signed integers. So +// if an array has a fixed size of more than 2^31 elements, then elements +// from 2^31 and above are never accessible with a 32-bit index, +// signed or unsigned. For this case, this pass will clamp the index +// between 0 and at 2^31-1, inclusive. +// Similarly, if an array has more then 2^15 element and is accessed with +// a 16-bit index, then elements from 2^15 and above are not accessible. +// In this case, the pass will clamp the index between 0 and 2^15-1 +// inclusive. +Optimizer::PassToken CreateGraphicsRobustAccessPass(); + +// Create a pass to spread Volatile semantics to variables with SMIDNV, +// WarpIDNV, SubgroupSize, SubgroupLocalInvocationId, SubgroupEqMask, +// SubgroupGeMask, SubgroupGtMask, SubgroupLeMask, or SubgroupLtMask BuiltIn +// decorations or OpLoad for them when the shader model is the ray generation, +// closest hit, miss, intersection, or callable. This pass can be used for +// VUID-StandaloneSpirv-VulkanMemoryModel-04678 and +// VUID-StandaloneSpirv-VulkanMemoryModel-04679 (See "Standalone SPIR-V +// Validation" section of Vulkan spec "Appendix A: Vulkan Environment for +// SPIR-V"). When the SPIR-V version is 1.6 or above, the pass also spreads +// the Volatile semantics to a variable with HelperInvocation BuiltIn decoration +// in the fragement shader. +Optimizer::PassToken CreateSpreadVolatileSemanticsPass(); + +// Create a pass to replace a descriptor access using variable index. +// This pass replaces every access using a variable index to array variable +// |desc| that has a DescriptorSet and Binding decorations with a constant +// element of the array. In order to replace the access using a variable index +// with the constant element, it uses a switch statement. +Optimizer::PassToken CreateReplaceDescArrayAccessUsingVarIndexPass(); + +// Create descriptor scalar replacement pass. +// This pass replaces every array variable |desc| that has a DescriptorSet and +// Binding decorations with a new variable for each element of the array. +// Suppose |desc| was bound at binding |b|. Then the variable corresponding to +// |desc[i]| will have binding |b+i|. The descriptor set will be the same. It +// is assumed that no other variable already has a binding that will used by one +// of the new variables. If not, the pass will generate invalid Spir-V. All +// accesses to |desc| must be OpAccessChain instructions with a literal index +// for the first index. +Optimizer::PassToken CreateDescriptorScalarReplacementPass(); + +// Create a pass to replace each OpKill instruction with a function call to a +// function that has a single OpKill. Also replace each OpTerminateInvocation +// instruction with a function call to a function that has a single +// OpTerminateInvocation. This allows more code to be inlined. +Optimizer::PassToken CreateWrapOpKillPass(); + +// Replaces the extensions VK_AMD_shader_ballot,VK_AMD_gcn_shader, and +// VK_AMD_shader_trinary_minmax with equivalent code using core instructions and +// capabilities. +Optimizer::PassToken CreateAmdExtToKhrPass(); + +// Replaces the internal version of GLSLstd450 InterpolateAt* extended +// instructions with the externally valid version. The internal version allows +// an OpLoad of the interpolant for the first argument. This pass removes the +// OpLoad and replaces it with its pointer. glslang and possibly other +// frontends will create the internal version for HLSL. This pass will be part +// of HLSL legalization and should be called after interpolants have been +// propagated into their final positions. +Optimizer::PassToken CreateInterpolateFixupPass(); + +// Removes unused components from composite input variables. Current +// implementation just removes trailing unused components from input arrays +// and structs. The pass performs best after maximizing dead code removal. +// A subsequent dead code elimination pass would be beneficial in removing +// newly unused component types. +// +// WARNING: This pass can only be safely applied standalone to vertex shaders +// as it can otherwise cause interface incompatibilities with the preceding +// shader in the pipeline. If applied to non-vertex shaders, the user should +// follow by applying EliminateDeadOutputStores and +// EliminateDeadOutputComponents to the preceding shader. +Optimizer::PassToken CreateEliminateDeadInputComponentsPass(); + +// Removes unused components from composite output variables. Current +// implementation just removes trailing unused components from output arrays +// and structs. The pass performs best after eliminating dead output stores. +// A subsequent dead code elimination pass would be beneficial in removing +// newly unused component types. Currently only supports vertex and fragment +// shaders. +// +// WARNING: This pass cannot be safely applied standalone as it can cause +// interface incompatibility with the following shader in the pipeline. The +// user should first apply EliminateDeadInputComponents to the following +// shader, then apply EliminateDeadOutputStores to this shader. +Optimizer::PassToken CreateEliminateDeadOutputComponentsPass(); + +// Removes unused components from composite input variables. This safe +// version will not cause interface incompatibilities since it only changes +// vertex shaders. The current implementation just removes trailing unused +// components from input structs and input arrays. The pass performs best +// after maximizing dead code removal. A subsequent dead code elimination +// pass would be beneficial in removing newly unused component types. +Optimizer::PassToken CreateEliminateDeadInputComponentsSafePass(); + +// Analyzes shader and populates |live_locs| and |live_builtins|. Best results +// will be obtained if shader has all dead code eliminated first. |live_locs| +// and |live_builtins| are subsequently used when calling +// CreateEliminateDeadOutputStoresPass on the preceding shader. Currently only +// supports tesc, tese, geom, and frag shaders. +Optimizer::PassToken CreateAnalyzeLiveInputPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins); + +// Removes stores to output locations not listed in |live_locs| or +// |live_builtins|. Best results are obtained if constant propagation is +// performed first. A subsequent call to ADCE will eliminate any dead code +// created by the removal of the stores. A subsequent call to +// CreateEliminateDeadOutputComponentsPass will eliminate any dead output +// components created by the elimination of the stores. Currently only supports +// vert, tesc, tese, and geom shaders. +Optimizer::PassToken CreateEliminateDeadOutputStoresPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins); + +// Creates a convert-to-sampled-image pass to convert images and/or +// samplers with given pairs of descriptor set and binding to sampled image. +// If a pair of an image and a sampler have the same pair of descriptor set and +// binding that is one of the given pairs, they will be converted to a sampled +// image. In addition, if only an image has the descriptor set and binding that +// is one of the given pairs, it will be converted to a sampled image as well. +Optimizer::PassToken CreateConvertToSampledImagePass( + const std::vector& + descriptor_set_binding_pairs); + +// Create an interface-variable-scalar-replacement pass that replaces array or +// matrix interface variables with a series of scalar or vector interface +// variables. For example, it replaces `float3 foo[2]` with `float3 foo0, foo1`. +Optimizer::PassToken CreateInterfaceVariableScalarReplacementPass(); + +// Creates a remove-dont-inline pass to remove the |DontInline| function control +// from every function in the module. This is useful if you want the inliner to +// inline these functions some reason. +Optimizer::PassToken CreateRemoveDontInlinePass(); +// Create a fix-func-call-param pass to fix non memory argument for the function +// call, as spirv-validation requires function parameters to be an memory +// object, currently the pass would remove accesschain pointer argument passed +// to the function +Optimizer::PassToken CreateFixFuncCallArgumentsPass(); + +// Creates a trim-capabilities pass. +// This pass removes unused capabilities for a given module, and if possible, +// associated extensions. +// See `trim_capabilities.h` for the list of supported capabilities. +// +// If the module contains unsupported capabilities, this pass will ignore them. +// This should be fine in most cases, but could yield to incorrect results if +// the unknown capability interacts with one of the trimmed capabilities. +Optimizer::PassToken CreateTrimCapabilitiesPass(); + +// Creates a switch-descriptorset pass. +// This pass changes any DescriptorSet decorations with the value |ds_from| to +// use the new value |ds_to|. +Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t ds_from, + uint32_t ds_to); + +// Creates an invocation interlock placement pass. +// This pass ensures that an entry point will have at most one +// OpBeginInterlockInvocationEXT and one OpEndInterlockInvocationEXT, in that +// order. +Optimizer::PassToken CreateInvocationInterlockPlacementPass(); + +// Creates a pass to add/remove maximal reconvergence execution mode. +// This pass either adds or removes maximal reconvergence from all entry points. +Optimizer::PassToken CreateModifyMaximalReconvergencePass(bool add); +} // namespace spvtools + +#endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ diff --git a/thirdparty/glslang/External/spirv-tools/source/CMakeLists.txt b/thirdparty/glslang/External/spirv-tools/source/CMakeLists.txt new file mode 100644 index 000000000000..f4ee3c84cf6e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/CMakeLists.txt @@ -0,0 +1,441 @@ +# Copyright (c) 2015-2016 The Khronos Group Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(GRAMMAR_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_grammar_tables.py") +set(VIMSYNTAX_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_vim_syntax.py") +set(XML_REGISTRY_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_registry_tables.py") +set(LANG_HEADER_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_language_headers.py") + +# Pull in grammar files that have migrated to SPIRV-Headers +set(DEBUGINFO_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/unified1/extinst.debuginfo.grammar.json") +set(CLDEBUGINFO100_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json") +set(VKDEBUGINFO100_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json") + +# macro() definitions are used in the following because we need to append .inc +# file paths into some global lists (*_CPP_DEPENDS). And those global lists are +# later used by set_source_files_properties() calls. +# function() definitions are not suitable because they create new scopes. +macro(spvtools_core_tables CONFIG_VERSION) + set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json") + set(GRAMMAR_INSTS_INC_FILE "${spirv-tools_BINARY_DIR}/core.insts-${CONFIG_VERSION}.inc") + set(GRAMMAR_KINDS_INC_FILE "${spirv-tools_BINARY_DIR}/operand.kinds-${CONFIG_VERSION}.inc") + add_custom_command(OUTPUT ${GRAMMAR_INSTS_INC_FILE} ${GRAMMAR_KINDS_INC_FILE} + COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + --spirv-core-grammar=${GRAMMAR_JSON_FILE} + --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE} + --extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE} + --core-insts-output=${GRAMMAR_INSTS_INC_FILE} + --operand-kinds-output=${GRAMMAR_KINDS_INC_FILE} + --output-language=c++ + DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} + ${GRAMMAR_JSON_FILE} + ${DEBUGINFO_GRAMMAR_JSON_FILE} + ${CLDEBUGINFO100_GRAMMAR_JSON_FILE} + COMMENT "Generate info tables for SPIR-V v${CONFIG_VERSION} core instructions and operands.") + list(APPEND OPCODE_CPP_DEPENDS ${GRAMMAR_INSTS_INC_FILE}) + list(APPEND OPERAND_CPP_DEPENDS ${GRAMMAR_KINDS_INC_FILE}) +endmacro(spvtools_core_tables) + +macro(spvtools_enum_string_mapping CONFIG_VERSION) + set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json") + set(GRAMMAR_EXTENSION_ENUM_INC_FILE "${spirv-tools_BINARY_DIR}/extension_enum.inc") + set(GRAMMAR_ENUM_STRING_MAPPING_INC_FILE "${spirv-tools_BINARY_DIR}/enum_string_mapping.inc") + add_custom_command(OUTPUT ${GRAMMAR_EXTENSION_ENUM_INC_FILE} + ${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE} + COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + --spirv-core-grammar=${GRAMMAR_JSON_FILE} + --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE} + --extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE} + --extension-enum-output=${GRAMMAR_EXTENSION_ENUM_INC_FILE} + --enum-string-mapping-output=${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE} + --output-language=c++ + DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} + ${GRAMMAR_JSON_FILE} + ${DEBUGINFO_GRAMMAR_JSON_FILE} + ${CLDEBUGINFO100_GRAMMAR_JSON_FILE} + COMMENT "Generate enum-string mapping for SPIR-V v${CONFIG_VERSION}.") + list(APPEND EXTENSION_H_DEPENDS ${GRAMMAR_EXTENSION_ENUM_INC_FILE}) + list(APPEND ENUM_STRING_MAPPING_CPP_DEPENDS ${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}) +endmacro(spvtools_enum_string_mapping) + +macro(spvtools_vimsyntax CONFIG_VERSION CLVERSION) + set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json") + set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.glsl.std.450.grammar.json") + set(OPENCL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.opencl.std.100.grammar.json") + set(VIMSYNTAX_FILE "${spirv-tools_BINARY_DIR}/spvasm.vim") + add_custom_command(OUTPUT ${VIMSYNTAX_FILE} + COMMAND Python3::Interpreter ${VIMSYNTAX_PROCESSING_SCRIPT} + --spirv-core-grammar=${GRAMMAR_JSON_FILE} + --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE} + --extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE} + --extinst-opencl-grammar=${OPENCL_GRAMMAR_JSON_FILE} + >${VIMSYNTAX_FILE} + DEPENDS ${VIMSYNTAX_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE} + ${GLSL_GRAMMAR_JSON_FILE} ${OPENCL_GRAMMAR_JSON_FILE} ${DEBUGINFO_GRAMMAR_JSON_FILE} + COMMENT "Generate spvasm.vim: Vim syntax file for SPIR-V assembly.") +endmacro(spvtools_vimsyntax) + +macro(spvtools_glsl_tables CONFIG_VERSION) + set(CORE_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json") + set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.glsl.std.450.grammar.json") + set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/glsl.std.450.insts.inc") + add_custom_command(OUTPUT ${GRAMMAR_INC_FILE} + COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + --extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE} + --glsl-insts-output=${GRAMMAR_INC_FILE} + --output-language=c++ + DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${GLSL_GRAMMAR_JSON_FILE} + COMMENT "Generate info tables for GLSL extended instructions and operands v${CONFIG_VERSION}.") + list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE}) +endmacro(spvtools_glsl_tables) + +macro(spvtools_opencl_tables CONFIG_VERSION) + set(CORE_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/spirv.core.grammar.json") + set(OPENCL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.opencl.std.100.grammar.json") + set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/opencl.std.insts.inc") + add_custom_command(OUTPUT ${GRAMMAR_INC_FILE} + COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + --extinst-opencl-grammar=${OPENCL_GRAMMAR_JSON_FILE} + --opencl-insts-output=${GRAMMAR_INC_FILE} + DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${OPENCL_GRAMMAR_JSON_FILE} + COMMENT "Generate info tables for OpenCL extended instructions and operands v${CONFIG_VERSION}.") + list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE}) +endmacro(spvtools_opencl_tables) + +macro(spvtools_vendor_tables VENDOR_TABLE SHORT_NAME OPERAND_KIND_PREFIX) + set(INSTS_FILE "${spirv-tools_BINARY_DIR}/${VENDOR_TABLE}.insts.inc") + set(GRAMMAR_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/unified1/extinst.${VENDOR_TABLE}.grammar.json") + if(NOT EXISTS ${GRAMMAR_FILE}) + set(GRAMMAR_FILE "${spirv-tools_SOURCE_DIR}/source/extinst.${VENDOR_TABLE}.grammar.json") + endif() + add_custom_command(OUTPUT ${INSTS_FILE} + COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + --extinst-vendor-grammar=${GRAMMAR_FILE} + --vendor-insts-output=${INSTS_FILE} + --vendor-operand-kind-prefix=${OPERAND_KIND_PREFIX} + DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_FILE} + COMMENT "Generate extended instruction tables for ${VENDOR_TABLE}.") + add_custom_target(spv-tools-${SHORT_NAME} DEPENDS ${INSTS_FILE}) + set_property(TARGET spv-tools-${SHORT_NAME} PROPERTY FOLDER "SPIRV-Tools build") + list(APPEND EXTINST_CPP_DEPENDS spv-tools-${SHORT_NAME}) +endmacro(spvtools_vendor_tables) + +macro(spvtools_extinst_lang_headers NAME GRAMMAR_FILE) + set(OUT_H ${spirv-tools_BINARY_DIR}/${NAME}.h) + add_custom_command(OUTPUT ${OUT_H} + COMMAND Python3::Interpreter ${LANG_HEADER_PROCESSING_SCRIPT} + --extinst-grammar=${GRAMMAR_FILE} + --extinst-output-path=${OUT_H} + DEPENDS ${LANG_HEADER_PROCESSING_SCRIPT} ${GRAMMAR_FILE} + COMMENT "Generate language specific header for ${NAME}.") + add_custom_target(spirv-tools-header-${NAME} DEPENDS ${OUT_H}) + set_property(TARGET spirv-tools-header-${NAME} PROPERTY FOLDER "SPIRV-Tools build") + list(APPEND EXTINST_CPP_DEPENDS spirv-tools-header-${NAME}) +endmacro(spvtools_extinst_lang_headers) + +spvtools_core_tables("unified1") +spvtools_enum_string_mapping("unified1") +spvtools_opencl_tables("unified1") +spvtools_glsl_tables("unified1") +spvtools_vendor_tables("spv-amd-shader-explicit-vertex-parameter" "spv-amd-sevp" "") +spvtools_vendor_tables("spv-amd-shader-trinary-minmax" "spv-amd-stm" "") +spvtools_vendor_tables("spv-amd-gcn-shader" "spv-amd-gs" "") +spvtools_vendor_tables("spv-amd-shader-ballot" "spv-amd-sb" "") +spvtools_vendor_tables("debuginfo" "debuginfo" "") +spvtools_vendor_tables("opencl.debuginfo.100" "cldi100" "CLDEBUG100_") +spvtools_vendor_tables("nonsemantic.shader.debuginfo.100" "shdi100" "SHDEBUG100_") +spvtools_vendor_tables("nonsemantic.clspvreflection" "clspvreflection" "") +spvtools_extinst_lang_headers("DebugInfo" ${DEBUGINFO_GRAMMAR_JSON_FILE}) +spvtools_extinst_lang_headers("OpenCLDebugInfo100" ${CLDEBUGINFO100_GRAMMAR_JSON_FILE}) +spvtools_extinst_lang_headers("NonSemanticShaderDebugInfo100" ${VKDEBUGINFO100_GRAMMAR_JSON_FILE}) + +spvtools_vimsyntax("unified1" "1.0") +add_custom_target(spirv-tools-vimsyntax DEPENDS ${VIMSYNTAX_FILE}) +set_property(TARGET spirv-tools-vimsyntax PROPERTY FOLDER "SPIRV-Tools utilities") + +# Extract the list of known generators from the SPIR-V XML registry file. +set(GENERATOR_INC_FILE ${spirv-tools_BINARY_DIR}/generators.inc) +set(SPIRV_XML_REGISTRY_FILE ${SPIRV_HEADER_INCLUDE_DIR}/spirv/spir-v.xml) +add_custom_command(OUTPUT ${GENERATOR_INC_FILE} + COMMAND Python3::Interpreter ${XML_REGISTRY_PROCESSING_SCRIPT} + --xml=${SPIRV_XML_REGISTRY_FILE} + --generator-output=${GENERATOR_INC_FILE} + DEPENDS ${XML_REGISTRY_PROCESSING_SCRIPT} ${SPIRV_XML_REGISTRY_FILE} + COMMENT "Generate tables based on the SPIR-V XML registry.") +list(APPEND OPCODE_CPP_DEPENDS ${GENERATOR_INC_FILE}) + +# The following .cpp files include the above generated .inc files. +# Add those .inc files as their dependencies. +# +# We need to wrap the .inc files with a custom target to avoid problems when +# multiple targets depend on the same custom command. +add_custom_target(core_tables + DEPENDS ${OPCODE_CPP_DEPENDS} ${OPERAND_CPP_DEPENDS}) +add_custom_target(enum_string_mapping + DEPENDS ${EXTENSION_H_DEPENDS} ${ENUM_STRING_MAPPING_CPP_DEPENDS}) +add_custom_target(extinst_tables + DEPENDS ${EXTINST_CPP_DEPENDS}) + +set_source_files_properties( + ${CMAKE_CURRENT_SOURCE_DIR}/extensions.h + PROPERTIES HEADER_FILE_ONLY TRUE) + +set(SPIRV_TOOLS_BUILD_VERSION_INC + ${spirv-tools_BINARY_DIR}/build-version.inc) +set(SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR + ${spirv-tools_SOURCE_DIR}/utils/update_build_version.py) +set(SPIRV_TOOLS_CHANGES_FILE + ${spirv-tools_SOURCE_DIR}/CHANGES) +add_custom_command(OUTPUT ${SPIRV_TOOLS_BUILD_VERSION_INC} + COMMAND Python3::Interpreter + ${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR} + ${SPIRV_TOOLS_CHANGES_FILE} ${SPIRV_TOOLS_BUILD_VERSION_INC} + DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR} + ${SPIRV_TOOLS_CHANGES_FILE} + COMMENT "Update build-version.inc in the SPIRV-Tools build directory (if necessary).") +# Convenience target for standalone generation of the build-version.inc file. +# This is not required for any dependence chain. +add_custom_target(spirv-tools-build-version + DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC}) +set_property(TARGET spirv-tools-build-version PROPERTY FOLDER "SPIRV-Tools build") + +list(APPEND PCH_DEPENDS ${ENUM_STRING_MAPPING_CPP_DEPENDS} ${OPCODE_CPP_DEPENDS} ${OPERAND_CPP_DEPENDS} ${EXTENSION_H_DEPENDS} ${EXTINST_CPP_DEPENDS} ${SPIRV_TOOLS_BUILD_VERSION_INC}) +set_source_files_properties( + ${CMAKE_CURRENT_SOURCE_DIR}/pch_source.cpp + PROPERTIES OBJECT_DEPENDS "${PCH_DEPENDS}") + +add_subdirectory(opt) +add_subdirectory(reduce) +add_subdirectory(fuzz) +add_subdirectory(link) +add_subdirectory(lint) +add_subdirectory(diff) + +set(SPIRV_SOURCES + ${spirv-tools_SOURCE_DIR}/include/spirv-tools/libspirv.h + + ${CMAKE_CURRENT_SOURCE_DIR}/util/bitutils.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/bit_vector.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/hash_combine.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/hex_float.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/make_unique.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/parse_number.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/small_vector.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/string_utils.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/timer.h + ${CMAKE_CURRENT_SOURCE_DIR}/assembly_grammar.h + ${CMAKE_CURRENT_SOURCE_DIR}/binary.h + ${CMAKE_CURRENT_SOURCE_DIR}/cfa.h + ${CMAKE_CURRENT_SOURCE_DIR}/common_debug_info.h + ${CMAKE_CURRENT_SOURCE_DIR}/diagnostic.h + ${CMAKE_CURRENT_SOURCE_DIR}/disassemble.h + ${CMAKE_CURRENT_SOURCE_DIR}/enum_set.h + ${CMAKE_CURRENT_SOURCE_DIR}/enum_string_mapping.h + ${CMAKE_CURRENT_SOURCE_DIR}/ext_inst.h + ${CMAKE_CURRENT_SOURCE_DIR}/extensions.h + ${CMAKE_CURRENT_SOURCE_DIR}/instruction.h + ${CMAKE_CURRENT_SOURCE_DIR}/latest_version_glsl_std_450_header.h + ${CMAKE_CURRENT_SOURCE_DIR}/latest_version_opencl_std_header.h + ${CMAKE_CURRENT_SOURCE_DIR}/latest_version_spirv_header.h + ${CMAKE_CURRENT_SOURCE_DIR}/macro.h + ${CMAKE_CURRENT_SOURCE_DIR}/name_mapper.h + ${CMAKE_CURRENT_SOURCE_DIR}/opcode.h + ${CMAKE_CURRENT_SOURCE_DIR}/operand.h + ${CMAKE_CURRENT_SOURCE_DIR}/parsed_operand.h + ${CMAKE_CURRENT_SOURCE_DIR}/print.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_constant.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_definition.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_endian.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_fuzzer_options.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_optimizer_options.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_reducer_options.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_target_env.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_validator_options.h + ${CMAKE_CURRENT_SOURCE_DIR}/table.h + ${CMAKE_CURRENT_SOURCE_DIR}/text.h + ${CMAKE_CURRENT_SOURCE_DIR}/text_handler.h + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate.h + + ${CMAKE_CURRENT_SOURCE_DIR}/util/bit_vector.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/util/parse_number.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/util/string_utils.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/assembly_grammar.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/binary.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/diagnostic.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/disassemble.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/enum_string_mapping.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ext_inst.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/extensions.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/libspirv.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/name_mapper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/opcode.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/operand.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/parsed_operand.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/print.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/software_version.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_endian.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_fuzzer_options.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_optimizer_options.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_reducer_options.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_target_env.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_validator_options.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/table.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/text.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/text_handler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_adjacency.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_annotation.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_arithmetics.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_atomics.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_barriers.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_bitwise.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_builtins.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_capability.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_cfg.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_composites.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_constants.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_conversion.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_debug.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_decorations.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_derivatives.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_extensions.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_execution_limitations.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_function.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_id.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_image.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_interfaces.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_instruction.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_layout.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_literals.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_logicals.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_memory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_memory_semantics.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_mesh_shading.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_misc.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_mode_setting.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_non_uniform.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_primitives.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_query.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_tracing.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_tracing_reorder.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_scopes.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_small_type_uses.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_type.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/decoration.h + ${CMAKE_CURRENT_SOURCE_DIR}/val/basic_block.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/construct.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/function.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/instruction.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/val/validation_state.cpp) + +if (${SPIRV_TIMER_ENABLED}) + set(SPIRV_SOURCES + ${SPIRV_SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/util/timer.cpp) +endif() + +# The software_version.cpp file includes build-version.inc. +# Rebuild the software_version.cpp object file if it is older than +# build-version.inc or whenever build-version.inc itself is out of +# date. In the latter case, rebuild build-version.inc first. +# CMake is not smart enough to detect this dependency automatically. +# Without this, the dependency detection system for #included files +# does not kick in on a clean build for the following reason: The +# build will fail early because it doesn't know how to build the +# missing source file build-version.inc. That occurs before the +# preprocessor is run on software_version.cpp to detect the +# #include dependency. +set_source_files_properties( + ${CMAKE_CURRENT_SOURCE_DIR}/software_version.cpp + PROPERTIES OBJECT_DEPENDS "${SPIRV_TOOLS_BUILD_VERSION_INC}") + +spvtools_pch(SPIRV_SOURCES pch_source) + +# spirv_tools_default_target_options() sets the target options that are common +# for all ${SPIRV_TOOLS} targets. +function(spirv_tools_default_target_options target) + spvtools_default_compile_options(${target}) + target_include_directories(${target} + PUBLIC + $ + $ + PRIVATE ${spirv-tools_BINARY_DIR} + PRIVATE ${SPIRV_HEADER_INCLUDE_DIR} + ) + set_property(TARGET ${target} PROPERTY FOLDER "SPIRV-Tools libraries") + spvtools_check_symbol_exports(${target}) + add_dependencies(${target} spirv-tools-build-version core_tables enum_string_mapping extinst_tables) +endfunction() + +# Always build ${SPIRV_TOOLS}-shared. This is expected distro packages, and +# unlike the other SPIRV_TOOLS target, defaults to hidden symbol visibility. +add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES}) +spirv_tools_default_target_options(${SPIRV_TOOLS}-shared) +set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${SPIRV_TOOLS}-shared + PRIVATE SPIRV_TOOLS_IMPLEMENTATION + PUBLIC SPIRV_TOOLS_SHAREDLIB +) + +if(SPIRV_TOOLS_BUILD_STATIC) + add_library(${SPIRV_TOOLS}-static STATIC ${SPIRV_SOURCES}) + spirv_tools_default_target_options(${SPIRV_TOOLS}-static) + # The static target does not have the '-static' suffix. + set_target_properties(${SPIRV_TOOLS}-static PROPERTIES OUTPUT_NAME "${SPIRV_TOOLS}") + + # Create the "${SPIRV_TOOLS}" target as an alias to either "${SPIRV_TOOLS}-static" + # or "${SPIRV_TOOLS}-shared" depending on the value of BUILD_SHARED_LIBS. + if(BUILD_SHARED_LIBS) + add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-shared) + else() + add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-static) + endif() + + set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static ${SPIRV_TOOLS}-shared) +else() + add_library(${SPIRV_TOOLS} ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_SOURCES}) + spirv_tools_default_target_options(${SPIRV_TOOLS}) + set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared) +endif() + +if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + find_library(LIBRT rt) + if(LIBRT) + foreach(target ${SPIRV_TOOLS_TARGETS}) + target_link_libraries(${target} rt) + endforeach() + endif() +endif() + +if(ENABLE_SPIRV_TOOLS_INSTALL) + install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets) + export(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake) + + spvtools_config_package_dir(${SPIRV_TOOLS} PACKAGE_DIR) + install(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake DESTINATION ${PACKAGE_DIR}) + + # Special config file for root library compared to other libs. + file(WRITE ${CMAKE_BINARY_DIR}/${SPIRV_TOOLS}Config.cmake + "include(\${CMAKE_CURRENT_LIST_DIR}/${SPIRV_TOOLS}Target.cmake)\n" + "if(TARGET ${SPIRV_TOOLS})\n" + " set(${SPIRV_TOOLS}_LIBRARIES ${SPIRV_TOOLS})\n" + " get_target_property(${SPIRV_TOOLS}_INCLUDE_DIRS ${SPIRV_TOOLS} INTERFACE_INCLUDE_DIRECTORIES)\n" + "endif()\n") + install(FILES ${CMAKE_BINARY_DIR}/${SPIRV_TOOLS}Config.cmake DESTINATION ${PACKAGE_DIR}) +endif(ENABLE_SPIRV_TOOLS_INSTALL) + +if(MSVC AND (NOT ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))) + # Enable parallel builds across four cores for this lib + add_definitions(/MP4) +endif() diff --git a/thirdparty/glslang/External/spirv-tools/source/assembly_grammar.cpp b/thirdparty/glslang/External/spirv-tools/source/assembly_grammar.cpp new file mode 100644 index 000000000000..0092d01a5003 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/assembly_grammar.cpp @@ -0,0 +1,269 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/assembly_grammar.h" + +#include +#include +#include + +#include "source/ext_inst.h" +#include "source/opcode.h" +#include "source/operand.h" +#include "source/spirv_target_env.h" +#include "source/table.h" + +namespace spvtools { +namespace { + +/// @brief Parses a mask expression string for the given operand type. +/// +/// A mask expression is a sequence of one or more terms separated by '|', +/// where each term a named enum value for the given type. No whitespace +/// is permitted. +/// +/// On success, the value is written to pValue. +/// +/// @param[in] operandTable operand lookup table +/// @param[in] type of the operand +/// @param[in] textValue word of text to be parsed +/// @param[out] pValue where the resulting value is written +/// +/// @return result code +spv_result_t spvTextParseMaskOperand(spv_target_env env, + const spv_operand_table operandTable, + const spv_operand_type_t type, + const char* textValue, uint32_t* pValue) { + if (textValue == nullptr) return SPV_ERROR_INVALID_TEXT; + size_t text_length = strlen(textValue); + if (text_length == 0) return SPV_ERROR_INVALID_TEXT; + const char* text_end = textValue + text_length; + + // We only support mask expressions in ASCII, so the separator value is a + // char. + const char separator = '|'; + + // Accumulate the result by interpreting one word at a time, scanning + // from left to right. + uint32_t value = 0; + const char* begin = textValue; // The left end of the current word. + const char* end = nullptr; // One character past the end of the current word. + do { + end = std::find(begin, text_end, separator); + + spv_operand_desc entry = nullptr; + if (auto error = spvOperandTableNameLookup(env, operandTable, type, begin, + end - begin, &entry)) { + return error; + } + value |= entry->value; + + // Advance to the next word by skipping over the separator. + begin = end + 1; + } while (end != text_end); + + *pValue = value; + return SPV_SUCCESS; +} + +// Associates an opcode with its name. +struct SpecConstantOpcodeEntry { + spv::Op opcode; + const char* name; +}; + +// All the opcodes allowed as the operation for OpSpecConstantOp. +// The name does not have the usual "Op" prefix. For example opcode +// spv::Op::IAdd is associated with the name "IAdd". +// +// clang-format off +#define CASE(NAME) { spv::Op::Op##NAME, #NAME } +const SpecConstantOpcodeEntry kOpSpecConstantOpcodes[] = { + // Conversion + CASE(SConvert), + CASE(FConvert), + CASE(ConvertFToS), + CASE(ConvertSToF), + CASE(ConvertFToU), + CASE(ConvertUToF), + CASE(UConvert), + CASE(ConvertPtrToU), + CASE(ConvertUToPtr), + CASE(GenericCastToPtr), + CASE(PtrCastToGeneric), + CASE(Bitcast), + CASE(QuantizeToF16), + // Arithmetic + CASE(SNegate), + CASE(Not), + CASE(IAdd), + CASE(ISub), + CASE(IMul), + CASE(UDiv), + CASE(SDiv), + CASE(UMod), + CASE(SRem), + CASE(SMod), + CASE(ShiftRightLogical), + CASE(ShiftRightArithmetic), + CASE(ShiftLeftLogical), + CASE(BitwiseOr), + CASE(BitwiseAnd), + CASE(BitwiseXor), + CASE(FNegate), + CASE(FAdd), + CASE(FSub), + CASE(FMul), + CASE(FDiv), + CASE(FRem), + CASE(FMod), + // Composite + CASE(VectorShuffle), + CASE(CompositeExtract), + CASE(CompositeInsert), + // Logical + CASE(LogicalOr), + CASE(LogicalAnd), + CASE(LogicalNot), + CASE(LogicalEqual), + CASE(LogicalNotEqual), + CASE(Select), + // Comparison + CASE(IEqual), + CASE(INotEqual), + CASE(ULessThan), + CASE(SLessThan), + CASE(UGreaterThan), + CASE(SGreaterThan), + CASE(ULessThanEqual), + CASE(SLessThanEqual), + CASE(UGreaterThanEqual), + CASE(SGreaterThanEqual), + // Memory + CASE(AccessChain), + CASE(InBoundsAccessChain), + CASE(PtrAccessChain), + CASE(InBoundsPtrAccessChain), + CASE(CooperativeMatrixLengthNV), + CASE(CooperativeMatrixLengthKHR) +}; + +// The 60 is determined by counting the opcodes listed in the spec. +static_assert(61 == sizeof(kOpSpecConstantOpcodes)/sizeof(kOpSpecConstantOpcodes[0]), + "OpSpecConstantOp opcode table is incomplete"); +#undef CASE +// clang-format on + +const size_t kNumOpSpecConstantOpcodes = + sizeof(kOpSpecConstantOpcodes) / sizeof(kOpSpecConstantOpcodes[0]); + +} // namespace + +bool AssemblyGrammar::isValid() const { + return operandTable_ && opcodeTable_ && extInstTable_; +} + +CapabilitySet AssemblyGrammar::filterCapsAgainstTargetEnv( + const spv::Capability* cap_array, uint32_t count) const { + CapabilitySet cap_set; + const auto version = spvVersionForTargetEnv(target_env_); + for (uint32_t i = 0; i < count; ++i) { + spv_operand_desc entry = {}; + if (SPV_SUCCESS == lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, + static_cast(cap_array[i]), + &entry)) { + // This token is visible in this environment if it's in an appropriate + // core version, or it is enabled by a capability or an extension. + if ((version >= entry->minVersion && version <= entry->lastVersion) || + entry->numExtensions > 0u || entry->numCapabilities > 0u) { + cap_set.insert(cap_array[i]); + } + } + } + return cap_set; +} + +spv_result_t AssemblyGrammar::lookupOpcode(const char* name, + spv_opcode_desc* desc) const { + return spvOpcodeTableNameLookup(target_env_, opcodeTable_, name, desc); +} + +spv_result_t AssemblyGrammar::lookupOpcode(spv::Op opcode, + spv_opcode_desc* desc) const { + return spvOpcodeTableValueLookup(target_env_, opcodeTable_, opcode, desc); +} + +spv_result_t AssemblyGrammar::lookupOperand(spv_operand_type_t type, + const char* name, size_t name_len, + spv_operand_desc* desc) const { + return spvOperandTableNameLookup(target_env_, operandTable_, type, name, + name_len, desc); +} + +spv_result_t AssemblyGrammar::lookupOperand(spv_operand_type_t type, + uint32_t operand, + spv_operand_desc* desc) const { + return spvOperandTableValueLookup(target_env_, operandTable_, type, operand, + desc); +} + +spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(const char* name, + spv::Op* opcode) const { + const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes; + const auto* found = + std::find_if(kOpSpecConstantOpcodes, last, + [name](const SpecConstantOpcodeEntry& entry) { + return 0 == strcmp(name, entry.name); + }); + if (found == last) return SPV_ERROR_INVALID_LOOKUP; + *opcode = found->opcode; + return SPV_SUCCESS; +} + +spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(spv::Op opcode) const { + const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes; + const auto* found = + std::find_if(kOpSpecConstantOpcodes, last, + [opcode](const SpecConstantOpcodeEntry& entry) { + return opcode == entry.opcode; + }); + if (found == last) return SPV_ERROR_INVALID_LOOKUP; + return SPV_SUCCESS; +} + +spv_result_t AssemblyGrammar::parseMaskOperand(const spv_operand_type_t type, + const char* textValue, + uint32_t* pValue) const { + return spvTextParseMaskOperand(target_env_, operandTable_, type, textValue, + pValue); +} +spv_result_t AssemblyGrammar::lookupExtInst(spv_ext_inst_type_t type, + const char* textValue, + spv_ext_inst_desc* extInst) const { + return spvExtInstTableNameLookup(extInstTable_, type, textValue, extInst); +} + +spv_result_t AssemblyGrammar::lookupExtInst(spv_ext_inst_type_t type, + uint32_t firstWord, + spv_ext_inst_desc* extInst) const { + return spvExtInstTableValueLookup(extInstTable_, type, firstWord, extInst); +} + +void AssemblyGrammar::pushOperandTypesForMask( + const spv_operand_type_t type, const uint32_t mask, + spv_operand_pattern_t* pattern) const { + spvPushOperandTypesForMask(target_env_, operandTable_, type, mask, pattern); +} + +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/assembly_grammar.h b/thirdparty/glslang/External/spirv-tools/source/assembly_grammar.h new file mode 100644 index 000000000000..36fdd08a6d6a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/assembly_grammar.h @@ -0,0 +1,139 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_ASSEMBLY_GRAMMAR_H_ +#define SOURCE_ASSEMBLY_GRAMMAR_H_ + +#include "source/enum_set.h" +#include "source/latest_version_spirv_header.h" +#include "source/operand.h" +#include "source/table.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { + +// Encapsulates the grammar to use for SPIR-V assembly. +// Contains methods to query for valid instructions and operands. +class AssemblyGrammar { + public: + explicit AssemblyGrammar(const spv_const_context context) + : target_env_(context->target_env), + operandTable_(context->operand_table), + opcodeTable_(context->opcode_table), + extInstTable_(context->ext_inst_table) {} + + // Returns true if the internal tables have been initialized with valid data. + bool isValid() const; + + // Returns the SPIR-V target environment. + spv_target_env target_env() const { return target_env_; } + + // Removes capabilities not available in the current target environment and + // returns the rest. + CapabilitySet filterCapsAgainstTargetEnv(const spv::Capability* cap_array, + uint32_t count) const; + + // Fills in the desc parameter with the information about the opcode + // of the given name. Returns SPV_SUCCESS if the opcode was found, and + // SPV_ERROR_INVALID_LOOKUP if the opcode does not exist. + spv_result_t lookupOpcode(const char* name, spv_opcode_desc* desc) const; + + // Fills in the desc parameter with the information about the opcode + // of the valid. Returns SPV_SUCCESS if the opcode was found, and + // SPV_ERROR_INVALID_LOOKUP if the opcode does not exist. + spv_result_t lookupOpcode(spv::Op opcode, spv_opcode_desc* desc) const; + + // Fills in the desc parameter with the information about the given + // operand. Returns SPV_SUCCESS if the operand was found, and + // SPV_ERROR_INVALID_LOOKUP otherwise. + spv_result_t lookupOperand(spv_operand_type_t type, const char* name, + size_t name_len, spv_operand_desc* desc) const; + + // Fills in the desc parameter with the information about the given + // operand. Returns SPV_SUCCESS if the operand was found, and + // SPV_ERROR_INVALID_LOOKUP otherwise. + spv_result_t lookupOperand(spv_operand_type_t type, uint32_t operand, + spv_operand_desc* desc) const; + + // Finds operand entry in the grammar table and returns its name. + // Returns "Unknown" if not found. + const char* lookupOperandName(spv_operand_type_t type, + uint32_t operand) const { + spv_operand_desc desc = nullptr; + if (lookupOperand(type, operand, &desc) != SPV_SUCCESS || !desc) { + return "Unknown"; + } + return desc->name; + } + + // Finds the opcode for the given OpSpecConstantOp opcode name. The name + // should not have the "Op" prefix. For example, "IAdd" corresponds to + // the integer add opcode for OpSpecConstantOp. On success, returns + // SPV_SUCCESS and sends the discovered operation code through the opcode + // parameter. On failure, returns SPV_ERROR_INVALID_LOOKUP. + spv_result_t lookupSpecConstantOpcode(const char* name, + spv::Op* opcode) const; + + // Returns SPV_SUCCESS if the given opcode is valid as the opcode operand + // to OpSpecConstantOp. + spv_result_t lookupSpecConstantOpcode(spv::Op opcode) const; + + // Parses a mask expression string for the given operand type. + // + // A mask expression is a sequence of one or more terms separated by '|', + // where each term is a named enum value for a given type. No whitespace + // is permitted. + // + // On success, the value is written to pValue, and SPV_SUCCESS is returned. + // The operand type is defined by the type parameter, and the text to be + // parsed is defined by the textValue parameter. + spv_result_t parseMaskOperand(const spv_operand_type_t type, + const char* textValue, uint32_t* pValue) const; + + // Writes the extended operand with the given type and text to the *extInst + // parameter. + // Returns SPV_SUCCESS if the value could be found. + spv_result_t lookupExtInst(spv_ext_inst_type_t type, const char* textValue, + spv_ext_inst_desc* extInst) const; + + // Writes the extended operand with the given type and first encoded word + // to the *extInst parameter. + // Returns SPV_SUCCESS if the value could be found. + spv_result_t lookupExtInst(spv_ext_inst_type_t type, uint32_t firstWord, + spv_ext_inst_desc* extInst) const; + + // Inserts the operands expected after the given typed mask onto the end + // of the given pattern. + // + // Each set bit in the mask represents zero or more operand types that + // should be appended onto the pattern. Operands for a less significant + // bit must always match before operands for a more significant bit, so + // the operands for a less significant bit must appear closer to the end + // of the pattern stack. + // + // If a set bit is unknown, then we assume it has no operands. + void pushOperandTypesForMask(const spv_operand_type_t type, + const uint32_t mask, + spv_operand_pattern_t* pattern) const; + + private: + const spv_target_env target_env_; + const spv_operand_table operandTable_; + const spv_opcode_table opcodeTable_; + const spv_ext_inst_table extInstTable_; +}; + +} // namespace spvtools + +#endif // SOURCE_ASSEMBLY_GRAMMAR_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/binary.cpp b/thirdparty/glslang/External/spirv-tools/source/binary.cpp new file mode 100644 index 000000000000..3cfdee043448 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/binary.cpp @@ -0,0 +1,865 @@ +// Copyright (c) 2015-2020 The Khronos Group Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/binary.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/assembly_grammar.h" +#include "source/diagnostic.h" +#include "source/ext_inst.h" +#include "source/latest_version_spirv_header.h" +#include "source/opcode.h" +#include "source/operand.h" +#include "source/spirv_constant.h" +#include "source/spirv_endian.h" +#include "source/util/string_utils.h" + +spv_result_t spvBinaryHeaderGet(const spv_const_binary binary, + const spv_endianness_t endian, + spv_header_t* pHeader) { + if (!binary->code) return SPV_ERROR_INVALID_BINARY; + if (binary->wordCount < SPV_INDEX_INSTRUCTION) + return SPV_ERROR_INVALID_BINARY; + if (!pHeader) return SPV_ERROR_INVALID_POINTER; + + // TODO: Validation checking? + pHeader->magic = spvFixWord(binary->code[SPV_INDEX_MAGIC_NUMBER], endian); + pHeader->version = spvFixWord(binary->code[SPV_INDEX_VERSION_NUMBER], endian); + // Per 2.3.1 version's high and low bytes are 0 + if ((pHeader->version & 0x000000ff) || pHeader->version & 0xff000000) + return SPV_ERROR_INVALID_BINARY; + // Minimum version was 1.0 and max version is defined by SPV_VERSION. + if (pHeader->version < SPV_SPIRV_VERSION_WORD(1, 0) || + pHeader->version > SPV_VERSION) + return SPV_ERROR_INVALID_BINARY; + + pHeader->generator = + spvFixWord(binary->code[SPV_INDEX_GENERATOR_NUMBER], endian); + pHeader->bound = spvFixWord(binary->code[SPV_INDEX_BOUND], endian); + pHeader->schema = spvFixWord(binary->code[SPV_INDEX_SCHEMA], endian); + pHeader->instructions = &binary->code[SPV_INDEX_INSTRUCTION]; + + return SPV_SUCCESS; +} + +std::string spvDecodeLiteralStringOperand(const spv_parsed_instruction_t& inst, + const uint16_t operand_index) { + assert(operand_index < inst.num_operands); + const spv_parsed_operand_t& operand = inst.operands[operand_index]; + + return spvtools::utils::MakeString(inst.words + operand.offset, + operand.num_words); +} + +namespace { + +// A SPIR-V binary parser. A parser instance communicates detailed parse +// results via callbacks. +class Parser { + public: + // The user_data value is provided to the callbacks as context. + Parser(const spv_const_context context, void* user_data, + spv_parsed_header_fn_t parsed_header_fn, + spv_parsed_instruction_fn_t parsed_instruction_fn) + : grammar_(context), + consumer_(context->consumer), + user_data_(user_data), + parsed_header_fn_(parsed_header_fn), + parsed_instruction_fn_(parsed_instruction_fn) {} + + // Parses the specified binary SPIR-V module, issuing callbacks on a parsed + // header and for each parsed instruction. Returns SPV_SUCCESS on success. + // Otherwise returns an error code and issues a diagnostic. + spv_result_t parse(const uint32_t* words, size_t num_words, + spv_diagnostic* diagnostic); + + private: + // All remaining methods work on the current module parse state. + + // Like the parse method, but works on the current module parse state. + spv_result_t parseModule(); + + // Parses an instruction at the current position of the binary. Assumes + // the header has been parsed, the endian has been set, and the word index is + // still in range. Advances the parsing position past the instruction, and + // updates other parsing state for the current module. + // On success, returns SPV_SUCCESS and issues the parsed-instruction callback. + // On failure, returns an error code and issues a diagnostic. + spv_result_t parseInstruction(); + + // Parses an instruction operand with the given type, for an instruction + // starting at inst_offset words into the SPIR-V binary. + // If the SPIR-V binary is the same endianness as the host, then the + // endian_converted_inst_words parameter is ignored. Otherwise, this method + // appends the words for this operand, converted to host native endianness, + // to the end of endian_converted_inst_words. This method also updates the + // expected_operands parameter, and the scalar members of the inst parameter. + // On success, returns SPV_SUCCESS, advances past the operand, and pushes a + // new entry on to the operands vector. Otherwise returns an error code and + // issues a diagnostic. + spv_result_t parseOperand(size_t inst_offset, spv_parsed_instruction_t* inst, + const spv_operand_type_t type, + std::vector* endian_converted_inst_words, + std::vector* operands, + spv_operand_pattern_t* expected_operands); + + // Records the numeric type for an operand according to the type information + // associated with the given non-zero type Id. This can fail if the type Id + // is not a type Id, or if the type Id does not reference a scalar numeric + // type. On success, return SPV_SUCCESS and populates the num_words, + // number_kind, and number_bit_width fields of parsed_operand. + spv_result_t setNumericTypeInfoForType(spv_parsed_operand_t* parsed_operand, + uint32_t type_id); + + // Records the number type for an instruction at the given offset, if that + // instruction generates a type. For types that aren't scalar numbers, + // record something with number kind SPV_NUMBER_NONE. + void recordNumberType(size_t inst_offset, + const spv_parsed_instruction_t* inst); + + // Returns a diagnostic stream object initialized with current position in + // the input stream, and for the given error code. Any data written to the + // returned object will be propagated to the current parse's diagnostic + // object. + spvtools::DiagnosticStream diagnostic(spv_result_t error) { + return spvtools::DiagnosticStream({0, 0, _.instruction_count}, consumer_, + "", error); + } + + // Returns a diagnostic stream object with the default parse error code. + spvtools::DiagnosticStream diagnostic() { + // The default failure for parsing is invalid binary. + return diagnostic(SPV_ERROR_INVALID_BINARY); + } + + // Issues a diagnostic describing an exhaustion of input condition when + // trying to decode an instruction operand, and returns + // SPV_ERROR_INVALID_BINARY. + spv_result_t exhaustedInputDiagnostic(size_t inst_offset, spv::Op opcode, + spv_operand_type_t type) { + return diagnostic() << "End of input reached while decoding Op" + << spvOpcodeString(opcode) << " starting at word " + << inst_offset + << ((_.word_index < _.num_words) ? ": truncated " + : ": missing ") + << spvOperandTypeStr(type) << " operand at word offset " + << _.word_index - inst_offset << "."; + } + + // Returns the endian-corrected word at the current position. + uint32_t peek() const { return peekAt(_.word_index); } + + // Returns the endian-corrected word at the given position. + uint32_t peekAt(size_t index) const { + assert(index < _.num_words); + return spvFixWord(_.words[index], _.endian); + } + + // Data members + + const spvtools::AssemblyGrammar grammar_; // SPIR-V syntax utility. + const spvtools::MessageConsumer& consumer_; // Message consumer callback. + void* const user_data_; // Context for the callbacks + const spv_parsed_header_fn_t parsed_header_fn_; // Parsed header callback + const spv_parsed_instruction_fn_t + parsed_instruction_fn_; // Parsed instruction callback + + // Describes the format of a typed literal number. + struct NumberType { + spv_number_kind_t type; + uint32_t bit_width; + }; + + // The state used to parse a single SPIR-V binary module. + struct State { + State(const uint32_t* words_arg, size_t num_words_arg, + spv_diagnostic* diagnostic_arg) + : words(words_arg), + num_words(num_words_arg), + diagnostic(diagnostic_arg), + word_index(0), + instruction_count(0), + endian(), + requires_endian_conversion(false) { + // Temporary storage for parser state within a single instruction. + // Most instructions require fewer than 25 words or operands. + operands.reserve(25); + endian_converted_words.reserve(25); + expected_operands.reserve(25); + } + State() : State(0, 0, nullptr) {} + const uint32_t* words; // Words in the binary SPIR-V module. + size_t num_words; // Number of words in the module. + spv_diagnostic* diagnostic; // Where diagnostics go. + size_t word_index; // The current position in words. + size_t instruction_count; // The count of processed instructions + spv_endianness_t endian; // The endianness of the binary. + // Is the SPIR-V binary in a different endianness from the host native + // endianness? + bool requires_endian_conversion; + + // Maps a result ID to its type ID. By convention: + // - a result ID that is a type definition maps to itself. + // - a result ID without a type maps to 0. (E.g. for OpLabel) + std::unordered_map id_to_type_id; + // Maps a type ID to its number type description. + std::unordered_map type_id_to_number_type_info; + // Maps an ExtInstImport id to the extended instruction type. + std::unordered_map + import_id_to_ext_inst_type; + + // Used by parseOperand + std::vector operands; + std::vector endian_converted_words; + spv_operand_pattern_t expected_operands; + } _; +}; + +spv_result_t Parser::parse(const uint32_t* words, size_t num_words, + spv_diagnostic* diagnostic_arg) { + _ = State(words, num_words, diagnostic_arg); + + const spv_result_t result = parseModule(); + + // Clear the module state. The tables might be big. + _ = State(); + + return result; +} + +spv_result_t Parser::parseModule() { + if (!_.words) return diagnostic() << "Missing module."; + + if (_.num_words < SPV_INDEX_INSTRUCTION) + return diagnostic() << "Module has incomplete header: only " << _.num_words + << " words instead of " << SPV_INDEX_INSTRUCTION; + + // Check the magic number and detect the module's endianness. + spv_const_binary_t binary{_.words, _.num_words}; + if (spvBinaryEndianness(&binary, &_.endian)) { + return diagnostic() << "Invalid SPIR-V magic number '" << std::hex + << _.words[0] << "'."; + } + _.requires_endian_conversion = !spvIsHostEndian(_.endian); + + // Process the header. + spv_header_t header; + if (spvBinaryHeaderGet(&binary, _.endian, &header)) { + // It turns out there is no way to trigger this error since the only + // failure cases are already handled above, with better messages. + return diagnostic(SPV_ERROR_INTERNAL) + << "Internal error: unhandled header parse failure"; + } + if (parsed_header_fn_) { + if (auto error = parsed_header_fn_(user_data_, _.endian, header.magic, + header.version, header.generator, + header.bound, header.schema)) { + return error; + } + } + + // Process the instructions. + _.word_index = SPV_INDEX_INSTRUCTION; + while (_.word_index < _.num_words) + if (auto error = parseInstruction()) return error; + + // Running off the end should already have been reported earlier. + assert(_.word_index == _.num_words); + + return SPV_SUCCESS; +} + +spv_result_t Parser::parseInstruction() { + _.instruction_count++; + + // The zero values for all members except for opcode are the + // correct initial values. + spv_parsed_instruction_t inst = {}; + + const uint32_t first_word = peek(); + + // If the module's endianness is different from the host native endianness, + // then converted_words contains the endian-translated words in the + // instruction. + _.endian_converted_words.clear(); + _.endian_converted_words.push_back(first_word); + + // After a successful parse of the instruction, the inst.operands member + // will point to this vector's storage. + _.operands.clear(); + + assert(_.word_index < _.num_words); + // Decompose and check the first word. + uint16_t inst_word_count = 0; + spvOpcodeSplit(first_word, &inst_word_count, &inst.opcode); + if (inst_word_count < 1) { + return diagnostic() << "Invalid instruction word count: " + << inst_word_count; + } + spv_opcode_desc opcode_desc; + if (grammar_.lookupOpcode(static_cast(inst.opcode), &opcode_desc)) + return diagnostic() << "Invalid opcode: " << inst.opcode; + + // Advance past the opcode word. But remember the of the start + // of the instruction. + const size_t inst_offset = _.word_index; + _.word_index++; + + // Maintains the ordered list of expected operand types. + // For many instructions we only need the {numTypes, operandTypes} + // entries in opcode_desc. However, sometimes we need to modify + // the list as we parse the operands. This occurs when an operand + // has its own logical operands (such as the LocalSize operand for + // ExecutionMode), or for extended instructions that may have their + // own operands depending on the selected extended instruction. + _.expected_operands.clear(); + for (auto i = 0; i < opcode_desc->numTypes; i++) + _.expected_operands.push_back( + opcode_desc->operandTypes[opcode_desc->numTypes - i - 1]); + + while (_.word_index < inst_offset + inst_word_count) { + const uint16_t inst_word_index = uint16_t(_.word_index - inst_offset); + if (_.expected_operands.empty()) { + return diagnostic() << "Invalid instruction Op" << opcode_desc->name + << " starting at word " << inst_offset + << ": expected no more operands after " + << inst_word_index + << " words, but stated word count is " + << inst_word_count << "."; + } + + spv_operand_type_t type = + spvTakeFirstMatchableOperand(&_.expected_operands); + + if (auto error = + parseOperand(inst_offset, &inst, type, &_.endian_converted_words, + &_.operands, &_.expected_operands)) { + return error; + } + } + + if (!_.expected_operands.empty() && + !spvOperandIsOptional(_.expected_operands.back())) { + return diagnostic() << "End of input reached while decoding Op" + << opcode_desc->name << " starting at word " + << inst_offset << ": expected more operands after " + << inst_word_count << " words."; + } + + if ((inst_offset + inst_word_count) != _.word_index) { + return diagnostic() << "Invalid word count: Op" << opcode_desc->name + << " starting at word " << inst_offset + << " says it has " << inst_word_count + << " words, but found " << _.word_index - inst_offset + << " words instead."; + } + + // Check the computed length of the endian-converted words vector against + // the declared number of words in the instruction. If endian conversion + // is required, then they should match. If no endian conversion was + // performed, then the vector only contains the initial opcode/word-count + // word. + assert(!_.requires_endian_conversion || + (inst_word_count == _.endian_converted_words.size())); + assert(_.requires_endian_conversion || + (_.endian_converted_words.size() == 1)); + + recordNumberType(inst_offset, &inst); + + if (_.requires_endian_conversion) { + // We must wait until here to set this pointer, because the vector might + // have been be resized while we accumulated its elements. + inst.words = _.endian_converted_words.data(); + } else { + // If no conversion is required, then just point to the underlying binary. + // This saves time and space. + inst.words = _.words + inst_offset; + } + inst.num_words = inst_word_count; + + // We must wait until here to set this pointer, because the vector might + // have been be resized while we accumulated its elements. + inst.operands = _.operands.data(); + inst.num_operands = uint16_t(_.operands.size()); + + // Issue the callback. The callee should know that all the storage in inst + // is transient, and will disappear immediately afterward. + if (parsed_instruction_fn_) { + if (auto error = parsed_instruction_fn_(user_data_, &inst)) return error; + } + + return SPV_SUCCESS; +} + +spv_result_t Parser::parseOperand(size_t inst_offset, + spv_parsed_instruction_t* inst, + const spv_operand_type_t type, + std::vector* words, + std::vector* operands, + spv_operand_pattern_t* expected_operands) { + const spv::Op opcode = static_cast(inst->opcode); + // We'll fill in this result as we go along. + spv_parsed_operand_t parsed_operand; + parsed_operand.offset = uint16_t(_.word_index - inst_offset); + // Most operands occupy one word. This might be be adjusted later. + parsed_operand.num_words = 1; + // The type argument is the one used by the grammar to parse the instruction. + // But it can exposes internal parser details such as whether an operand is + // optional or actually represents a variable-length sequence of operands. + // The resulting type should be adjusted to avoid those internal details. + // In most cases, the resulting operand type is the same as the grammar type. + parsed_operand.type = type; + + // Assume non-numeric values. This will be updated for literal numbers. + parsed_operand.number_kind = SPV_NUMBER_NONE; + parsed_operand.number_bit_width = 0; + + if (_.word_index >= _.num_words) + return exhaustedInputDiagnostic(inst_offset, opcode, type); + + const uint32_t word = peek(); + + // Do the words in this operand have to be converted to native endianness? + // True for all but literal strings. + bool convert_operand_endianness = true; + + switch (type) { + case SPV_OPERAND_TYPE_TYPE_ID: + if (!word) + return diagnostic(SPV_ERROR_INVALID_ID) << "Error: Type Id is 0"; + inst->type_id = word; + break; + + case SPV_OPERAND_TYPE_RESULT_ID: + if (!word) + return diagnostic(SPV_ERROR_INVALID_ID) << "Error: Result Id is 0"; + inst->result_id = word; + // Save the result ID to type ID mapping. + // In the grammar, type ID always appears before result ID. + if (_.id_to_type_id.find(inst->result_id) != _.id_to_type_id.end()) + return diagnostic(SPV_ERROR_INVALID_ID) + << "Id " << inst->result_id << " is defined more than once"; + // Record it. + // A regular value maps to its type. Some instructions (e.g. OpLabel) + // have no type Id, and will map to 0. The result Id for a + // type-generating instruction (e.g. OpTypeInt) maps to itself. + _.id_to_type_id[inst->result_id] = + spvOpcodeGeneratesType(opcode) ? inst->result_id : inst->type_id; + break; + + case SPV_OPERAND_TYPE_ID: + case SPV_OPERAND_TYPE_OPTIONAL_ID: + if (!word) return diagnostic(SPV_ERROR_INVALID_ID) << "Id is 0"; + parsed_operand.type = SPV_OPERAND_TYPE_ID; + + if (opcode == spv::Op::OpExtInst && parsed_operand.offset == 3) { + // The current word is the extended instruction set Id. + // Set the extended instruction set type for the current instruction. + auto ext_inst_type_iter = _.import_id_to_ext_inst_type.find(word); + if (ext_inst_type_iter == _.import_id_to_ext_inst_type.end()) { + return diagnostic(SPV_ERROR_INVALID_ID) + << "OpExtInst set Id " << word + << " does not reference an OpExtInstImport result Id"; + } + inst->ext_inst_type = ext_inst_type_iter->second; + } + break; + + case SPV_OPERAND_TYPE_SCOPE_ID: + case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: + // Check for trivially invalid values. The operand descriptions already + // have the word "ID" in them. + if (!word) return diagnostic() << spvOperandTypeStr(type) << " is 0"; + break; + + case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: { + assert(spv::Op::OpExtInst == opcode); + assert(inst->ext_inst_type != SPV_EXT_INST_TYPE_NONE); + spv_ext_inst_desc ext_inst; + if (grammar_.lookupExtInst(inst->ext_inst_type, word, &ext_inst) == + SPV_SUCCESS) { + // if we know about this ext inst, push the expected operands + spvPushOperandTypes(ext_inst->operandTypes, expected_operands); + } else { + // if we don't know this extended instruction and the set isn't + // non-semantic, we cannot process further + if (!spvExtInstIsNonSemantic(inst->ext_inst_type)) { + return diagnostic() + << "Invalid extended instruction number: " << word; + } else { + // for non-semantic instruction sets, we know the form of all such + // extended instructions contains a series of IDs as parameters + expected_operands->push_back(SPV_OPERAND_TYPE_VARIABLE_ID); + } + } + } break; + + case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: { + assert(spv::Op::OpSpecConstantOp == opcode); + if (word > static_cast(spv::Op::Max) || + grammar_.lookupSpecConstantOpcode(spv::Op(word))) { + return diagnostic() + << "Invalid " << spvOperandTypeStr(type) << ": " << word; + } + spv_opcode_desc opcode_entry = nullptr; + if (grammar_.lookupOpcode(spv::Op(word), &opcode_entry)) { + return diagnostic(SPV_ERROR_INTERNAL) + << "OpSpecConstant opcode table out of sync"; + } + // OpSpecConstant opcodes must have a type and result. We've already + // processed them, so skip them when preparing to parse the other + // operants for the opcode. + assert(opcode_entry->hasType); + assert(opcode_entry->hasResult); + assert(opcode_entry->numTypes >= 2); + spvPushOperandTypes(opcode_entry->operandTypes + 2, expected_operands); + } break; + + case SPV_OPERAND_TYPE_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER: + // These are regular single-word literal integer operands. + // Post-parsing validation should check the range of the parsed value. + parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_INTEGER; + // It turns out they are always unsigned integers! + parsed_operand.number_kind = SPV_NUMBER_UNSIGNED_INT; + parsed_operand.number_bit_width = 32; + break; + + case SPV_OPERAND_TYPE_LITERAL_FLOAT: + // These are regular single-word literal float operands. + parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_FLOAT; + parsed_operand.number_kind = SPV_NUMBER_FLOATING; + parsed_operand.number_bit_width = 32; + break; + + case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: + case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: + parsed_operand.type = SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER; + if (opcode == spv::Op::OpSwitch) { + // The literal operands have the same type as the value + // referenced by the selector Id. + const uint32_t selector_id = peekAt(inst_offset + 1); + const auto type_id_iter = _.id_to_type_id.find(selector_id); + if (type_id_iter == _.id_to_type_id.end() || + type_id_iter->second == 0) { + return diagnostic() << "Invalid OpSwitch: selector id " << selector_id + << " has no type"; + } + uint32_t type_id = type_id_iter->second; + + if (selector_id == type_id) { + // Recall that by convention, a result ID that is a type definition + // maps to itself. + return diagnostic() << "Invalid OpSwitch: selector id " << selector_id + << " is a type, not a value"; + } + if (auto error = setNumericTypeInfoForType(&parsed_operand, type_id)) + return error; + if (parsed_operand.number_kind != SPV_NUMBER_UNSIGNED_INT && + parsed_operand.number_kind != SPV_NUMBER_SIGNED_INT) { + return diagnostic() << "Invalid OpSwitch: selector id " << selector_id + << " is not a scalar integer"; + } + } else { + assert(opcode == spv::Op::OpConstant || + opcode == spv::Op::OpSpecConstant); + // The literal number type is determined by the type Id for the + // constant. + assert(inst->type_id); + if (auto error = + setNumericTypeInfoForType(&parsed_operand, inst->type_id)) + return error; + } + break; + + case SPV_OPERAND_TYPE_LITERAL_STRING: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: { + const size_t max_words = _.num_words - _.word_index; + std::string string = + spvtools::utils::MakeString(_.words + _.word_index, max_words, false); + + if (string.length() == max_words * 4) + return exhaustedInputDiagnostic(inst_offset, opcode, type); + + // Make sure we can record the word count without overflow. + // + // This error can't currently be triggered because of validity + // checks elsewhere. + const size_t string_num_words = string.length() / 4 + 1; + if (string_num_words > std::numeric_limits::max()) { + return diagnostic() << "Literal string is longer than " + << std::numeric_limits::max() + << " words: " << string_num_words << " words long"; + } + parsed_operand.num_words = uint16_t(string_num_words); + parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_STRING; + + if (spv::Op::OpExtInstImport == opcode) { + // Record the extended instruction type for the ID for this import. + // There is only one string literal argument to OpExtInstImport, + // so it's sufficient to guard this just on the opcode. + const spv_ext_inst_type_t ext_inst_type = + spvExtInstImportTypeGet(string.c_str()); + if (SPV_EXT_INST_TYPE_NONE == ext_inst_type) { + return diagnostic() + << "Invalid extended instruction import '" << string << "'"; + } + // We must have parsed a valid result ID. It's a condition + // of the grammar, and we only accept non-zero result Ids. + assert(inst->result_id); + _.import_id_to_ext_inst_type[inst->result_id] = ext_inst_type; + } + } break; + + case SPV_OPERAND_TYPE_CAPABILITY: + case SPV_OPERAND_TYPE_EXECUTION_MODEL: + case SPV_OPERAND_TYPE_ADDRESSING_MODEL: + case SPV_OPERAND_TYPE_MEMORY_MODEL: + case SPV_OPERAND_TYPE_EXECUTION_MODE: + case SPV_OPERAND_TYPE_STORAGE_CLASS: + case SPV_OPERAND_TYPE_DIMENSIONALITY: + case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE: + case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE: + case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT: + case SPV_OPERAND_TYPE_FP_ROUNDING_MODE: + case SPV_OPERAND_TYPE_LINKAGE_TYPE: + case SPV_OPERAND_TYPE_ACCESS_QUALIFIER: + case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER: + case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE: + case SPV_OPERAND_TYPE_DECORATION: + case SPV_OPERAND_TYPE_BUILT_IN: + case SPV_OPERAND_TYPE_GROUP_OPERATION: + case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS: + case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO: + case SPV_OPERAND_TYPE_RAY_FLAGS: + case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION: + case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE: + case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE: + case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: + case SPV_OPERAND_TYPE_FPDENORM_MODE: + case SPV_OPERAND_TYPE_FPOPERATION_MODE: + case SPV_OPERAND_TYPE_QUANTIZATION_MODES: + case SPV_OPERAND_TYPE_OVERFLOW_MODES: + case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT: + case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: { + // A single word that is a plain enum value. + + // Map an optional operand type to its corresponding concrete type. + if (type == SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER) + parsed_operand.type = SPV_OPERAND_TYPE_ACCESS_QUALIFIER; + if (type == SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT) + parsed_operand.type = SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT; + + spv_operand_desc entry; + if (grammar_.lookupOperand(type, word, &entry)) { + return diagnostic() + << "Invalid " << spvOperandTypeStr(parsed_operand.type) + << " operand: " << word; + } + // Prepare to accept operands to this operand, if needed. + spvPushOperandTypes(entry->operandTypes, expected_operands); + } break; + + case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: { + spv_operand_desc entry; + if (grammar_.lookupOperand(type, word, &entry)) { + return diagnostic() + << "Invalid " << spvOperandTypeStr(parsed_operand.type) + << " operand: " << word + << ", if you are creating a new source language please use " + "value 0 " + "(Unknown) and when ready, add your source language to " + "SPRIV-Headers"; + } + // Prepare to accept operands to this operand, if needed. + spvPushOperandTypes(entry->operandTypes, expected_operands); + } break; + + case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE: + case SPV_OPERAND_TYPE_FUNCTION_CONTROL: + case SPV_OPERAND_TYPE_LOOP_CONTROL: + case SPV_OPERAND_TYPE_IMAGE: + case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: + case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: + case SPV_OPERAND_TYPE_SELECTION_CONTROL: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: + case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: { + // This operand is a mask. + + // Map an optional operand type to its corresponding concrete type. + if (type == SPV_OPERAND_TYPE_OPTIONAL_IMAGE) + parsed_operand.type = SPV_OPERAND_TYPE_IMAGE; + else if (type == SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS) + parsed_operand.type = SPV_OPERAND_TYPE_MEMORY_ACCESS; + if (type == SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS) + parsed_operand.type = SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS; + + // Check validity of set mask bits. Also prepare for operands for those + // masks if they have any. To get operand order correct, scan from + // MSB to LSB since we can only prepend operands to a pattern. + // The only case in the grammar where you have more than one mask bit + // having an operand is for image operands. See SPIR-V 3.14 Image + // Operands. + uint32_t remaining_word = word; + for (uint32_t mask = (1u << 31); remaining_word; mask >>= 1) { + if (remaining_word & mask) { + spv_operand_desc entry; + if (grammar_.lookupOperand(type, mask, &entry)) { + return diagnostic() + << "Invalid " << spvOperandTypeStr(parsed_operand.type) + << " operand: " << word << " has invalid mask component " + << mask; + } + remaining_word ^= mask; + spvPushOperandTypes(entry->operandTypes, expected_operands); + } + } + if (word == 0) { + // An all-zeroes mask *might* also be valid. + spv_operand_desc entry; + if (SPV_SUCCESS == grammar_.lookupOperand(type, 0, &entry)) { + // Prepare for its operands, if any. + spvPushOperandTypes(entry->operandTypes, expected_operands); + } + } + } break; + default: + return diagnostic() << "Internal error: Unhandled operand type: " << type; + } + + assert(spvOperandIsConcrete(parsed_operand.type)); + + operands->push_back(parsed_operand); + + const size_t index_after_operand = _.word_index + parsed_operand.num_words; + + // Avoid buffer overrun for the cases where the operand has more than one + // word, and where it isn't a string. (Those other cases have already been + // handled earlier.) For example, this error can occur for a multi-word + // argument to OpConstant, or a multi-word case literal operand for OpSwitch. + if (_.num_words < index_after_operand) + return exhaustedInputDiagnostic(inst_offset, opcode, type); + + if (_.requires_endian_conversion) { + // Copy instruction words. Translate to native endianness as needed. + if (convert_operand_endianness) { + const spv_endianness_t endianness = _.endian; + std::transform(_.words + _.word_index, _.words + index_after_operand, + std::back_inserter(*words), + [endianness](const uint32_t raw_word) { + return spvFixWord(raw_word, endianness); + }); + } else { + words->insert(words->end(), _.words + _.word_index, + _.words + index_after_operand); + } + } + + // Advance past the operand. + _.word_index = index_after_operand; + + return SPV_SUCCESS; +} + +spv_result_t Parser::setNumericTypeInfoForType( + spv_parsed_operand_t* parsed_operand, uint32_t type_id) { + assert(type_id != 0); + auto type_info_iter = _.type_id_to_number_type_info.find(type_id); + if (type_info_iter == _.type_id_to_number_type_info.end()) { + return diagnostic() << "Type Id " << type_id << " is not a type"; + } + const NumberType& info = type_info_iter->second; + if (info.type == SPV_NUMBER_NONE) { + // This is a valid type, but for something other than a scalar number. + return diagnostic() << "Type Id " << type_id + << " is not a scalar numeric type"; + } + + parsed_operand->number_kind = info.type; + parsed_operand->number_bit_width = info.bit_width; + // Round up the word count. + parsed_operand->num_words = static_cast((info.bit_width + 31) / 32); + return SPV_SUCCESS; +} + +void Parser::recordNumberType(size_t inst_offset, + const spv_parsed_instruction_t* inst) { + const spv::Op opcode = static_cast(inst->opcode); + if (spvOpcodeGeneratesType(opcode)) { + NumberType info = {SPV_NUMBER_NONE, 0}; + if (spv::Op::OpTypeInt == opcode) { + const bool is_signed = peekAt(inst_offset + 3) != 0; + info.type = is_signed ? SPV_NUMBER_SIGNED_INT : SPV_NUMBER_UNSIGNED_INT; + info.bit_width = peekAt(inst_offset + 2); + } else if (spv::Op::OpTypeFloat == opcode) { + info.type = SPV_NUMBER_FLOATING; + info.bit_width = peekAt(inst_offset + 2); + } + // The *result* Id of a type generating instruction is the type Id. + _.type_id_to_number_type_info[inst->result_id] = info; + } +} + +} // anonymous namespace + +spv_result_t spvBinaryParse(const spv_const_context context, void* user_data, + const uint32_t* code, const size_t num_words, + spv_parsed_header_fn_t parsed_header, + spv_parsed_instruction_fn_t parsed_instruction, + spv_diagnostic* diagnostic) { + spv_context_t hijack_context = *context; + if (diagnostic) { + *diagnostic = nullptr; + spvtools::UseDiagnosticAsMessageConsumer(&hijack_context, diagnostic); + } + Parser parser(&hijack_context, user_data, parsed_header, parsed_instruction); + return parser.parse(code, num_words, diagnostic); +} + +// TODO(dneto): This probably belongs in text.cpp since that's the only place +// that a spv_binary_t value is created. +void spvBinaryDestroy(spv_binary binary) { + if (binary) { + if (binary->code) delete[] binary->code; + delete binary; + } +} + +size_t spv_strnlen_s(const char* str, size_t strsz) { + if (!str) return 0; + for (size_t i = 0; i < strsz; i++) { + if (!str[i]) return i; + } + return strsz; +} diff --git a/thirdparty/glslang/External/spirv-tools/source/binary.h b/thirdparty/glslang/External/spirv-tools/source/binary.h new file mode 100644 index 000000000000..eb3beacac34b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/binary.h @@ -0,0 +1,43 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_BINARY_H_ +#define SOURCE_BINARY_H_ + +#include + +#include "source/spirv_definition.h" +#include "spirv-tools/libspirv.h" + +// Functions + +// Grabs the header from the SPIR-V module given in the binary parameter. The +// endian parameter specifies the endianness of the binary module. On success, +// returns SPV_SUCCESS and writes the parsed header into *header. +spv_result_t spvBinaryHeaderGet(const spv_const_binary binary, + const spv_endianness_t endian, + spv_header_t* header); + +// Returns the number of non-null characters in str before the first null +// character, or strsz if there is no null character. Examines at most the +// first strsz characters in str. Returns 0 if str is nullptr. This is a +// replacement for C11's strnlen_s which might not exist in all environments. +size_t spv_strnlen_s(const char* str, size_t strsz); + +// Decode the string literal operand with index operand_index from instruction +// inst. +std::string spvDecodeLiteralStringOperand(const spv_parsed_instruction_t& inst, + const uint16_t operand_index); + +#endif // SOURCE_BINARY_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/build-version.inc b/thirdparty/glslang/External/spirv-tools/source/build-version.inc new file mode 100644 index 000000000000..bc52ec47aef3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/build-version.inc @@ -0,0 +1 @@ +"v2023.6", "SPIRV-Tools v2023.6 unknown hash, 2024-02-29T14:38:23+00:00" diff --git a/thirdparty/glslang/External/spirv-tools/source/cfa.h b/thirdparty/glslang/External/spirv-tools/source/cfa.h new file mode 100644 index 000000000000..9ae3e39a1915 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/cfa.h @@ -0,0 +1,396 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_CFA_H_ +#define SOURCE_CFA_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace spvtools { + +// Control Flow Analysis of control flow graphs of basic block nodes |BB|. +template +class CFA { + using bb_ptr = BB*; + using cbb_ptr = const BB*; + using bb_iter = typename std::vector::const_iterator; + using get_blocks_func = std::function*(const BB*)>; + + struct block_info { + cbb_ptr block; ///< pointer to the block + bb_iter iter; ///< Iterator to the current child node being processed + }; + + /// Returns true if a block with @p id is found in the @p work_list vector + /// + /// @param[in] work_list Set of blocks visited in the depth first + /// traversal + /// of the CFG + /// @param[in] id The ID of the block being checked + /// + /// @return true if the edge work_list.back().block->id() => id is a back-edge + static bool FindInWorkList(const std::vector& work_list, + uint32_t id); + + public: + /// @brief Depth first traversal starting from the \p entry BasicBlock + /// + /// This function performs a depth first traversal from the \p entry + /// BasicBlock and calls the pre/postorder functions when it needs to process + /// the node in pre order, post order. + /// + /// @param[in] entry The root BasicBlock of a CFG + /// @param[in] successor_func A function which will return a pointer to the + /// successor nodes + /// @param[in] preorder A function that will be called for every block in a + /// CFG following preorder traversal semantics + /// @param[in] postorder A function that will be called for every block in a + /// CFG following postorder traversal semantics + /// @param[in] terminal A function that will be called to determine if the + /// search should stop at the given node. + /// NOTE: The @p successor_func and predecessor_func each return a pointer to + /// a collection such that iterators to that collection remain valid for the + /// lifetime of the algorithm. + static void DepthFirstTraversal(const BB* entry, + get_blocks_func successor_func, + std::function preorder, + std::function postorder, + std::function terminal); + + /// @brief Depth first traversal starting from the \p entry BasicBlock + /// + /// This function performs a depth first traversal from the \p entry + /// BasicBlock and calls the pre/postorder functions when it needs to process + /// the node in pre order, post order. It also calls the backedge function + /// when a back edge is encountered. The backedge function can be empty. The + /// runtime of the algorithm is improved if backedge is empty. + /// + /// @param[in] entry The root BasicBlock of a CFG + /// @param[in] successor_func A function which will return a pointer to the + /// successor nodes + /// @param[in] preorder A function that will be called for every block in a + /// CFG following preorder traversal semantics + /// @param[in] postorder A function that will be called for every block in a + /// CFG following postorder traversal semantics + /// @param[in] backedge A function that will be called when a backedge is + /// encountered during a traversal. + /// @param[in] terminal A function that will be called to determine if the + /// search should stop at the given node. + /// NOTE: The @p successor_func and predecessor_func each return a pointer to + /// a collection such that iterators to that collection remain valid for the + /// lifetime of the algorithm. + static void DepthFirstTraversal( + const BB* entry, get_blocks_func successor_func, + std::function preorder, + std::function postorder, + std::function backedge, + std::function terminal); + + /// @brief Calculates dominator edges for a set of blocks + /// + /// Computes dominators using the algorithm of Cooper, Harvey, and Kennedy + /// "A Simple, Fast Dominance Algorithm", 2001. + /// + /// The algorithm assumes there is a unique root node (a node without + /// predecessors), and it is therefore at the end of the postorder vector. + /// + /// This function calculates the dominator edges for a set of blocks in the + /// CFG. + /// Uses the dominator algorithm by Cooper et al. + /// + /// @param[in] postorder A vector of blocks in post order traversal + /// order + /// in a CFG + /// @param[in] predecessor_func Function used to get the predecessor nodes of + /// a + /// block + /// + /// @return the dominator tree of the graph, as a vector of pairs of nodes. + /// The first node in the pair is a node in the graph. The second node in the + /// pair is its immediate dominator in the sense of Cooper et.al., where a + /// block + /// without predecessors (such as the root node) is its own immediate + /// dominator. + static std::vector> CalculateDominators( + const std::vector& postorder, get_blocks_func predecessor_func); + + // Computes a minimal set of root nodes required to traverse, in the forward + // direction, the CFG represented by the given vector of blocks, and successor + // and predecessor functions. When considering adding two nodes, each having + // predecessors, favour using the one that appears earlier on the input blocks + // list. + static std::vector TraversalRoots(const std::vector& blocks, + get_blocks_func succ_func, + get_blocks_func pred_func); + + static void ComputeAugmentedCFG( + std::vector& ordered_blocks, BB* pseudo_entry_block, + BB* pseudo_exit_block, + std::unordered_map>* augmented_successors_map, + std::unordered_map>* + augmented_predecessors_map, + get_blocks_func succ_func, get_blocks_func pred_func); +}; + +template +bool CFA::FindInWorkList(const std::vector& work_list, + uint32_t id) { + for (const auto& b : work_list) { + if (b.block->id() == id) return true; + } + return false; +} + +template +void CFA::DepthFirstTraversal(const BB* entry, + get_blocks_func successor_func, + std::function preorder, + std::function postorder, + std::function terminal) { + DepthFirstTraversal(entry, successor_func, preorder, postorder, + /* backedge = */ {}, terminal); +} + +template +void CFA::DepthFirstTraversal( + const BB* entry, get_blocks_func successor_func, + std::function preorder, + std::function postorder, + std::function backedge, + std::function terminal) { + assert(successor_func && "The successor function cannot be empty."); + assert(preorder && "The preorder function cannot be empty."); + assert(postorder && "The postorder function cannot be empty."); + assert(terminal && "The terminal function cannot be empty."); + + std::unordered_set processed; + + /// NOTE: work_list is the sequence of nodes from the root node to the node + /// being processed in the traversal + std::vector work_list; + work_list.reserve(10); + + work_list.push_back({entry, std::begin(*successor_func(entry))}); + preorder(entry); + processed.insert(entry->id()); + + while (!work_list.empty()) { + block_info& top = work_list.back(); + if (terminal(top.block) || top.iter == end(*successor_func(top.block))) { + postorder(top.block); + work_list.pop_back(); + } else { + BB* child = *top.iter; + top.iter++; + if (backedge && FindInWorkList(work_list, child->id())) { + backedge(top.block, child); + } + if (processed.count(child->id()) == 0) { + preorder(child); + work_list.emplace_back( + block_info{child, std::begin(*successor_func(child))}); + processed.insert(child->id()); + } + } + } +} + +template +std::vector> CFA::CalculateDominators( + const std::vector& postorder, get_blocks_func predecessor_func) { + struct block_detail { + size_t dominator; ///< The index of blocks's dominator in post order array + size_t postorder_index; ///< The index of the block in the post order array + }; + const size_t undefined_dom = postorder.size(); + + std::unordered_map idoms; + for (size_t i = 0; i < postorder.size(); i++) { + idoms[postorder[i]] = {undefined_dom, i}; + } + idoms[postorder.back()].dominator = idoms[postorder.back()].postorder_index; + + bool changed = true; + while (changed) { + changed = false; + for (auto b = postorder.rbegin() + 1; b != postorder.rend(); ++b) { + const std::vector& predecessors = *predecessor_func(*b); + // Find the first processed/reachable predecessor that is reachable + // in the forward traversal. + auto res = std::find_if(std::begin(predecessors), std::end(predecessors), + [&idoms, undefined_dom](BB* pred) { + return idoms.count(pred) && + idoms[pred].dominator != undefined_dom; + }); + if (res == end(predecessors)) continue; + const BB* idom = *res; + size_t idom_idx = idoms[idom].postorder_index; + + // all other predecessors + for (const auto* p : predecessors) { + if (idom == p) continue; + // Only consider nodes reachable in the forward traversal. + // Otherwise the intersection doesn't make sense and will never + // terminate. + if (!idoms.count(p)) continue; + if (idoms[p].dominator != undefined_dom) { + size_t finger1 = idoms[p].postorder_index; + size_t finger2 = idom_idx; + while (finger1 != finger2) { + while (finger1 < finger2) { + finger1 = idoms[postorder[finger1]].dominator; + } + while (finger2 < finger1) { + finger2 = idoms[postorder[finger2]].dominator; + } + } + idom_idx = finger1; + } + } + if (idoms[*b].dominator != idom_idx) { + idoms[*b].dominator = idom_idx; + changed = true; + } + } + } + + std::vector> out; + for (auto idom : idoms) { + // At this point if there is no dominator for the node, just make it + // reflexive. + auto dominator = std::get<1>(idom).dominator; + if (dominator == undefined_dom) { + dominator = std::get<1>(idom).postorder_index; + } + // NOTE: performing a const cast for convenient usage with + // UpdateImmediateDominators + out.push_back({const_cast(std::get<0>(idom)), + const_cast(postorder[dominator])}); + } + + // Sort by postorder index to generate a deterministic ordering of edges. + std::sort( + out.begin(), out.end(), + [&idoms](const std::pair& lhs, + const std::pair& rhs) { + assert(lhs.first); + assert(lhs.second); + assert(rhs.first); + assert(rhs.second); + auto lhs_indices = std::make_pair(idoms[lhs.first].postorder_index, + idoms[lhs.second].postorder_index); + auto rhs_indices = std::make_pair(idoms[rhs.first].postorder_index, + idoms[rhs.second].postorder_index); + return lhs_indices < rhs_indices; + }); + return out; +} + +template +std::vector CFA::TraversalRoots(const std::vector& blocks, + get_blocks_func succ_func, + get_blocks_func pred_func) { + // The set of nodes which have been visited from any of the roots so far. + std::unordered_set visited; + + auto mark_visited = [&visited](const BB* b) { visited.insert(b); }; + auto ignore_block = [](const BB*) {}; + auto no_terminal_blocks = [](const BB*) { return false; }; + + auto traverse_from_root = [&mark_visited, &succ_func, &ignore_block, + &no_terminal_blocks](const BB* entry) { + DepthFirstTraversal(entry, succ_func, mark_visited, ignore_block, + no_terminal_blocks); + }; + + std::vector result; + + // First collect nodes without predecessors. + for (auto block : blocks) { + if (pred_func(block)->empty()) { + assert(visited.count(block) == 0 && "Malformed graph!"); + result.push_back(block); + traverse_from_root(block); + } + } + + // Now collect other stranded nodes. These must be in unreachable cycles. + for (auto block : blocks) { + if (visited.count(block) == 0) { + result.push_back(block); + traverse_from_root(block); + } + } + + return result; +} + +template +void CFA::ComputeAugmentedCFG( + std::vector& ordered_blocks, BB* pseudo_entry_block, + BB* pseudo_exit_block, + std::unordered_map>* augmented_successors_map, + std::unordered_map>* augmented_predecessors_map, + get_blocks_func succ_func, get_blocks_func pred_func) { + // Compute the successors of the pseudo-entry block, and + // the predecessors of the pseudo exit block. + auto sources = TraversalRoots(ordered_blocks, succ_func, pred_func); + + // For the predecessor traversals, reverse the order of blocks. This + // will affect the post-dominance calculation as follows: + // - Suppose you have blocks A and B, with A appearing before B in + // the list of blocks. + // - Also, A branches only to B, and B branches only to A. + // - We want to compute A as dominating B, and B as post-dominating B. + // By using reversed blocks for predecessor traversal roots discovery, + // we'll add an edge from B to the pseudo-exit node, rather than from A. + // All this is needed to correctly process the dominance/post-dominance + // constraint when A is a loop header that points to itself as its + // own continue target, and B is the latch block for the loop. + std::vector reversed_blocks(ordered_blocks.rbegin(), + ordered_blocks.rend()); + auto sinks = TraversalRoots(reversed_blocks, pred_func, succ_func); + + // Wire up the pseudo entry block. + (*augmented_successors_map)[pseudo_entry_block] = sources; + for (auto block : sources) { + auto& augmented_preds = (*augmented_predecessors_map)[block]; + const auto preds = pred_func(block); + augmented_preds.reserve(1 + preds->size()); + augmented_preds.push_back(pseudo_entry_block); + augmented_preds.insert(augmented_preds.end(), preds->begin(), preds->end()); + } + + // Wire up the pseudo exit block. + (*augmented_predecessors_map)[pseudo_exit_block] = sinks; + for (auto block : sinks) { + auto& augmented_succ = (*augmented_successors_map)[block]; + const auto succ = succ_func(block); + augmented_succ.reserve(1 + succ->size()); + augmented_succ.push_back(pseudo_exit_block); + augmented_succ.insert(augmented_succ.end(), succ->begin(), succ->end()); + } +} + +} // namespace spvtools + +#endif // SOURCE_CFA_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/common_debug_info.h b/thirdparty/glslang/External/spirv-tools/source/common_debug_info.h new file mode 100644 index 000000000000..ffa5d340c0cb --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/common_debug_info.h @@ -0,0 +1,64 @@ +// Copyright (c) 2021 The Khronos Group Inc. +// Copyright (c) 2021 Valve Corporation +// Copyright (c) 2021 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_COMMON_DEBUG_INFO_HEADER_H_ +#define SOURCE_COMMON_DEBUG_INFO_HEADER_H_ + +// This enum defines the known common set of instructions that are the same +// between OpenCL.DebugInfo.100 and NonSemantic.Shader.DebugInfo.100. +// Note that NonSemantic.Shader.* instructions can still have slightly +// different encoding, as it does not use literals anywhere and only constants. +enum CommonDebugInfoInstructions { + CommonDebugInfoDebugInfoNone = 0, + CommonDebugInfoDebugCompilationUnit = 1, + CommonDebugInfoDebugTypeBasic = 2, + CommonDebugInfoDebugTypePointer = 3, + CommonDebugInfoDebugTypeQualifier = 4, + CommonDebugInfoDebugTypeArray = 5, + CommonDebugInfoDebugTypeVector = 6, + CommonDebugInfoDebugTypedef = 7, + CommonDebugInfoDebugTypeFunction = 8, + CommonDebugInfoDebugTypeEnum = 9, + CommonDebugInfoDebugTypeComposite = 10, + CommonDebugInfoDebugTypeMember = 11, + CommonDebugInfoDebugTypeInheritance = 12, + CommonDebugInfoDebugTypePtrToMember = 13, + CommonDebugInfoDebugTypeTemplate = 14, + CommonDebugInfoDebugTypeTemplateParameter = 15, + CommonDebugInfoDebugTypeTemplateTemplateParameter = 16, + CommonDebugInfoDebugTypeTemplateParameterPack = 17, + CommonDebugInfoDebugGlobalVariable = 18, + CommonDebugInfoDebugFunctionDeclaration = 19, + CommonDebugInfoDebugFunction = 20, + CommonDebugInfoDebugLexicalBlock = 21, + CommonDebugInfoDebugLexicalBlockDiscriminator = 22, + CommonDebugInfoDebugScope = 23, + CommonDebugInfoDebugNoScope = 24, + CommonDebugInfoDebugInlinedAt = 25, + CommonDebugInfoDebugLocalVariable = 26, + CommonDebugInfoDebugInlinedVariable = 27, + CommonDebugInfoDebugDeclare = 28, + CommonDebugInfoDebugValue = 29, + CommonDebugInfoDebugOperation = 30, + CommonDebugInfoDebugExpression = 31, + CommonDebugInfoDebugMacroDef = 32, + CommonDebugInfoDebugMacroUndef = 33, + CommonDebugInfoDebugImportedEntity = 34, + CommonDebugInfoDebugSource = 35, + CommonDebugInfoInstructionsMax = 0x7ffffff +}; + +#endif // SOURCE_COMMON_DEBUG_INFO_HEADER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/core.insts-unified1.inc b/thirdparty/glslang/External/spirv-tools/source/core.insts-unified1.inc new file mode 100644 index 000000000000..85e2f19b17b0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/core.insts-unified1.inc @@ -0,0 +1,856 @@ +static const spv::Capability pygen_variable_caps_Addresses[] = {spv::Capability::Addresses}; +static const spv::Capability pygen_variable_caps_AddressesPhysicalStorageBufferAddresses[] = {spv::Capability::Addresses, spv::Capability::PhysicalStorageBufferAddresses}; +static const spv::Capability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer[] = {spv::Capability::Addresses, spv::Capability::VariablePointers, spv::Capability::VariablePointersStorageBuffer}; +static const spv::Capability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses[] = {spv::Capability::Addresses, spv::Capability::VariablePointers, spv::Capability::VariablePointersStorageBuffer, spv::Capability::PhysicalStorageBufferAddresses}; +static const spv::Capability pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL[] = {spv::Capability::ArbitraryPrecisionFixedPointINTEL}; +static const spv::Capability pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL[] = {spv::Capability::ArbitraryPrecisionFloatingPointINTEL}; +static const spv::Capability pygen_variable_caps_AsmINTEL[] = {spv::Capability::AsmINTEL}; +static const spv::Capability pygen_variable_caps_AtomicFloat16AddEXTAtomicFloat32AddEXTAtomicFloat64AddEXTAtomicFloat16VectorNV[] = {spv::Capability::AtomicFloat16AddEXT, spv::Capability::AtomicFloat32AddEXT, spv::Capability::AtomicFloat64AddEXT, spv::Capability::AtomicFloat16VectorNV}; +static const spv::Capability pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXTAtomicFloat16VectorNV[] = {spv::Capability::AtomicFloat16MinMaxEXT, spv::Capability::AtomicFloat32MinMaxEXT, spv::Capability::AtomicFloat64MinMaxEXT, spv::Capability::AtomicFloat16VectorNV}; +static const spv::Capability pygen_variable_caps_BFloat16ConversionINTEL[] = {spv::Capability::BFloat16ConversionINTEL}; +static const spv::Capability pygen_variable_caps_BindlessTextureNV[] = {spv::Capability::BindlessTextureNV}; +static const spv::Capability pygen_variable_caps_BlockingPipesINTEL[] = {spv::Capability::BlockingPipesINTEL}; +static const spv::Capability pygen_variable_caps_CooperativeMatrixKHR[] = {spv::Capability::CooperativeMatrixKHR}; +static const spv::Capability pygen_variable_caps_CooperativeMatrixNV[] = {spv::Capability::CooperativeMatrixNV}; +static const spv::Capability pygen_variable_caps_DemoteToHelperInvocation[] = {spv::Capability::DemoteToHelperInvocation}; +static const spv::Capability pygen_variable_caps_DemoteToHelperInvocationEXT[] = {spv::Capability::DemoteToHelperInvocationEXT}; +static const spv::Capability pygen_variable_caps_DerivativeControl[] = {spv::Capability::DerivativeControl}; +static const spv::Capability pygen_variable_caps_DeviceEnqueue[] = {spv::Capability::DeviceEnqueue}; +static const spv::Capability pygen_variable_caps_DisplacementMicromapNV[] = {spv::Capability::DisplacementMicromapNV}; +static const spv::Capability pygen_variable_caps_DotProduct[] = {spv::Capability::DotProduct}; +static const spv::Capability pygen_variable_caps_DotProductKHR[] = {spv::Capability::DotProductKHR}; +static const spv::Capability pygen_variable_caps_ExpectAssumeKHR[] = {spv::Capability::ExpectAssumeKHR}; +static const spv::Capability pygen_variable_caps_FPGARegINTEL[] = {spv::Capability::FPGARegINTEL}; +static const spv::Capability pygen_variable_caps_FragmentMaskAMD[] = {spv::Capability::FragmentMaskAMD}; +static const spv::Capability pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT[] = {spv::Capability::FragmentShaderSampleInterlockEXT, spv::Capability::FragmentShaderPixelInterlockEXT, spv::Capability::FragmentShaderShadingRateInterlockEXT}; +static const spv::Capability pygen_variable_caps_FunctionPointersINTEL[] = {spv::Capability::FunctionPointersINTEL}; +static const spv::Capability pygen_variable_caps_Geometry[] = {spv::Capability::Geometry}; +static const spv::Capability pygen_variable_caps_GeometryStreams[] = {spv::Capability::GeometryStreams}; +static const spv::Capability pygen_variable_caps_GroupNonUniform[] = {spv::Capability::GroupNonUniform}; +static const spv::Capability pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV[] = {spv::Capability::GroupNonUniformArithmetic, spv::Capability::GroupNonUniformClustered, spv::Capability::GroupNonUniformPartitionedNV}; +static const spv::Capability pygen_variable_caps_GroupNonUniformBallot[] = {spv::Capability::GroupNonUniformBallot}; +static const spv::Capability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {spv::Capability::GroupNonUniformPartitionedNV}; +static const spv::Capability pygen_variable_caps_GroupNonUniformQuad[] = {spv::Capability::GroupNonUniformQuad}; +static const spv::Capability pygen_variable_caps_GroupNonUniformRotateKHR[] = {spv::Capability::GroupNonUniformRotateKHR}; +static const spv::Capability pygen_variable_caps_GroupNonUniformShuffle[] = {spv::Capability::GroupNonUniformShuffle}; +static const spv::Capability pygen_variable_caps_GroupNonUniformShuffleRelative[] = {spv::Capability::GroupNonUniformShuffleRelative}; +static const spv::Capability pygen_variable_caps_GroupNonUniformVote[] = {spv::Capability::GroupNonUniformVote}; +static const spv::Capability pygen_variable_caps_GroupUniformArithmeticKHR[] = {spv::Capability::GroupUniformArithmeticKHR}; +static const spv::Capability pygen_variable_caps_Groups[] = {spv::Capability::Groups}; +static const spv::Capability pygen_variable_caps_ImageFootprintNV[] = {spv::Capability::ImageFootprintNV}; +static const spv::Capability pygen_variable_caps_ImageQuery[] = {spv::Capability::ImageQuery}; +static const spv::Capability pygen_variable_caps_IntegerFunctions2INTEL[] = {spv::Capability::IntegerFunctions2INTEL}; +static const spv::Capability pygen_variable_caps_Kernel[] = {spv::Capability::Kernel}; +static const spv::Capability pygen_variable_caps_KernelImageQuery[] = {spv::Capability::Kernel, spv::Capability::ImageQuery}; +static const spv::Capability pygen_variable_caps_LiteralSampler[] = {spv::Capability::LiteralSampler}; +static const spv::Capability pygen_variable_caps_LongCompositesINTEL[] = {spv::Capability::LongCompositesINTEL}; +static const spv::Capability pygen_variable_caps_MaskedGatherScatterINTEL[] = {spv::Capability::MaskedGatherScatterINTEL}; +static const spv::Capability pygen_variable_caps_Matrix[] = {spv::Capability::Matrix}; +static const spv::Capability pygen_variable_caps_MemoryAccessAliasingINTEL[] = {spv::Capability::MemoryAccessAliasingINTEL}; +static const spv::Capability pygen_variable_caps_MeshShadingEXT[] = {spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_MeshShadingNV[] = {spv::Capability::MeshShadingNV}; +static const spv::Capability pygen_variable_caps_NamedBarrier[] = {spv::Capability::NamedBarrier}; +static const spv::Capability pygen_variable_caps_PipeStorage[] = {spv::Capability::PipeStorage}; +static const spv::Capability pygen_variable_caps_Pipes[] = {spv::Capability::Pipes}; +static const spv::Capability pygen_variable_caps_QuadControlKHR[] = {spv::Capability::QuadControlKHR}; +static const spv::Capability pygen_variable_caps_RayQueryKHR[] = {spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_RayQueryPositionFetchKHR[] = {spv::Capability::RayQueryPositionFetchKHR}; +static const spv::Capability pygen_variable_caps_RayTracingKHR[] = {spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingKHRRayQueryKHR[] = {spv::Capability::RayTracingKHR, spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_RayTracingMotionBlurNV[] = {spv::Capability::RayTracingMotionBlurNV}; +static const spv::Capability pygen_variable_caps_RayTracingNV[] = {spv::Capability::RayTracingNV}; +static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR, spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_Shader[] = {spv::Capability::Shader}; +static const spv::Capability pygen_variable_caps_ShaderBitInstructions[] = {spv::Capability::Shader, spv::Capability::BitInstructions}; +static const spv::Capability pygen_variable_caps_ShaderClockKHR[] = {spv::Capability::ShaderClockKHR}; +static const spv::Capability pygen_variable_caps_ShaderEnqueueAMDX[] = {spv::Capability::ShaderEnqueueAMDX}; +static const spv::Capability pygen_variable_caps_ShaderInvocationReorderNV[] = {spv::Capability::ShaderInvocationReorderNV}; +static const spv::Capability pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV[] = {spv::Capability::ShaderInvocationReorderNV, spv::Capability::RayTracingMotionBlurNV}; +static const spv::Capability pygen_variable_caps_SparseResidency[] = {spv::Capability::SparseResidency}; +static const spv::Capability pygen_variable_caps_SplitBarrierINTEL[] = {spv::Capability::SplitBarrierINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupAvcMotionEstimationINTEL[] = {spv::Capability::SubgroupAvcMotionEstimationINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL[] = {spv::Capability::SubgroupAvcMotionEstimationINTEL, spv::Capability::SubgroupAvcMotionEstimationChromaINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL[] = {spv::Capability::SubgroupAvcMotionEstimationINTEL, spv::Capability::SubgroupAvcMotionEstimationIntraINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupBallotKHR[] = {spv::Capability::SubgroupBallotKHR}; +static const spv::Capability pygen_variable_caps_SubgroupBufferBlockIOINTEL[] = {spv::Capability::SubgroupBufferBlockIOINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupDispatch[] = {spv::Capability::SubgroupDispatch}; +static const spv::Capability pygen_variable_caps_SubgroupImageBlockIOINTEL[] = {spv::Capability::SubgroupImageBlockIOINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupImageMediaBlockIOINTEL[] = {spv::Capability::SubgroupImageMediaBlockIOINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupShuffleINTEL[] = {spv::Capability::SubgroupShuffleINTEL}; +static const spv::Capability pygen_variable_caps_SubgroupVoteKHR[] = {spv::Capability::SubgroupVoteKHR}; +static const spv::Capability pygen_variable_caps_TextureBlockMatch2QCOM[] = {spv::Capability::TextureBlockMatch2QCOM}; +static const spv::Capability pygen_variable_caps_TextureBlockMatchQCOM[] = {spv::Capability::TextureBlockMatchQCOM}; +static const spv::Capability pygen_variable_caps_TextureBoxFilterQCOM[] = {spv::Capability::TextureBoxFilterQCOM}; +static const spv::Capability pygen_variable_caps_TextureSampleWeightedQCOM[] = {spv::Capability::TextureSampleWeightedQCOM}; +static const spv::Capability pygen_variable_caps_TileImageColorReadAccessEXT[] = {spv::Capability::TileImageColorReadAccessEXT}; +static const spv::Capability pygen_variable_caps_TileImageDepthReadAccessEXT[] = {spv::Capability::TileImageDepthReadAccessEXT}; +static const spv::Capability pygen_variable_caps_TileImageStencilReadAccessEXT[] = {spv::Capability::TileImageStencilReadAccessEXT}; +static const spv::Capability pygen_variable_caps_USMStorageClassesINTEL[] = {spv::Capability::USMStorageClassesINTEL}; +static const spv::Capability pygen_variable_caps_UnstructuredLoopControlsINTEL[] = {spv::Capability::UnstructuredLoopControlsINTEL}; +static const spv::Capability pygen_variable_caps_VariableLengthArrayINTEL[] = {spv::Capability::VariableLengthArrayINTEL}; +static const spv::Capability pygen_variable_caps_VectorComputeINTEL[] = {spv::Capability::VectorComputeINTEL}; + +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_ballot[] = {spvtools::Extension::kSPV_AMD_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_fragment_mask[] = {spvtools::Extension::kSPV_AMD_shader_fragment_mask}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_demote_to_helper_invocation[] = {spvtools::Extension::kSPV_EXT_demote_to_helper_invocation}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_interlock[] = {spvtools::Extension::kSPV_EXT_fragment_shader_interlock}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add}; +static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_decorate_string, spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; +static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_blocking_pipes[] = {spvtools::Extension::kSPV_INTEL_blocking_pipes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_reg[] = {spvtools::Extension::kSPV_INTEL_fpga_reg}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_function_pointers[] = {spvtools::Extension::kSPV_INTEL_function_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_memory_access_aliasing[] = {spvtools::Extension::kSPV_INTEL_memory_access_aliasing}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_unstructured_loop_controls[] = {spvtools::Extension::kSPV_INTEL_unstructured_loop_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_expect_assume[] = {spvtools::Extension::kSPV_KHR_expect_assume}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_integer_dot_product[] = {spvtools::Extension::kSPV_KHR_integer_dot_product}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_query}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracingSPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_KHR_ray_query}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_terminate_invocation[] = {spvtools::Extension::kSPV_KHR_terminate_invocation}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing, spvtools::Extension::kSPV_KHR_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query[] = {spvtools::Extension::kSPV_NV_ray_tracing, spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_KHR_ray_query}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing_motion_blur[] = {spvtools::Extension::kSPV_NV_ray_tracing_motion_blur}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footprint[] = {spvtools::Extension::kSPV_NV_shader_image_footprint}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_subgroup_partitioned[] = {spvtools::Extension::kSPV_NV_shader_subgroup_partitioned}; + +static const spv_opcode_desc_t kOpcodeTableEntries[] = { + {"Nop", spv::Op::OpNop, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Undef", spv::Op::OpUndef, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SourceContinued", spv::Op::OpSourceContinued, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Source", spv::Op::OpSource, 0, nullptr, 4, {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SourceExtension", spv::Op::OpSourceExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Name", spv::Op::OpName, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MemberName", spv::Op::OpMemberName, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"String", spv::Op::OpString, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Line", spv::Op::OpLine, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Extension", spv::Op::OpExtension, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ExtInstImport", spv::Op::OpExtInstImport, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ExtInst", spv::Op::OpExtInst, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MemoryModel", spv::Op::OpMemoryModel, 0, nullptr, 2, {SPV_OPERAND_TYPE_ADDRESSING_MODEL, SPV_OPERAND_TYPE_MEMORY_MODEL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EntryPoint", spv::Op::OpEntryPoint, 0, nullptr, 4, {SPV_OPERAND_TYPE_EXECUTION_MODEL, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ExecutionMode", spv::Op::OpExecutionMode, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Capability", spv::Op::OpCapability, 0, nullptr, 1, {SPV_OPERAND_TYPE_CAPABILITY}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeVoid", spv::Op::OpTypeVoid, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeBool", spv::Op::OpTypeBool, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeInt", spv::Op::OpTypeInt, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeFloat", spv::Op::OpTypeFloat, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeVector", spv::Op::OpTypeVector, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeMatrix", spv::Op::OpTypeMatrix, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeImage", spv::Op::OpTypeImage, 0, nullptr, 9, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DIMENSIONALITY, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeSampler", spv::Op::OpTypeSampler, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeSampledImage", spv::Op::OpTypeSampledImage, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeArray", spv::Op::OpTypeArray, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeRuntimeArray", spv::Op::OpTypeRuntimeArray, 1, pygen_variable_caps_Shader, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeStruct", spv::Op::OpTypeStruct, 0, nullptr, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeOpaque", spv::Op::OpTypeOpaque, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypePointer", spv::Op::OpTypePointer, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeFunction", spv::Op::OpTypeFunction, 0, nullptr, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeEvent", spv::Op::OpTypeEvent, 1, pygen_variable_caps_Kernel, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeDeviceEvent", spv::Op::OpTypeDeviceEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeReserveId", spv::Op::OpTypeReserveId, 1, pygen_variable_caps_Pipes, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeQueue", spv::Op::OpTypeQueue, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypePipe", spv::Op::OpTypePipe, 1, pygen_variable_caps_Pipes, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TypeForwardPointer", spv::Op::OpTypeForwardPointer, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConstantTrue", spv::Op::OpConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConstantFalse", spv::Op::OpConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Constant", spv::Op::OpConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConstantComposite", spv::Op::OpConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConstantSampler", spv::Op::OpConstantSampler, 1, pygen_variable_caps_LiteralSampler, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConstantNull", spv::Op::OpConstantNull, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpecConstantTrue", spv::Op::OpSpecConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpecConstantFalse", spv::Op::OpSpecConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpecConstant", spv::Op::OpSpecConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpecConstantComposite", spv::Op::OpSpecConstantComposite, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpecConstantOp", spv::Op::OpSpecConstantOp, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Function", spv::Op::OpFunction, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_FUNCTION_CONTROL, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FunctionParameter", spv::Op::OpFunctionParameter, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FunctionEnd", spv::Op::OpFunctionEnd, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FunctionCall", spv::Op::OpFunctionCall, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Variable", spv::Op::OpVariable, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageTexelPointer", spv::Op::OpImageTexelPointer, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Load", spv::Op::OpLoad, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Store", spv::Op::OpStore, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CopyMemory", spv::Op::OpCopyMemory, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CopyMemorySized", spv::Op::OpCopyMemorySized, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AccessChain", spv::Op::OpAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InBoundsAccessChain", spv::Op::OpInBoundsAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PtrAccessChain", spv::Op::OpPtrAccessChain, 4, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ArrayLength", spv::Op::OpArrayLength, 1, pygen_variable_caps_Shader, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GenericPtrMemSemantics", spv::Op::OpGenericPtrMemSemantics, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InBoundsPtrAccessChain", spv::Op::OpInBoundsPtrAccessChain, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Decorate", spv::Op::OpDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MemberDecorate", spv::Op::OpMemberDecorate, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DecorationGroup", spv::Op::OpDecorationGroup, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupDecorate", spv::Op::OpGroupDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupMemberDecorate", spv::Op::OpGroupMemberDecorate, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VectorExtractDynamic", spv::Op::OpVectorExtractDynamic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VectorInsertDynamic", spv::Op::OpVectorInsertDynamic, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VectorShuffle", spv::Op::OpVectorShuffle, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CompositeConstruct", spv::Op::OpCompositeConstruct, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CompositeExtract", spv::Op::OpCompositeExtract, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CompositeInsert", spv::Op::OpCompositeInsert, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CopyObject", spv::Op::OpCopyObject, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Transpose", spv::Op::OpTranspose, 1, pygen_variable_caps_Matrix, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SampledImage", spv::Op::OpSampledImage, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSampleImplicitLod", spv::Op::OpImageSampleImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSampleExplicitLod", spv::Op::OpImageSampleExplicitLod, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSampleDrefImplicitLod", spv::Op::OpImageSampleDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSampleDrefExplicitLod", spv::Op::OpImageSampleDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSampleProjImplicitLod", spv::Op::OpImageSampleProjImplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSampleProjExplicitLod", spv::Op::OpImageSampleProjExplicitLod, 1, pygen_variable_caps_Shader, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSampleProjDrefImplicitLod", spv::Op::OpImageSampleProjDrefImplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSampleProjDrefExplicitLod", spv::Op::OpImageSampleProjDrefExplicitLod, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageFetch", spv::Op::OpImageFetch, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageGather", spv::Op::OpImageGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageDrefGather", spv::Op::OpImageDrefGather, 1, pygen_variable_caps_Shader, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageRead", spv::Op::OpImageRead, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageWrite", spv::Op::OpImageWrite, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Image", spv::Op::OpImage, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageQueryFormat", spv::Op::OpImageQueryFormat, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageQueryOrder", spv::Op::OpImageQueryOrder, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageQuerySizeLod", spv::Op::OpImageQuerySizeLod, 2, pygen_variable_caps_KernelImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageQuerySize", spv::Op::OpImageQuerySize, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageQueryLod", spv::Op::OpImageQueryLod, 1, pygen_variable_caps_ImageQuery, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageQueryLevels", spv::Op::OpImageQueryLevels, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageQuerySamples", spv::Op::OpImageQuerySamples, 2, pygen_variable_caps_KernelImageQuery, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConvertFToU", spv::Op::OpConvertFToU, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConvertFToS", spv::Op::OpConvertFToS, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConvertSToF", spv::Op::OpConvertSToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConvertUToF", spv::Op::OpConvertUToF, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UConvert", spv::Op::OpUConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SConvert", spv::Op::OpSConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FConvert", spv::Op::OpFConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"QuantizeToF16", spv::Op::OpQuantizeToF16, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConvertPtrToU", spv::Op::OpConvertPtrToU, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SatConvertSToU", spv::Op::OpSatConvertSToU, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SatConvertUToS", spv::Op::OpSatConvertUToS, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConvertUToPtr", spv::Op::OpConvertUToPtr, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PtrCastToGeneric", spv::Op::OpPtrCastToGeneric, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GenericCastToPtr", spv::Op::OpGenericCastToPtr, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GenericCastToPtrExplicit", spv::Op::OpGenericCastToPtrExplicit, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Bitcast", spv::Op::OpBitcast, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SNegate", spv::Op::OpSNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FNegate", spv::Op::OpFNegate, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IAdd", spv::Op::OpIAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FAdd", spv::Op::OpFAdd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ISub", spv::Op::OpISub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FSub", spv::Op::OpFSub, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IMul", spv::Op::OpIMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FMul", spv::Op::OpFMul, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UDiv", spv::Op::OpUDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SDiv", spv::Op::OpSDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FDiv", spv::Op::OpFDiv, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UMod", spv::Op::OpUMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SRem", spv::Op::OpSRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SMod", spv::Op::OpSMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FRem", spv::Op::OpFRem, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FMod", spv::Op::OpFMod, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VectorTimesScalar", spv::Op::OpVectorTimesScalar, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MatrixTimesScalar", spv::Op::OpMatrixTimesScalar, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VectorTimesMatrix", spv::Op::OpVectorTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MatrixTimesVector", spv::Op::OpMatrixTimesVector, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MatrixTimesMatrix", spv::Op::OpMatrixTimesMatrix, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OuterProduct", spv::Op::OpOuterProduct, 1, pygen_variable_caps_Matrix, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Dot", spv::Op::OpDot, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IAddCarry", spv::Op::OpIAddCarry, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ISubBorrow", spv::Op::OpISubBorrow, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UMulExtended", spv::Op::OpUMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SMulExtended", spv::Op::OpSMulExtended, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Any", spv::Op::OpAny, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"All", spv::Op::OpAll, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IsNan", spv::Op::OpIsNan, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IsInf", spv::Op::OpIsInf, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IsFinite", spv::Op::OpIsFinite, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IsNormal", spv::Op::OpIsNormal, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SignBitSet", spv::Op::OpSignBitSet, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LessOrGreater", spv::Op::OpLessOrGreater, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), SPV_SPIRV_VERSION_WORD(1,5)}, + {"Ordered", spv::Op::OpOrdered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Unordered", spv::Op::OpUnordered, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LogicalEqual", spv::Op::OpLogicalEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LogicalNotEqual", spv::Op::OpLogicalNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LogicalOr", spv::Op::OpLogicalOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LogicalAnd", spv::Op::OpLogicalAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LogicalNot", spv::Op::OpLogicalNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Select", spv::Op::OpSelect, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IEqual", spv::Op::OpIEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"INotEqual", spv::Op::OpINotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UGreaterThan", spv::Op::OpUGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SGreaterThan", spv::Op::OpSGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UGreaterThanEqual", spv::Op::OpUGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SGreaterThanEqual", spv::Op::OpSGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ULessThan", spv::Op::OpULessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SLessThan", spv::Op::OpSLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ULessThanEqual", spv::Op::OpULessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SLessThanEqual", spv::Op::OpSLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FOrdEqual", spv::Op::OpFOrdEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FUnordEqual", spv::Op::OpFUnordEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FOrdNotEqual", spv::Op::OpFOrdNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FUnordNotEqual", spv::Op::OpFUnordNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FOrdLessThan", spv::Op::OpFOrdLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FUnordLessThan", spv::Op::OpFUnordLessThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FOrdGreaterThan", spv::Op::OpFOrdGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FUnordGreaterThan", spv::Op::OpFUnordGreaterThan, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FOrdLessThanEqual", spv::Op::OpFOrdLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FUnordLessThanEqual", spv::Op::OpFUnordLessThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FOrdGreaterThanEqual", spv::Op::OpFOrdGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FUnordGreaterThanEqual", spv::Op::OpFUnordGreaterThanEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ShiftRightLogical", spv::Op::OpShiftRightLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ShiftRightArithmetic", spv::Op::OpShiftRightArithmetic, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ShiftLeftLogical", spv::Op::OpShiftLeftLogical, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BitwiseOr", spv::Op::OpBitwiseOr, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BitwiseXor", spv::Op::OpBitwiseXor, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BitwiseAnd", spv::Op::OpBitwiseAnd, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Not", spv::Op::OpNot, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BitFieldInsert", spv::Op::OpBitFieldInsert, 2, pygen_variable_caps_ShaderBitInstructions, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BitFieldSExtract", spv::Op::OpBitFieldSExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BitFieldUExtract", spv::Op::OpBitFieldUExtract, 2, pygen_variable_caps_ShaderBitInstructions, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BitReverse", spv::Op::OpBitReverse, 2, pygen_variable_caps_ShaderBitInstructions, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BitCount", spv::Op::OpBitCount, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DPdx", spv::Op::OpDPdx, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DPdy", spv::Op::OpDPdy, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Fwidth", spv::Op::OpFwidth, 1, pygen_variable_caps_Shader, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DPdxFine", spv::Op::OpDPdxFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DPdyFine", spv::Op::OpDPdyFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FwidthFine", spv::Op::OpFwidthFine, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DPdxCoarse", spv::Op::OpDPdxCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DPdyCoarse", spv::Op::OpDPdyCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FwidthCoarse", spv::Op::OpFwidthCoarse, 1, pygen_variable_caps_DerivativeControl, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EmitVertex", spv::Op::OpEmitVertex, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EndPrimitive", spv::Op::OpEndPrimitive, 1, pygen_variable_caps_Geometry, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EmitStreamVertex", spv::Op::OpEmitStreamVertex, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EndStreamPrimitive", spv::Op::OpEndStreamPrimitive, 1, pygen_variable_caps_GeometryStreams, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ControlBarrier", spv::Op::OpControlBarrier, 0, nullptr, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MemoryBarrier", spv::Op::OpMemoryBarrier, 0, nullptr, 2, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicLoad", spv::Op::OpAtomicLoad, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicStore", spv::Op::OpAtomicStore, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicExchange", spv::Op::OpAtomicExchange, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicCompareExchange", spv::Op::OpAtomicCompareExchange, 0, nullptr, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicCompareExchangeWeak", spv::Op::OpAtomicCompareExchangeWeak, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), SPV_SPIRV_VERSION_WORD(1,3)}, + {"AtomicIIncrement", spv::Op::OpAtomicIIncrement, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicIDecrement", spv::Op::OpAtomicIDecrement, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicIAdd", spv::Op::OpAtomicIAdd, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicISub", spv::Op::OpAtomicISub, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicSMin", spv::Op::OpAtomicSMin, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicUMin", spv::Op::OpAtomicUMin, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicSMax", spv::Op::OpAtomicSMax, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicUMax", spv::Op::OpAtomicUMax, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicAnd", spv::Op::OpAtomicAnd, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicOr", spv::Op::OpAtomicOr, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicXor", spv::Op::OpAtomicXor, 0, nullptr, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Phi", spv::Op::OpPhi, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LoopMerge", spv::Op::OpLoopMerge, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LOOP_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SelectionMerge", spv::Op::OpSelectionMerge, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SELECTION_CONTROL}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Label", spv::Op::OpLabel, 0, nullptr, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Branch", spv::Op::OpBranch, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BranchConditional", spv::Op::OpBranchConditional, 0, nullptr, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Switch", spv::Op::OpSwitch, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Kill", spv::Op::OpKill, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Return", spv::Op::OpReturn, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ReturnValue", spv::Op::OpReturnValue, 0, nullptr, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Unreachable", spv::Op::OpUnreachable, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LifetimeStart", spv::Op::OpLifetimeStart, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LifetimeStop", spv::Op::OpLifetimeStop, 1, pygen_variable_caps_Kernel, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupAsyncCopy", spv::Op::OpGroupAsyncCopy, 1, pygen_variable_caps_Kernel, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupWaitEvents", spv::Op::OpGroupWaitEvents, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupAll", spv::Op::OpGroupAll, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupAny", spv::Op::OpGroupAny, 1, pygen_variable_caps_Groups, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupBroadcast", spv::Op::OpGroupBroadcast, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupIAdd", spv::Op::OpGroupIAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupFAdd", spv::Op::OpGroupFAdd, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupFMin", spv::Op::OpGroupFMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupUMin", spv::Op::OpGroupUMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupSMin", spv::Op::OpGroupSMin, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupFMax", spv::Op::OpGroupFMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupUMax", spv::Op::OpGroupUMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupSMax", spv::Op::OpGroupSMax, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ReadPipe", spv::Op::OpReadPipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WritePipe", spv::Op::OpWritePipe, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ReservedReadPipe", spv::Op::OpReservedReadPipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ReservedWritePipe", spv::Op::OpReservedWritePipe, 1, pygen_variable_caps_Pipes, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ReserveReadPipePackets", spv::Op::OpReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ReserveWritePipePackets", spv::Op::OpReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CommitReadPipe", spv::Op::OpCommitReadPipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CommitWritePipe", spv::Op::OpCommitWritePipe, 1, pygen_variable_caps_Pipes, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IsValidReserveId", spv::Op::OpIsValidReserveId, 1, pygen_variable_caps_Pipes, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GetNumPipePackets", spv::Op::OpGetNumPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GetMaxPipePackets", spv::Op::OpGetMaxPipePackets, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupReserveReadPipePackets", spv::Op::OpGroupReserveReadPipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupReserveWritePipePackets", spv::Op::OpGroupReserveWritePipePackets, 1, pygen_variable_caps_Pipes, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupCommitReadPipe", spv::Op::OpGroupCommitReadPipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GroupCommitWritePipe", spv::Op::OpGroupCommitWritePipe, 1, pygen_variable_caps_Pipes, 5, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EnqueueMarker", spv::Op::OpEnqueueMarker, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EnqueueKernel", spv::Op::OpEnqueueKernel, 1, pygen_variable_caps_DeviceEnqueue, 13, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GetKernelNDrangeSubGroupCount", spv::Op::OpGetKernelNDrangeSubGroupCount, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GetKernelNDrangeMaxSubGroupSize", spv::Op::OpGetKernelNDrangeMaxSubGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GetKernelWorkGroupSize", spv::Op::OpGetKernelWorkGroupSize, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GetKernelPreferredWorkGroupSizeMultiple", spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple, 1, pygen_variable_caps_DeviceEnqueue, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RetainEvent", spv::Op::OpRetainEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ReleaseEvent", spv::Op::OpReleaseEvent, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CreateUserEvent", spv::Op::OpCreateUserEvent, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"IsValidEvent", spv::Op::OpIsValidEvent, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SetUserEventStatus", spv::Op::OpSetUserEventStatus, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CaptureEventProfilingInfo", spv::Op::OpCaptureEventProfilingInfo, 1, pygen_variable_caps_DeviceEnqueue, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GetDefaultQueue", spv::Op::OpGetDefaultQueue, 1, pygen_variable_caps_DeviceEnqueue, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BuildNDRange", spv::Op::OpBuildNDRange, 1, pygen_variable_caps_DeviceEnqueue, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseSampleImplicitLod", spv::Op::OpImageSparseSampleImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseSampleExplicitLod", spv::Op::OpImageSparseSampleExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseSampleDrefImplicitLod", spv::Op::OpImageSparseSampleDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseSampleDrefExplicitLod", spv::Op::OpImageSparseSampleDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseSampleProjImplicitLod", spv::Op::OpImageSparseSampleProjImplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSparseSampleProjExplicitLod", spv::Op::OpImageSparseSampleProjExplicitLod, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSparseSampleProjDrefImplicitLod", spv::Op::OpImageSparseSampleProjDrefImplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSparseSampleProjDrefExplicitLod", spv::Op::OpImageSparseSampleProjDrefExplicitLod, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_IMAGE}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSparseFetch", spv::Op::OpImageSparseFetch, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseGather", spv::Op::OpImageSparseGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseDrefGather", spv::Op::OpImageSparseDrefGather, 1, pygen_variable_caps_SparseResidency, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseTexelsResident", spv::Op::OpImageSparseTexelsResident, 1, pygen_variable_caps_SparseResidency, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NoLine", spv::Op::OpNoLine, 0, nullptr, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicFlagTestAndSet", spv::Op::OpAtomicFlagTestAndSet, 1, pygen_variable_caps_Kernel, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicFlagClear", spv::Op::OpAtomicFlagClear, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageSparseRead", spv::Op::OpImageSparseRead, 1, pygen_variable_caps_SparseResidency, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SizeOf", spv::Op::OpSizeOf, 1, pygen_variable_caps_Addresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"TypePipeStorage", spv::Op::OpTypePipeStorage, 1, pygen_variable_caps_PipeStorage, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"ConstantPipeStorage", spv::Op::OpConstantPipeStorage, 1, pygen_variable_caps_PipeStorage, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"CreatePipeFromPipeStorage", spv::Op::OpCreatePipeFromPipeStorage, 1, pygen_variable_caps_PipeStorage, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"GetKernelLocalSizeForSubgroupCount", spv::Op::OpGetKernelLocalSizeForSubgroupCount, 1, pygen_variable_caps_SubgroupDispatch, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"GetKernelMaxNumSubgroups", spv::Op::OpGetKernelMaxNumSubgroups, 1, pygen_variable_caps_SubgroupDispatch, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"TypeNamedBarrier", spv::Op::OpTypeNamedBarrier, 1, pygen_variable_caps_NamedBarrier, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"NamedBarrierInitialize", spv::Op::OpNamedBarrierInitialize, 1, pygen_variable_caps_NamedBarrier, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"MemoryNamedBarrier", spv::Op::OpMemoryNamedBarrier, 1, pygen_variable_caps_NamedBarrier, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"ModuleProcessed", spv::Op::OpModuleProcessed, 0, nullptr, 1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"ExecutionModeId", spv::Op::OpExecutionModeId, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXECUTION_MODE}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"DecorateId", spv::Op::OpDecorateId, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"GroupNonUniformElect", spv::Op::OpGroupNonUniformElect, 1, pygen_variable_caps_GroupNonUniform, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformAll", spv::Op::OpGroupNonUniformAll, 1, pygen_variable_caps_GroupNonUniformVote, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformAny", spv::Op::OpGroupNonUniformAny, 1, pygen_variable_caps_GroupNonUniformVote, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformAllEqual", spv::Op::OpGroupNonUniformAllEqual, 1, pygen_variable_caps_GroupNonUniformVote, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBroadcast", spv::Op::OpGroupNonUniformBroadcast, 1, pygen_variable_caps_GroupNonUniformBallot, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBroadcastFirst", spv::Op::OpGroupNonUniformBroadcastFirst, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBallot", spv::Op::OpGroupNonUniformBallot, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformInverseBallot", spv::Op::OpGroupNonUniformInverseBallot, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBallotBitExtract", spv::Op::OpGroupNonUniformBallotBitExtract, 1, pygen_variable_caps_GroupNonUniformBallot, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBallotBitCount", spv::Op::OpGroupNonUniformBallotBitCount, 1, pygen_variable_caps_GroupNonUniformBallot, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBallotFindLSB", spv::Op::OpGroupNonUniformBallotFindLSB, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBallotFindMSB", spv::Op::OpGroupNonUniformBallotFindMSB, 1, pygen_variable_caps_GroupNonUniformBallot, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformShuffle", spv::Op::OpGroupNonUniformShuffle, 1, pygen_variable_caps_GroupNonUniformShuffle, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformShuffleXor", spv::Op::OpGroupNonUniformShuffleXor, 1, pygen_variable_caps_GroupNonUniformShuffle, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformShuffleUp", spv::Op::OpGroupNonUniformShuffleUp, 1, pygen_variable_caps_GroupNonUniformShuffleRelative, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformShuffleDown", spv::Op::OpGroupNonUniformShuffleDown, 1, pygen_variable_caps_GroupNonUniformShuffleRelative, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformIAdd", spv::Op::OpGroupNonUniformIAdd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformFAdd", spv::Op::OpGroupNonUniformFAdd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformIMul", spv::Op::OpGroupNonUniformIMul, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformFMul", spv::Op::OpGroupNonUniformFMul, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformSMin", spv::Op::OpGroupNonUniformSMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformUMin", spv::Op::OpGroupNonUniformUMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformFMin", spv::Op::OpGroupNonUniformFMin, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformSMax", spv::Op::OpGroupNonUniformSMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformUMax", spv::Op::OpGroupNonUniformUMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformFMax", spv::Op::OpGroupNonUniformFMax, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBitwiseAnd", spv::Op::OpGroupNonUniformBitwiseAnd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBitwiseOr", spv::Op::OpGroupNonUniformBitwiseOr, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBitwiseXor", spv::Op::OpGroupNonUniformBitwiseXor, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformLogicalAnd", spv::Op::OpGroupNonUniformLogicalAnd, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformLogicalOr", spv::Op::OpGroupNonUniformLogicalOr, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformLogicalXor", spv::Op::OpGroupNonUniformLogicalXor, 3, pygen_variable_caps_GroupNonUniformArithmeticGroupNonUniformClusteredGroupNonUniformPartitionedNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformQuadBroadcast", spv::Op::OpGroupNonUniformQuadBroadcast, 1, pygen_variable_caps_GroupNonUniformQuad, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformQuadSwap", spv::Op::OpGroupNonUniformQuadSwap, 1, pygen_variable_caps_GroupNonUniformQuad, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"CopyLogical", spv::Op::OpCopyLogical, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"PtrEqual", spv::Op::OpPtrEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"PtrNotEqual", spv::Op::OpPtrNotEqual, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"PtrDiff", spv::Op::OpPtrDiff, 3, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"ColorAttachmentReadEXT", spv::Op::OpColorAttachmentReadEXT, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"DepthAttachmentReadEXT", spv::Op::OpDepthAttachmentReadEXT, 1, pygen_variable_caps_TileImageDepthReadAccessEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"StencilAttachmentReadEXT", spv::Op::OpStencilAttachmentReadEXT, 1, pygen_variable_caps_TileImageStencilReadAccessEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TerminateInvocation", spv::Op::OpTerminateInvocation, 1, pygen_variable_caps_Shader, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_terminate_invocation, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SubgroupBallotKHR", spv::Op::OpSubgroupBallotKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"SubgroupFirstInvocationKHR", spv::Op::OpSubgroupFirstInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"SubgroupAllKHR", spv::Op::OpSubgroupAllKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, + {"SubgroupAnyKHR", spv::Op::OpSubgroupAnyKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, + {"SubgroupAllEqualKHR", spv::Op::OpSubgroupAllEqualKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformRotateKHR", spv::Op::OpGroupNonUniformRotateKHR, 1, pygen_variable_caps_GroupNonUniformRotateKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupReadInvocationKHR", spv::Op::OpSubgroupReadInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"TraceRayKHR", spv::Op::OpTraceRayKHR, 1, pygen_variable_caps_RayTracingKHR, 11, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"ExecuteCallableKHR", spv::Op::OpExecuteCallableKHR, 1, pygen_variable_caps_RayTracingKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"ConvertUToAccelerationStructureKHR", spv::Op::OpConvertUToAccelerationStructureKHR, 2, pygen_variable_caps_RayTracingKHRRayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"IgnoreIntersectionKHR", spv::Op::OpIgnoreIntersectionKHR, 1, pygen_variable_caps_RayTracingKHR, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TerminateRayKHR", spv::Op::OpTerminateRayKHR, 1, pygen_variable_caps_RayTracingKHR, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"SDot", spv::Op::OpSDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SDotKHR", spv::Op::OpSDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"UDot", spv::Op::OpUDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"UDotKHR", spv::Op::OpUDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SUDot", spv::Op::OpSUDot, 1, pygen_variable_caps_DotProduct, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SUDotKHR", spv::Op::OpSUDotKHR, 1, pygen_variable_caps_DotProductKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SDotAccSat", spv::Op::OpSDotAccSat, 1, pygen_variable_caps_DotProduct, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SDotAccSatKHR", spv::Op::OpSDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"UDotAccSat", spv::Op::OpUDotAccSat, 1, pygen_variable_caps_DotProduct, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"UDotAccSatKHR", spv::Op::OpUDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SUDotAccSat", spv::Op::OpSUDotAccSat, 1, pygen_variable_caps_DotProduct, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"SUDotAccSatKHR", spv::Op::OpSUDotAccSatKHR, 1, pygen_variable_caps_DotProductKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT}, 1, 1, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"TypeCooperativeMatrixKHR", spv::Op::OpTypeCooperativeMatrixKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 6, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixLoadKHR", spv::Op::OpCooperativeMatrixLoadKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixStoreKHR", spv::Op::OpCooperativeMatrixStoreKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixMulAddKHR", spv::Op::OpCooperativeMatrixMulAddKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixLengthKHR", spv::Op::OpCooperativeMatrixLengthKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeRayQueryKHR", spv::Op::OpTypeRayQueryKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryInitializeKHR", spv::Op::OpRayQueryInitializeKHR, 1, pygen_variable_caps_RayQueryKHR, 8, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryTerminateKHR", spv::Op::OpRayQueryTerminateKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGenerateIntersectionKHR", spv::Op::OpRayQueryGenerateIntersectionKHR, 1, pygen_variable_caps_RayQueryKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryConfirmIntersectionKHR", spv::Op::OpRayQueryConfirmIntersectionKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryProceedKHR", spv::Op::OpRayQueryProceedKHR, 1, pygen_variable_caps_RayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionTypeKHR", spv::Op::OpRayQueryGetIntersectionTypeKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"ImageSampleWeightedQCOM", spv::Op::OpImageSampleWeightedQCOM, 1, pygen_variable_caps_TextureSampleWeightedQCOM, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageBoxFilterQCOM", spv::Op::OpImageBoxFilterQCOM, 1, pygen_variable_caps_TextureBoxFilterQCOM, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageBlockMatchSSDQCOM", spv::Op::OpImageBlockMatchSSDQCOM, 1, pygen_variable_caps_TextureBlockMatchQCOM, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageBlockMatchSADQCOM", spv::Op::OpImageBlockMatchSADQCOM, 1, pygen_variable_caps_TextureBlockMatchQCOM, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageBlockMatchWindowSSDQCOM", spv::Op::OpImageBlockMatchWindowSSDQCOM, 1, pygen_variable_caps_TextureBlockMatch2QCOM, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageBlockMatchWindowSADQCOM", spv::Op::OpImageBlockMatchWindowSADQCOM, 1, pygen_variable_caps_TextureBlockMatch2QCOM, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageBlockMatchGatherSSDQCOM", spv::Op::OpImageBlockMatchGatherSSDQCOM, 1, pygen_variable_caps_TextureBlockMatch2QCOM, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageBlockMatchGatherSADQCOM", spv::Op::OpImageBlockMatchGatherSADQCOM, 1, pygen_variable_caps_TextureBlockMatch2QCOM, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupIAddNonUniformAMD", spv::Op::OpGroupIAddNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupFAddNonUniformAMD", spv::Op::OpGroupFAddNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupFMinNonUniformAMD", spv::Op::OpGroupFMinNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupUMinNonUniformAMD", spv::Op::OpGroupUMinNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupSMinNonUniformAMD", spv::Op::OpGroupSMinNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupFMaxNonUniformAMD", spv::Op::OpGroupFMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupUMaxNonUniformAMD", spv::Op::OpGroupUMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"GroupSMaxNonUniformAMD", spv::Op::OpGroupSMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"FragmentMaskFetchAMD", spv::Op::OpFragmentMaskFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu}, + {"FragmentFetchAMD", spv::Op::OpFragmentFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu}, + {"ReadClockKHR", spv::Op::OpReadClockKHR, 1, pygen_variable_caps_ShaderClockKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FinalizeNodePayloadsAMDX", spv::Op::OpFinalizeNodePayloadsAMDX, 1, pygen_variable_caps_ShaderEnqueueAMDX, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FinishWritingNodePayloadAMDX", spv::Op::OpFinishWritingNodePayloadAMDX, 1, pygen_variable_caps_ShaderEnqueueAMDX, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"InitializeNodePayloadsAMDX", spv::Op::OpInitializeNodePayloadsAMDX, 1, pygen_variable_caps_ShaderEnqueueAMDX, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformQuadAllKHR", spv::Op::OpGroupNonUniformQuadAllKHR, 1, pygen_variable_caps_QuadControlKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformQuadAnyKHR", spv::Op::OpGroupNonUniformQuadAnyKHR, 1, pygen_variable_caps_QuadControlKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordHitMotionNV", spv::Op::OpHitObjectRecordHitMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 14, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordHitWithIndexMotionNV", spv::Op::OpHitObjectRecordHitWithIndexMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 13, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordMissMotionNV", spv::Op::OpHitObjectRecordMissMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 7, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetWorldToObjectNV", spv::Op::OpHitObjectGetWorldToObjectNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetObjectToWorldNV", spv::Op::OpHitObjectGetObjectToWorldNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetObjectRayDirectionNV", spv::Op::OpHitObjectGetObjectRayDirectionNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetObjectRayOriginNV", spv::Op::OpHitObjectGetObjectRayOriginNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectTraceRayMotionNV", spv::Op::OpHitObjectTraceRayMotionNV, 2, pygen_variable_caps_ShaderInvocationReorderNVRayTracingMotionBlurNV, 13, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetShaderRecordBufferHandleNV", spv::Op::OpHitObjectGetShaderRecordBufferHandleNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetShaderBindingTableRecordIndexNV", spv::Op::OpHitObjectGetShaderBindingTableRecordIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordEmptyNV", spv::Op::OpHitObjectRecordEmptyNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectTraceRayNV", spv::Op::OpHitObjectTraceRayNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordHitNV", spv::Op::OpHitObjectRecordHitNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 13, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordHitWithIndexNV", spv::Op::OpHitObjectRecordHitWithIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectRecordMissNV", spv::Op::OpHitObjectRecordMissNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 6, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectExecuteShaderNV", spv::Op::OpHitObjectExecuteShaderNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetCurrentTimeNV", spv::Op::OpHitObjectGetCurrentTimeNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetAttributesNV", spv::Op::OpHitObjectGetAttributesNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetHitKindNV", spv::Op::OpHitObjectGetHitKindNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetPrimitiveIndexNV", spv::Op::OpHitObjectGetPrimitiveIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetGeometryIndexNV", spv::Op::OpHitObjectGetGeometryIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetInstanceIdNV", spv::Op::OpHitObjectGetInstanceIdNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetInstanceCustomIndexNV", spv::Op::OpHitObjectGetInstanceCustomIndexNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetWorldRayDirectionNV", spv::Op::OpHitObjectGetWorldRayDirectionNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetWorldRayOriginNV", spv::Op::OpHitObjectGetWorldRayOriginNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetRayTMaxNV", spv::Op::OpHitObjectGetRayTMaxNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectGetRayTMinNV", spv::Op::OpHitObjectGetRayTMinNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectIsEmptyNV", spv::Op::OpHitObjectIsEmptyNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectIsHitNV", spv::Op::OpHitObjectIsHitNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"HitObjectIsMissNV", spv::Op::OpHitObjectIsMissNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ReorderThreadWithHitObjectNV", spv::Op::OpReorderThreadWithHitObjectNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ReorderThreadWithHintNV", spv::Op::OpReorderThreadWithHintNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeHitObjectNV", spv::Op::OpTypeHitObjectNV, 1, pygen_variable_caps_ShaderInvocationReorderNV, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ImageSampleFootprintNV", spv::Op::OpImageSampleFootprintNV, 1, pygen_variable_caps_ImageFootprintNV, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_image_footprint, 0xffffffffu, 0xffffffffu}, + {"EmitMeshTasksEXT", spv::Op::OpEmitMeshTasksEXT, 1, pygen_variable_caps_MeshShadingEXT, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SetMeshOutputsEXT", spv::Op::OpSetMeshOutputsEXT, 1, pygen_variable_caps_MeshShadingEXT, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformPartitionNV", spv::Op::OpGroupNonUniformPartitionNV, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, 0xffffffffu, 0xffffffffu}, + {"WritePackedPrimitiveIndices4x8NV", spv::Op::OpWritePackedPrimitiveIndices4x8NV, 1, pygen_variable_caps_MeshShadingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_mesh_shader, 0xffffffffu, 0xffffffffu}, + {"FetchMicroTriangleVertexPositionNV", spv::Op::OpFetchMicroTriangleVertexPositionNV, 1, pygen_variable_caps_DisplacementMicromapNV, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FetchMicroTriangleVertexBarycentricNV", spv::Op::OpFetchMicroTriangleVertexBarycentricNV, 1, pygen_variable_caps_DisplacementMicromapNV, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ReportIntersectionKHR", spv::Op::OpReportIntersectionKHR, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"ReportIntersectionNV", spv::Op::OpReportIntersectionNV, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"IgnoreIntersectionNV", spv::Op::OpIgnoreIntersectionNV, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TerminateRayNV", spv::Op::OpTerminateRayNV, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TraceNV", spv::Op::OpTraceNV, 1, pygen_variable_caps_RayTracingNV, 11, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TraceMotionNV", spv::Op::OpTraceMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu}, + {"TraceRayMotionNV", spv::Op::OpTraceRayMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionTriangleVertexPositionsKHR", spv::Op::OpRayQueryGetIntersectionTriangleVertexPositionsKHR, 1, pygen_variable_caps_RayQueryPositionFetchKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAccelerationStructureKHR", spv::Op::OpTypeAccelerationStructureKHR, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"TypeAccelerationStructureNV", spv::Op::OpTypeAccelerationStructureNV, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"ExecuteCallableNV", spv::Op::OpExecuteCallableNV, 1, pygen_variable_caps_RayTracingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu}, + {"TypeCooperativeMatrixNV", spv::Op::OpTypeCooperativeMatrixNV, 1, pygen_variable_caps_CooperativeMatrixNV, 5, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixLoadNV", spv::Op::OpCooperativeMatrixLoadNV, 1, pygen_variable_caps_CooperativeMatrixNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 1, 1, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixStoreNV", spv::Op::OpCooperativeMatrixStoreNV, 1, pygen_variable_caps_CooperativeMatrixNV, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixMulAddNV", spv::Op::OpCooperativeMatrixMulAddNV, 1, pygen_variable_caps_CooperativeMatrixNV, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixLengthNV", spv::Op::OpCooperativeMatrixLengthNV, 1, pygen_variable_caps_CooperativeMatrixNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, 0xffffffffu, 0xffffffffu}, + {"BeginInvocationInterlockEXT", spv::Op::OpBeginInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu}, + {"EndInvocationInterlockEXT", spv::Op::OpEndInvocationInterlockEXT, 3, pygen_variable_caps_FragmentShaderSampleInterlockEXTFragmentShaderPixelInterlockEXTFragmentShaderShadingRateInterlockEXT, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, 0xffffffffu, 0xffffffffu}, + {"DemoteToHelperInvocation", spv::Op::OpDemoteToHelperInvocation, 1, pygen_variable_caps_DemoteToHelperInvocation, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DemoteToHelperInvocationEXT", spv::Op::OpDemoteToHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 0, {}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"IsHelperInvocationEXT", spv::Op::OpIsHelperInvocationEXT, 1, pygen_variable_caps_DemoteToHelperInvocationEXT, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, 0xffffffffu, 0xffffffffu}, + {"ConvertUToImageNV", spv::Op::OpConvertUToImageNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertUToSamplerNV", spv::Op::OpConvertUToSamplerNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertImageToUNV", spv::Op::OpConvertImageToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertSamplerToUNV", spv::Op::OpConvertSamplerToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertUToSampledImageNV", spv::Op::OpConvertUToSampledImageNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertSampledImageToUNV", spv::Op::OpConvertSampledImageToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SamplerImageAddressingModeNV", spv::Op::OpSamplerImageAddressingModeNV, 1, pygen_variable_caps_BindlessTextureNV, 1, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleINTEL", spv::Op::OpSubgroupShuffleINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleDownINTEL", spv::Op::OpSubgroupShuffleDownINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleUpINTEL", spv::Op::OpSubgroupShuffleUpINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleXorINTEL", spv::Op::OpSubgroupShuffleXorINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupBlockReadINTEL", spv::Op::OpSubgroupBlockReadINTEL, 1, pygen_variable_caps_SubgroupBufferBlockIOINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupBlockWriteINTEL", spv::Op::OpSubgroupBlockWriteINTEL, 1, pygen_variable_caps_SubgroupBufferBlockIOINTEL, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageBlockReadINTEL", spv::Op::OpSubgroupImageBlockReadINTEL, 1, pygen_variable_caps_SubgroupImageBlockIOINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageBlockWriteINTEL", spv::Op::OpSubgroupImageBlockWriteINTEL, 1, pygen_variable_caps_SubgroupImageBlockIOINTEL, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageMediaBlockReadINTEL", spv::Op::OpSubgroupImageMediaBlockReadINTEL, 1, pygen_variable_caps_SubgroupImageMediaBlockIOINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageMediaBlockWriteINTEL", spv::Op::OpSubgroupImageMediaBlockWriteINTEL, 1, pygen_variable_caps_SubgroupImageMediaBlockIOINTEL, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UCountLeadingZerosINTEL", spv::Op::OpUCountLeadingZerosINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UCountTrailingZerosINTEL", spv::Op::OpUCountTrailingZerosINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AbsISubINTEL", spv::Op::OpAbsISubINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AbsUSubINTEL", spv::Op::OpAbsUSubINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"IAddSatINTEL", spv::Op::OpIAddSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UAddSatINTEL", spv::Op::OpUAddSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"IAverageINTEL", spv::Op::OpIAverageINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UAverageINTEL", spv::Op::OpUAverageINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"IAverageRoundedINTEL", spv::Op::OpIAverageRoundedINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UAverageRoundedINTEL", spv::Op::OpUAverageRoundedINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ISubSatINTEL", spv::Op::OpISubSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"USubSatINTEL", spv::Op::OpUSubSatINTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"IMul32x16INTEL", spv::Op::OpIMul32x16INTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"UMul32x16INTEL", spv::Op::OpUMul32x16INTEL, 1, pygen_variable_caps_IntegerFunctions2INTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConstantFunctionPointerINTEL", spv::Op::OpConstantFunctionPointerINTEL, 1, pygen_variable_caps_FunctionPointersINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_function_pointers, 0xffffffffu, 0xffffffffu}, + {"FunctionPointerCallINTEL", spv::Op::OpFunctionPointerCallINTEL, 1, pygen_variable_caps_FunctionPointersINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_function_pointers, 0xffffffffu, 0xffffffffu}, + {"AsmTargetINTEL", spv::Op::OpAsmTargetINTEL, 1, pygen_variable_caps_AsmINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AsmINTEL", spv::Op::OpAsmINTEL, 1, pygen_variable_caps_AsmINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AsmCallINTEL", spv::Op::OpAsmCallINTEL, 1, pygen_variable_caps_AsmINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AtomicFMinEXT", spv::Op::OpAtomicFMinEXT, 4, pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXTAtomicFloat16VectorNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AtomicFMaxEXT", spv::Op::OpAtomicFMaxEXT, 4, pygen_variable_caps_AtomicFloat16MinMaxEXTAtomicFloat32MinMaxEXTAtomicFloat64MinMaxEXTAtomicFloat16VectorNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"AssumeTrueKHR", spv::Op::OpAssumeTrueKHR, 1, pygen_variable_caps_ExpectAssumeKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_expect_assume, 0xffffffffu, 0xffffffffu}, + {"ExpectKHR", spv::Op::OpExpectKHR, 1, pygen_variable_caps_ExpectAssumeKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_expect_assume, 0xffffffffu, 0xffffffffu}, + {"DecorateString", spv::Op::OpDecorateString, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"DecorateStringGOOGLE", spv::Op::OpDecorateStringGOOGLE, 0, nullptr, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"MemberDecorateString", spv::Op::OpMemberDecorateString, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"MemberDecorateStringGOOGLE", spv::Op::OpMemberDecorateStringGOOGLE, 0, nullptr, 3, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_DECORATION}, 0, 0, 2, pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"VmeImageINTEL", spv::Op::OpVmeImageINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeVmeImageINTEL", spv::Op::OpTypeVmeImageINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImePayloadINTEL", spv::Op::OpTypeAvcImePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcRefPayloadINTEL", spv::Op::OpTypeAvcRefPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcSicPayloadINTEL", spv::Op::OpTypeAvcSicPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcMcePayloadINTEL", spv::Op::OpTypeAvcMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcMceResultINTEL", spv::Op::OpTypeAvcMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultINTEL", spv::Op::OpTypeAvcImeResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultSingleReferenceStreamoutINTEL", spv::Op::OpTypeAvcImeResultSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeResultDualReferenceStreamoutINTEL", spv::Op::OpTypeAvcImeResultDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeSingleReferenceStreaminINTEL", spv::Op::OpTypeAvcImeSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcImeDualReferenceStreaminINTEL", spv::Op::OpTypeAvcImeDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcRefResultINTEL", spv::Op::OpTypeAvcRefResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeAvcSicResultINTEL", spv::Op::OpTypeAvcSicResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL", spv::Op::OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterShapePenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetInterShapePenaltyINTEL", spv::Op::OpSubgroupAvcMceSetInterShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetInterDirectionPenaltyINTEL", spv::Op::OpSubgroupAvcMceSetInterDirectionPenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL", spv::Op::OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL", spv::Op::OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL", spv::Op::OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL", spv::Op::OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetMotionVectorCostFunctionINTEL", spv::Op::OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL", spv::Op::OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetAcOnlyHaarINTEL", spv::Op::OpSubgroupAvcMceSetAcOnlyHaarINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL", spv::Op::OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL", spv::Op::OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL", spv::Op::OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToImePayloadINTEL", spv::Op::OpSubgroupAvcMceConvertToImePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToImeResultINTEL", spv::Op::OpSubgroupAvcMceConvertToImeResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToRefPayloadINTEL", spv::Op::OpSubgroupAvcMceConvertToRefPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToRefResultINTEL", spv::Op::OpSubgroupAvcMceConvertToRefResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToSicPayloadINTEL", spv::Op::OpSubgroupAvcMceConvertToSicPayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceConvertToSicResultINTEL", spv::Op::OpSubgroupAvcMceConvertToSicResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetMotionVectorsINTEL", spv::Op::OpSubgroupAvcMceGetMotionVectorsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterDistortionsINTEL", spv::Op::OpSubgroupAvcMceGetInterDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetBestInterDistortionsINTEL", spv::Op::OpSubgroupAvcMceGetBestInterDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterMajorShapeINTEL", spv::Op::OpSubgroupAvcMceGetInterMajorShapeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterMinorShapeINTEL", spv::Op::OpSubgroupAvcMceGetInterMinorShapeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterDirectionsINTEL", spv::Op::OpSubgroupAvcMceGetInterDirectionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterMotionVectorCountINTEL", spv::Op::OpSubgroupAvcMceGetInterMotionVectorCountINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterReferenceIdsINTEL", spv::Op::OpSubgroupAvcMceGetInterReferenceIdsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL", spv::Op::OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeInitializeINTEL", spv::Op::OpSubgroupAvcImeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetSingleReferenceINTEL", spv::Op::OpSubgroupAvcImeSetSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetDualReferenceINTEL", spv::Op::OpSubgroupAvcImeSetDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeRefWindowSizeINTEL", spv::Op::OpSubgroupAvcImeRefWindowSizeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeAdjustRefOffsetINTEL", spv::Op::OpSubgroupAvcImeAdjustRefOffsetINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeConvertToMcePayloadINTEL", spv::Op::OpSubgroupAvcImeConvertToMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetMaxMotionVectorCountINTEL", spv::Op::OpSubgroupAvcImeSetMaxMotionVectorCountINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetUnidirectionalMixDisableINTEL", spv::Op::OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetEarlySearchTerminationThresholdINTEL", spv::Op::OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeSetWeightedSadINTEL", spv::Op::OpSubgroupAvcImeSetWeightedSadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithSingleReferenceINTEL", spv::Op::OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithDualReferenceINTEL", spv::Op::OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL", spv::Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL", spv::Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL", spv::Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL", spv::Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL", spv::Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL", spv::Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeConvertToMceResultINTEL", spv::Op::OpSubgroupAvcImeConvertToMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetSingleReferenceStreaminINTEL", spv::Op::OpSubgroupAvcImeGetSingleReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetDualReferenceStreaminINTEL", spv::Op::OpSubgroupAvcImeGetDualReferenceStreaminINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeStripSingleReferenceStreamoutINTEL", spv::Op::OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeStripDualReferenceStreamoutINTEL", spv::Op::OpSubgroupAvcImeStripDualReferenceStreamoutINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL", spv::Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL", spv::Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL", spv::Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL", spv::Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL", spv::Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL", spv::Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetBorderReachedINTEL", spv::Op::OpSubgroupAvcImeGetBorderReachedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetTruncatedSearchIndicationINTEL", spv::Op::OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL", spv::Op::OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL", spv::Op::OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL", spv::Op::OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcFmeInitializeINTEL", spv::Op::OpSubgroupAvcFmeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcBmeInitializeINTEL", spv::Op::OpSubgroupAvcBmeInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefConvertToMcePayloadINTEL", spv::Op::OpSubgroupAvcRefConvertToMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefSetBidirectionalMixDisableINTEL", spv::Op::OpSubgroupAvcRefSetBidirectionalMixDisableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefSetBilinearFilterEnableINTEL", spv::Op::OpSubgroupAvcRefSetBilinearFilterEnableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefEvaluateWithSingleReferenceINTEL", spv::Op::OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefEvaluateWithDualReferenceINTEL", spv::Op::OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefEvaluateWithMultiReferenceINTEL", spv::Op::OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL", spv::Op::OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcRefConvertToMceResultINTEL", spv::Op::OpSubgroupAvcRefConvertToMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicInitializeINTEL", spv::Op::OpSubgroupAvcSicInitializeINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConfigureSkcINTEL", spv::Op::OpSubgroupAvcSicConfigureSkcINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConfigureIpeLumaINTEL", spv::Op::OpSubgroupAvcSicConfigureIpeLumaINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConfigureIpeLumaChromaINTEL", spv::Op::OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 13, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetMotionVectorMaskINTEL", spv::Op::OpSubgroupAvcSicGetMotionVectorMaskINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConvertToMcePayloadINTEL", spv::Op::OpSubgroupAvcSicConvertToMcePayloadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetIntraLumaShapePenaltyINTEL", spv::Op::OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetIntraLumaModeCostFunctionINTEL", spv::Op::OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetIntraChromaModeCostFunctionINTEL", spv::Op::OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetBilinearFilterEnableINTEL", spv::Op::OpSubgroupAvcSicSetBilinearFilterEnableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetSkcForwardTransformEnableINTEL", spv::Op::OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicSetBlockBasedRawSkipSadINTEL", spv::Op::OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateIpeINTEL", spv::Op::OpSubgroupAvcSicEvaluateIpeINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateWithSingleReferenceINTEL", spv::Op::OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateWithDualReferenceINTEL", spv::Op::OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateWithMultiReferenceINTEL", spv::Op::OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL", spv::Op::OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicConvertToMceResultINTEL", spv::Op::OpSubgroupAvcSicConvertToMceResultINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetIpeLumaShapeINTEL", spv::Op::OpSubgroupAvcSicGetIpeLumaShapeINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetBestIpeLumaDistortionINTEL", spv::Op::OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetBestIpeChromaDistortionINTEL", spv::Op::OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetPackedIpeLumaModesINTEL", spv::Op::OpSubgroupAvcSicGetPackedIpeLumaModesINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetIpeChromaModeINTEL", spv::Op::OpSubgroupAvcSicGetIpeChromaModeINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", spv::Op::OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", spv::Op::OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcSicGetInterRawSadsINTEL", spv::Op::OpSubgroupAvcSicGetInterRawSadsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"VariableLengthArrayINTEL", spv::Op::OpVariableLengthArrayINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SaveMemoryINTEL", spv::Op::OpSaveMemoryINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"RestoreMemoryINTEL", spv::Op::OpRestoreMemoryINTEL, 1, pygen_variable_caps_VariableLengthArrayINTEL, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSinCosPiINTEL", spv::Op::OpArbitraryFloatSinCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCastINTEL", spv::Op::OpArbitraryFloatCastINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCastFromIntINTEL", spv::Op::OpArbitraryFloatCastFromIntINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCastToIntINTEL", spv::Op::OpArbitraryFloatCastToIntINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatAddINTEL", spv::Op::OpArbitraryFloatAddINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSubINTEL", spv::Op::OpArbitraryFloatSubINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatMulINTEL", spv::Op::OpArbitraryFloatMulINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatDivINTEL", spv::Op::OpArbitraryFloatDivINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatGTINTEL", spv::Op::OpArbitraryFloatGTINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatGEINTEL", spv::Op::OpArbitraryFloatGEINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLTINTEL", spv::Op::OpArbitraryFloatLTINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLEINTEL", spv::Op::OpArbitraryFloatLEINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatEQINTEL", spv::Op::OpArbitraryFloatEQINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatRecipINTEL", spv::Op::OpArbitraryFloatRecipINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatRSqrtINTEL", spv::Op::OpArbitraryFloatRSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCbrtINTEL", spv::Op::OpArbitraryFloatCbrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatHypotINTEL", spv::Op::OpArbitraryFloatHypotINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSqrtINTEL", spv::Op::OpArbitraryFloatSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLogINTEL", spv::Op::OpArbitraryFloatLogINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLog2INTEL", spv::Op::OpArbitraryFloatLog2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLog10INTEL", spv::Op::OpArbitraryFloatLog10INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatLog1pINTEL", spv::Op::OpArbitraryFloatLog1pINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatExpINTEL", spv::Op::OpArbitraryFloatExpINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatExp2INTEL", spv::Op::OpArbitraryFloatExp2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatExp10INTEL", spv::Op::OpArbitraryFloatExp10INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatExpm1INTEL", spv::Op::OpArbitraryFloatExpm1INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSinINTEL", spv::Op::OpArbitraryFloatSinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCosINTEL", spv::Op::OpArbitraryFloatCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSinCosINTEL", spv::Op::OpArbitraryFloatSinCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatSinPiINTEL", spv::Op::OpArbitraryFloatSinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatCosPiINTEL", spv::Op::OpArbitraryFloatCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatASinINTEL", spv::Op::OpArbitraryFloatASinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatASinPiINTEL", spv::Op::OpArbitraryFloatASinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatACosINTEL", spv::Op::OpArbitraryFloatACosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatACosPiINTEL", spv::Op::OpArbitraryFloatACosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatATanINTEL", spv::Op::OpArbitraryFloatATanINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatATanPiINTEL", spv::Op::OpArbitraryFloatATanPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 8, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatATan2INTEL", spv::Op::OpArbitraryFloatATan2INTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatPowINTEL", spv::Op::OpArbitraryFloatPowINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatPowRINTEL", spv::Op::OpArbitraryFloatPowRINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ArbitraryFloatPowNINTEL", spv::Op::OpArbitraryFloatPowNINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"LoopControlINTEL", spv::Op::OpLoopControlINTEL, 1, pygen_variable_caps_UnstructuredLoopControlsINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 1, pygen_variable_exts_SPV_INTEL_unstructured_loop_controls, 0xffffffffu, 0xffffffffu}, + {"AliasDomainDeclINTEL", spv::Op::OpAliasDomainDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, + {"AliasScopeDeclINTEL", spv::Op::OpAliasScopeDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 3, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, + {"AliasScopeListDeclINTEL", spv::Op::OpAliasScopeListDeclINTEL, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 0, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, 0xffffffffu, 0xffffffffu}, + {"FixedSqrtINTEL", spv::Op::OpFixedSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedRecipINTEL", spv::Op::OpFixedRecipINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedRsqrtINTEL", spv::Op::OpFixedRsqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedSinINTEL", spv::Op::OpFixedSinINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedCosINTEL", spv::Op::OpFixedCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedSinCosINTEL", spv::Op::OpFixedSinCosINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedSinPiINTEL", spv::Op::OpFixedSinPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedCosPiINTEL", spv::Op::OpFixedCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedSinCosPiINTEL", spv::Op::OpFixedSinCosPiINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedLogINTEL", spv::Op::OpFixedLogINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"FixedExpINTEL", spv::Op::OpFixedExpINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"PtrCastToCrossWorkgroupINTEL", spv::Op::OpPtrCastToCrossWorkgroupINTEL, 1, pygen_variable_caps_USMStorageClassesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"CrossWorkgroupCastToPtrINTEL", spv::Op::OpCrossWorkgroupCastToPtrINTEL, 1, pygen_variable_caps_USMStorageClassesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ReadPipeBlockingINTEL", spv::Op::OpReadPipeBlockingINTEL, 1, pygen_variable_caps_BlockingPipesINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_blocking_pipes, 0xffffffffu, 0xffffffffu}, + {"WritePipeBlockingINTEL", spv::Op::OpWritePipeBlockingINTEL, 1, pygen_variable_caps_BlockingPipesINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_blocking_pipes, 0xffffffffu, 0xffffffffu}, + {"FPGARegINTEL", spv::Op::OpFPGARegINTEL, 1, pygen_variable_caps_FPGARegINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_INTEL_fpga_reg, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetRayTMinKHR", spv::Op::OpRayQueryGetRayTMinKHR, 1, pygen_variable_caps_RayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetRayFlagsKHR", spv::Op::OpRayQueryGetRayFlagsKHR, 1, pygen_variable_caps_RayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionTKHR", spv::Op::OpRayQueryGetIntersectionTKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionInstanceCustomIndexKHR", spv::Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionInstanceIdKHR", spv::Op::OpRayQueryGetIntersectionInstanceIdKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR", spv::Op::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionGeometryIndexKHR", spv::Op::OpRayQueryGetIntersectionGeometryIndexKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionPrimitiveIndexKHR", spv::Op::OpRayQueryGetIntersectionPrimitiveIndexKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionBarycentricsKHR", spv::Op::OpRayQueryGetIntersectionBarycentricsKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionFrontFaceKHR", spv::Op::OpRayQueryGetIntersectionFrontFaceKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionCandidateAABBOpaqueKHR", spv::Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR, 1, pygen_variable_caps_RayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionObjectRayDirectionKHR", spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionObjectRayOriginKHR", spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetWorldRayDirectionKHR", spv::Op::OpRayQueryGetWorldRayDirectionKHR, 1, pygen_variable_caps_RayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetWorldRayOriginKHR", spv::Op::OpRayQueryGetWorldRayOriginKHR, 1, pygen_variable_caps_RayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionObjectToWorldKHR", spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"RayQueryGetIntersectionWorldToObjectKHR", spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR, 1, pygen_variable_caps_RayQueryKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, + {"AtomicFAddEXT", spv::Op::OpAtomicFAddEXT, 4, pygen_variable_caps_AtomicFloat16AddEXTAtomicFloat32AddEXTAtomicFloat64AddEXTAtomicFloat16VectorNV, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, 0xffffffffu, 0xffffffffu}, + {"TypeBufferSurfaceINTEL", spv::Op::OpTypeBufferSurfaceINTEL, 1, pygen_variable_caps_VectorComputeINTEL, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"TypeStructContinuedINTEL", spv::Op::OpTypeStructContinuedINTEL, 1, pygen_variable_caps_LongCompositesINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConstantCompositeContinuedINTEL", spv::Op::OpConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongCompositesINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SpecConstantCompositeContinuedINTEL", spv::Op::OpSpecConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongCompositesINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"CompositeConstructContinuedINTEL", spv::Op::OpCompositeConstructContinuedINTEL, 1, pygen_variable_caps_LongCompositesINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertFToBF16INTEL", spv::Op::OpConvertFToBF16INTEL, 1, pygen_variable_caps_BFloat16ConversionINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConvertBF16ToFINTEL", spv::Op::OpConvertBF16ToFINTEL, 1, pygen_variable_caps_BFloat16ConversionINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ControlBarrierArriveINTEL", spv::Op::OpControlBarrierArriveINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ControlBarrierWaitINTEL", spv::Op::OpControlBarrierWaitINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupIMulKHR", spv::Op::OpGroupIMulKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupFMulKHR", spv::Op::OpGroupFMulKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupBitwiseAndKHR", spv::Op::OpGroupBitwiseAndKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupBitwiseOrKHR", spv::Op::OpGroupBitwiseOrKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupBitwiseXorKHR", spv::Op::OpGroupBitwiseXorKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupLogicalAndKHR", spv::Op::OpGroupLogicalAndKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupLogicalOrKHR", spv::Op::OpGroupLogicalOrKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"GroupLogicalXorKHR", spv::Op::OpGroupLogicalXorKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"MaskedGatherINTEL", spv::Op::OpMaskedGatherINTEL, 1, pygen_variable_caps_MaskedGatherScatterINTEL, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"MaskedScatterINTEL", spv::Op::OpMaskedScatterINTEL, 1, pygen_variable_caps_MaskedGatherScatterINTEL, 4, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/debuginfo.insts.inc b/thirdparty/glslang/External/spirv-tools/source/debuginfo.insts.inc new file mode 100644 index 000000000000..4fc30e3b04d3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/debuginfo.insts.inc @@ -0,0 +1,38 @@ + + +static const spv_ext_inst_desc_t debuginfo_entries[] = { + {"DebugInfoNone", 0, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugCompilationUnit", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeBasic", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypedef", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeEnum", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeComposite", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeMember", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameter", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugGlobalVariable", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunctionDeclaration", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunction", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLocalVariable", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_DEBUG_OPERATION, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/diagnostic.cpp b/thirdparty/glslang/External/spirv-tools/source/diagnostic.cpp new file mode 100644 index 000000000000..f3aa259431dc --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/diagnostic.cpp @@ -0,0 +1,193 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/diagnostic.h" + +#include +#include +#include +#include +#include + +#include "source/table.h" + +// Diagnostic API + +spv_diagnostic spvDiagnosticCreate(const spv_position position, + const char* message) { + spv_diagnostic diagnostic = new spv_diagnostic_t; + if (!diagnostic) return nullptr; + size_t length = strlen(message) + 1; + diagnostic->error = new char[length]; + if (!diagnostic->error) { + delete diagnostic; + return nullptr; + } + diagnostic->position = *position; + diagnostic->isTextSource = false; + memset(diagnostic->error, 0, length); + strcpy(diagnostic->error, message); + return diagnostic; +} + +void spvDiagnosticDestroy(spv_diagnostic diagnostic) { + if (!diagnostic) return; + delete[] diagnostic->error; + delete diagnostic; +} + +spv_result_t spvDiagnosticPrint(const spv_diagnostic diagnostic) { + if (!diagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC; + + if (diagnostic->isTextSource) { + // NOTE: This is a text position + // NOTE: add 1 to the line as editors start at line 1, we are counting new + // line characters to start at line 0 + std::cerr << "error: " << diagnostic->position.line + 1 << ": " + << diagnostic->position.column + 1 << ": " << diagnostic->error + << "\n"; + return SPV_SUCCESS; + } + + // NOTE: Assume this is a binary position + std::cerr << "error: "; + if (diagnostic->position.index > 0) + std::cerr << diagnostic->position.index << ": "; + std::cerr << diagnostic->error << "\n"; + return SPV_SUCCESS; +} + +namespace spvtools { + +DiagnosticStream::DiagnosticStream(DiagnosticStream&& other) + : stream_(), + position_(other.position_), + consumer_(other.consumer_), + disassembled_instruction_(std::move(other.disassembled_instruction_)), + error_(other.error_) { + // Prevent the other object from emitting output during destruction. + other.error_ = SPV_FAILED_MATCH; + // Some platforms are missing support for std::ostringstream functionality, + // including: move constructor, swap method. Either would have been a + // better choice than copying the string. + stream_ << other.stream_.str(); +} + +DiagnosticStream::~DiagnosticStream() { + if (error_ != SPV_FAILED_MATCH && consumer_ != nullptr) { + auto level = SPV_MSG_ERROR; + switch (error_) { + case SPV_SUCCESS: + case SPV_REQUESTED_TERMINATION: // Essentially success. + level = SPV_MSG_INFO; + break; + case SPV_WARNING: + level = SPV_MSG_WARNING; + break; + case SPV_UNSUPPORTED: + case SPV_ERROR_INTERNAL: + case SPV_ERROR_INVALID_TABLE: + level = SPV_MSG_INTERNAL_ERROR; + break; + case SPV_ERROR_OUT_OF_MEMORY: + level = SPV_MSG_FATAL; + break; + default: + break; + } + if (disassembled_instruction_.size() > 0) + stream_ << std::endl << " " << disassembled_instruction_ << std::endl; + + consumer_(level, "input", position_, stream_.str().c_str()); + } +} + +void UseDiagnosticAsMessageConsumer(spv_context context, + spv_diagnostic* diagnostic) { + assert(diagnostic && *diagnostic == nullptr); + + auto create_diagnostic = [diagnostic](spv_message_level_t, const char*, + const spv_position_t& position, + const char* message) { + auto p = position; + spvDiagnosticDestroy(*diagnostic); // Avoid memory leak. + *diagnostic = spvDiagnosticCreate(&p, message); + }; + SetContextMessageConsumer(context, std::move(create_diagnostic)); +} + +std::string spvResultToString(spv_result_t res) { + std::string out; + switch (res) { + case SPV_SUCCESS: + out = "SPV_SUCCESS"; + break; + case SPV_UNSUPPORTED: + out = "SPV_UNSUPPORTED"; + break; + case SPV_END_OF_STREAM: + out = "SPV_END_OF_STREAM"; + break; + case SPV_WARNING: + out = "SPV_WARNING"; + break; + case SPV_FAILED_MATCH: + out = "SPV_FAILED_MATCH"; + break; + case SPV_REQUESTED_TERMINATION: + out = "SPV_REQUESTED_TERMINATION"; + break; + case SPV_ERROR_INTERNAL: + out = "SPV_ERROR_INTERNAL"; + break; + case SPV_ERROR_OUT_OF_MEMORY: + out = "SPV_ERROR_OUT_OF_MEMORY"; + break; + case SPV_ERROR_INVALID_POINTER: + out = "SPV_ERROR_INVALID_POINTER"; + break; + case SPV_ERROR_INVALID_BINARY: + out = "SPV_ERROR_INVALID_BINARY"; + break; + case SPV_ERROR_INVALID_TEXT: + out = "SPV_ERROR_INVALID_TEXT"; + break; + case SPV_ERROR_INVALID_TABLE: + out = "SPV_ERROR_INVALID_TABLE"; + break; + case SPV_ERROR_INVALID_VALUE: + out = "SPV_ERROR_INVALID_VALUE"; + break; + case SPV_ERROR_INVALID_DIAGNOSTIC: + out = "SPV_ERROR_INVALID_DIAGNOSTIC"; + break; + case SPV_ERROR_INVALID_LOOKUP: + out = "SPV_ERROR_INVALID_LOOKUP"; + break; + case SPV_ERROR_INVALID_ID: + out = "SPV_ERROR_INVALID_ID"; + break; + case SPV_ERROR_INVALID_CFG: + out = "SPV_ERROR_INVALID_CFG"; + break; + case SPV_ERROR_INVALID_LAYOUT: + out = "SPV_ERROR_INVALID_LAYOUT"; + break; + default: + out = "Unknown Error"; + } + return out; +} + +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/diagnostic.h b/thirdparty/glslang/External/spirv-tools/source/diagnostic.h new file mode 100644 index 000000000000..22df961432f1 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/diagnostic.h @@ -0,0 +1,79 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_DIAGNOSTIC_H_ +#define SOURCE_DIAGNOSTIC_H_ + +#include +#include + +#include "spirv-tools/libspirv.hpp" + +namespace spvtools { + +// A DiagnosticStream remembers the current position of the input and an error +// code, and captures diagnostic messages via the left-shift operator. +// If the error code is not SPV_FAILED_MATCH, then captured messages are +// emitted during the destructor. +class DiagnosticStream { + public: + DiagnosticStream(spv_position_t position, const MessageConsumer& consumer, + const std::string& disassembled_instruction, + spv_result_t error) + : position_(position), + consumer_(consumer), + disassembled_instruction_(disassembled_instruction), + error_(error) {} + + // Creates a DiagnosticStream from an expiring DiagnosticStream. + // The new object takes the contents of the other, and prevents the + // other from emitting anything during destruction. + DiagnosticStream(DiagnosticStream&& other); + + // Destroys a DiagnosticStream. + // If its status code is something other than SPV_FAILED_MATCH + // then emit the accumulated message to the consumer. + ~DiagnosticStream(); + + // Adds the given value to the diagnostic message to be written. + template + DiagnosticStream& operator<<(const T& val) { + stream_ << val; + return *this; + } + + // Conversion operator to spv_result, returning the error code. + operator spv_result_t() { return error_; } + + private: + std::ostringstream stream_; + spv_position_t position_; + MessageConsumer consumer_; // Message consumer callback. + std::string disassembled_instruction_; + spv_result_t error_; +}; + +// Changes the MessageConsumer in |context| to one that updates |diagnostic| +// with the last message received. +// +// This function expects that |diagnostic| is not nullptr and its content is a +// nullptr. +void UseDiagnosticAsMessageConsumer(spv_context context, + spv_diagnostic* diagnostic); + +std::string spvResultToString(spv_result_t res); + +} // namespace spvtools + +#endif // SOURCE_DIAGNOSTIC_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/disassemble.cpp b/thirdparty/glslang/External/spirv-tools/source/disassemble.cpp new file mode 100644 index 000000000000..5173fbf67722 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/disassemble.cpp @@ -0,0 +1,566 @@ +// Copyright (c) 2015-2020 The Khronos Group Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains a disassembler: It converts a SPIR-V binary +// to text. + +#include "source/disassemble.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "source/assembly_grammar.h" +#include "source/binary.h" +#include "source/diagnostic.h" +#include "source/ext_inst.h" +#include "source/opcode.h" +#include "source/parsed_operand.h" +#include "source/print.h" +#include "source/spirv_constant.h" +#include "source/spirv_endian.h" +#include "source/util/hex_float.h" +#include "source/util/make_unique.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace { + +// A Disassembler instance converts a SPIR-V binary to its assembly +// representation. +class Disassembler { + public: + Disassembler(const AssemblyGrammar& grammar, uint32_t options, + NameMapper name_mapper) + : print_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options)), + text_(), + out_(print_ ? out_stream() : out_stream(text_)), + instruction_disassembler_(grammar, out_.get(), options, name_mapper), + header_(!spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER, options)), + byte_offset_(0) {} + + // Emits the assembly header for the module, and sets up internal state + // so subsequent callbacks can handle the cases where the entire module + // is either big-endian or little-endian. + spv_result_t HandleHeader(spv_endianness_t endian, uint32_t version, + uint32_t generator, uint32_t id_bound, + uint32_t schema); + // Emits the assembly text for the given instruction. + spv_result_t HandleInstruction(const spv_parsed_instruction_t& inst); + + // If not printing, populates text_result with the accumulated text. + // Returns SPV_SUCCESS on success. + spv_result_t SaveTextResult(spv_text* text_result) const; + + private: + const bool print_; // Should we also print to the standard output stream? + spv_endianness_t endian_; // The detected endianness of the binary. + std::stringstream text_; // Captures the text, if not printing. + out_stream out_; // The Output stream. Either to text_ or standard output. + disassemble::InstructionDisassembler instruction_disassembler_; + const bool header_; // Should we output header as the leading comment? + size_t byte_offset_; // The number of bytes processed so far. + bool inserted_decoration_space_ = false; + bool inserted_debug_space_ = false; + bool inserted_type_space_ = false; +}; + +spv_result_t Disassembler::HandleHeader(spv_endianness_t endian, + uint32_t version, uint32_t generator, + uint32_t id_bound, uint32_t schema) { + endian_ = endian; + + if (header_) { + instruction_disassembler_.EmitHeaderSpirv(); + instruction_disassembler_.EmitHeaderVersion(version); + instruction_disassembler_.EmitHeaderGenerator(generator); + instruction_disassembler_.EmitHeaderIdBound(id_bound); + instruction_disassembler_.EmitHeaderSchema(schema); + } + + byte_offset_ = SPV_INDEX_INSTRUCTION * sizeof(uint32_t); + + return SPV_SUCCESS; +} + +spv_result_t Disassembler::HandleInstruction( + const spv_parsed_instruction_t& inst) { + instruction_disassembler_.EmitSectionComment(inst, inserted_decoration_space_, + inserted_debug_space_, + inserted_type_space_); + + instruction_disassembler_.EmitInstruction(inst, byte_offset_); + + byte_offset_ += inst.num_words * sizeof(uint32_t); + + return SPV_SUCCESS; +} + +spv_result_t Disassembler::SaveTextResult(spv_text* text_result) const { + if (!print_) { + size_t length = text_.str().size(); + char* str = new char[length + 1]; + if (!str) return SPV_ERROR_OUT_OF_MEMORY; + strncpy(str, text_.str().c_str(), length + 1); + spv_text text = new spv_text_t(); + if (!text) { + delete[] str; + return SPV_ERROR_OUT_OF_MEMORY; + } + text->str = str; + text->length = length; + *text_result = text; + } + return SPV_SUCCESS; +} + +spv_result_t DisassembleHeader(void* user_data, spv_endianness_t endian, + uint32_t /* magic */, uint32_t version, + uint32_t generator, uint32_t id_bound, + uint32_t schema) { + assert(user_data); + auto disassembler = static_cast(user_data); + return disassembler->HandleHeader(endian, version, generator, id_bound, + schema); +} + +spv_result_t DisassembleInstruction( + void* user_data, const spv_parsed_instruction_t* parsed_instruction) { + assert(user_data); + auto disassembler = static_cast(user_data); + return disassembler->HandleInstruction(*parsed_instruction); +} + +// Simple wrapper class to provide extra data necessary for targeted +// instruction disassembly. +class WrappedDisassembler { + public: + WrappedDisassembler(Disassembler* dis, const uint32_t* binary, size_t wc) + : disassembler_(dis), inst_binary_(binary), word_count_(wc) {} + + Disassembler* disassembler() { return disassembler_; } + const uint32_t* inst_binary() const { return inst_binary_; } + size_t word_count() const { return word_count_; } + + private: + Disassembler* disassembler_; + const uint32_t* inst_binary_; + const size_t word_count_; +}; + +spv_result_t DisassembleTargetHeader(void* user_data, spv_endianness_t endian, + uint32_t /* magic */, uint32_t version, + uint32_t generator, uint32_t id_bound, + uint32_t schema) { + assert(user_data); + auto wrapped = static_cast(user_data); + return wrapped->disassembler()->HandleHeader(endian, version, generator, + id_bound, schema); +} + +spv_result_t DisassembleTargetInstruction( + void* user_data, const spv_parsed_instruction_t* parsed_instruction) { + assert(user_data); + auto wrapped = static_cast(user_data); + // Check if this is the instruction we want to disassemble. + if (wrapped->word_count() == parsed_instruction->num_words && + std::equal(wrapped->inst_binary(), + wrapped->inst_binary() + wrapped->word_count(), + parsed_instruction->words)) { + // Found the target instruction. Disassemble it and signal that we should + // stop searching so we don't output the same instruction again. + if (auto error = + wrapped->disassembler()->HandleInstruction(*parsed_instruction)) + return error; + return SPV_REQUESTED_TERMINATION; + } + return SPV_SUCCESS; +} + +constexpr int kStandardIndent = 15; +} // namespace + +namespace disassemble { +InstructionDisassembler::InstructionDisassembler(const AssemblyGrammar& grammar, + std::ostream& stream, + uint32_t options, + NameMapper name_mapper) + : grammar_(grammar), + stream_(stream), + print_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options)), + color_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_COLOR, options)), + indent_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_INDENT, options) + ? kStandardIndent + : 0), + comment_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_COMMENT, options)), + show_byte_offset_( + spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET, options)), + name_mapper_(std::move(name_mapper)) {} + +void InstructionDisassembler::EmitHeaderSpirv() { stream_ << "; SPIR-V\n"; } + +void InstructionDisassembler::EmitHeaderVersion(uint32_t version) { + stream_ << "; Version: " << SPV_SPIRV_VERSION_MAJOR_PART(version) << "." + << SPV_SPIRV_VERSION_MINOR_PART(version) << "\n"; +} + +void InstructionDisassembler::EmitHeaderGenerator(uint32_t generator) { + const char* generator_tool = + spvGeneratorStr(SPV_GENERATOR_TOOL_PART(generator)); + stream_ << "; Generator: " << generator_tool; + // For unknown tools, print the numeric tool value. + if (0 == strcmp("Unknown", generator_tool)) { + stream_ << "(" << SPV_GENERATOR_TOOL_PART(generator) << ")"; + } + // Print the miscellaneous part of the generator word on the same + // line as the tool name. + stream_ << "; " << SPV_GENERATOR_MISC_PART(generator) << "\n"; +} + +void InstructionDisassembler::EmitHeaderIdBound(uint32_t id_bound) { + stream_ << "; Bound: " << id_bound << "\n"; +} + +void InstructionDisassembler::EmitHeaderSchema(uint32_t schema) { + stream_ << "; Schema: " << schema << "\n"; +} + +void InstructionDisassembler::EmitInstruction( + const spv_parsed_instruction_t& inst, size_t inst_byte_offset) { + auto opcode = static_cast(inst.opcode); + + if (inst.result_id) { + SetBlue(); + const std::string id_name = name_mapper_(inst.result_id); + if (indent_) + stream_ << std::setw(std::max(0, indent_ - 3 - int(id_name.size()))); + stream_ << "%" << id_name; + ResetColor(); + stream_ << " = "; + } else { + stream_ << std::string(indent_, ' '); + } + + stream_ << "Op" << spvOpcodeString(opcode); + + for (uint16_t i = 0; i < inst.num_operands; i++) { + const spv_operand_type_t type = inst.operands[i].type; + assert(type != SPV_OPERAND_TYPE_NONE); + if (type == SPV_OPERAND_TYPE_RESULT_ID) continue; + stream_ << " "; + EmitOperand(inst, i); + } + + if (comment_ && opcode == spv::Op::OpName) { + const spv_parsed_operand_t& operand = inst.operands[0]; + const uint32_t word = inst.words[operand.offset]; + stream_ << " ; id %" << word; + } + + if (show_byte_offset_) { + SetGrey(); + auto saved_flags = stream_.flags(); + auto saved_fill = stream_.fill(); + stream_ << " ; 0x" << std::setw(8) << std::hex << std::setfill('0') + << inst_byte_offset; + stream_.flags(saved_flags); + stream_.fill(saved_fill); + ResetColor(); + } + stream_ << "\n"; +} + +void InstructionDisassembler::EmitSectionComment( + const spv_parsed_instruction_t& inst, bool& inserted_decoration_space, + bool& inserted_debug_space, bool& inserted_type_space) { + auto opcode = static_cast(inst.opcode); + if (comment_ && opcode == spv::Op::OpFunction) { + stream_ << std::endl; + stream_ << std::string(indent_, ' '); + stream_ << "; Function " << name_mapper_(inst.result_id) << std::endl; + } + if (comment_ && !inserted_decoration_space && spvOpcodeIsDecoration(opcode)) { + inserted_decoration_space = true; + stream_ << std::endl; + stream_ << std::string(indent_, ' '); + stream_ << "; Annotations" << std::endl; + } + if (comment_ && !inserted_debug_space && spvOpcodeIsDebug(opcode)) { + inserted_debug_space = true; + stream_ << std::endl; + stream_ << std::string(indent_, ' '); + stream_ << "; Debug Information" << std::endl; + } + if (comment_ && !inserted_type_space && spvOpcodeGeneratesType(opcode)) { + inserted_type_space = true; + stream_ << std::endl; + stream_ << std::string(indent_, ' '); + stream_ << "; Types, variables and constants" << std::endl; + } +} + +void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst, + const uint16_t operand_index) { + assert(operand_index < inst.num_operands); + const spv_parsed_operand_t& operand = inst.operands[operand_index]; + const uint32_t word = inst.words[operand.offset]; + switch (operand.type) { + case SPV_OPERAND_TYPE_RESULT_ID: + assert(false && " is not supposed to be handled here"); + SetBlue(); + stream_ << "%" << name_mapper_(word); + break; + case SPV_OPERAND_TYPE_ID: + case SPV_OPERAND_TYPE_TYPE_ID: + case SPV_OPERAND_TYPE_SCOPE_ID: + case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: + SetYellow(); + stream_ << "%" << name_mapper_(word); + break; + case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: { + spv_ext_inst_desc ext_inst; + SetRed(); + if (grammar_.lookupExtInst(inst.ext_inst_type, word, &ext_inst) == + SPV_SUCCESS) { + stream_ << ext_inst->name; + } else { + if (!spvExtInstIsNonSemantic(inst.ext_inst_type)) { + assert(false && "should have caught this earlier"); + } else { + // for non-semantic instruction sets we can just print the number + stream_ << word; + } + } + } break; + case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: { + spv_opcode_desc opcode_desc; + if (grammar_.lookupOpcode(spv::Op(word), &opcode_desc)) + assert(false && "should have caught this earlier"); + SetRed(); + stream_ << opcode_desc->name; + } break; + case SPV_OPERAND_TYPE_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: + case SPV_OPERAND_TYPE_LITERAL_FLOAT: { + SetRed(); + EmitNumericLiteral(&stream_, inst, operand); + ResetColor(); + } break; + case SPV_OPERAND_TYPE_LITERAL_STRING: { + stream_ << "\""; + SetGreen(); + + std::string str = spvDecodeLiteralStringOperand(inst, operand_index); + for (char const& c : str) { + if (c == '"' || c == '\\') stream_ << '\\'; + stream_ << c; + } + ResetColor(); + stream_ << '"'; + } break; + case SPV_OPERAND_TYPE_CAPABILITY: + case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: + case SPV_OPERAND_TYPE_EXECUTION_MODEL: + case SPV_OPERAND_TYPE_ADDRESSING_MODEL: + case SPV_OPERAND_TYPE_MEMORY_MODEL: + case SPV_OPERAND_TYPE_EXECUTION_MODE: + case SPV_OPERAND_TYPE_STORAGE_CLASS: + case SPV_OPERAND_TYPE_DIMENSIONALITY: + case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE: + case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE: + case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT: + case SPV_OPERAND_TYPE_FP_ROUNDING_MODE: + case SPV_OPERAND_TYPE_LINKAGE_TYPE: + case SPV_OPERAND_TYPE_ACCESS_QUALIFIER: + case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE: + case SPV_OPERAND_TYPE_DECORATION: + case SPV_OPERAND_TYPE_BUILT_IN: + case SPV_OPERAND_TYPE_GROUP_OPERATION: + case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS: + case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO: + case SPV_OPERAND_TYPE_RAY_FLAGS: + case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION: + case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE: + case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE: + case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: + case SPV_OPERAND_TYPE_FPDENORM_MODE: + case SPV_OPERAND_TYPE_FPOPERATION_MODE: + case SPV_OPERAND_TYPE_QUANTIZATION_MODES: + case SPV_OPERAND_TYPE_OVERFLOW_MODES: { + spv_operand_desc entry; + if (grammar_.lookupOperand(operand.type, word, &entry)) + assert(false && "should have caught this earlier"); + stream_ << entry->name; + } break; + case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE: + case SPV_OPERAND_TYPE_FUNCTION_CONTROL: + case SPV_OPERAND_TYPE_LOOP_CONTROL: + case SPV_OPERAND_TYPE_IMAGE: + case SPV_OPERAND_TYPE_MEMORY_ACCESS: + case SPV_OPERAND_TYPE_SELECTION_CONTROL: + case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: + EmitMaskOperand(operand.type, word); + break; + default: + if (spvOperandIsConcreteMask(operand.type)) { + EmitMaskOperand(operand.type, word); + } else if (spvOperandIsConcrete(operand.type)) { + spv_operand_desc entry; + if (grammar_.lookupOperand(operand.type, word, &entry)) + assert(false && "should have caught this earlier"); + stream_ << entry->name; + } else { + assert(false && "unhandled or invalid case"); + } + break; + } + ResetColor(); +} + +void InstructionDisassembler::EmitMaskOperand(const spv_operand_type_t type, + const uint32_t word) { + // Scan the mask from least significant bit to most significant bit. For each + // set bit, emit the name of that bit. Separate multiple names with '|'. + uint32_t remaining_word = word; + uint32_t mask; + int num_emitted = 0; + for (mask = 1; remaining_word; mask <<= 1) { + if (remaining_word & mask) { + remaining_word ^= mask; + spv_operand_desc entry; + if (grammar_.lookupOperand(type, mask, &entry)) + assert(false && "should have caught this earlier"); + if (num_emitted) stream_ << "|"; + stream_ << entry->name; + num_emitted++; + } + } + if (!num_emitted) { + // An operand value of 0 was provided, so represent it by the name + // of the 0 value. In many cases, that's "None". + spv_operand_desc entry; + if (SPV_SUCCESS == grammar_.lookupOperand(type, 0, &entry)) + stream_ << entry->name; + } +} + +void InstructionDisassembler::ResetColor() { + if (color_) stream_ << spvtools::clr::reset{print_}; +} +void InstructionDisassembler::SetGrey() { + if (color_) stream_ << spvtools::clr::grey{print_}; +} +void InstructionDisassembler::SetBlue() { + if (color_) stream_ << spvtools::clr::blue{print_}; +} +void InstructionDisassembler::SetYellow() { + if (color_) stream_ << spvtools::clr::yellow{print_}; +} +void InstructionDisassembler::SetRed() { + if (color_) stream_ << spvtools::clr::red{print_}; +} +void InstructionDisassembler::SetGreen() { + if (color_) stream_ << spvtools::clr::green{print_}; +} +} // namespace disassemble + +std::string spvInstructionBinaryToText(const spv_target_env env, + const uint32_t* instCode, + const size_t instWordCount, + const uint32_t* code, + const size_t wordCount, + const uint32_t options) { + spv_context context = spvContextCreate(env); + const AssemblyGrammar grammar(context); + if (!grammar.isValid()) { + spvContextDestroy(context); + return ""; + } + + // Generate friendly names for Ids if requested. + std::unique_ptr friendly_mapper; + NameMapper name_mapper = GetTrivialNameMapper(); + if (options & SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) { + friendly_mapper = MakeUnique(context, code, wordCount); + name_mapper = friendly_mapper->GetNameMapper(); + } + + // Now disassemble! + Disassembler disassembler(grammar, options, name_mapper); + WrappedDisassembler wrapped(&disassembler, instCode, instWordCount); + spvBinaryParse(context, &wrapped, code, wordCount, DisassembleTargetHeader, + DisassembleTargetInstruction, nullptr); + + spv_text text = nullptr; + std::string output; + if (disassembler.SaveTextResult(&text) == SPV_SUCCESS) { + output.assign(text->str, text->str + text->length); + // Drop trailing newline characters. + while (!output.empty() && output.back() == '\n') output.pop_back(); + } + spvTextDestroy(text); + spvContextDestroy(context); + + return output; +} +} // namespace spvtools + +spv_result_t spvBinaryToText(const spv_const_context context, + const uint32_t* code, const size_t wordCount, + const uint32_t options, spv_text* pText, + spv_diagnostic* pDiagnostic) { + spv_context_t hijack_context = *context; + if (pDiagnostic) { + *pDiagnostic = nullptr; + spvtools::UseDiagnosticAsMessageConsumer(&hijack_context, pDiagnostic); + } + + const spvtools::AssemblyGrammar grammar(&hijack_context); + if (!grammar.isValid()) return SPV_ERROR_INVALID_TABLE; + + // Generate friendly names for Ids if requested. + std::unique_ptr friendly_mapper; + spvtools::NameMapper name_mapper = spvtools::GetTrivialNameMapper(); + if (options & SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) { + friendly_mapper = spvtools::MakeUnique( + &hijack_context, code, wordCount); + name_mapper = friendly_mapper->GetNameMapper(); + } + + // Now disassemble! + spvtools::Disassembler disassembler(grammar, options, name_mapper); + if (auto error = + spvBinaryParse(&hijack_context, &disassembler, code, wordCount, + spvtools::DisassembleHeader, + spvtools::DisassembleInstruction, pDiagnostic)) { + return error; + } + + return disassembler.SaveTextResult(pText); +} diff --git a/thirdparty/glslang/External/spirv-tools/source/disassemble.h b/thirdparty/glslang/External/spirv-tools/source/disassemble.h new file mode 100644 index 000000000000..b520a1ea91af --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/disassemble.h @@ -0,0 +1,98 @@ +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_DISASSEMBLE_H_ +#define SOURCE_DISASSEMBLE_H_ + +#include +#include + +#include "source/name_mapper.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { + +// Decodes the given SPIR-V instruction binary representation to its assembly +// text. The context is inferred from the provided module binary. The options +// parameter is a bit field of spv_binary_to_text_options_t (note: the option +// SPV_BINARY_TO_TEXT_OPTION_PRINT will be ignored). Decoded text will be +// stored into *text. Any error will be written into *diagnostic if diagnostic +// is non-null. +std::string spvInstructionBinaryToText(const spv_target_env env, + const uint32_t* inst_binary, + const size_t inst_word_count, + const uint32_t* binary, + const size_t word_count, + const uint32_t options); + +class AssemblyGrammar; +namespace disassemble { + +// Shared code with other tools (than the disassembler) that might need to +// output disassembly. An InstructionDisassembler instance converts SPIR-V +// binary for an instruction to its assembly representation. +class InstructionDisassembler { + public: + InstructionDisassembler(const AssemblyGrammar& grammar, std::ostream& stream, + uint32_t options, NameMapper name_mapper); + + // Emits the assembly header for the module. + void EmitHeaderSpirv(); + void EmitHeaderVersion(uint32_t version); + void EmitHeaderGenerator(uint32_t generator); + void EmitHeaderIdBound(uint32_t id_bound); + void EmitHeaderSchema(uint32_t schema); + + // Emits the assembly text for the given instruction. + void EmitInstruction(const spv_parsed_instruction_t& inst, + size_t inst_byte_offset); + + // Emits a comment between different sections of the module. + void EmitSectionComment(const spv_parsed_instruction_t& inst, + bool& inserted_decoration_space, + bool& inserted_debug_space, + bool& inserted_type_space); + + // Resets the output color, if color is turned on. + void ResetColor(); + // Set the output color, if color is turned on. + void SetGrey(); + void SetBlue(); + void SetYellow(); + void SetRed(); + void SetGreen(); + + private: + // Emits an operand for the given instruction, where the instruction + // is at offset words from the start of the binary. + void EmitOperand(const spv_parsed_instruction_t& inst, + const uint16_t operand_index); + + // Emits a mask expression for the given mask word of the specified type. + void EmitMaskOperand(const spv_operand_type_t type, const uint32_t word); + + const spvtools::AssemblyGrammar& grammar_; + std::ostream& stream_; + const bool print_; // Should we also print to the standard output stream? + const bool color_; // Should we print in colour? + const int indent_; // How much to indent. 0 means don't indent + const int comment_; // Should we comment the source + const bool show_byte_offset_; // Should we print byte offset, in hex? + spvtools::NameMapper name_mapper_; +}; + +} // namespace disassemble +} // namespace spvtools + +#endif // SOURCE_DISASSEMBLE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/enum_set.h b/thirdparty/glslang/External/spirv-tools/source/enum_set.h new file mode 100644 index 000000000000..a3751388abd3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/enum_set.h @@ -0,0 +1,469 @@ +// Copyright (c) 2023 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef SOURCE_ENUM_SET_H_ +#define SOURCE_ENUM_SET_H_ + +#include "source/latest_version_spirv_header.h" + +namespace spvtools { + +// This container is optimized to store and retrieve unsigned enum values. +// The base model for this implementation is an open-addressing hashtable with +// linear probing. For small enums (max index < 64), all operations are O(1). +// +// - Enums are stored in buckets (64 contiguous values max per bucket) +// - Buckets ranges don't overlap, but don't have to be contiguous. +// - Enums are packed into 64-bits buckets, using 1 bit per enum value. +// +// Example: +// - MyEnum { A = 0, B = 1, C = 64, D = 65 } +// - 2 buckets are required: +// - bucket 0, storing values in the range [ 0; 64[ +// - bucket 1, storing values in the range [64; 128[ +// +// - Buckets are stored in a sorted vector (sorted by bucket range). +// - Retrieval is done by computing the theoretical bucket index using the enum +// value, and +// doing a linear scan from this position. +// - Insertion is done by retrieving the bucket and either: +// - inserting a new bucket in the sorted vector when no buckets has a +// compatible range. +// - setting the corresponding bit in the bucket. +// This means insertion in the middle/beginning can cause a memmove when no +// bucket is available. In our case, this happens at most 23 times for the +// largest enum we have (Opcodes). +template +class EnumSet { + private: + using BucketType = uint64_t; + using ElementType = std::underlying_type_t; + static_assert(std::is_enum_v, "EnumSets only works with enums."); + static_assert(std::is_signed_v == false, + "EnumSet doesn't supports signed enums."); + + // Each bucket can hold up to `kBucketSize` distinct, contiguous enum values. + // The first value a bucket can hold must be aligned on `kBucketSize`. + struct Bucket { + // bit mask to store `kBucketSize` enums. + BucketType data; + // 1st enum this bucket can represent. + T start; + + friend bool operator==(const Bucket& lhs, const Bucket& rhs) { + return lhs.start == rhs.start && lhs.data == rhs.data; + } + }; + + // How many distinct values can a bucket hold? 1 bit per value. + static constexpr size_t kBucketSize = sizeof(BucketType) * 8ULL; + + public: + class Iterator { + public: + typedef Iterator self_type; + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef std::forward_iterator_tag iterator_category; + typedef size_t difference_type; + + Iterator(const Iterator& other) + : set_(other.set_), + bucketIndex_(other.bucketIndex_), + bucketOffset_(other.bucketOffset_) {} + + Iterator& operator++() { + do { + if (bucketIndex_ >= set_->buckets_.size()) { + bucketIndex_ = set_->buckets_.size(); + bucketOffset_ = 0; + break; + } + + if (bucketOffset_ + 1 == kBucketSize) { + bucketOffset_ = 0; + ++bucketIndex_; + } else { + ++bucketOffset_; + } + + } while (bucketIndex_ < set_->buckets_.size() && + !set_->HasEnumAt(bucketIndex_, bucketOffset_)); + return *this; + } + + Iterator operator++(int) { + Iterator old = *this; + operator++(); + return old; + } + + T operator*() const { + assert(set_->HasEnumAt(bucketIndex_, bucketOffset_) && + "operator*() called on an invalid iterator."); + return GetValueFromBucket(set_->buckets_[bucketIndex_], bucketOffset_); + } + + bool operator!=(const Iterator& other) const { + return set_ != other.set_ || bucketOffset_ != other.bucketOffset_ || + bucketIndex_ != other.bucketIndex_; + } + + bool operator==(const Iterator& other) const { + return !(operator!=(other)); + } + + Iterator& operator=(const Iterator& other) { + set_ = other.set_; + bucketIndex_ = other.bucketIndex_; + bucketOffset_ = other.bucketOffset_; + return *this; + } + + private: + Iterator(const EnumSet* set, size_t bucketIndex, ElementType bucketOffset) + : set_(set), bucketIndex_(bucketIndex), bucketOffset_(bucketOffset) {} + + private: + const EnumSet* set_ = nullptr; + // Index of the bucket in the vector. + size_t bucketIndex_ = 0; + // Offset in bits in the current bucket. + ElementType bucketOffset_ = 0; + + friend class EnumSet; + }; + + // Required to allow the use of std::inserter. + using value_type = T; + using const_iterator = Iterator; + using iterator = Iterator; + + public: + iterator cbegin() const noexcept { + auto it = iterator(this, /* bucketIndex= */ 0, /* bucketOffset= */ 0); + if (buckets_.size() == 0) { + return it; + } + + // The iterator has the logic to find the next valid bit. If the value 0 + // is not stored, use it to find the next valid bit. + if (!HasEnumAt(it.bucketIndex_, it.bucketOffset_)) { + ++it; + } + + return it; + } + + iterator begin() const noexcept { return cbegin(); } + + iterator cend() const noexcept { + return iterator(this, buckets_.size(), /* bucketOffset= */ 0); + } + + iterator end() const noexcept { return cend(); } + + // Creates an empty set. + EnumSet() : buckets_(0), size_(0) {} + + // Creates a set and store `value` in it. + EnumSet(T value) : EnumSet() { insert(value); } + + // Creates a set and stores each `values` in it. + EnumSet(std::initializer_list values) : EnumSet() { + for (auto item : values) { + insert(item); + } + } + + // Creates a set, and insert `count` enum values pointed by `array` in it. + EnumSet(ElementType count, const T* array) : EnumSet() { + for (ElementType i = 0; i < count; i++) { + insert(array[i]); + } + } + + // Creates a set initialized with the content of the range [begin; end[. + template + EnumSet(InputIt begin, InputIt end) : EnumSet() { + for (; begin != end; ++begin) { + insert(*begin); + } + } + + // Copies the EnumSet `other` into a new EnumSet. + EnumSet(const EnumSet& other) + : buckets_(other.buckets_), size_(other.size_) {} + + // Moves the EnumSet `other` into a new EnumSet. + EnumSet(EnumSet&& other) + : buckets_(std::move(other.buckets_)), size_(other.size_) {} + + // Deep-copies the EnumSet `other` into this EnumSet. + EnumSet& operator=(const EnumSet& other) { + buckets_ = other.buckets_; + size_ = other.size_; + return *this; + } + + // Matches std::unordered_set::insert behavior. + std::pair insert(const T& value) { + const size_t index = FindBucketForValue(value); + const ElementType offset = ComputeBucketOffset(value); + + if (index >= buckets_.size() || + buckets_[index].start != ComputeBucketStart(value)) { + size_ += 1; + InsertBucketFor(index, value); + return std::make_pair(Iterator(this, index, offset), true); + } + + auto& bucket = buckets_[index]; + const auto mask = ComputeMaskForValue(value); + if (bucket.data & mask) { + return std::make_pair(Iterator(this, index, offset), false); + } + + size_ += 1; + bucket.data |= ComputeMaskForValue(value); + return std::make_pair(Iterator(this, index, offset), true); + } + + // Inserts `value` in the set if possible. + // Similar to `std::unordered_set::insert`, except the hint is ignored. + // Returns an iterator to the inserted element, or the element preventing + // insertion. + iterator insert(const_iterator, const T& value) { + return insert(value).first; + } + + // Inserts `value` in the set if possible. + // Similar to `std::unordered_set::insert`, except the hint is ignored. + // Returns an iterator to the inserted element, or the element preventing + // insertion. + iterator insert(const_iterator, T&& value) { return insert(value).first; } + + // Inserts all the values in the range [`first`; `last[. + // Similar to `std::unordered_set::insert`. + template + void insert(InputIt first, InputIt last) { + for (auto it = first; it != last; ++it) { + insert(*it); + } + } + + // Removes the value `value` into the set. + // Similar to `std::unordered_set::erase`. + // Returns the number of erased elements. + size_t erase(const T& value) { + const size_t index = FindBucketForValue(value); + if (index >= buckets_.size() || + buckets_[index].start != ComputeBucketStart(value)) { + return 0; + } + + auto& bucket = buckets_[index]; + const auto mask = ComputeMaskForValue(value); + if (!(bucket.data & mask)) { + return 0; + } + + size_ -= 1; + bucket.data &= ~mask; + if (bucket.data == 0) { + buckets_.erase(buckets_.cbegin() + index); + } + return 1; + } + + // Returns true if `value` is present in the set. + bool contains(T value) const { + const size_t index = FindBucketForValue(value); + if (index >= buckets_.size() || + buckets_[index].start != ComputeBucketStart(value)) { + return false; + } + auto& bucket = buckets_[index]; + return bucket.data & ComputeMaskForValue(value); + } + + // Returns the 1 if `value` is present in the set, `0` otherwise. + inline size_t count(T value) const { return contains(value) ? 1 : 0; } + + // Returns true if the set is holds no values. + inline bool empty() const { return size_ == 0; } + + // Returns the number of enums stored in this set. + size_t size() const { return size_; } + + // Returns true if this set contains at least one value contained in `in_set`. + // Note: If `in_set` is empty, this function returns true. + bool HasAnyOf(const EnumSet& in_set) const { + if (in_set.empty()) { + return true; + } + + auto lhs = buckets_.cbegin(); + auto rhs = in_set.buckets_.cbegin(); + + while (lhs != buckets_.cend() && rhs != in_set.buckets_.cend()) { + if (lhs->start == rhs->start) { + if (lhs->data & rhs->data) { + // At least 1 bit is shared. Early return. + return true; + } + + lhs++; + rhs++; + continue; + } + + // LHS bucket is smaller than the current RHS bucket. Catching up on RHS. + if (lhs->start < rhs->start) { + lhs++; + continue; + } + + // Otherwise, RHS needs to catch up on LHS. + rhs++; + } + + return false; + } + + private: + // Returns the index of the last bucket in which `value` could be stored. + static constexpr inline size_t ComputeLargestPossibleBucketIndexFor(T value) { + return static_cast(value) / kBucketSize; + } + + // Returns the smallest enum value that could be contained in the same bucket + // as `value`. + static constexpr inline T ComputeBucketStart(T value) { + return static_cast(kBucketSize * + ComputeLargestPossibleBucketIndexFor(value)); + } + + // Returns the index of the bit that corresponds to `value` in the bucket. + static constexpr inline ElementType ComputeBucketOffset(T value) { + return static_cast(value) % kBucketSize; + } + + // Returns the bitmask used to represent the enum `value` in its bucket. + static constexpr inline BucketType ComputeMaskForValue(T value) { + return 1ULL << ComputeBucketOffset(value); + } + + // Returns the `enum` stored in `bucket` at `offset`. + // `offset` is the bit-offset in the bucket storage. + static constexpr inline T GetValueFromBucket(const Bucket& bucket, + BucketType offset) { + return static_cast(static_cast(bucket.start) + offset); + } + + // For a given enum `value`, finds the bucket index that could contain this + // value. If no such bucket is found, the index at which the new bucket should + // be inserted is returned. + size_t FindBucketForValue(T value) const { + // Set is empty, insert at 0. + if (buckets_.size() == 0) { + return 0; + } + + const T wanted_start = ComputeBucketStart(value); + assert(buckets_.size() > 0 && + "Size must not be 0 here. Has the code above changed?"); + size_t index = std::min(buckets_.size() - 1, + ComputeLargestPossibleBucketIndexFor(value)); + + // This loops behaves like std::upper_bound with a reverse iterator. + // Buckets are sorted. 3 main cases: + // - The bucket matches + // => returns the bucket index. + // - The found bucket is larger + // => scans left until it finds the correct bucket, or insertion point. + // - The found bucket is smaller + // => We are at the end, so we return past-end index for insertion. + for (; buckets_[index].start >= wanted_start; index--) { + if (index == 0) { + return 0; + } + } + + return index + 1; + } + + // Creates a new bucket to store `value` and inserts it at `index`. + // If the `index` is past the end, the bucket is inserted at the end of the + // vector. + void InsertBucketFor(size_t index, T value) { + const T bucket_start = ComputeBucketStart(value); + Bucket bucket = {1ULL << ComputeBucketOffset(value), bucket_start}; + auto it = buckets_.emplace(buckets_.begin() + index, std::move(bucket)); +#if defined(NDEBUG) + (void)it; // Silencing unused variable warning. +#else + assert(std::next(it) == buckets_.end() || + std::next(it)->start > bucket_start); + assert(it == buckets_.begin() || std::prev(it)->start < bucket_start); +#endif + } + + // Returns true if the bucket at `bucketIndex/ stores the enum at + // `bucketOffset`, false otherwise. + bool HasEnumAt(size_t bucketIndex, BucketType bucketOffset) const { + assert(bucketIndex < buckets_.size()); + assert(bucketOffset < kBucketSize); + return buckets_[bucketIndex].data & (1ULL << bucketOffset); + } + + // Returns true if `lhs` and `rhs` hold the exact same values. + friend bool operator==(const EnumSet& lhs, const EnumSet& rhs) { + if (lhs.size_ != rhs.size_) { + return false; + } + + if (lhs.buckets_.size() != rhs.buckets_.size()) { + return false; + } + return lhs.buckets_ == rhs.buckets_; + } + + // Returns true if `lhs` and `rhs` hold at least 1 different value. + friend bool operator!=(const EnumSet& lhs, const EnumSet& rhs) { + return !(lhs == rhs); + } + + // Storage for the buckets. + std::vector buckets_; + // How many enums is this set storing. + size_t size_ = 0; +}; + +// A set of spv::Capability. +using CapabilitySet = EnumSet; + +} // namespace spvtools + +#endif // SOURCE_ENUM_SET_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.cpp b/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.cpp new file mode 100644 index 000000000000..32361a08d382 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/enum_string_mapping.h" + +#include +#include +#include +#include +#include + +#include "source/extensions.h" + +namespace spvtools { + +#include "enum_string_mapping.inc" + +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.h b/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.h new file mode 100644 index 000000000000..b136584063c8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.h @@ -0,0 +1,36 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_ENUM_STRING_MAPPING_H_ +#define SOURCE_ENUM_STRING_MAPPING_H_ + +#include + +#include "source/extensions.h" +#include "source/latest_version_spirv_header.h" + +namespace spvtools { + +// Finds Extension enum corresponding to |str|. Returns false if not found. +bool GetExtensionFromString(const char* str, Extension* extension); + +// Returns text string corresponding to |extension|. +const char* ExtensionToString(Extension extension); + +// Returns text string corresponding to |capability|. +const char* CapabilityToString(spv::Capability capability); + +} // namespace spvtools + +#endif // SOURCE_ENUM_STRING_MAPPING_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.inc b/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.inc new file mode 100644 index 000000000000..9dced143f514 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/enum_string_mapping.inc @@ -0,0 +1,761 @@ +const char* ExtensionToString(Extension extension) { + switch (extension) { + case Extension::kSPV_AMDX_shader_enqueue: + return "SPV_AMDX_shader_enqueue"; + case Extension::kSPV_AMD_gcn_shader: + return "SPV_AMD_gcn_shader"; + case Extension::kSPV_AMD_gpu_shader_half_float: + return "SPV_AMD_gpu_shader_half_float"; + case Extension::kSPV_AMD_gpu_shader_half_float_fetch: + return "SPV_AMD_gpu_shader_half_float_fetch"; + case Extension::kSPV_AMD_gpu_shader_int16: + return "SPV_AMD_gpu_shader_int16"; + case Extension::kSPV_AMD_shader_ballot: + return "SPV_AMD_shader_ballot"; + case Extension::kSPV_AMD_shader_early_and_late_fragment_tests: + return "SPV_AMD_shader_early_and_late_fragment_tests"; + case Extension::kSPV_AMD_shader_explicit_vertex_parameter: + return "SPV_AMD_shader_explicit_vertex_parameter"; + case Extension::kSPV_AMD_shader_fragment_mask: + return "SPV_AMD_shader_fragment_mask"; + case Extension::kSPV_AMD_shader_image_load_store_lod: + return "SPV_AMD_shader_image_load_store_lod"; + case Extension::kSPV_AMD_shader_trinary_minmax: + return "SPV_AMD_shader_trinary_minmax"; + case Extension::kSPV_AMD_texture_gather_bias_lod: + return "SPV_AMD_texture_gather_bias_lod"; + case Extension::kSPV_ARM_core_builtins: + return "SPV_ARM_core_builtins"; + case Extension::kSPV_EXT_demote_to_helper_invocation: + return "SPV_EXT_demote_to_helper_invocation"; + case Extension::kSPV_EXT_descriptor_indexing: + return "SPV_EXT_descriptor_indexing"; + case Extension::kSPV_EXT_fragment_fully_covered: + return "SPV_EXT_fragment_fully_covered"; + case Extension::kSPV_EXT_fragment_invocation_density: + return "SPV_EXT_fragment_invocation_density"; + case Extension::kSPV_EXT_fragment_shader_interlock: + return "SPV_EXT_fragment_shader_interlock"; + case Extension::kSPV_EXT_mesh_shader: + return "SPV_EXT_mesh_shader"; + case Extension::kSPV_EXT_opacity_micromap: + return "SPV_EXT_opacity_micromap"; + case Extension::kSPV_EXT_physical_storage_buffer: + return "SPV_EXT_physical_storage_buffer"; + case Extension::kSPV_EXT_shader_atomic_float16_add: + return "SPV_EXT_shader_atomic_float16_add"; + case Extension::kSPV_EXT_shader_atomic_float_add: + return "SPV_EXT_shader_atomic_float_add"; + case Extension::kSPV_EXT_shader_atomic_float_min_max: + return "SPV_EXT_shader_atomic_float_min_max"; + case Extension::kSPV_EXT_shader_image_int64: + return "SPV_EXT_shader_image_int64"; + case Extension::kSPV_EXT_shader_stencil_export: + return "SPV_EXT_shader_stencil_export"; + case Extension::kSPV_EXT_shader_tile_image: + return "SPV_EXT_shader_tile_image"; + case Extension::kSPV_EXT_shader_viewport_index_layer: + return "SPV_EXT_shader_viewport_index_layer"; + case Extension::kSPV_GOOGLE_decorate_string: + return "SPV_GOOGLE_decorate_string"; + case Extension::kSPV_GOOGLE_hlsl_functionality1: + return "SPV_GOOGLE_hlsl_functionality1"; + case Extension::kSPV_GOOGLE_user_type: + return "SPV_GOOGLE_user_type"; + case Extension::kSPV_INTEL_arbitrary_precision_fixed_point: + return "SPV_INTEL_arbitrary_precision_fixed_point"; + case Extension::kSPV_INTEL_arbitrary_precision_floating_point: + return "SPV_INTEL_arbitrary_precision_floating_point"; + case Extension::kSPV_INTEL_arbitrary_precision_integers: + return "SPV_INTEL_arbitrary_precision_integers"; + case Extension::kSPV_INTEL_bfloat16_conversion: + return "SPV_INTEL_bfloat16_conversion"; + case Extension::kSPV_INTEL_blocking_pipes: + return "SPV_INTEL_blocking_pipes"; + case Extension::kSPV_INTEL_cache_controls: + return "SPV_INTEL_cache_controls"; + case Extension::kSPV_INTEL_debug_module: + return "SPV_INTEL_debug_module"; + case Extension::kSPV_INTEL_device_side_avc_motion_estimation: + return "SPV_INTEL_device_side_avc_motion_estimation"; + case Extension::kSPV_INTEL_float_controls2: + return "SPV_INTEL_float_controls2"; + case Extension::kSPV_INTEL_fp_fast_math_mode: + return "SPV_INTEL_fp_fast_math_mode"; + case Extension::kSPV_INTEL_fp_max_error: + return "SPV_INTEL_fp_max_error"; + case Extension::kSPV_INTEL_fpga_argument_interfaces: + return "SPV_INTEL_fpga_argument_interfaces"; + case Extension::kSPV_INTEL_fpga_buffer_location: + return "SPV_INTEL_fpga_buffer_location"; + case Extension::kSPV_INTEL_fpga_cluster_attributes: + return "SPV_INTEL_fpga_cluster_attributes"; + case Extension::kSPV_INTEL_fpga_dsp_control: + return "SPV_INTEL_fpga_dsp_control"; + case Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes: + return "SPV_INTEL_fpga_invocation_pipelining_attributes"; + case Extension::kSPV_INTEL_fpga_latency_control: + return "SPV_INTEL_fpga_latency_control"; + case Extension::kSPV_INTEL_fpga_loop_controls: + return "SPV_INTEL_fpga_loop_controls"; + case Extension::kSPV_INTEL_fpga_memory_accesses: + return "SPV_INTEL_fpga_memory_accesses"; + case Extension::kSPV_INTEL_fpga_memory_attributes: + return "SPV_INTEL_fpga_memory_attributes"; + case Extension::kSPV_INTEL_fpga_reg: + return "SPV_INTEL_fpga_reg"; + case Extension::kSPV_INTEL_function_pointers: + return "SPV_INTEL_function_pointers"; + case Extension::kSPV_INTEL_global_variable_fpga_decorations: + return "SPV_INTEL_global_variable_fpga_decorations"; + case Extension::kSPV_INTEL_global_variable_host_access: + return "SPV_INTEL_global_variable_host_access"; + case Extension::kSPV_INTEL_inline_assembly: + return "SPV_INTEL_inline_assembly"; + case Extension::kSPV_INTEL_io_pipes: + return "SPV_INTEL_io_pipes"; + case Extension::kSPV_INTEL_kernel_attributes: + return "SPV_INTEL_kernel_attributes"; + case Extension::kSPV_INTEL_long_composites: + return "SPV_INTEL_long_composites"; + case Extension::kSPV_INTEL_loop_fuse: + return "SPV_INTEL_loop_fuse"; + case Extension::kSPV_INTEL_masked_gather_scatter: + return "SPV_INTEL_masked_gather_scatter"; + case Extension::kSPV_INTEL_maximum_registers: + return "SPV_INTEL_maximum_registers"; + case Extension::kSPV_INTEL_media_block_io: + return "SPV_INTEL_media_block_io"; + case Extension::kSPV_INTEL_memory_access_aliasing: + return "SPV_INTEL_memory_access_aliasing"; + case Extension::kSPV_INTEL_optnone: + return "SPV_INTEL_optnone"; + case Extension::kSPV_INTEL_runtime_aligned: + return "SPV_INTEL_runtime_aligned"; + case Extension::kSPV_INTEL_shader_integer_functions2: + return "SPV_INTEL_shader_integer_functions2"; + case Extension::kSPV_INTEL_split_barrier: + return "SPV_INTEL_split_barrier"; + case Extension::kSPV_INTEL_subgroups: + return "SPV_INTEL_subgroups"; + case Extension::kSPV_INTEL_unstructured_loop_controls: + return "SPV_INTEL_unstructured_loop_controls"; + case Extension::kSPV_INTEL_usm_storage_classes: + return "SPV_INTEL_usm_storage_classes"; + case Extension::kSPV_INTEL_variable_length_array: + return "SPV_INTEL_variable_length_array"; + case Extension::kSPV_INTEL_vector_compute: + return "SPV_INTEL_vector_compute"; + case Extension::kSPV_KHR_16bit_storage: + return "SPV_KHR_16bit_storage"; + case Extension::kSPV_KHR_8bit_storage: + return "SPV_KHR_8bit_storage"; + case Extension::kSPV_KHR_bit_instructions: + return "SPV_KHR_bit_instructions"; + case Extension::kSPV_KHR_cooperative_matrix: + return "SPV_KHR_cooperative_matrix"; + case Extension::kSPV_KHR_device_group: + return "SPV_KHR_device_group"; + case Extension::kSPV_KHR_expect_assume: + return "SPV_KHR_expect_assume"; + case Extension::kSPV_KHR_float_controls: + return "SPV_KHR_float_controls"; + case Extension::kSPV_KHR_float_controls2: + return "SPV_KHR_float_controls2"; + case Extension::kSPV_KHR_fragment_shader_barycentric: + return "SPV_KHR_fragment_shader_barycentric"; + case Extension::kSPV_KHR_fragment_shading_rate: + return "SPV_KHR_fragment_shading_rate"; + case Extension::kSPV_KHR_integer_dot_product: + return "SPV_KHR_integer_dot_product"; + case Extension::kSPV_KHR_linkonce_odr: + return "SPV_KHR_linkonce_odr"; + case Extension::kSPV_KHR_maximal_reconvergence: + return "SPV_KHR_maximal_reconvergence"; + case Extension::kSPV_KHR_multiview: + return "SPV_KHR_multiview"; + case Extension::kSPV_KHR_no_integer_wrap_decoration: + return "SPV_KHR_no_integer_wrap_decoration"; + case Extension::kSPV_KHR_non_semantic_info: + return "SPV_KHR_non_semantic_info"; + case Extension::kSPV_KHR_physical_storage_buffer: + return "SPV_KHR_physical_storage_buffer"; + case Extension::kSPV_KHR_post_depth_coverage: + return "SPV_KHR_post_depth_coverage"; + case Extension::kSPV_KHR_quad_control: + return "SPV_KHR_quad_control"; + case Extension::kSPV_KHR_ray_cull_mask: + return "SPV_KHR_ray_cull_mask"; + case Extension::kSPV_KHR_ray_query: + return "SPV_KHR_ray_query"; + case Extension::kSPV_KHR_ray_tracing: + return "SPV_KHR_ray_tracing"; + case Extension::kSPV_KHR_ray_tracing_position_fetch: + return "SPV_KHR_ray_tracing_position_fetch"; + case Extension::kSPV_KHR_shader_atomic_counter_ops: + return "SPV_KHR_shader_atomic_counter_ops"; + case Extension::kSPV_KHR_shader_ballot: + return "SPV_KHR_shader_ballot"; + case Extension::kSPV_KHR_shader_clock: + return "SPV_KHR_shader_clock"; + case Extension::kSPV_KHR_shader_draw_parameters: + return "SPV_KHR_shader_draw_parameters"; + case Extension::kSPV_KHR_storage_buffer_storage_class: + return "SPV_KHR_storage_buffer_storage_class"; + case Extension::kSPV_KHR_subgroup_rotate: + return "SPV_KHR_subgroup_rotate"; + case Extension::kSPV_KHR_subgroup_uniform_control_flow: + return "SPV_KHR_subgroup_uniform_control_flow"; + case Extension::kSPV_KHR_subgroup_vote: + return "SPV_KHR_subgroup_vote"; + case Extension::kSPV_KHR_terminate_invocation: + return "SPV_KHR_terminate_invocation"; + case Extension::kSPV_KHR_uniform_group_instructions: + return "SPV_KHR_uniform_group_instructions"; + case Extension::kSPV_KHR_variable_pointers: + return "SPV_KHR_variable_pointers"; + case Extension::kSPV_KHR_vulkan_memory_model: + return "SPV_KHR_vulkan_memory_model"; + case Extension::kSPV_KHR_workgroup_memory_explicit_layout: + return "SPV_KHR_workgroup_memory_explicit_layout"; + case Extension::kSPV_NVX_multiview_per_view_attributes: + return "SPV_NVX_multiview_per_view_attributes"; + case Extension::kSPV_NV_bindless_texture: + return "SPV_NV_bindless_texture"; + case Extension::kSPV_NV_compute_shader_derivatives: + return "SPV_NV_compute_shader_derivatives"; + case Extension::kSPV_NV_cooperative_matrix: + return "SPV_NV_cooperative_matrix"; + case Extension::kSPV_NV_displacement_micromap: + return "SPV_NV_displacement_micromap"; + case Extension::kSPV_NV_fragment_shader_barycentric: + return "SPV_NV_fragment_shader_barycentric"; + case Extension::kSPV_NV_geometry_shader_passthrough: + return "SPV_NV_geometry_shader_passthrough"; + case Extension::kSPV_NV_mesh_shader: + return "SPV_NV_mesh_shader"; + case Extension::kSPV_NV_ray_tracing: + return "SPV_NV_ray_tracing"; + case Extension::kSPV_NV_ray_tracing_motion_blur: + return "SPV_NV_ray_tracing_motion_blur"; + case Extension::kSPV_NV_sample_mask_override_coverage: + return "SPV_NV_sample_mask_override_coverage"; + case Extension::kSPV_NV_shader_atomic_fp16_vector: + return "SPV_NV_shader_atomic_fp16_vector"; + case Extension::kSPV_NV_shader_image_footprint: + return "SPV_NV_shader_image_footprint"; + case Extension::kSPV_NV_shader_invocation_reorder: + return "SPV_NV_shader_invocation_reorder"; + case Extension::kSPV_NV_shader_sm_builtins: + return "SPV_NV_shader_sm_builtins"; + case Extension::kSPV_NV_shader_subgroup_partitioned: + return "SPV_NV_shader_subgroup_partitioned"; + case Extension::kSPV_NV_shading_rate: + return "SPV_NV_shading_rate"; + case Extension::kSPV_NV_stereo_view_rendering: + return "SPV_NV_stereo_view_rendering"; + case Extension::kSPV_NV_viewport_array2: + return "SPV_NV_viewport_array2"; + case Extension::kSPV_QCOM_image_processing: + return "SPV_QCOM_image_processing"; + case Extension::kSPV_QCOM_image_processing2: + return "SPV_QCOM_image_processing2"; + case Extension::kSPV_VALIDATOR_ignore_type_decl_unique: + return "SPV_VALIDATOR_ignore_type_decl_unique"; + } + + return ""; +} + + + bool GetExtensionFromString(const char* str, Extension* extension) { + static const char* known_ext_strs[] = { "SPV_AMDX_shader_enqueue", "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_ARM_core_builtins", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_mesh_shader", "SPV_EXT_opacity_micromap", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_tile_image", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_bfloat16_conversion", "SPV_INTEL_blocking_pipes", "SPV_INTEL_cache_controls", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fp_max_error", "SPV_INTEL_fpga_argument_interfaces", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_dsp_control", "SPV_INTEL_fpga_invocation_pipelining_attributes", "SPV_INTEL_fpga_latency_control", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_global_variable_fpga_decorations", "SPV_INTEL_global_variable_host_access", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_composites", "SPV_INTEL_loop_fuse", "SPV_INTEL_masked_gather_scatter", "SPV_INTEL_maximum_registers", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_runtime_aligned", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_cooperative_matrix", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_float_controls2", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_maximal_reconvergence", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_quad_control", "SPV_KHR_ray_cull_mask", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_ray_tracing_position_fetch", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_displacement_micromap", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_atomic_fp16_vector", "SPV_NV_shader_image_footprint", "SPV_NV_shader_invocation_reorder", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_QCOM_image_processing", "SPV_QCOM_image_processing2", "SPV_VALIDATOR_ignore_type_decl_unique" }; + static const Extension known_ext_ids[] = { Extension::kSPV_AMDX_shader_enqueue, Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_early_and_late_fragment_tests, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_ARM_core_builtins, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_mesh_shader, Extension::kSPV_EXT_opacity_micromap, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_tile_image, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_bfloat16_conversion, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_cache_controls, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fp_max_error, Extension::kSPV_INTEL_fpga_argument_interfaces, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_dsp_control, Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes, Extension::kSPV_INTEL_fpga_latency_control, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_global_variable_fpga_decorations, Extension::kSPV_INTEL_global_variable_host_access, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_composites, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_masked_gather_scatter, Extension::kSPV_INTEL_maximum_registers, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_runtime_aligned, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_cooperative_matrix, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_float_controls2, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_maximal_reconvergence, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_quad_control, Extension::kSPV_KHR_ray_cull_mask, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_ray_tracing_position_fetch, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_bindless_texture, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_displacement_micromap, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_atomic_fp16_vector, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_invocation_reorder, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_QCOM_image_processing, Extension::kSPV_QCOM_image_processing2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique }; + const auto b = std::begin(known_ext_strs); + const auto e = std::end(known_ext_strs); + const auto found = std::equal_range( + b, e, str, [](const char* str1, const char* str2) { + return std::strcmp(str1, str2) < 0; + }); + if (found.first == e || found.first == found.second) return false; + + *extension = known_ext_ids[found.first - b]; + return true; + } + + +const char* CapabilityToString(spv::Capability capability) { + switch (capability) { + case spv::Capability::Matrix: + return "Matrix"; + case spv::Capability::Shader: + return "Shader"; + case spv::Capability::Geometry: + return "Geometry"; + case spv::Capability::Tessellation: + return "Tessellation"; + case spv::Capability::Addresses: + return "Addresses"; + case spv::Capability::Linkage: + return "Linkage"; + case spv::Capability::Kernel: + return "Kernel"; + case spv::Capability::Vector16: + return "Vector16"; + case spv::Capability::Float16Buffer: + return "Float16Buffer"; + case spv::Capability::Float16: + return "Float16"; + case spv::Capability::Float64: + return "Float64"; + case spv::Capability::Int64: + return "Int64"; + case spv::Capability::Int64Atomics: + return "Int64Atomics"; + case spv::Capability::ImageBasic: + return "ImageBasic"; + case spv::Capability::ImageReadWrite: + return "ImageReadWrite"; + case spv::Capability::ImageMipmap: + return "ImageMipmap"; + case spv::Capability::Pipes: + return "Pipes"; + case spv::Capability::Groups: + return "Groups"; + case spv::Capability::DeviceEnqueue: + return "DeviceEnqueue"; + case spv::Capability::LiteralSampler: + return "LiteralSampler"; + case spv::Capability::AtomicStorage: + return "AtomicStorage"; + case spv::Capability::Int16: + return "Int16"; + case spv::Capability::TessellationPointSize: + return "TessellationPointSize"; + case spv::Capability::GeometryPointSize: + return "GeometryPointSize"; + case spv::Capability::ImageGatherExtended: + return "ImageGatherExtended"; + case spv::Capability::StorageImageMultisample: + return "StorageImageMultisample"; + case spv::Capability::UniformBufferArrayDynamicIndexing: + return "UniformBufferArrayDynamicIndexing"; + case spv::Capability::SampledImageArrayDynamicIndexing: + return "SampledImageArrayDynamicIndexing"; + case spv::Capability::StorageBufferArrayDynamicIndexing: + return "StorageBufferArrayDynamicIndexing"; + case spv::Capability::StorageImageArrayDynamicIndexing: + return "StorageImageArrayDynamicIndexing"; + case spv::Capability::ClipDistance: + return "ClipDistance"; + case spv::Capability::CullDistance: + return "CullDistance"; + case spv::Capability::ImageCubeArray: + return "ImageCubeArray"; + case spv::Capability::SampleRateShading: + return "SampleRateShading"; + case spv::Capability::ImageRect: + return "ImageRect"; + case spv::Capability::SampledRect: + return "SampledRect"; + case spv::Capability::GenericPointer: + return "GenericPointer"; + case spv::Capability::Int8: + return "Int8"; + case spv::Capability::InputAttachment: + return "InputAttachment"; + case spv::Capability::SparseResidency: + return "SparseResidency"; + case spv::Capability::MinLod: + return "MinLod"; + case spv::Capability::Sampled1D: + return "Sampled1D"; + case spv::Capability::Image1D: + return "Image1D"; + case spv::Capability::SampledCubeArray: + return "SampledCubeArray"; + case spv::Capability::SampledBuffer: + return "SampledBuffer"; + case spv::Capability::ImageBuffer: + return "ImageBuffer"; + case spv::Capability::ImageMSArray: + return "ImageMSArray"; + case spv::Capability::StorageImageExtendedFormats: + return "StorageImageExtendedFormats"; + case spv::Capability::ImageQuery: + return "ImageQuery"; + case spv::Capability::DerivativeControl: + return "DerivativeControl"; + case spv::Capability::InterpolationFunction: + return "InterpolationFunction"; + case spv::Capability::TransformFeedback: + return "TransformFeedback"; + case spv::Capability::GeometryStreams: + return "GeometryStreams"; + case spv::Capability::StorageImageReadWithoutFormat: + return "StorageImageReadWithoutFormat"; + case spv::Capability::StorageImageWriteWithoutFormat: + return "StorageImageWriteWithoutFormat"; + case spv::Capability::MultiViewport: + return "MultiViewport"; + case spv::Capability::SubgroupDispatch: + return "SubgroupDispatch"; + case spv::Capability::NamedBarrier: + return "NamedBarrier"; + case spv::Capability::PipeStorage: + return "PipeStorage"; + case spv::Capability::GroupNonUniform: + return "GroupNonUniform"; + case spv::Capability::GroupNonUniformVote: + return "GroupNonUniformVote"; + case spv::Capability::GroupNonUniformArithmetic: + return "GroupNonUniformArithmetic"; + case spv::Capability::GroupNonUniformBallot: + return "GroupNonUniformBallot"; + case spv::Capability::GroupNonUniformShuffle: + return "GroupNonUniformShuffle"; + case spv::Capability::GroupNonUniformShuffleRelative: + return "GroupNonUniformShuffleRelative"; + case spv::Capability::GroupNonUniformClustered: + return "GroupNonUniformClustered"; + case spv::Capability::GroupNonUniformQuad: + return "GroupNonUniformQuad"; + case spv::Capability::ShaderLayer: + return "ShaderLayer"; + case spv::Capability::ShaderViewportIndex: + return "ShaderViewportIndex"; + case spv::Capability::UniformDecoration: + return "UniformDecoration"; + case spv::Capability::CoreBuiltinsARM: + return "CoreBuiltinsARM"; + case spv::Capability::TileImageColorReadAccessEXT: + return "TileImageColorReadAccessEXT"; + case spv::Capability::TileImageDepthReadAccessEXT: + return "TileImageDepthReadAccessEXT"; + case spv::Capability::TileImageStencilReadAccessEXT: + return "TileImageStencilReadAccessEXT"; + case spv::Capability::FragmentShadingRateKHR: + return "FragmentShadingRateKHR"; + case spv::Capability::SubgroupBallotKHR: + return "SubgroupBallotKHR"; + case spv::Capability::DrawParameters: + return "DrawParameters"; + case spv::Capability::WorkgroupMemoryExplicitLayoutKHR: + return "WorkgroupMemoryExplicitLayoutKHR"; + case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR: + return "WorkgroupMemoryExplicitLayout8BitAccessKHR"; + case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR: + return "WorkgroupMemoryExplicitLayout16BitAccessKHR"; + case spv::Capability::SubgroupVoteKHR: + return "SubgroupVoteKHR"; + case spv::Capability::StorageBuffer16BitAccess: + return "StorageBuffer16BitAccess"; + case spv::Capability::UniformAndStorageBuffer16BitAccess: + return "UniformAndStorageBuffer16BitAccess"; + case spv::Capability::StoragePushConstant16: + return "StoragePushConstant16"; + case spv::Capability::StorageInputOutput16: + return "StorageInputOutput16"; + case spv::Capability::DeviceGroup: + return "DeviceGroup"; + case spv::Capability::MultiView: + return "MultiView"; + case spv::Capability::VariablePointersStorageBuffer: + return "VariablePointersStorageBuffer"; + case spv::Capability::VariablePointers: + return "VariablePointers"; + case spv::Capability::AtomicStorageOps: + return "AtomicStorageOps"; + case spv::Capability::SampleMaskPostDepthCoverage: + return "SampleMaskPostDepthCoverage"; + case spv::Capability::StorageBuffer8BitAccess: + return "StorageBuffer8BitAccess"; + case spv::Capability::UniformAndStorageBuffer8BitAccess: + return "UniformAndStorageBuffer8BitAccess"; + case spv::Capability::StoragePushConstant8: + return "StoragePushConstant8"; + case spv::Capability::DenormPreserve: + return "DenormPreserve"; + case spv::Capability::DenormFlushToZero: + return "DenormFlushToZero"; + case spv::Capability::SignedZeroInfNanPreserve: + return "SignedZeroInfNanPreserve"; + case spv::Capability::RoundingModeRTE: + return "RoundingModeRTE"; + case spv::Capability::RoundingModeRTZ: + return "RoundingModeRTZ"; + case spv::Capability::RayQueryProvisionalKHR: + return "RayQueryProvisionalKHR"; + case spv::Capability::RayQueryKHR: + return "RayQueryKHR"; + case spv::Capability::RayTraversalPrimitiveCullingKHR: + return "RayTraversalPrimitiveCullingKHR"; + case spv::Capability::RayTracingKHR: + return "RayTracingKHR"; + case spv::Capability::TextureSampleWeightedQCOM: + return "TextureSampleWeightedQCOM"; + case spv::Capability::TextureBoxFilterQCOM: + return "TextureBoxFilterQCOM"; + case spv::Capability::TextureBlockMatchQCOM: + return "TextureBlockMatchQCOM"; + case spv::Capability::TextureBlockMatch2QCOM: + return "TextureBlockMatch2QCOM"; + case spv::Capability::Float16ImageAMD: + return "Float16ImageAMD"; + case spv::Capability::ImageGatherBiasLodAMD: + return "ImageGatherBiasLodAMD"; + case spv::Capability::FragmentMaskAMD: + return "FragmentMaskAMD"; + case spv::Capability::StencilExportEXT: + return "StencilExportEXT"; + case spv::Capability::ImageReadWriteLodAMD: + return "ImageReadWriteLodAMD"; + case spv::Capability::Int64ImageEXT: + return "Int64ImageEXT"; + case spv::Capability::ShaderClockKHR: + return "ShaderClockKHR"; + case spv::Capability::ShaderEnqueueAMDX: + return "ShaderEnqueueAMDX"; + case spv::Capability::QuadControlKHR: + return "QuadControlKHR"; + case spv::Capability::SampleMaskOverrideCoverageNV: + return "SampleMaskOverrideCoverageNV"; + case spv::Capability::GeometryShaderPassthroughNV: + return "GeometryShaderPassthroughNV"; + case spv::Capability::ShaderViewportIndexLayerEXT: + return "ShaderViewportIndexLayerEXT"; + case spv::Capability::ShaderViewportMaskNV: + return "ShaderViewportMaskNV"; + case spv::Capability::ShaderStereoViewNV: + return "ShaderStereoViewNV"; + case spv::Capability::PerViewAttributesNV: + return "PerViewAttributesNV"; + case spv::Capability::FragmentFullyCoveredEXT: + return "FragmentFullyCoveredEXT"; + case spv::Capability::MeshShadingNV: + return "MeshShadingNV"; + case spv::Capability::ImageFootprintNV: + return "ImageFootprintNV"; + case spv::Capability::MeshShadingEXT: + return "MeshShadingEXT"; + case spv::Capability::FragmentBarycentricKHR: + return "FragmentBarycentricKHR"; + case spv::Capability::ComputeDerivativeGroupQuadsNV: + return "ComputeDerivativeGroupQuadsNV"; + case spv::Capability::FragmentDensityEXT: + return "FragmentDensityEXT"; + case spv::Capability::GroupNonUniformPartitionedNV: + return "GroupNonUniformPartitionedNV"; + case spv::Capability::ShaderNonUniform: + return "ShaderNonUniform"; + case spv::Capability::RuntimeDescriptorArray: + return "RuntimeDescriptorArray"; + case spv::Capability::InputAttachmentArrayDynamicIndexing: + return "InputAttachmentArrayDynamicIndexing"; + case spv::Capability::UniformTexelBufferArrayDynamicIndexing: + return "UniformTexelBufferArrayDynamicIndexing"; + case spv::Capability::StorageTexelBufferArrayDynamicIndexing: + return "StorageTexelBufferArrayDynamicIndexing"; + case spv::Capability::UniformBufferArrayNonUniformIndexing: + return "UniformBufferArrayNonUniformIndexing"; + case spv::Capability::SampledImageArrayNonUniformIndexing: + return "SampledImageArrayNonUniformIndexing"; + case spv::Capability::StorageBufferArrayNonUniformIndexing: + return "StorageBufferArrayNonUniformIndexing"; + case spv::Capability::StorageImageArrayNonUniformIndexing: + return "StorageImageArrayNonUniformIndexing"; + case spv::Capability::InputAttachmentArrayNonUniformIndexing: + return "InputAttachmentArrayNonUniformIndexing"; + case spv::Capability::UniformTexelBufferArrayNonUniformIndexing: + return "UniformTexelBufferArrayNonUniformIndexing"; + case spv::Capability::StorageTexelBufferArrayNonUniformIndexing: + return "StorageTexelBufferArrayNonUniformIndexing"; + case spv::Capability::RayTracingPositionFetchKHR: + return "RayTracingPositionFetchKHR"; + case spv::Capability::RayTracingNV: + return "RayTracingNV"; + case spv::Capability::RayTracingMotionBlurNV: + return "RayTracingMotionBlurNV"; + case spv::Capability::VulkanMemoryModel: + return "VulkanMemoryModel"; + case spv::Capability::VulkanMemoryModelDeviceScope: + return "VulkanMemoryModelDeviceScope"; + case spv::Capability::PhysicalStorageBufferAddresses: + return "PhysicalStorageBufferAddresses"; + case spv::Capability::ComputeDerivativeGroupLinearNV: + return "ComputeDerivativeGroupLinearNV"; + case spv::Capability::RayTracingProvisionalKHR: + return "RayTracingProvisionalKHR"; + case spv::Capability::CooperativeMatrixNV: + return "CooperativeMatrixNV"; + case spv::Capability::FragmentShaderSampleInterlockEXT: + return "FragmentShaderSampleInterlockEXT"; + case spv::Capability::FragmentShaderShadingRateInterlockEXT: + return "FragmentShaderShadingRateInterlockEXT"; + case spv::Capability::ShaderSMBuiltinsNV: + return "ShaderSMBuiltinsNV"; + case spv::Capability::FragmentShaderPixelInterlockEXT: + return "FragmentShaderPixelInterlockEXT"; + case spv::Capability::DemoteToHelperInvocation: + return "DemoteToHelperInvocation"; + case spv::Capability::DisplacementMicromapNV: + return "DisplacementMicromapNV"; + case spv::Capability::RayTracingOpacityMicromapEXT: + return "RayTracingOpacityMicromapEXT"; + case spv::Capability::ShaderInvocationReorderNV: + return "ShaderInvocationReorderNV"; + case spv::Capability::BindlessTextureNV: + return "BindlessTextureNV"; + case spv::Capability::RayQueryPositionFetchKHR: + return "RayQueryPositionFetchKHR"; + case spv::Capability::AtomicFloat16VectorNV: + return "AtomicFloat16VectorNV"; + case spv::Capability::RayTracingDisplacementMicromapNV: + return "RayTracingDisplacementMicromapNV"; + case spv::Capability::SubgroupShuffleINTEL: + return "SubgroupShuffleINTEL"; + case spv::Capability::SubgroupBufferBlockIOINTEL: + return "SubgroupBufferBlockIOINTEL"; + case spv::Capability::SubgroupImageBlockIOINTEL: + return "SubgroupImageBlockIOINTEL"; + case spv::Capability::SubgroupImageMediaBlockIOINTEL: + return "SubgroupImageMediaBlockIOINTEL"; + case spv::Capability::RoundToInfinityINTEL: + return "RoundToInfinityINTEL"; + case spv::Capability::FloatingPointModeINTEL: + return "FloatingPointModeINTEL"; + case spv::Capability::IntegerFunctions2INTEL: + return "IntegerFunctions2INTEL"; + case spv::Capability::FunctionPointersINTEL: + return "FunctionPointersINTEL"; + case spv::Capability::IndirectReferencesINTEL: + return "IndirectReferencesINTEL"; + case spv::Capability::AsmINTEL: + return "AsmINTEL"; + case spv::Capability::AtomicFloat32MinMaxEXT: + return "AtomicFloat32MinMaxEXT"; + case spv::Capability::AtomicFloat64MinMaxEXT: + return "AtomicFloat64MinMaxEXT"; + case spv::Capability::AtomicFloat16MinMaxEXT: + return "AtomicFloat16MinMaxEXT"; + case spv::Capability::VectorComputeINTEL: + return "VectorComputeINTEL"; + case spv::Capability::VectorAnyINTEL: + return "VectorAnyINTEL"; + case spv::Capability::ExpectAssumeKHR: + return "ExpectAssumeKHR"; + case spv::Capability::SubgroupAvcMotionEstimationINTEL: + return "SubgroupAvcMotionEstimationINTEL"; + case spv::Capability::SubgroupAvcMotionEstimationIntraINTEL: + return "SubgroupAvcMotionEstimationIntraINTEL"; + case spv::Capability::SubgroupAvcMotionEstimationChromaINTEL: + return "SubgroupAvcMotionEstimationChromaINTEL"; + case spv::Capability::VariableLengthArrayINTEL: + return "VariableLengthArrayINTEL"; + case spv::Capability::FunctionFloatControlINTEL: + return "FunctionFloatControlINTEL"; + case spv::Capability::FPGAMemoryAttributesINTEL: + return "FPGAMemoryAttributesINTEL"; + case spv::Capability::FPFastMathModeINTEL: + return "FPFastMathModeINTEL"; + case spv::Capability::ArbitraryPrecisionIntegersINTEL: + return "ArbitraryPrecisionIntegersINTEL"; + case spv::Capability::ArbitraryPrecisionFloatingPointINTEL: + return "ArbitraryPrecisionFloatingPointINTEL"; + case spv::Capability::UnstructuredLoopControlsINTEL: + return "UnstructuredLoopControlsINTEL"; + case spv::Capability::FPGALoopControlsINTEL: + return "FPGALoopControlsINTEL"; + case spv::Capability::KernelAttributesINTEL: + return "KernelAttributesINTEL"; + case spv::Capability::FPGAKernelAttributesINTEL: + return "FPGAKernelAttributesINTEL"; + case spv::Capability::FPGAMemoryAccessesINTEL: + return "FPGAMemoryAccessesINTEL"; + case spv::Capability::FPGAClusterAttributesINTEL: + return "FPGAClusterAttributesINTEL"; + case spv::Capability::LoopFuseINTEL: + return "LoopFuseINTEL"; + case spv::Capability::FPGADSPControlINTEL: + return "FPGADSPControlINTEL"; + case spv::Capability::MemoryAccessAliasingINTEL: + return "MemoryAccessAliasingINTEL"; + case spv::Capability::FPGAInvocationPipeliningAttributesINTEL: + return "FPGAInvocationPipeliningAttributesINTEL"; + case spv::Capability::FPGABufferLocationINTEL: + return "FPGABufferLocationINTEL"; + case spv::Capability::ArbitraryPrecisionFixedPointINTEL: + return "ArbitraryPrecisionFixedPointINTEL"; + case spv::Capability::USMStorageClassesINTEL: + return "USMStorageClassesINTEL"; + case spv::Capability::RuntimeAlignedAttributeINTEL: + return "RuntimeAlignedAttributeINTEL"; + case spv::Capability::IOPipesINTEL: + return "IOPipesINTEL"; + case spv::Capability::BlockingPipesINTEL: + return "BlockingPipesINTEL"; + case spv::Capability::FPGARegINTEL: + return "FPGARegINTEL"; + case spv::Capability::DotProductInputAll: + return "DotProductInputAll"; + case spv::Capability::DotProductInput4x8Bit: + return "DotProductInput4x8Bit"; + case spv::Capability::DotProductInput4x8BitPacked: + return "DotProductInput4x8BitPacked"; + case spv::Capability::DotProduct: + return "DotProduct"; + case spv::Capability::RayCullMaskKHR: + return "RayCullMaskKHR"; + case spv::Capability::CooperativeMatrixKHR: + return "CooperativeMatrixKHR"; + case spv::Capability::BitInstructions: + return "BitInstructions"; + case spv::Capability::GroupNonUniformRotateKHR: + return "GroupNonUniformRotateKHR"; + case spv::Capability::FloatControls2: + return "FloatControls2"; + case spv::Capability::AtomicFloat32AddEXT: + return "AtomicFloat32AddEXT"; + case spv::Capability::AtomicFloat64AddEXT: + return "AtomicFloat64AddEXT"; + case spv::Capability::LongCompositesINTEL: + return "LongCompositesINTEL"; + case spv::Capability::OptNoneINTEL: + return "OptNoneINTEL"; + case spv::Capability::AtomicFloat16AddEXT: + return "AtomicFloat16AddEXT"; + case spv::Capability::DebugInfoModuleINTEL: + return "DebugInfoModuleINTEL"; + case spv::Capability::BFloat16ConversionINTEL: + return "BFloat16ConversionINTEL"; + case spv::Capability::SplitBarrierINTEL: + return "SplitBarrierINTEL"; + case spv::Capability::FPGAClusterAttributesV2INTEL: + return "FPGAClusterAttributesV2INTEL"; + case spv::Capability::FPGAKernelAttributesv2INTEL: + return "FPGAKernelAttributesv2INTEL"; + case spv::Capability::FPMaxErrorINTEL: + return "FPMaxErrorINTEL"; + case spv::Capability::FPGALatencyControlINTEL: + return "FPGALatencyControlINTEL"; + case spv::Capability::FPGAArgumentInterfacesINTEL: + return "FPGAArgumentInterfacesINTEL"; + case spv::Capability::GlobalVariableHostAccessINTEL: + return "GlobalVariableHostAccessINTEL"; + case spv::Capability::GlobalVariableFPGADecorationsINTEL: + return "GlobalVariableFPGADecorationsINTEL"; + case spv::Capability::GroupUniformArithmeticKHR: + return "GroupUniformArithmeticKHR"; + case spv::Capability::MaskedGatherScatterINTEL: + return "MaskedGatherScatterINTEL"; + case spv::Capability::CacheControlsINTEL: + return "CacheControlsINTEL"; + case spv::Capability::RegisterLimitsINTEL: + return "RegisterLimitsINTEL"; + case spv::Capability::Max: + assert(0 && "Attempting to convert spv::Capability::Max to string"); + return ""; + } + + return ""; +} \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/ext_inst.cpp b/thirdparty/glslang/External/spirv-tools/source/ext_inst.cpp new file mode 100644 index 000000000000..4e2795453f40 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/ext_inst.cpp @@ -0,0 +1,209 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/ext_inst.h" + +#include + +// DebugInfo extended instruction set. +// See https://www.khronos.org/registry/spir-v/specs/1.0/DebugInfo.html +// TODO(dneto): DebugInfo.h should probably move to SPIRV-Headers. +#include "DebugInfo.h" + +#include "source/latest_version_glsl_std_450_header.h" +#include "source/latest_version_opencl_std_header.h" +#include "source/macro.h" +#include "source/spirv_definition.h" + +#include "debuginfo.insts.inc" +#include "glsl.std.450.insts.inc" +#include "nonsemantic.clspvreflection.insts.inc" +#include "nonsemantic.shader.debuginfo.100.insts.inc" +#include "opencl.debuginfo.100.insts.inc" +#include "opencl.std.insts.inc" + +#include "spirv-tools/libspirv.h" +#include "spv-amd-gcn-shader.insts.inc" +#include "spv-amd-shader-ballot.insts.inc" +#include "spv-amd-shader-explicit-vertex-parameter.insts.inc" +#include "spv-amd-shader-trinary-minmax.insts.inc" + +static const spv_ext_inst_group_t kGroups_1_0[] = { + {SPV_EXT_INST_TYPE_GLSL_STD_450, ARRAY_SIZE(glsl_entries), glsl_entries}, + {SPV_EXT_INST_TYPE_OPENCL_STD, ARRAY_SIZE(opencl_entries), opencl_entries}, + {SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER, + ARRAY_SIZE(spv_amd_shader_explicit_vertex_parameter_entries), + spv_amd_shader_explicit_vertex_parameter_entries}, + {SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX, + ARRAY_SIZE(spv_amd_shader_trinary_minmax_entries), + spv_amd_shader_trinary_minmax_entries}, + {SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER, + ARRAY_SIZE(spv_amd_gcn_shader_entries), spv_amd_gcn_shader_entries}, + {SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT, + ARRAY_SIZE(spv_amd_shader_ballot_entries), spv_amd_shader_ballot_entries}, + {SPV_EXT_INST_TYPE_DEBUGINFO, ARRAY_SIZE(debuginfo_entries), + debuginfo_entries}, + {SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100, + ARRAY_SIZE(opencl_debuginfo_100_entries), opencl_debuginfo_100_entries}, + {SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100, + ARRAY_SIZE(nonsemantic_shader_debuginfo_100_entries), + nonsemantic_shader_debuginfo_100_entries}, + {SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION, + ARRAY_SIZE(nonsemantic_clspvreflection_entries), + nonsemantic_clspvreflection_entries}, +}; + +static const spv_ext_inst_table_t kTable_1_0 = {ARRAY_SIZE(kGroups_1_0), + kGroups_1_0}; + +spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable, + spv_target_env env) { + if (!pExtInstTable) return SPV_ERROR_INVALID_POINTER; + + switch (env) { + // The extended instruction sets are all version 1.0 so far. + case SPV_ENV_UNIVERSAL_1_0: + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_UNIVERSAL_1_1: + case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_OPENCL_1_2: + case SPV_ENV_OPENCL_EMBEDDED_1_2: + case SPV_ENV_OPENCL_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_0: + case SPV_ENV_OPENCL_2_1: + case SPV_ENV_OPENCL_EMBEDDED_2_1: + case SPV_ENV_OPENCL_2_2: + case SPV_ENV_OPENCL_EMBEDDED_2_2: + case SPV_ENV_OPENGL_4_0: + case SPV_ENV_OPENGL_4_1: + case SPV_ENV_OPENGL_4_2: + case SPV_ENV_OPENGL_4_3: + case SPV_ENV_OPENGL_4_5: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + case SPV_ENV_UNIVERSAL_1_4: + case SPV_ENV_UNIVERSAL_1_5: + case SPV_ENV_VULKAN_1_2: + case SPV_ENV_UNIVERSAL_1_6: + case SPV_ENV_VULKAN_1_3: + *pExtInstTable = &kTable_1_0; + return SPV_SUCCESS; + default: + return SPV_ERROR_INVALID_TABLE; + } +} + +spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) { + // The names are specified by the respective extension instruction + // specifications. + if (!strcmp("GLSL.std.450", name)) { + return SPV_EXT_INST_TYPE_GLSL_STD_450; + } + if (!strcmp("OpenCL.std", name)) { + return SPV_EXT_INST_TYPE_OPENCL_STD; + } + if (!strcmp("SPV_AMD_shader_explicit_vertex_parameter", name)) { + return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER; + } + if (!strcmp("SPV_AMD_shader_trinary_minmax", name)) { + return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX; + } + if (!strcmp("SPV_AMD_gcn_shader", name)) { + return SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER; + } + if (!strcmp("SPV_AMD_shader_ballot", name)) { + return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT; + } + if (!strcmp("DebugInfo", name)) { + return SPV_EXT_INST_TYPE_DEBUGINFO; + } + if (!strcmp("OpenCL.DebugInfo.100", name)) { + return SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100; + } + if (!strcmp("NonSemantic.Shader.DebugInfo.100", name)) { + return SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100; + } + if (!strncmp("NonSemantic.ClspvReflection.", name, 28)) { + return SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION; + } + // ensure to add any known non-semantic extended instruction sets + // above this point, and update spvExtInstIsNonSemantic() + if (!strncmp("NonSemantic.", name, 12)) { + return SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN; + } + return SPV_EXT_INST_TYPE_NONE; +} + +bool spvExtInstIsNonSemantic(const spv_ext_inst_type_t type) { + if (type == SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN || + type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 || + type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) { + return true; + } + return false; +} + +bool spvExtInstIsDebugInfo(const spv_ext_inst_type_t type) { + if (type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 || + type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 || + type == SPV_EXT_INST_TYPE_DEBUGINFO) { + return true; + } + return false; +} + +spv_result_t spvExtInstTableNameLookup(const spv_ext_inst_table table, + const spv_ext_inst_type_t type, + const char* name, + spv_ext_inst_desc* pEntry) { + if (!table) return SPV_ERROR_INVALID_TABLE; + if (!pEntry) return SPV_ERROR_INVALID_POINTER; + + for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) { + const auto& group = table->groups[groupIndex]; + if (type != group.type) continue; + for (uint32_t index = 0; index < group.count; index++) { + const auto& entry = group.entries[index]; + if (!strcmp(name, entry.name)) { + *pEntry = &entry; + return SPV_SUCCESS; + } + } + } + + return SPV_ERROR_INVALID_LOOKUP; +} + +spv_result_t spvExtInstTableValueLookup(const spv_ext_inst_table table, + const spv_ext_inst_type_t type, + const uint32_t value, + spv_ext_inst_desc* pEntry) { + if (!table) return SPV_ERROR_INVALID_TABLE; + if (!pEntry) return SPV_ERROR_INVALID_POINTER; + + for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) { + const auto& group = table->groups[groupIndex]; + if (type != group.type) continue; + for (uint32_t index = 0; index < group.count; index++) { + const auto& entry = group.entries[index]; + if (value == entry.ext_inst) { + *pEntry = &entry; + return SPV_SUCCESS; + } + } + } + + return SPV_ERROR_INVALID_LOOKUP; +} diff --git a/thirdparty/glslang/External/spirv-tools/source/ext_inst.h b/thirdparty/glslang/External/spirv-tools/source/ext_inst.h new file mode 100644 index 000000000000..4027f4c3c817 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/ext_inst.h @@ -0,0 +1,46 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_EXT_INST_H_ +#define SOURCE_EXT_INST_H_ + +#include "source/table.h" +#include "spirv-tools/libspirv.h" + +// Gets the type of the extended instruction set with the specified name. +spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name); + +// Returns true if the extended instruction set is non-semantic +bool spvExtInstIsNonSemantic(const spv_ext_inst_type_t type); + +// Returns true if the extended instruction set is debug info +bool spvExtInstIsDebugInfo(const spv_ext_inst_type_t type); + +// Finds the named extended instruction of the given type in the given extended +// instruction table. On success, returns SPV_SUCCESS and writes a handle of +// the instruction entry into *entry. +spv_result_t spvExtInstTableNameLookup(const spv_ext_inst_table table, + const spv_ext_inst_type_t type, + const char* name, + spv_ext_inst_desc* entry); + +// Finds the extended instruction of the given type in the given extended +// instruction table by value. On success, returns SPV_SUCCESS and writes a +// handle of the instruction entry into *entry. +spv_result_t spvExtInstTableValueLookup(const spv_ext_inst_table table, + const spv_ext_inst_type_t type, + const uint32_t value, + spv_ext_inst_desc* pEntry); + +#endif // SOURCE_EXT_INST_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/extension_enum.inc b/thirdparty/glslang/External/spirv-tools/source/extension_enum.inc new file mode 100644 index 000000000000..63e8e5568b70 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/extension_enum.inc @@ -0,0 +1,131 @@ +kSPV_AMDX_shader_enqueue, +kSPV_AMD_gcn_shader, +kSPV_AMD_gpu_shader_half_float, +kSPV_AMD_gpu_shader_half_float_fetch, +kSPV_AMD_gpu_shader_int16, +kSPV_AMD_shader_ballot, +kSPV_AMD_shader_early_and_late_fragment_tests, +kSPV_AMD_shader_explicit_vertex_parameter, +kSPV_AMD_shader_fragment_mask, +kSPV_AMD_shader_image_load_store_lod, +kSPV_AMD_shader_trinary_minmax, +kSPV_AMD_texture_gather_bias_lod, +kSPV_ARM_core_builtins, +kSPV_EXT_demote_to_helper_invocation, +kSPV_EXT_descriptor_indexing, +kSPV_EXT_fragment_fully_covered, +kSPV_EXT_fragment_invocation_density, +kSPV_EXT_fragment_shader_interlock, +kSPV_EXT_mesh_shader, +kSPV_EXT_opacity_micromap, +kSPV_EXT_physical_storage_buffer, +kSPV_EXT_shader_atomic_float16_add, +kSPV_EXT_shader_atomic_float_add, +kSPV_EXT_shader_atomic_float_min_max, +kSPV_EXT_shader_image_int64, +kSPV_EXT_shader_stencil_export, +kSPV_EXT_shader_tile_image, +kSPV_EXT_shader_viewport_index_layer, +kSPV_GOOGLE_decorate_string, +kSPV_GOOGLE_hlsl_functionality1, +kSPV_GOOGLE_user_type, +kSPV_INTEL_arbitrary_precision_fixed_point, +kSPV_INTEL_arbitrary_precision_floating_point, +kSPV_INTEL_arbitrary_precision_integers, +kSPV_INTEL_bfloat16_conversion, +kSPV_INTEL_blocking_pipes, +kSPV_INTEL_cache_controls, +kSPV_INTEL_debug_module, +kSPV_INTEL_device_side_avc_motion_estimation, +kSPV_INTEL_float_controls2, +kSPV_INTEL_fp_fast_math_mode, +kSPV_INTEL_fp_max_error, +kSPV_INTEL_fpga_argument_interfaces, +kSPV_INTEL_fpga_buffer_location, +kSPV_INTEL_fpga_cluster_attributes, +kSPV_INTEL_fpga_dsp_control, +kSPV_INTEL_fpga_invocation_pipelining_attributes, +kSPV_INTEL_fpga_latency_control, +kSPV_INTEL_fpga_loop_controls, +kSPV_INTEL_fpga_memory_accesses, +kSPV_INTEL_fpga_memory_attributes, +kSPV_INTEL_fpga_reg, +kSPV_INTEL_function_pointers, +kSPV_INTEL_global_variable_fpga_decorations, +kSPV_INTEL_global_variable_host_access, +kSPV_INTEL_inline_assembly, +kSPV_INTEL_io_pipes, +kSPV_INTEL_kernel_attributes, +kSPV_INTEL_long_composites, +kSPV_INTEL_loop_fuse, +kSPV_INTEL_masked_gather_scatter, +kSPV_INTEL_maximum_registers, +kSPV_INTEL_media_block_io, +kSPV_INTEL_memory_access_aliasing, +kSPV_INTEL_optnone, +kSPV_INTEL_runtime_aligned, +kSPV_INTEL_shader_integer_functions2, +kSPV_INTEL_split_barrier, +kSPV_INTEL_subgroups, +kSPV_INTEL_unstructured_loop_controls, +kSPV_INTEL_usm_storage_classes, +kSPV_INTEL_variable_length_array, +kSPV_INTEL_vector_compute, +kSPV_KHR_16bit_storage, +kSPV_KHR_8bit_storage, +kSPV_KHR_bit_instructions, +kSPV_KHR_cooperative_matrix, +kSPV_KHR_device_group, +kSPV_KHR_expect_assume, +kSPV_KHR_float_controls, +kSPV_KHR_float_controls2, +kSPV_KHR_fragment_shader_barycentric, +kSPV_KHR_fragment_shading_rate, +kSPV_KHR_integer_dot_product, +kSPV_KHR_linkonce_odr, +kSPV_KHR_maximal_reconvergence, +kSPV_KHR_multiview, +kSPV_KHR_no_integer_wrap_decoration, +kSPV_KHR_non_semantic_info, +kSPV_KHR_physical_storage_buffer, +kSPV_KHR_post_depth_coverage, +kSPV_KHR_quad_control, +kSPV_KHR_ray_cull_mask, +kSPV_KHR_ray_query, +kSPV_KHR_ray_tracing, +kSPV_KHR_ray_tracing_position_fetch, +kSPV_KHR_shader_atomic_counter_ops, +kSPV_KHR_shader_ballot, +kSPV_KHR_shader_clock, +kSPV_KHR_shader_draw_parameters, +kSPV_KHR_storage_buffer_storage_class, +kSPV_KHR_subgroup_rotate, +kSPV_KHR_subgroup_uniform_control_flow, +kSPV_KHR_subgroup_vote, +kSPV_KHR_terminate_invocation, +kSPV_KHR_uniform_group_instructions, +kSPV_KHR_variable_pointers, +kSPV_KHR_vulkan_memory_model, +kSPV_KHR_workgroup_memory_explicit_layout, +kSPV_NVX_multiview_per_view_attributes, +kSPV_NV_bindless_texture, +kSPV_NV_compute_shader_derivatives, +kSPV_NV_cooperative_matrix, +kSPV_NV_displacement_micromap, +kSPV_NV_fragment_shader_barycentric, +kSPV_NV_geometry_shader_passthrough, +kSPV_NV_mesh_shader, +kSPV_NV_ray_tracing, +kSPV_NV_ray_tracing_motion_blur, +kSPV_NV_sample_mask_override_coverage, +kSPV_NV_shader_atomic_fp16_vector, +kSPV_NV_shader_image_footprint, +kSPV_NV_shader_invocation_reorder, +kSPV_NV_shader_sm_builtins, +kSPV_NV_shader_subgroup_partitioned, +kSPV_NV_shading_rate, +kSPV_NV_stereo_view_rendering, +kSPV_NV_viewport_array2, +kSPV_QCOM_image_processing, +kSPV_QCOM_image_processing2, +kSPV_VALIDATOR_ignore_type_decl_unique \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/extensions.cpp b/thirdparty/glslang/External/spirv-tools/source/extensions.cpp new file mode 100644 index 000000000000..ac987fcc0e47 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/extensions.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/extensions.h" + +#include +#include +#include + +#include "source/binary.h" +#include "source/enum_string_mapping.h" + +namespace spvtools { + +std::string GetExtensionString(const spv_parsed_instruction_t* inst) { + if (inst->opcode != static_cast(spv::Op::OpExtension)) { + return "ERROR_not_op_extension"; + } + + assert(inst->num_operands == 1); + + const auto& operand = inst->operands[0]; + assert(operand.type == SPV_OPERAND_TYPE_LITERAL_STRING); + assert(inst->num_words > operand.offset); + (void)operand; /* No unused variables in release builds. */ + + return spvDecodeLiteralStringOperand(*inst, 0); +} + +std::string ExtensionSetToString(const ExtensionSet& extensions) { + std::stringstream ss; + for (auto extension : extensions) { + ss << ExtensionToString(extension) << " "; + } + return ss.str(); +} + +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/extensions.h b/thirdparty/glslang/External/spirv-tools/source/extensions.h new file mode 100644 index 000000000000..cda4924a47d8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/extensions.h @@ -0,0 +1,41 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_EXTENSIONS_H_ +#define SOURCE_EXTENSIONS_H_ + +#include +#include + +#include "source/enum_set.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { + +// The known SPIR-V extensions. +enum Extension : uint32_t { +#include "extension_enum.inc" +}; + +using ExtensionSet = EnumSet; + +// Returns literal string operand of OpExtension instruction. +std::string GetExtensionString(const spv_parsed_instruction_t* inst); + +// Returns text string listing |extensions| separated by whitespace. +std::string ExtensionSetToString(const ExtensionSet& extensions); + +} // namespace spvtools + +#endif // SOURCE_EXTENSIONS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/generators.inc b/thirdparty/glslang/External/spirv-tools/source/generators.inc new file mode 100644 index 000000000000..34f120f8d678 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/generators.inc @@ -0,0 +1,42 @@ +{0, "Khronos", "", "Khronos"}, +{1, "LunarG", "", "LunarG"}, +{2, "Valve", "", "Valve"}, +{3, "Codeplay", "", "Codeplay"}, +{4, "NVIDIA", "", "NVIDIA"}, +{5, "ARM", "", "ARM"}, +{6, "Khronos", "LLVM/SPIR-V Translator", "Khronos LLVM/SPIR-V Translator"}, +{7, "Khronos", "SPIR-V Tools Assembler", "Khronos SPIR-V Tools Assembler"}, +{8, "Khronos", "Glslang Reference Front End", "Khronos Glslang Reference Front End"}, +{9, "Qualcomm", "", "Qualcomm"}, +{10, "AMD", "", "AMD"}, +{11, "Intel", "", "Intel"}, +{12, "Imagination", "", "Imagination"}, +{13, "Google", "Shaderc over Glslang", "Google Shaderc over Glslang"}, +{14, "Google", "spiregg", "Google spiregg"}, +{15, "Google", "rspirv", "Google rspirv"}, +{16, "X-LEGEND", "Mesa-IR/SPIR-V Translator", "X-LEGEND Mesa-IR/SPIR-V Translator"}, +{17, "Khronos", "SPIR-V Tools Linker", "Khronos SPIR-V Tools Linker"}, +{18, "Wine", "VKD3D Shader Compiler", "Wine VKD3D Shader Compiler"}, +{19, "Tellusim", "Clay Shader Compiler", "Tellusim Clay Shader Compiler"}, +{20, "W3C WebGPU Group", "WHLSL Shader Translator", "W3C WebGPU Group WHLSL Shader Translator"}, +{21, "Google", "Clspv", "Google Clspv"}, +{22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"}, +{23, "Google", "Tint Compiler", "Google Tint Compiler"}, +{24, "Google", "ANGLE Shader Compiler", "Google ANGLE Shader Compiler"}, +{25, "Netease Games", "Messiah Shader Compiler", "Netease Games Messiah Shader Compiler"}, +{26, "Xenia", "Xenia Emulator Microcode Translator", "Xenia Xenia Emulator Microcode Translator"}, +{27, "Embark Studios", "Rust GPU Compiler Backend", "Embark Studios Rust GPU Compiler Backend"}, +{28, "gfx-rs community", "Naga", "gfx-rs community Naga"}, +{29, "Mikkosoft Productions", "MSP Shader Compiler", "Mikkosoft Productions MSP Shader Compiler"}, +{30, "SpvGenTwo community", "SpvGenTwo SPIR-V IR Tools", "SpvGenTwo community SpvGenTwo SPIR-V IR Tools"}, +{31, "Google", "Skia SkSL", "Google Skia SkSL"}, +{32, "TornadoVM", "Beehive SPIRV Toolkit", "TornadoVM Beehive SPIRV Toolkit"}, +{33, "DragonJoker", "ShaderWriter", "DragonJoker ShaderWriter"}, +{34, "Rayan Hatout", "SPIRVSmith", "Rayan Hatout SPIRVSmith"}, +{35, "Saarland University", "Shady", "Saarland University Shady"}, +{36, "Taichi Graphics", "Taichi", "Taichi Graphics Taichi"}, +{37, "heroseh", "Hero C Compiler", "heroseh Hero C Compiler"}, +{38, "Meta", "SparkSL", "Meta SparkSL"}, +{39, "SirLynix", "Nazara ShaderLang Compiler", "SirLynix Nazara ShaderLang Compiler"}, +{40, "NVIDIA", "Slang Compiler", "NVIDIA Slang Compiler"}, +{41, "Zig Software Foundation", "Zig Compiler", "Zig Software Foundation Zig Compiler"}, \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/glsl.std.450.insts.inc b/thirdparty/glslang/External/spirv-tools/source/glsl.std.450.insts.inc new file mode 100644 index 000000000000..89fe94805812 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/glsl.std.450.insts.inc @@ -0,0 +1,86 @@ +static const spv::Capability pygen_variable_caps_Float64[] = {spv::Capability::Float64}; +static const spv::Capability pygen_variable_caps_InterpolationFunction[] = {spv::Capability::InterpolationFunction}; + +static const spv_ext_inst_desc_t glsl_entries[] = { + {"Round", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"RoundEven", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Trunc", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FAbs", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SAbs", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FSign", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SSign", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Floor", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Ceil", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Fract", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Radians", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Degrees", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Sin", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Cos", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Tan", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Asin", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Acos", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Atan", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Sinh", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Cosh", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Tanh", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Asinh", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Acosh", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Atanh", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Atan2", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Pow", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Exp", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Log", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Exp2", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Log2", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Sqrt", 31, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"InverseSqrt", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Determinant", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"MatrixInverse", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Modf", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ModfStruct", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMin", 37, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMin", 38, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMin", 39, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMax", 40, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMax", 41, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMax", 42, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FClamp", 43, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UClamp", 44, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SClamp", 45, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMix", 46, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"IMix", 47, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Step", 48, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SmoothStep", 49, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Fma", 50, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Frexp", 51, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FrexpStruct", 52, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Ldexp", 53, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackSnorm4x8", 54, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackUnorm4x8", 55, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackSnorm2x16", 56, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackUnorm2x16", 57, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackHalf2x16", 58, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PackDouble2x32", 59, 1, pygen_variable_caps_Float64, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackSnorm2x16", 60, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackUnorm2x16", 61, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackHalf2x16", 62, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackSnorm4x8", 63, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackUnorm4x8", 64, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UnpackDouble2x32", 65, 1, pygen_variable_caps_Float64, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Length", 66, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Distance", 67, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Cross", 68, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Normalize", 69, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FaceForward", 70, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Reflect", 71, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"Refract", 72, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FindILsb", 73, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FindSMsb", 74, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FindUMsb", 75, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"InterpolateAtCentroid", 76, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"InterpolateAtSample", 77, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"InterpolateAtOffset", 78, 1, pygen_variable_caps_InterpolationFunction, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"NMin", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"NMax", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"NClamp", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/instruction.h b/thirdparty/glslang/External/spirv-tools/source/instruction.h new file mode 100644 index 000000000000..2acbb5729f40 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/instruction.h @@ -0,0 +1,49 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_INSTRUCTION_H_ +#define SOURCE_INSTRUCTION_H_ + +#include +#include + +#include "source/latest_version_spirv_header.h" +#include "spirv-tools/libspirv.h" + +// Describes an instruction. +struct spv_instruction_t { + // Normally, both opcode and extInstType contain valid data. + // However, when the assembler parses ! as the first word in + // an instruction and opcode and extInstType are invalid. + spv::Op opcode; + spv_ext_inst_type_t extInstType; + + // The Id of the result type, if this instruction has one. Zero otherwise. + uint32_t resultTypeId; + + // The instruction, as a sequence of 32-bit words. + // For a regular instruction the opcode and word count are combined + // in words[0], as described in the SPIR-V spec. + // Otherwise, the first token was !, and that number appears + // in words[0]. Subsequent elements are the result of parsing + // tokens in the alternate parsing mode as described in syntax.md. + std::vector words; +}; + +// Appends a word to an instruction, without checking for overflow. +inline void spvInstructionAddWord(spv_instruction_t* inst, uint32_t value) { + inst->words.push_back(value); +} + +#endif // SOURCE_INSTRUCTION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/latest_version_glsl_std_450_header.h b/thirdparty/glslang/External/spirv-tools/source/latest_version_glsl_std_450_header.h new file mode 100644 index 000000000000..bed1f2502eee --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/latest_version_glsl_std_450_header.h @@ -0,0 +1,20 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_LATEST_VERSION_GLSL_STD_450_HEADER_H_ +#define SOURCE_LATEST_VERSION_GLSL_STD_450_HEADER_H_ + +#include "spirv/unified1/GLSL.std.450.h" + +#endif // SOURCE_LATEST_VERSION_GLSL_STD_450_HEADER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/latest_version_opencl_std_header.h b/thirdparty/glslang/External/spirv-tools/source/latest_version_opencl_std_header.h new file mode 100644 index 000000000000..90ff9c033608 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/latest_version_opencl_std_header.h @@ -0,0 +1,20 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_LATEST_VERSION_OPENCL_STD_HEADER_H_ +#define SOURCE_LATEST_VERSION_OPENCL_STD_HEADER_H_ + +#include "spirv/unified1/OpenCL.std.h" + +#endif // SOURCE_LATEST_VERSION_OPENCL_STD_HEADER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/latest_version_spirv_header.h b/thirdparty/glslang/External/spirv-tools/source/latest_version_spirv_header.h new file mode 100644 index 000000000000..f6ab5c8453fb --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/latest_version_spirv_header.h @@ -0,0 +1,20 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ +#define SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ + +#include "spirv/unified1/spirv.hpp11" + +#endif // SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/libspirv.cpp b/thirdparty/glslang/External/spirv-tools/source/libspirv.cpp new file mode 100644 index 000000000000..83e8629b7023 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/libspirv.cpp @@ -0,0 +1,171 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "spirv-tools/libspirv.hpp" + +#include +#include +#include +#include +#include + +#include "source/table.h" + +namespace spvtools { + +Context::Context(spv_target_env env) : context_(spvContextCreate(env)) {} + +Context::Context(Context&& other) : context_(other.context_) { + other.context_ = nullptr; +} + +Context& Context::operator=(Context&& other) { + spvContextDestroy(context_); + context_ = other.context_; + other.context_ = nullptr; + + return *this; +} + +Context::~Context() { spvContextDestroy(context_); } + +void Context::SetMessageConsumer(MessageConsumer consumer) { + SetContextMessageConsumer(context_, std::move(consumer)); +} + +spv_context& Context::CContext() { return context_; } + +const spv_context& Context::CContext() const { return context_; } + +// Structs for holding the data members for SpvTools. +struct SpirvTools::Impl { + explicit Impl(spv_target_env env) : context(spvContextCreate(env)) { + // The default consumer in spv_context_t is a null consumer, which provides + // equivalent functionality (from the user's perspective) as a real consumer + // does nothing. + } + ~Impl() { spvContextDestroy(context); } + + spv_context context; // C interface context object. +}; + +SpirvTools::SpirvTools(spv_target_env env) : impl_(new Impl(env)) { + assert(env != SPV_ENV_WEBGPU_0); +} + +SpirvTools::~SpirvTools() {} + +void SpirvTools::SetMessageConsumer(MessageConsumer consumer) { + SetContextMessageConsumer(impl_->context, std::move(consumer)); +} + +bool SpirvTools::Assemble(const std::string& text, + std::vector* binary, + uint32_t options) const { + return Assemble(text.data(), text.size(), binary, options); +} + +bool SpirvTools::Assemble(const char* text, const size_t text_size, + std::vector* binary, + uint32_t options) const { + spv_binary spvbinary = nullptr; + spv_result_t status = spvTextToBinaryWithOptions( + impl_->context, text, text_size, options, &spvbinary, nullptr); + if (status == SPV_SUCCESS) { + binary->assign(spvbinary->code, spvbinary->code + spvbinary->wordCount); + } + spvBinaryDestroy(spvbinary); + return status == SPV_SUCCESS; +} + +bool SpirvTools::Disassemble(const std::vector& binary, + std::string* text, uint32_t options) const { + return Disassemble(binary.data(), binary.size(), text, options); +} + +bool SpirvTools::Disassemble(const uint32_t* binary, const size_t binary_size, + std::string* text, uint32_t options) const { + spv_text spvtext = nullptr; + spv_result_t status = spvBinaryToText(impl_->context, binary, binary_size, + options, &spvtext, nullptr); + if (status == SPV_SUCCESS && + (options & SPV_BINARY_TO_TEXT_OPTION_PRINT) == 0) { + assert(spvtext); + text->assign(spvtext->str, spvtext->str + spvtext->length); + } + spvTextDestroy(spvtext); + return status == SPV_SUCCESS; +} + +struct CxxParserContext { + const HeaderParser& header_parser; + const InstructionParser& instruction_parser; +}; + +bool SpirvTools::Parse(const std::vector& binary, + const HeaderParser& header_parser, + const InstructionParser& instruction_parser, + spv_diagnostic* diagnostic) { + CxxParserContext parser_context = {header_parser, instruction_parser}; + + spv_parsed_header_fn_t header_fn_wrapper = + [](void* user_data, spv_endianness_t endianness, uint32_t magic, + uint32_t version, uint32_t generator, uint32_t id_bound, + uint32_t reserved) { + CxxParserContext* ctx = reinterpret_cast(user_data); + spv_parsed_header_t header = {magic, version, generator, id_bound, + reserved}; + + return ctx->header_parser(endianness, header); + }; + + spv_parsed_instruction_fn_t instruction_fn_wrapper = + [](void* user_data, const spv_parsed_instruction_t* instruction) { + CxxParserContext* ctx = reinterpret_cast(user_data); + return ctx->instruction_parser(*instruction); + }; + + spv_result_t status = spvBinaryParse( + impl_->context, &parser_context, binary.data(), binary.size(), + header_fn_wrapper, instruction_fn_wrapper, diagnostic); + return status == SPV_SUCCESS; +} + +bool SpirvTools::Validate(const std::vector& binary) const { + return Validate(binary.data(), binary.size()); +} + +bool SpirvTools::Validate(const uint32_t* binary, + const size_t binary_size) const { + return spvValidateBinary(impl_->context, binary, binary_size, nullptr) == + SPV_SUCCESS; +} + +bool SpirvTools::Validate(const uint32_t* binary, const size_t binary_size, + spv_validator_options options) const { + spv_const_binary_t the_binary{binary, binary_size}; + spv_diagnostic diagnostic = nullptr; + bool valid = spvValidateWithOptions(impl_->context, options, &the_binary, + &diagnostic) == SPV_SUCCESS; + if (!valid && impl_->context->consumer) { + impl_->context->consumer.operator()( + SPV_MSG_ERROR, nullptr, diagnostic->position, diagnostic->error); + } + spvDiagnosticDestroy(diagnostic); + return valid; +} + +bool SpirvTools::IsValid() const { return impl_->context != nullptr; } + +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/macro.h b/thirdparty/glslang/External/spirv-tools/source/macro.h new file mode 100644 index 000000000000..7219ffed1f4d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/macro.h @@ -0,0 +1,25 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_MACRO_H_ +#define SOURCE_MACRO_H_ + +// Evaluates to the number of elements of array A. +// +// If we could use constexpr, then we could make this a template function. +// If the source arrays were std::array, then we could have used +// std::array::size. +#define ARRAY_SIZE(A) (static_cast(sizeof(A) / sizeof(A[0]))) + +#endif // SOURCE_MACRO_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/name_mapper.cpp b/thirdparty/glslang/External/spirv-tools/source/name_mapper.cpp new file mode 100644 index 000000000000..b2d0f4452588 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/name_mapper.cpp @@ -0,0 +1,331 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/name_mapper.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "source/binary.h" +#include "source/latest_version_spirv_header.h" +#include "source/parsed_operand.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace { + +// Converts a uint32_t to its string decimal representation. +std::string to_string(uint32_t id) { + // Use stringstream, since some versions of Android compilers lack + // std::to_string. + std::stringstream os; + os << id; + return os.str(); +} + +} // anonymous namespace + +NameMapper GetTrivialNameMapper() { return to_string; } + +FriendlyNameMapper::FriendlyNameMapper(const spv_const_context context, + const uint32_t* code, + const size_t wordCount) + : grammar_(AssemblyGrammar(context)) { + spv_diagnostic diag = nullptr; + // We don't care if the parse fails. + spvBinaryParse(context, this, code, wordCount, nullptr, + ParseInstructionForwarder, &diag); + spvDiagnosticDestroy(diag); +} + +std::string FriendlyNameMapper::NameForId(uint32_t id) { + auto iter = name_for_id_.find(id); + if (iter == name_for_id_.end()) { + // It must have been an invalid module, so just return a trivial mapping. + // We don't care about uniqueness. + return to_string(id); + } else { + return iter->second; + } +} + +std::string FriendlyNameMapper::Sanitize(const std::string& suggested_name) { + if (suggested_name.empty()) return "_"; + // Otherwise, replace invalid characters by '_'. + std::string result; + std::string valid = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "_0123456789"; + std::transform(suggested_name.begin(), suggested_name.end(), + std::back_inserter(result), [&valid](const char c) { + return (std::string::npos == valid.find(c)) ? '_' : c; + }); + return result; +} + +void FriendlyNameMapper::SaveName(uint32_t id, + const std::string& suggested_name) { + if (name_for_id_.find(id) != name_for_id_.end()) return; + + const std::string sanitized_suggested_name = Sanitize(suggested_name); + std::string name = sanitized_suggested_name; + auto inserted = used_names_.insert(name); + if (!inserted.second) { + const std::string base_name = sanitized_suggested_name + "_"; + for (uint32_t index = 0; !inserted.second; ++index) { + name = base_name + to_string(index); + inserted = used_names_.insert(name); + } + } + name_for_id_[id] = name; +} + +void FriendlyNameMapper::SaveBuiltInName(uint32_t target_id, + uint32_t built_in) { +#define GLCASE(name) \ + case spv::BuiltIn::name: \ + SaveName(target_id, "gl_" #name); \ + return; +#define GLCASE2(name, suggested) \ + case spv::BuiltIn::name: \ + SaveName(target_id, "gl_" #suggested); \ + return; +#define CASE(name) \ + case spv::BuiltIn::name: \ + SaveName(target_id, #name); \ + return; + switch (spv::BuiltIn(built_in)) { + GLCASE(Position) + GLCASE(PointSize) + GLCASE(ClipDistance) + GLCASE(CullDistance) + GLCASE2(VertexId, VertexID) + GLCASE2(InstanceId, InstanceID) + GLCASE2(PrimitiveId, PrimitiveID) + GLCASE2(InvocationId, InvocationID) + GLCASE(Layer) + GLCASE(ViewportIndex) + GLCASE(TessLevelOuter) + GLCASE(TessLevelInner) + GLCASE(TessCoord) + GLCASE(PatchVertices) + GLCASE(FragCoord) + GLCASE(PointCoord) + GLCASE(FrontFacing) + GLCASE2(SampleId, SampleID) + GLCASE(SamplePosition) + GLCASE(SampleMask) + GLCASE(FragDepth) + GLCASE(HelperInvocation) + GLCASE2(NumWorkgroups, NumWorkGroups) + GLCASE2(WorkgroupSize, WorkGroupSize) + GLCASE2(WorkgroupId, WorkGroupID) + GLCASE2(LocalInvocationId, LocalInvocationID) + GLCASE2(GlobalInvocationId, GlobalInvocationID) + GLCASE(LocalInvocationIndex) + CASE(WorkDim) + CASE(GlobalSize) + CASE(EnqueuedWorkgroupSize) + CASE(GlobalOffset) + CASE(GlobalLinearId) + CASE(SubgroupSize) + CASE(SubgroupMaxSize) + CASE(NumSubgroups) + CASE(NumEnqueuedSubgroups) + CASE(SubgroupId) + CASE(SubgroupLocalInvocationId) + GLCASE(VertexIndex) + GLCASE(InstanceIndex) + GLCASE(BaseInstance) + CASE(SubgroupEqMaskKHR) + CASE(SubgroupGeMaskKHR) + CASE(SubgroupGtMaskKHR) + CASE(SubgroupLeMaskKHR) + CASE(SubgroupLtMaskKHR) + default: + break; + } +#undef GLCASE +#undef GLCASE2 +#undef CASE +} + +spv_result_t FriendlyNameMapper::ParseInstruction( + const spv_parsed_instruction_t& inst) { + const auto result_id = inst.result_id; + switch (spv::Op(inst.opcode)) { + case spv::Op::OpName: + SaveName(inst.words[1], spvDecodeLiteralStringOperand(inst, 1)); + break; + case spv::Op::OpDecorate: + // Decorations come after OpName. So OpName will take precedence over + // decorations. + // + // In theory, we should also handle OpGroupDecorate. But that's unlikely + // to occur. + if (spv::Decoration(inst.words[2]) == spv::Decoration::BuiltIn) { + assert(inst.num_words > 3); + SaveBuiltInName(inst.words[1], inst.words[3]); + } + break; + case spv::Op::OpTypeVoid: + SaveName(result_id, "void"); + break; + case spv::Op::OpTypeBool: + SaveName(result_id, "bool"); + break; + case spv::Op::OpTypeInt: { + std::string signedness; + std::string root; + const auto bit_width = inst.words[2]; + switch (bit_width) { + case 8: + root = "char"; + break; + case 16: + root = "short"; + break; + case 32: + root = "int"; + break; + case 64: + root = "long"; + break; + default: + root = to_string(bit_width); + signedness = "i"; + break; + } + if (0 == inst.words[3]) signedness = "u"; + SaveName(result_id, signedness + root); + } break; + case spv::Op::OpTypeFloat: { + const auto bit_width = inst.words[2]; + switch (bit_width) { + case 16: + SaveName(result_id, "half"); + break; + case 32: + SaveName(result_id, "float"); + break; + case 64: + SaveName(result_id, "double"); + break; + default: + SaveName(result_id, std::string("fp") + to_string(bit_width)); + break; + } + } break; + case spv::Op::OpTypeVector: + SaveName(result_id, std::string("v") + to_string(inst.words[3]) + + NameForId(inst.words[2])); + break; + case spv::Op::OpTypeMatrix: + SaveName(result_id, std::string("mat") + to_string(inst.words[3]) + + NameForId(inst.words[2])); + break; + case spv::Op::OpTypeArray: + SaveName(result_id, std::string("_arr_") + NameForId(inst.words[2]) + + "_" + NameForId(inst.words[3])); + break; + case spv::Op::OpTypeRuntimeArray: + SaveName(result_id, + std::string("_runtimearr_") + NameForId(inst.words[2])); + break; + case spv::Op::OpTypePointer: + SaveName(result_id, std::string("_ptr_") + + NameForEnumOperand(SPV_OPERAND_TYPE_STORAGE_CLASS, + inst.words[2]) + + "_" + NameForId(inst.words[3])); + break; + case spv::Op::OpTypePipe: + SaveName(result_id, + std::string("Pipe") + + NameForEnumOperand(SPV_OPERAND_TYPE_ACCESS_QUALIFIER, + inst.words[2])); + break; + case spv::Op::OpTypeEvent: + SaveName(result_id, "Event"); + break; + case spv::Op::OpTypeDeviceEvent: + SaveName(result_id, "DeviceEvent"); + break; + case spv::Op::OpTypeReserveId: + SaveName(result_id, "ReserveId"); + break; + case spv::Op::OpTypeQueue: + SaveName(result_id, "Queue"); + break; + case spv::Op::OpTypeOpaque: + SaveName(result_id, std::string("Opaque_") + + Sanitize(spvDecodeLiteralStringOperand(inst, 1))); + break; + case spv::Op::OpTypePipeStorage: + SaveName(result_id, "PipeStorage"); + break; + case spv::Op::OpTypeNamedBarrier: + SaveName(result_id, "NamedBarrier"); + break; + case spv::Op::OpTypeStruct: + // Structs are mapped rather simplisitically. Just indicate that they + // are a struct and then give the raw Id number. + SaveName(result_id, std::string("_struct_") + to_string(result_id)); + break; + case spv::Op::OpConstantTrue: + SaveName(result_id, "true"); + break; + case spv::Op::OpConstantFalse: + SaveName(result_id, "false"); + break; + case spv::Op::OpConstant: { + std::ostringstream value; + EmitNumericLiteral(&value, inst, inst.operands[2]); + auto value_str = value.str(); + // Use 'n' to signify negative. Other invalid characters will be mapped + // to underscore. + for (auto& c : value_str) + if (c == '-') c = 'n'; + SaveName(result_id, NameForId(inst.type_id) + "_" + value_str); + } break; + default: + // If this instruction otherwise defines an Id, then save a mapping for + // it. This is needed to ensure uniqueness in there is an OpName with + // string something like "1" that might collide with this result_id. + // We should only do this if a name hasn't already been registered by some + // previous forward reference. + if (result_id && name_for_id_.find(result_id) == name_for_id_.end()) + SaveName(result_id, to_string(result_id)); + break; + } + return SPV_SUCCESS; +} + +std::string FriendlyNameMapper::NameForEnumOperand(spv_operand_type_t type, + uint32_t word) { + spv_operand_desc desc = nullptr; + if (SPV_SUCCESS == grammar_.lookupOperand(type, word, &desc)) { + return desc->name; + } else { + // Invalid input. Just give something. + return std::string("StorageClass") + to_string(word); + } +} + +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/name_mapper.h b/thirdparty/glslang/External/spirv-tools/source/name_mapper.h new file mode 100644 index 000000000000..6902141b1987 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/name_mapper.h @@ -0,0 +1,122 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_NAME_MAPPER_H_ +#define SOURCE_NAME_MAPPER_H_ + +#include +#include +#include +#include + +#include "source/assembly_grammar.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { + +// A NameMapper maps SPIR-V Id values to names. Each name is valid to use in +// SPIR-V assembly. The mapping is one-to-one, i.e. no two Ids map to the same +// name. +using NameMapper = std::function; + +// Returns a NameMapper which always maps an Id to its decimal representation. +NameMapper GetTrivialNameMapper(); + +// A FriendlyNameMapper parses a module upon construction. If the parse is +// successful, then the NameForId method maps an Id to a friendly name +// while also satisfying the constraints on a NameMapper. +// +// The mapping is friendly in the following sense: +// - If an Id has a debug name (via OpName), then that will be used when +// possible. +// - Well known scalar types map to friendly names. For example, +// OpTypeVoid should be %void. Scalar types map to their names in OpenCL +// when +// there is a correspondence, and otherwise as follows: +// - unsigned integer type of n bits map to "u" followed by n +// - signed integer type of n bits map to "i" followed by n +// - floating point type of n bits map to "fp" followed by n +// - Vector type names map to "v" followed by the number of components, +// followed by the friendly name for the base type. +// - Matrix type names map to "mat" followed by the number of columns, +// followed by the friendly name for the base vector type. +// - Pointer types map to "_ptr_", then the name of the storage class, then the +// name for the pointee type. +// - Exotic types like event, pipe, opaque, queue, reserve-id map to their own +// human readable names. +// - A struct type maps to "_struct_" followed by the raw Id number. That's +// pretty simplistic, but workable. +// - A built-in variable maps to its GLSL variable name. +// - Numeric literals in OpConstant map to a human-friendly name. +class FriendlyNameMapper { + public: + // Construct a friendly name mapper, and determine friendly names for each + // defined Id in the specified module. The module is specified by the code + // wordCount, and should be parseable in the specified context. + FriendlyNameMapper(const spv_const_context context, const uint32_t* code, + const size_t wordCount); + + // Returns a NameMapper which maps ids to the friendly names parsed from the + // module provided to the constructor. + NameMapper GetNameMapper() { + return [this](uint32_t id) { return this->NameForId(id); }; + } + + // Returns the friendly name for the given id. If the module parsed during + // construction is valid, then the mapping satisfies the rules for a + // NameMapper. + std::string NameForId(uint32_t id); + + private: + // Transforms the given string so that it is acceptable as an Id name in + // assembly language. Two distinct inputs can map to the same output. + std::string Sanitize(const std::string& suggested_name); + + // Records a name for the given id. If this id already has a name, then + // this is a no-op. If the id doesn't have a name, use the given + // suggested_name if it hasn't already been taken, and otherwise generate + // a new (unused) name based on the suggested name. + void SaveName(uint32_t id, const std::string& suggested_name); + + // Records a built-in variable name for target_id. If target_id already + // has a name then this is a no-op. + void SaveBuiltInName(uint32_t target_id, uint32_t built_in); + + // Collects information from the given parsed instruction to populate + // name_for_id_. Returns SPV_SUCCESS; + spv_result_t ParseInstruction(const spv_parsed_instruction_t& inst); + + // Forwards a parsed-instruction callback from the binary parser into the + // FriendlyNameMapper hidden inside the user_data parameter. + static spv_result_t ParseInstructionForwarder( + void* user_data, const spv_parsed_instruction_t* parsed_instruction) { + return reinterpret_cast(user_data)->ParseInstruction( + *parsed_instruction); + } + + // Returns the friendly name for an enumerant. + std::string NameForEnumOperand(spv_operand_type_t type, uint32_t word); + + // Maps an id to its friendly name. This will have an entry for each Id + // defined in the module. + std::unordered_map name_for_id_; + // The set of names that have a mapping in name_for_id_; + std::unordered_set used_names_; + // The assembly grammar for the current context. + const AssemblyGrammar grammar_; +}; + +} // namespace spvtools + +#endif // SOURCE_NAME_MAPPER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/nonsemantic.clspvreflection.insts.inc b/thirdparty/glslang/External/spirv-tools/source/nonsemantic.clspvreflection.insts.inc new file mode 100644 index 000000000000..4ed11a6db683 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/nonsemantic.clspvreflection.insts.inc @@ -0,0 +1,45 @@ + + +static const spv_ext_inst_desc_t nonsemantic_clspvreflection_entries[] = { + {"Kernel", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentInfo", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentStorageBuffer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentUniform", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentPodStorageBuffer", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentPodUniform", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentPodPushConstant", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentSampledImage", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentStorageImage", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentSampler", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentWorkgroup", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"SpecConstantWorkgroupSize", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SpecConstantGlobalOffset", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SpecConstantWorkDim", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantGlobalOffset", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantEnqueuedLocalSize", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantGlobalSize", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantRegionOffset", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantNumWorkgroups", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstantRegionGroupOffset", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ConstantDataStorageBuffer", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ConstantDataUniform", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"LiteralSampler", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PropertyRequiredWorkgroupSize", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SpecConstantSubgroupMaxSize", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentPointerPushConstant", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentPointerUniform", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ProgramScopeVariablesStorageBuffer", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ProgramScopeVariablePointerRelocation", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ImageArgumentInfoChannelOrderPushConstant", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ImageArgumentInfoChannelDataTypePushConstant", 31, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ImageArgumentInfoChannelOrderUniform", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ImageArgumentInfoChannelDataTypeUniform", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentStorageTexelBuffer", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ArgumentUniformTexelBuffer", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"ConstantDataPointerPushConstant", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ProgramScopeVariablePointerPushConstant", 37, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PrintfInfo", 38, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PrintfBufferStorageBuffer", 39, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PrintfBufferPointerPushConstant", 40, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"NormalizedSamplerMaskPushConstant", 41, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/nonsemantic.shader.debuginfo.100.insts.inc b/thirdparty/glslang/External/spirv-tools/source/nonsemantic.shader.debuginfo.100.insts.inc new file mode 100644 index 000000000000..27ce78fa94fe --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/nonsemantic.shader.debuginfo.100.insts.inc @@ -0,0 +1,48 @@ + + +static const spv_ext_inst_desc_t nonsemantic_shader_debuginfo_100_entries[] = { + {"DebugInfoNone", 0, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugCompilationUnit", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeBasic", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypedef", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeEnum", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeComposite", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeMember", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameter", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugGlobalVariable", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunctionDeclaration", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunction", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLocalVariable", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugImportedEntity", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugSource", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunctionDefinition", 101, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugSourceContinued", 102, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLine", 103, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugNoLine", 104, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugBuildIdentifier", 105, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugStoragePath", 106, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugEntryPoint", 107, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeMatrix", 108, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/opcode.cpp b/thirdparty/glslang/External/spirv-tools/source/opcode.cpp new file mode 100644 index 000000000000..38d1a1be6e49 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opcode.cpp @@ -0,0 +1,778 @@ +// Copyright (c) 2015-2022 The Khronos Group Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opcode.h" + +#include +#include + +#include +#include + +#include "source/instruction.h" +#include "source/macro.h" +#include "source/spirv_constant.h" +#include "source/spirv_endian.h" +#include "source/spirv_target_env.h" +#include "spirv-tools/libspirv.h" + +namespace { +struct OpcodeDescPtrLen { + const spv_opcode_desc_t* ptr; + uint32_t len; +}; + +#include "core.insts-unified1.inc" + +static const spv_opcode_table_t kOpcodeTable = {ARRAY_SIZE(kOpcodeTableEntries), + kOpcodeTableEntries}; + +// Represents a vendor tool entry in the SPIR-V XML Registry. +struct VendorTool { + uint32_t value; + const char* vendor; + const char* tool; // Might be empty string. + const char* vendor_tool; // Combination of vendor and tool. +}; + +const VendorTool vendor_tools[] = { +#include "generators.inc" +}; + +} // anonymous namespace + +// TODO(dneto): Move this to another file. It doesn't belong with opcode +// processing. +const char* spvGeneratorStr(uint32_t generator) { + auto where = std::find_if( + std::begin(vendor_tools), std::end(vendor_tools), + [generator](const VendorTool& vt) { return generator == vt.value; }); + if (where != std::end(vendor_tools)) return where->vendor_tool; + return "Unknown"; +} + +uint32_t spvOpcodeMake(uint16_t wordCount, spv::Op opcode) { + return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16); +} + +void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount, + uint16_t* pOpcode) { + if (pWordCount) { + *pWordCount = (uint16_t)((0xffff0000 & word) >> 16); + } + if (pOpcode) { + *pOpcode = 0x0000ffff & word; + } +} + +spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable, spv_target_env) { + if (!pInstTable) return SPV_ERROR_INVALID_POINTER; + + // Descriptions of each opcode. Each entry describes the format of the + // instruction that follows a particular opcode. + + *pInstTable = &kOpcodeTable; + return SPV_SUCCESS; +} + +spv_result_t spvOpcodeTableNameLookup(spv_target_env env, + const spv_opcode_table table, + const char* name, + spv_opcode_desc* pEntry) { + if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER; + if (!table) return SPV_ERROR_INVALID_TABLE; + + // TODO: This lookup of the Opcode table is suboptimal! Binary sort would be + // preferable but the table requires sorting on the Opcode name, but it's + // static const initialized and matches the order of the spec. + const size_t nameLength = strlen(name); + const auto version = spvVersionForTargetEnv(env); + for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) { + const spv_opcode_desc_t& entry = table->entries[opcodeIndex]; + // We considers the current opcode as available as long as + // 1. The target environment satisfies the minimal requirement of the + // opcode; or + // 2. There is at least one extension enabling this opcode. + // + // Note that the second rule assumes the extension enabling this instruction + // is indeed requested in the SPIR-V code; checking that should be + // validator's work. + if (((version >= entry.minVersion && version <= entry.lastVersion) || + entry.numExtensions > 0u || entry.numCapabilities > 0u) && + nameLength == strlen(entry.name) && + !strncmp(name, entry.name, nameLength)) { + // NOTE: Found out Opcode! + *pEntry = &entry; + return SPV_SUCCESS; + } + } + + return SPV_ERROR_INVALID_LOOKUP; +} + +spv_result_t spvOpcodeTableValueLookup(spv_target_env env, + const spv_opcode_table table, + const spv::Op opcode, + spv_opcode_desc* pEntry) { + if (!table) return SPV_ERROR_INVALID_TABLE; + if (!pEntry) return SPV_ERROR_INVALID_POINTER; + + const auto beg = table->entries; + const auto end = table->entries + table->count; + + spv_opcode_desc_t needle = {"", opcode, 0, nullptr, 0, {}, + false, false, 0, nullptr, ~0u, ~0u}; + + auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) { + return lhs.opcode < rhs.opcode; + }; + + // We need to loop here because there can exist multiple symbols for the same + // opcode value, and they can be introduced in different target environments, + // which means they can have different minimal version requirements. + // Assumes the underlying table is already sorted ascendingly according to + // opcode value. + const auto version = spvVersionForTargetEnv(env); + for (auto it = std::lower_bound(beg, end, needle, comp); + it != end && it->opcode == opcode; ++it) { + // We considers the current opcode as available as long as + // 1. The target environment satisfies the minimal requirement of the + // opcode; or + // 2. There is at least one extension enabling this opcode. + // + // Note that the second rule assumes the extension enabling this instruction + // is indeed requested in the SPIR-V code; checking that should be + // validator's work. + if ((version >= it->minVersion && version <= it->lastVersion) || + it->numExtensions > 0u || it->numCapabilities > 0u) { + *pEntry = it; + return SPV_SUCCESS; + } + } + + return SPV_ERROR_INVALID_LOOKUP; +} + +void spvInstructionCopy(const uint32_t* words, const spv::Op opcode, + const uint16_t wordCount, const spv_endianness_t endian, + spv_instruction_t* pInst) { + pInst->opcode = opcode; + pInst->words.resize(wordCount); + for (uint16_t wordIndex = 0; wordIndex < wordCount; ++wordIndex) { + pInst->words[wordIndex] = spvFixWord(words[wordIndex], endian); + if (!wordIndex) { + uint16_t thisWordCount; + uint16_t thisOpcode; + spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode); + assert(opcode == static_cast(thisOpcode) && + wordCount == thisWordCount && "Endianness failed!"); + } + } +} + +const char* spvOpcodeString(const uint32_t opcode) { + const auto beg = kOpcodeTableEntries; + const auto end = kOpcodeTableEntries + ARRAY_SIZE(kOpcodeTableEntries); + spv_opcode_desc_t needle = {"", static_cast(opcode), + 0, nullptr, + 0, {}, + false, false, + 0, nullptr, + ~0u, ~0u}; + auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) { + return lhs.opcode < rhs.opcode; + }; + auto it = std::lower_bound(beg, end, needle, comp); + if (it != end && it->opcode == spv::Op(opcode)) { + return it->name; + } + + assert(0 && "Unreachable!"); + return "unknown"; +} + +const char* spvOpcodeString(const spv::Op opcode) { + return spvOpcodeString(static_cast(opcode)); +} + +int32_t spvOpcodeIsScalarType(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeBool: + return true; + default: + return false; + } +} + +int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstant: + case spv::Op::OpSpecConstantComposite: + case spv::Op::OpSpecConstantOp: + return true; + default: + return false; + } +} + +int32_t spvOpcodeIsConstant(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: + case spv::Op::OpConstant: + case spv::Op::OpConstantComposite: + case spv::Op::OpConstantSampler: + case spv::Op::OpConstantNull: + case spv::Op::OpConstantFunctionPointerINTEL: + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstant: + case spv::Op::OpSpecConstantComposite: + case spv::Op::OpSpecConstantOp: + return true; + default: + return false; + } +} + +bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) { + return opcode == spv::Op::OpUndef || spvOpcodeIsConstant(opcode); +} + +bool spvOpcodeIsScalarSpecConstant(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstant: + return true; + default: + return false; + } +} + +int32_t spvOpcodeIsComposite(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeStruct: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + return true; + default: + return false; + } +} + +bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpVariable: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpFunctionParameter: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpCopyObject: + case spv::Op::OpSelect: + case spv::Op::OpPhi: + case spv::Op::OpFunctionCall: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpLoad: + case spv::Op::OpConstantNull: + return true; + default: + return false; + } +} + +int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpVariable: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpFunctionParameter: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpCopyObject: + return true; + default: + return false; + } +} + +int32_t spvOpcodeGeneratesType(spv::Op op) { + switch (op) { + case spv::Op::OpTypeVoid: + case spv::Op::OpTypeBool: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeStruct: + case spv::Op::OpTypeOpaque: + case spv::Op::OpTypePointer: + case spv::Op::OpTypeFunction: + case spv::Op::OpTypeEvent: + case spv::Op::OpTypeDeviceEvent: + case spv::Op::OpTypeReserveId: + case spv::Op::OpTypeQueue: + case spv::Op::OpTypePipe: + case spv::Op::OpTypePipeStorage: + case spv::Op::OpTypeNamedBarrier: + case spv::Op::OpTypeAccelerationStructureNV: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + // case spv::Op::OpTypeAccelerationStructureKHR: covered by + // spv::Op::OpTypeAccelerationStructureNV + case spv::Op::OpTypeRayQueryKHR: + case spv::Op::OpTypeHitObjectNV: + return true; + default: + // In particular, OpTypeForwardPointer does not generate a type, + // but declares a storage class for a pointer type generated + // by a different instruction. + break; + } + return 0; +} + +bool spvOpcodeIsDecoration(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpMemberDecorate: + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorateStringGOOGLE: + return true; + default: + break; + } + return false; +} + +bool spvOpcodeIsLoad(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpLoad: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageFetch: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpImageSparseRead: + return true; + default: + return false; + } +} + +bool spvOpcodeIsBranch(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpBranch: + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: + return true; + default: + return false; + } +} + +bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicExchange: + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicFMinEXT: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicFMaxEXT: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + case spv::Op::OpAtomicFlagTestAndSet: + return true; + default: + return false; + } +} + +bool spvOpcodeIsAtomicOp(const spv::Op opcode) { + return (spvOpcodeIsAtomicWithLoad(opcode) || + opcode == spv::Op::OpAtomicStore || + opcode == spv::Op::OpAtomicFlagClear); +} + +bool spvOpcodeIsReturn(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpReturn: + case spv::Op::OpReturnValue: + return true; + default: + return false; + } +} + +bool spvOpcodeIsAbort(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpKill: + case spv::Op::OpUnreachable: + case spv::Op::OpTerminateInvocation: + case spv::Op::OpTerminateRayKHR: + case spv::Op::OpIgnoreIntersectionKHR: + case spv::Op::OpEmitMeshTasksEXT: + return true; + default: + return false; + } +} + +bool spvOpcodeIsReturnOrAbort(spv::Op opcode) { + return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode); +} + +bool spvOpcodeIsBlockTerminator(spv::Op opcode) { + return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode); +} + +bool spvOpcodeIsBaseOpaqueType(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeOpaque: + case spv::Op::OpTypeEvent: + case spv::Op::OpTypeDeviceEvent: + case spv::Op::OpTypeReserveId: + case spv::Op::OpTypeQueue: + case spv::Op::OpTypePipe: + case spv::Op::OpTypeForwardPointer: + case spv::Op::OpTypePipeStorage: + case spv::Op::OpTypeNamedBarrier: + return true; + default: + return false; + } +} + +bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpGroupNonUniformElect: + case spv::Op::OpGroupNonUniformAll: + case spv::Op::OpGroupNonUniformAny: + case spv::Op::OpGroupNonUniformAllEqual: + case spv::Op::OpGroupNonUniformBroadcast: + case spv::Op::OpGroupNonUniformBroadcastFirst: + case spv::Op::OpGroupNonUniformBallot: + case spv::Op::OpGroupNonUniformInverseBallot: + case spv::Op::OpGroupNonUniformBallotBitExtract: + case spv::Op::OpGroupNonUniformBallotBitCount: + case spv::Op::OpGroupNonUniformBallotFindLSB: + case spv::Op::OpGroupNonUniformBallotFindMSB: + case spv::Op::OpGroupNonUniformShuffle: + case spv::Op::OpGroupNonUniformShuffleXor: + case spv::Op::OpGroupNonUniformShuffleUp: + case spv::Op::OpGroupNonUniformShuffleDown: + case spv::Op::OpGroupNonUniformIAdd: + case spv::Op::OpGroupNonUniformFAdd: + case spv::Op::OpGroupNonUniformIMul: + case spv::Op::OpGroupNonUniformFMul: + case spv::Op::OpGroupNonUniformSMin: + case spv::Op::OpGroupNonUniformUMin: + case spv::Op::OpGroupNonUniformFMin: + case spv::Op::OpGroupNonUniformSMax: + case spv::Op::OpGroupNonUniformUMax: + case spv::Op::OpGroupNonUniformFMax: + case spv::Op::OpGroupNonUniformBitwiseAnd: + case spv::Op::OpGroupNonUniformBitwiseOr: + case spv::Op::OpGroupNonUniformBitwiseXor: + case spv::Op::OpGroupNonUniformLogicalAnd: + case spv::Op::OpGroupNonUniformLogicalOr: + case spv::Op::OpGroupNonUniformLogicalXor: + case spv::Op::OpGroupNonUniformQuadBroadcast: + case spv::Op::OpGroupNonUniformQuadSwap: + case spv::Op::OpGroupNonUniformRotateKHR: + case spv::Op::OpGroupNonUniformQuadAllKHR: + case spv::Op::OpGroupNonUniformQuadAnyKHR: + return true; + default: + return false; + } +} + +bool spvOpcodeIsScalarizable(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpPhi: + case spv::Op::OpCopyObject: + case spv::Op::OpConvertFToU: + case spv::Op::OpConvertFToS: + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertUToF: + case spv::Op::OpUConvert: + case spv::Op::OpSConvert: + case spv::Op::OpFConvert: + case spv::Op::OpQuantizeToF16: + case spv::Op::OpVectorInsertDynamic: + case spv::Op::OpSNegate: + case spv::Op::OpFNegate: + case spv::Op::OpIAdd: + case spv::Op::OpFAdd: + case spv::Op::OpISub: + case spv::Op::OpFSub: + case spv::Op::OpIMul: + case spv::Op::OpFMul: + case spv::Op::OpUDiv: + case spv::Op::OpSDiv: + case spv::Op::OpFDiv: + case spv::Op::OpUMod: + case spv::Op::OpSRem: + case spv::Op::OpSMod: + case spv::Op::OpFRem: + case spv::Op::OpFMod: + case spv::Op::OpVectorTimesScalar: + case spv::Op::OpIAddCarry: + case spv::Op::OpISubBorrow: + case spv::Op::OpUMulExtended: + case spv::Op::OpSMulExtended: + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpNot: + case spv::Op::OpBitFieldInsert: + case spv::Op::OpBitFieldSExtract: + case spv::Op::OpBitFieldUExtract: + case spv::Op::OpBitReverse: + case spv::Op::OpBitCount: + case spv::Op::OpIsNan: + case spv::Op::OpIsInf: + case spv::Op::OpIsFinite: + case spv::Op::OpIsNormal: + case spv::Op::OpSignBitSet: + case spv::Op::OpLessOrGreater: + case spv::Op::OpOrdered: + case spv::Op::OpUnordered: + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpLogicalAnd: + case spv::Op::OpLogicalNot: + case spv::Op::OpSelect: + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpFOrdEqual: + case spv::Op::OpFUnordEqual: + case spv::Op::OpFOrdNotEqual: + case spv::Op::OpFUnordNotEqual: + case spv::Op::OpFOrdLessThan: + case spv::Op::OpFUnordLessThan: + case spv::Op::OpFOrdGreaterThan: + case spv::Op::OpFUnordGreaterThan: + case spv::Op::OpFOrdLessThanEqual: + case spv::Op::OpFUnordLessThanEqual: + case spv::Op::OpFOrdGreaterThanEqual: + case spv::Op::OpFUnordGreaterThanEqual: + return true; + default: + return false; + } +} + +bool spvOpcodeIsDebug(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpName: + case spv::Op::OpMemberName: + case spv::Op::OpSource: + case spv::Op::OpSourceContinued: + case spv::Op::OpSourceExtension: + case spv::Op::OpString: + case spv::Op::OpLine: + case spv::Op::OpNoLine: + case spv::Op::OpModuleProcessed: + return true; + default: + return false; + } +} + +bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpPtrEqual: + case spv::Op::OpPtrNotEqual: + case spv::Op::OpIAdd: + case spv::Op::OpFAdd: + case spv::Op::OpIMul: + case spv::Op::OpFMul: + case spv::Op::OpDot: + case spv::Op::OpIAddCarry: + case spv::Op::OpUMulExtended: + case spv::Op::OpSMulExtended: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpOrdered: + case spv::Op::OpUnordered: + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpLogicalAnd: + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpFOrdEqual: + case spv::Op::OpFUnordEqual: + case spv::Op::OpFOrdNotEqual: + case spv::Op::OpFUnordNotEqual: + return true; + default: + return false; + } +} + +bool spvOpcodeIsLinearAlgebra(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpTranspose: + case spv::Op::OpVectorTimesScalar: + case spv::Op::OpMatrixTimesScalar: + case spv::Op::OpVectorTimesMatrix: + case spv::Op::OpMatrixTimesVector: + case spv::Op::OpMatrixTimesMatrix: + case spv::Op::OpOuterProduct: + case spv::Op::OpDot: + return true; + default: + return false; + } +} + +bool spvOpcodeIsImageSample(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + return true; + default: + return false; + } +} + +std::vector spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpMemoryBarrier: + return {1}; + case spv::Op::OpAtomicStore: + case spv::Op::OpControlBarrier: + case spv::Op::OpAtomicFlagClear: + case spv::Op::OpMemoryNamedBarrier: + return {2}; + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicExchange: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + case spv::Op::OpAtomicFlagTestAndSet: + return {4}; + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: + return {4, 5}; + default: + return {}; + } +} + +bool spvOpcodeIsAccessChain(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + return true; + default: + return false; + } +} + +bool spvOpcodeIsBit(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpNot: + case spv::Op::OpBitReverse: + case spv::Op::OpBitCount: + return true; + default: + return false; + } +} diff --git a/thirdparty/glslang/External/spirv-tools/source/opcode.h b/thirdparty/glslang/External/spirv-tools/source/opcode.h new file mode 100644 index 000000000000..217aeb2b6f20 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opcode.h @@ -0,0 +1,162 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPCODE_H_ +#define SOURCE_OPCODE_H_ + +#include "source/instruction.h" +#include "source/latest_version_spirv_header.h" +#include "source/table.h" +#include "spirv-tools/libspirv.h" + +// Returns the name of a registered SPIR-V generator as a null-terminated +// string. If the generator is not known, then returns the string "Unknown". +// The generator parameter should be most significant 16-bits of the generator +// word in the SPIR-V module header. +// +// See the registry at https://www.khronos.org/registry/spir-v/api/spir-v.xml. +const char* spvGeneratorStr(uint32_t generator); + +// Combines word_count and opcode enumerant in single word. +uint32_t spvOpcodeMake(uint16_t word_count, spv::Op opcode); + +// Splits word into into two constituent parts: word_count and opcode. +void spvOpcodeSplit(const uint32_t word, uint16_t* word_count, + uint16_t* opcode); + +// Finds the named opcode in the given opcode table. On success, returns +// SPV_SUCCESS and writes a handle of the table entry into *entry. +spv_result_t spvOpcodeTableNameLookup(spv_target_env, + const spv_opcode_table table, + const char* name, spv_opcode_desc* entry); + +// Finds the opcode by enumerant in the given opcode table. On success, returns +// SPV_SUCCESS and writes a handle of the table entry into *entry. +spv_result_t spvOpcodeTableValueLookup(spv_target_env, + const spv_opcode_table table, + const spv::Op opcode, + spv_opcode_desc* entry); + +// Copies an instruction's word and fixes the endianness to host native. The +// source instruction's stream/opcode/endianness is in the words/opcode/endian +// parameter. The word_count parameter specifies the number of words to copy. +// Writes copied instruction into *inst. +void spvInstructionCopy(const uint32_t* words, const spv::Op opcode, + const uint16_t word_count, + const spv_endianness_t endian, spv_instruction_t* inst); + +// Determine if the given opcode is a scalar type. Returns zero if false, +// non-zero otherwise. +int32_t spvOpcodeIsScalarType(const spv::Op opcode); + +// Determines if the given opcode is a specialization constant. Returns zero if +// false, non-zero otherwise. +int32_t spvOpcodeIsSpecConstant(const spv::Op opcode); + +// Determines if the given opcode is a constant. Returns zero if false, non-zero +// otherwise. +int32_t spvOpcodeIsConstant(const spv::Op opcode); + +// Returns true if the given opcode is a constant or undef. +bool spvOpcodeIsConstantOrUndef(const spv::Op opcode); + +// Returns true if the given opcode is a scalar specialization constant. +bool spvOpcodeIsScalarSpecConstant(const spv::Op opcode); + +// Determines if the given opcode is a composite type. Returns zero if false, +// non-zero otherwise. +int32_t spvOpcodeIsComposite(const spv::Op opcode); + +// Determines if the given opcode results in a pointer when using the logical +// addressing model. Returns zero if false, non-zero otherwise. +int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode); + +// Returns whether the given opcode could result in a pointer or a variable +// pointer when using the logical addressing model. +bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode); + +// Determines if the given opcode generates a type. Returns zero if false, +// non-zero otherwise. +int32_t spvOpcodeGeneratesType(spv::Op opcode); + +// Returns true if the opcode adds a decoration to an id. +bool spvOpcodeIsDecoration(const spv::Op opcode); + +// Returns true if the opcode is a load from memory into a result id. This +// function only considers core instructions. +bool spvOpcodeIsLoad(const spv::Op opcode); + +// Returns true if the opcode is an atomic operation that uses the original +// value. +bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode); + +// Returns true if the opcode is an atomic operation. +bool spvOpcodeIsAtomicOp(const spv::Op opcode); + +// Returns true if the given opcode is a branch instruction. +bool spvOpcodeIsBranch(spv::Op opcode); + +// Returns true if the given opcode is a return instruction. +bool spvOpcodeIsReturn(spv::Op opcode); + +// Returns true if the given opcode aborts execution. To abort means that after +// executing that instruction, no other instructions will be executed regardless +// of the context in which the instruction appears. Note that `OpUnreachable` +// is considered an abort even if its behaviour is undefined. +bool spvOpcodeIsAbort(spv::Op opcode); + +// Returns true if the given opcode is a return instruction or it aborts +// execution. +bool spvOpcodeIsReturnOrAbort(spv::Op opcode); + +// Returns true if the given opcode is a basic block terminator. +bool spvOpcodeIsBlockTerminator(spv::Op opcode); + +// Returns true if the given opcode always defines an opaque type. +bool spvOpcodeIsBaseOpaqueType(spv::Op opcode); + +// Returns true if the given opcode is a non-uniform group operation. +bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode); + +// Returns true if the opcode with vector inputs could be divided into a series +// of independent scalar operations that would give the same result. +bool spvOpcodeIsScalarizable(spv::Op opcode); + +// Returns true if the given opcode is a debug instruction. +bool spvOpcodeIsDebug(spv::Op opcode); + +// Returns true for opcodes that are binary operators, +// where the order of the operands is irrelevant. +bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode); + +// Returns true for opcodes that represent linear algebra instructions. +bool spvOpcodeIsLinearAlgebra(spv::Op opcode); + +// Returns true for opcodes that represent image sample instructions. +bool spvOpcodeIsImageSample(spv::Op opcode); + +// Returns a vector containing the indices of the memory semantics +// operands for |opcode|. +std::vector spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode); + +// Returns true for opcodes that represent access chain instructions. +bool spvOpcodeIsAccessChain(spv::Op opcode); + +// Returns true for opcodes that represent bit instructions. +bool spvOpcodeIsBit(spv::Op opcode); + +// Gets the name of an instruction, without the "Op" prefix. +const char* spvOpcodeString(const spv::Op opcode); + +#endif // SOURCE_OPCODE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opencl.debuginfo.100.insts.inc b/thirdparty/glslang/External/spirv-tools/source/opencl.debuginfo.100.insts.inc new file mode 100644 index 000000000000..389d9127e231 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opencl.debuginfo.100.insts.inc @@ -0,0 +1,41 @@ + + +static const spv_ext_inst_desc_t opencl_debuginfo_100_entries[] = { + {"DebugInfoNone", 0, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugCompilationUnit", 1, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SOURCE_LANGUAGE, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeBasic", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypedef", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeEnum", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeComposite", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeMember", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameter", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugGlobalVariable", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunctionDeclaration", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunction", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLocalVariable", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugImportedEntity", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugSource", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugModuleINTEL", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/opencl.std.insts.inc b/thirdparty/glslang/External/spirv-tools/source/opencl.std.insts.inc new file mode 100644 index 000000000000..cd0a9c37a52d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opencl.std.insts.inc @@ -0,0 +1,166 @@ + + +static const spv_ext_inst_desc_t opencl_entries[] = { + {"acos", 0, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"acosh", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"acospi", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"asin", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"asinh", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"asinpi", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atan", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atan2", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atanh", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atanpi", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"atan2pi", 10, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cbrt", 11, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ceil", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"copysign", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cos", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cosh", 15, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cospi", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"erfc", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"erf", 18, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"exp", 19, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"exp2", 20, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"exp10", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"expm1", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fabs", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fdim", 24, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"floor", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fma", 26, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmax", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmin", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmod", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fract", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"frexp", 31, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"hypot", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ilogb", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ldexp", 34, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"lgamma", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"lgamma_r", 36, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"log", 37, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"log2", 38, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"log10", 39, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"log1p", 40, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"logb", 41, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"mad", 42, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"maxmag", 43, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"minmag", 44, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"modf", 45, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"nan", 46, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"nextafter", 47, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"pow", 48, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"pown", 49, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"powr", 50, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"remainder", 51, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"remquo", 52, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"rint", 53, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"rootn", 54, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"round", 55, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"rsqrt", 56, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sin", 57, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sincos", 58, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sinh", 59, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sinpi", 60, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sqrt", 61, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"tan", 62, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"tanh", 63, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"tanpi", 64, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"tgamma", 65, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"trunc", 66, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_cos", 67, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_divide", 68, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_exp", 69, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_exp2", 70, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_exp10", 71, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_log", 72, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_log2", 73, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_log10", 74, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_powr", 75, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_recip", 76, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_rsqrt", 77, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_sin", 78, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_sqrt", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"half_tan", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_cos", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_divide", 82, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_exp", 83, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_exp2", 84, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_exp10", 85, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_log", 86, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_log2", 87, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_log10", 88, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_powr", 89, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_recip", 90, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_rsqrt", 91, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_sin", 92, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_sqrt", 93, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"native_tan", 94, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fclamp", 95, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"degrees", 96, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmax_common", 97, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fmin_common", 98, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"mix", 99, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"radians", 100, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"step", 101, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"smoothstep", 102, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"sign", 103, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"cross", 104, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"distance", 105, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"length", 106, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"normalize", 107, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fast_distance", 108, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fast_length", 109, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"fast_normalize", 110, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_abs", 141, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_abs_diff", 142, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_add_sat", 143, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_add_sat", 144, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_hadd", 145, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_hadd", 146, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_rhadd", 147, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_rhadd", 148, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_clamp", 149, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_clamp", 150, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"clz", 151, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"ctz", 152, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mad_hi", 153, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mad_sat", 154, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mad_sat", 155, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_max", 156, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_max", 157, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_min", 158, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_min", 159, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mul_hi", 160, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"rotate", 161, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_sub_sat", 162, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_sub_sat", 163, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_upsample", 164, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_upsample", 165, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"popcount", 166, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mad24", 167, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mad24", 168, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"s_mul24", 169, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mul24", 170, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vloadn", 171, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"vstoren", 172, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vload_half", 173, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vload_halfn", 174, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"vstore_half", 175, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vstore_half_r", 176, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}}, + {"vstore_halfn", 177, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vstore_halfn_r", 178, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}}, + {"vloada_halfn", 179, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"vstorea_halfn", 180, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"vstorea_halfn_r", 181, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_NONE}}, + {"shuffle", 182, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"shuffle2", 183, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"printf", 184, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"prefetch", 185, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"bitselect", 186, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"select", 187, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_abs", 201, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_abs_diff", 202, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mul_hi", 203, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"u_mad_hi", 204, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/operand.cpp b/thirdparty/glslang/External/spirv-tools/source/operand.cpp new file mode 100644 index 000000000000..6577f8f7db77 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/operand.cpp @@ -0,0 +1,614 @@ +// Copyright (c) 2015-2020 The Khronos Group Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/operand.h" + +#include +#include + +#include + +#include "DebugInfo.h" +#include "OpenCLDebugInfo100.h" +#include "source/macro.h" +#include "source/opcode.h" +#include "source/spirv_constant.h" + +// For now, assume unified1 contains up to SPIR-V 1.3 and no later +// SPIR-V version. +// TODO(dneto): Make one set of tables, but with version tags on a +// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195 + +#include "operand.kinds-unified1.inc" +#include "spirv-tools/libspirv.h" + +static const spv_operand_table_t kOperandTable = { + ARRAY_SIZE(pygen_variable_OperandInfoTable), + pygen_variable_OperandInfoTable}; + +spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable, + spv_target_env) { + if (!pOperandTable) return SPV_ERROR_INVALID_POINTER; + + *pOperandTable = &kOperandTable; + return SPV_SUCCESS; +} + +spv_result_t spvOperandTableNameLookup(spv_target_env, + const spv_operand_table table, + const spv_operand_type_t type, + const char* name, + const size_t nameLength, + spv_operand_desc* pEntry) { + if (!table) return SPV_ERROR_INVALID_TABLE; + if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER; + + for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) { + const auto& group = table->types[typeIndex]; + if (type != group.type) continue; + for (uint64_t index = 0; index < group.count; ++index) { + const auto& entry = group.entries[index]; + // We consider the current operand as available as long as + // it is in the grammar. It might not be *valid* to use, + // but that should be checked by the validator, not by parsing. + if (nameLength == strlen(entry.name) && + !strncmp(entry.name, name, nameLength)) { + *pEntry = &entry; + return SPV_SUCCESS; + } + } + } + + return SPV_ERROR_INVALID_LOOKUP; +} + +spv_result_t spvOperandTableValueLookup(spv_target_env, + const spv_operand_table table, + const spv_operand_type_t type, + const uint32_t value, + spv_operand_desc* pEntry) { + if (!table) return SPV_ERROR_INVALID_TABLE; + if (!pEntry) return SPV_ERROR_INVALID_POINTER; + + spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u, ~0u}; + + auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) { + return lhs.value < rhs.value; + }; + + for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) { + const auto& group = table->types[typeIndex]; + if (type != group.type) continue; + + const auto beg = group.entries; + const auto end = group.entries + group.count; + + // Assumes the underlying table is already sorted ascendingly according to + // opcode value. + auto it = std::lower_bound(beg, end, needle, comp); + if (it != end && it->value == value) { + // The current operand is considered available as long as + // it is in the grammar. It might not be *valid* to use, + // but that should be checked by the validator, not by parsing. + *pEntry = it; + return SPV_SUCCESS; + } + } + + return SPV_ERROR_INVALID_LOOKUP; +} + +const char* spvOperandTypeStr(spv_operand_type_t type) { + switch (type) { + case SPV_OPERAND_TYPE_ID: + case SPV_OPERAND_TYPE_OPTIONAL_ID: + return "ID"; + case SPV_OPERAND_TYPE_TYPE_ID: + return "type ID"; + case SPV_OPERAND_TYPE_RESULT_ID: + return "result ID"; + case SPV_OPERAND_TYPE_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER: + case SPV_OPERAND_TYPE_LITERAL_FLOAT: + return "literal number"; + case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: + return "possibly multi-word literal integer"; + case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: + return "possibly multi-word literal number"; + case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: + return "extension instruction number"; + case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: + return "OpSpecConstantOp opcode"; + case SPV_OPERAND_TYPE_LITERAL_STRING: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: + return "literal string"; + case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: + return "source language"; + case SPV_OPERAND_TYPE_EXECUTION_MODEL: + return "execution model"; + case SPV_OPERAND_TYPE_ADDRESSING_MODEL: + return "addressing model"; + case SPV_OPERAND_TYPE_MEMORY_MODEL: + return "memory model"; + case SPV_OPERAND_TYPE_EXECUTION_MODE: + return "execution mode"; + case SPV_OPERAND_TYPE_STORAGE_CLASS: + return "storage class"; + case SPV_OPERAND_TYPE_DIMENSIONALITY: + return "dimensionality"; + case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE: + return "sampler addressing mode"; + case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE: + return "sampler filter mode"; + case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT: + return "image format"; + case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE: + return "floating-point fast math mode"; + case SPV_OPERAND_TYPE_FP_ROUNDING_MODE: + return "floating-point rounding mode"; + case SPV_OPERAND_TYPE_LINKAGE_TYPE: + return "linkage type"; + case SPV_OPERAND_TYPE_ACCESS_QUALIFIER: + case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER: + return "access qualifier"; + case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE: + return "function parameter attribute"; + case SPV_OPERAND_TYPE_DECORATION: + return "decoration"; + case SPV_OPERAND_TYPE_BUILT_IN: + return "built-in"; + case SPV_OPERAND_TYPE_SELECTION_CONTROL: + return "selection control"; + case SPV_OPERAND_TYPE_LOOP_CONTROL: + return "loop control"; + case SPV_OPERAND_TYPE_FUNCTION_CONTROL: + return "function control"; + case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: + return "memory semantics ID"; + case SPV_OPERAND_TYPE_MEMORY_ACCESS: + case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: + return "memory access"; + case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE: + return "shading rate"; + case SPV_OPERAND_TYPE_SCOPE_ID: + return "scope ID"; + case SPV_OPERAND_TYPE_GROUP_OPERATION: + return "group operation"; + case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS: + return "kernel enqeue flags"; + case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO: + return "kernel profiling info"; + case SPV_OPERAND_TYPE_CAPABILITY: + return "capability"; + case SPV_OPERAND_TYPE_RAY_FLAGS: + return "ray flags"; + case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION: + return "ray query intersection"; + case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE: + return "ray query committed intersection type"; + case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE: + return "ray query candidate intersection type"; + case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT: + case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: + return "packed vector format"; + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: + case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: + return "cooperative matrix operands"; + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT: + return "cooperative matrix layout"; + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE: + return "cooperative matrix use"; + case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER: + return "initialization mode qualifier"; + case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER: + return "host access qualifier"; + case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL: + return "load cache control"; + case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL: + return "store cache control"; + case SPV_OPERAND_TYPE_IMAGE: + case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: + return "image"; + case SPV_OPERAND_TYPE_OPTIONAL_CIV: + return "context-insensitive value"; + case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: + return "debug info flags"; + case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + return "debug base type encoding"; + case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE: + return "debug composite type"; + case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER: + return "debug type qualifier"; + case SPV_OPERAND_TYPE_DEBUG_OPERATION: + return "debug operation"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: + return "OpenCL.DebugInfo.100 debug info flags"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + return "OpenCL.DebugInfo.100 debug base type encoding"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE: + return "OpenCL.DebugInfo.100 debug composite type"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER: + return "OpenCL.DebugInfo.100 debug type qualifier"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION: + return "OpenCL.DebugInfo.100 debug operation"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: + return "OpenCL.DebugInfo.100 debug imported entity"; + + // The next values are for values returned from an instruction, not actually + // an operand. So the specific strings don't matter. But let's add them + // for completeness and ease of testing. + case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER: + return "image channel order"; + case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE: + return "image channel data type"; + + case SPV_OPERAND_TYPE_FPDENORM_MODE: + return "FP denorm mode"; + case SPV_OPERAND_TYPE_FPOPERATION_MODE: + return "FP operation mode"; + case SPV_OPERAND_TYPE_QUANTIZATION_MODES: + return "quantization mode"; + case SPV_OPERAND_TYPE_OVERFLOW_MODES: + return "overflow mode"; + + case SPV_OPERAND_TYPE_NONE: + return "NONE"; + default: + break; + } + return "unknown"; +} + +void spvPushOperandTypes(const spv_operand_type_t* types, + spv_operand_pattern_t* pattern) { + const spv_operand_type_t* endTypes; + for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) { + } + + while (endTypes-- != types) { + pattern->push_back(*endTypes); + } +} + +void spvPushOperandTypesForMask(spv_target_env env, + const spv_operand_table operandTable, + const spv_operand_type_t type, + const uint32_t mask, + spv_operand_pattern_t* pattern) { + // Scan from highest bits to lowest bits because we will append in LIFO + // fashion, and we need the operands for lower order bits to be consumed first + for (uint32_t candidate_bit = (1u << 31u); candidate_bit; + candidate_bit >>= 1) { + if (candidate_bit & mask) { + spv_operand_desc entry = nullptr; + if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type, + candidate_bit, &entry)) { + spvPushOperandTypes(entry->operandTypes, pattern); + } + } + } +} + +bool spvOperandIsConcrete(spv_operand_type_t type) { + if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) { + return true; + } + switch (type) { + case SPV_OPERAND_TYPE_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_LITERAL_FLOAT: + case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: + case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: + case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: + case SPV_OPERAND_TYPE_LITERAL_STRING: + case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: + case SPV_OPERAND_TYPE_EXECUTION_MODEL: + case SPV_OPERAND_TYPE_ADDRESSING_MODEL: + case SPV_OPERAND_TYPE_MEMORY_MODEL: + case SPV_OPERAND_TYPE_EXECUTION_MODE: + case SPV_OPERAND_TYPE_STORAGE_CLASS: + case SPV_OPERAND_TYPE_DIMENSIONALITY: + case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE: + case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE: + case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT: + case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER: + case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE: + case SPV_OPERAND_TYPE_FP_ROUNDING_MODE: + case SPV_OPERAND_TYPE_LINKAGE_TYPE: + case SPV_OPERAND_TYPE_ACCESS_QUALIFIER: + case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE: + case SPV_OPERAND_TYPE_DECORATION: + case SPV_OPERAND_TYPE_BUILT_IN: + case SPV_OPERAND_TYPE_GROUP_OPERATION: + case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS: + case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO: + case SPV_OPERAND_TYPE_CAPABILITY: + case SPV_OPERAND_TYPE_RAY_FLAGS: + case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION: + case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE: + case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE: + case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: + case SPV_OPERAND_TYPE_FPDENORM_MODE: + case SPV_OPERAND_TYPE_FPOPERATION_MODE: + case SPV_OPERAND_TYPE_QUANTIZATION_MODES: + case SPV_OPERAND_TYPE_OVERFLOW_MODES: + case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT: + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT: + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE: + case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER: + case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER: + case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL: + case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL: + return true; + default: + break; + } + return false; +} + +bool spvOperandIsConcreteMask(spv_operand_type_t type) { + switch (type) { + case SPV_OPERAND_TYPE_IMAGE: + case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE: + case SPV_OPERAND_TYPE_SELECTION_CONTROL: + case SPV_OPERAND_TYPE_LOOP_CONTROL: + case SPV_OPERAND_TYPE_FUNCTION_CONTROL: + case SPV_OPERAND_TYPE_MEMORY_ACCESS: + case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE: + case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: + return true; + default: + break; + } + return false; +} + +bool spvOperandIsOptional(spv_operand_type_t type) { + switch (type) { + case SPV_OPERAND_TYPE_OPTIONAL_ID: + case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: + case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER: + case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: + case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER: + case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: + case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: + case SPV_OPERAND_TYPE_OPTIONAL_CIV: + return true; + default: + break; + } + // Any variable operand is also optional. + return spvOperandIsVariable(type); +} + +bool spvOperandIsVariable(spv_operand_type_t type) { + switch (type) { + case SPV_OPERAND_TYPE_VARIABLE_ID: + case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID: + case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER: + return true; + default: + break; + } + return false; +} + +bool spvExpandOperandSequenceOnce(spv_operand_type_t type, + spv_operand_pattern_t* pattern) { + switch (type) { + case SPV_OPERAND_TYPE_VARIABLE_ID: + pattern->push_back(type); + pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID); + return true; + case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER: + pattern->push_back(type); + pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER); + return true; + case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID: + // Represents Zero or more (Literal number, Id) pairs, + // where the literal number must be a scalar integer. + pattern->push_back(type); + pattern->push_back(SPV_OPERAND_TYPE_ID); + pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER); + return true; + case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER: + // Represents Zero or more (Id, Literal number) pairs. + pattern->push_back(type); + pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER); + pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID); + return true; + default: + break; + } + return false; +} + +spv_operand_type_t spvTakeFirstMatchableOperand( + spv_operand_pattern_t* pattern) { + assert(!pattern->empty()); + spv_operand_type_t result; + do { + result = pattern->back(); + pattern->pop_back(); + } while (spvExpandOperandSequenceOnce(result, pattern)); + return result; +} + +spv_operand_pattern_t spvAlternatePatternFollowingImmediate( + const spv_operand_pattern_t& pattern) { + auto it = + std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID); + if (it != pattern.crend()) { + spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2, + SPV_OPERAND_TYPE_OPTIONAL_CIV); + alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID; + return alternatePattern; + } + + // No result-id found, so just expect CIVs. + return {SPV_OPERAND_TYPE_OPTIONAL_CIV}; +} + +bool spvIsIdType(spv_operand_type_t type) { + switch (type) { + case SPV_OPERAND_TYPE_ID: + case SPV_OPERAND_TYPE_TYPE_ID: + case SPV_OPERAND_TYPE_RESULT_ID: + case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: + case SPV_OPERAND_TYPE_SCOPE_ID: + return true; + default: + return false; + } +} + +bool spvIsInIdType(spv_operand_type_t type) { + if (!spvIsIdType(type)) { + // If it is not an ID it cannot be an input ID. + return false; + } + switch (type) { + // Deny non-input IDs. + case SPV_OPERAND_TYPE_TYPE_ID: + case SPV_OPERAND_TYPE_RESULT_ID: + return false; + default: + return true; + } +} + +std::function spvOperandCanBeForwardDeclaredFunction( + spv::Op opcode) { + std::function out; + if (spvOpcodeGeneratesType(opcode)) { + // All types can use forward pointers. + out = [](unsigned) { return true; }; + return out; + } + switch (opcode) { + case spv::Op::OpExecutionMode: + case spv::Op::OpExecutionModeId: + case spv::Op::OpEntryPoint: + case spv::Op::OpName: + case spv::Op::OpMemberName: + case spv::Op::OpSelectionMerge: + case spv::Op::OpDecorate: + case spv::Op::OpMemberDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorateStringGOOGLE: + case spv::Op::OpBranch: + case spv::Op::OpLoopMerge: + out = [](unsigned) { return true; }; + break; + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: + out = [](unsigned index) { return index != 0; }; + break; + + case spv::Op::OpFunctionCall: + // The Function parameter. + out = [](unsigned index) { return index == 2; }; + break; + + case spv::Op::OpPhi: + out = [](unsigned index) { return index > 1; }; + break; + + case spv::Op::OpEnqueueKernel: + // The Invoke parameter. + out = [](unsigned index) { return index == 8; }; + break; + + case spv::Op::OpGetKernelNDrangeSubGroupCount: + case spv::Op::OpGetKernelNDrangeMaxSubGroupSize: + // The Invoke parameter. + out = [](unsigned index) { return index == 3; }; + break; + + case spv::Op::OpGetKernelWorkGroupSize: + case spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple: + // The Invoke parameter. + out = [](unsigned index) { return index == 2; }; + break; + case spv::Op::OpTypeForwardPointer: + out = [](unsigned index) { return index == 0; }; + break; + case spv::Op::OpTypeArray: + out = [](unsigned index) { return index == 1; }; + break; + default: + out = [](unsigned) { return false; }; + break; + } + return out; +} + +std::function spvDbgInfoExtOperandCanBeForwardDeclaredFunction( + spv_ext_inst_type_t ext_type, uint32_t key) { + // The Vulkan debug info extended instruction set is non-semantic so allows no + // forward references ever + if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { + return [](unsigned) { return false; }; + } + + // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward + // references for debug info instructions are still in discussion. We must + // update the following lines of code when we conclude the spec. + std::function out; + if (ext_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) { + switch (OpenCLDebugInfo100Instructions(key)) { + case OpenCLDebugInfo100DebugFunction: + out = [](unsigned index) { return index == 13; }; + break; + case OpenCLDebugInfo100DebugTypeComposite: + out = [](unsigned index) { return index >= 13; }; + break; + default: + out = [](unsigned) { return false; }; + break; + } + } else { + switch (DebugInfoInstructions(key)) { + case DebugInfoDebugFunction: + out = [](unsigned index) { return index == 13; }; + break; + case DebugInfoDebugTypeComposite: + out = [](unsigned index) { return index >= 12; }; + break; + default: + out = [](unsigned) { return false; }; + break; + } + } + return out; +} diff --git a/thirdparty/glslang/External/spirv-tools/source/operand.h b/thirdparty/glslang/External/spirv-tools/source/operand.h new file mode 100644 index 000000000000..a3010d9341f4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/operand.h @@ -0,0 +1,151 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPERAND_H_ +#define SOURCE_OPERAND_H_ + +#include +#include + +#include "source/table.h" +#include "spirv-tools/libspirv.h" + +// A sequence of operand types. +// +// A SPIR-V parser uses an operand pattern to describe what is expected +// next on the input. +// +// As we parse an instruction in text or binary form from left to right, +// we pop and push at the end of the pattern vector. Symbols later in the +// pattern vector are matched against the input before symbols earlier in the +// pattern vector are matched. + +// Using a vector in this way reduces memory traffic, which is good for +// performance. +using spv_operand_pattern_t = std::vector; + +// Finds the named operand in the table. The type parameter specifies the +// operand's group. A handle of the operand table entry for this operand will +// be written into *entry. +spv_result_t spvOperandTableNameLookup(spv_target_env, + const spv_operand_table table, + const spv_operand_type_t type, + const char* name, + const size_t name_length, + spv_operand_desc* entry); + +// Finds the operand with value in the table. The type parameter specifies the +// operand's group. A handle of the operand table entry for this operand will +// be written into *entry. +spv_result_t spvOperandTableValueLookup(spv_target_env, + const spv_operand_table table, + const spv_operand_type_t type, + const uint32_t value, + spv_operand_desc* entry); + +// Gets the name string of the non-variable operand type. +const char* spvOperandTypeStr(spv_operand_type_t type); + +// Returns true if the given type is concrete. +bool spvOperandIsConcrete(spv_operand_type_t type); + +// Returns true if the given type is concrete and also a mask. +bool spvOperandIsConcreteMask(spv_operand_type_t type); + +// Returns true if an operand of the given type is optional. +bool spvOperandIsOptional(spv_operand_type_t type); + +// Returns true if an operand type represents zero or more logical operands. +// +// Note that a single logical operand may still be a variable number of words. +// For example, a literal string may be many words, but is just one logical +// operand. +bool spvOperandIsVariable(spv_operand_type_t type); + +// Append a list of operand types to the end of the pattern vector. +// The types parameter specifies the source array of types, ending with +// SPV_OPERAND_TYPE_NONE. +void spvPushOperandTypes(const spv_operand_type_t* types, + spv_operand_pattern_t* pattern); + +// Appends the operands expected after the given typed mask onto the +// end of the given pattern. +// +// Each set bit in the mask represents zero or more operand types that should +// be appended onto the pattern. Operands for a less significant bit always +// appear after operands for a more significant bit. +// +// If a set bit is unknown, then we assume it has no operands. +void spvPushOperandTypesForMask(spv_target_env, + const spv_operand_table operand_table, + const spv_operand_type_t mask_type, + const uint32_t mask, + spv_operand_pattern_t* pattern); + +// Expands an operand type representing zero or more logical operands, +// exactly once. +// +// If the given type represents potentially several logical operands, +// then prepend the given pattern with the first expansion of the logical +// operands, followed by original type. Otherwise, don't modify the pattern. +// +// For example, the SPV_OPERAND_TYPE_VARIABLE_ID represents zero or more +// IDs. In that case we would prepend the pattern with SPV_OPERAND_TYPE_ID +// followed by SPV_OPERAND_TYPE_VARIABLE_ID again. +// +// This also applies to zero or more tuples of logical operands. In that case +// we prepend pattern with for the members of the tuple, followed by the +// original type argument. The pattern must encode the fact that if any part +// of the tuple is present, then all tuple members should be. So the first +// member of the tuple must be optional, and the remaining members +// non-optional. +// +// Returns true if we modified the pattern. +bool spvExpandOperandSequenceOnce(spv_operand_type_t type, + spv_operand_pattern_t* pattern); + +// Expands the first element in the pattern until it is a matchable operand +// type, then pops it off the front and returns it. The pattern must not be +// empty. +// +// A matchable operand type is anything other than a zero-or-more-items +// operand type. +spv_operand_type_t spvTakeFirstMatchableOperand(spv_operand_pattern_t* pattern); + +// Calculates the corresponding post-immediate alternate pattern, which allows +// a limited set of operand types. +spv_operand_pattern_t spvAlternatePatternFollowingImmediate( + const spv_operand_pattern_t& pattern); + +// Is the operand an ID? +bool spvIsIdType(spv_operand_type_t type); + +// Is the operand an input ID? +bool spvIsInIdType(spv_operand_type_t type); + +// Takes the opcode of an instruction and returns +// a function object that will return true if the index +// of the operand can be forward declared. This function will +// used in the SSA validation stage of the pipeline +std::function spvOperandCanBeForwardDeclaredFunction( + spv::Op opcode); + +// Takes the instruction key of a debug info extension instruction +// and returns a function object that will return true if the index +// of the operand can be forward declared. This function will +// used in the SSA validation stage of the pipeline +std::function spvDbgInfoExtOperandCanBeForwardDeclaredFunction( + spv_ext_inst_type_t ext_type, uint32_t key); + +#endif // SOURCE_OPERAND_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/operand.kinds-unified1.inc b/thirdparty/glslang/External/spirv-tools/source/operand.kinds-unified1.inc new file mode 100644 index 000000000000..d0ba640c4723 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/operand.kinds-unified1.inc @@ -0,0 +1,1609 @@ +static const spv::Capability pygen_variable_caps_Addresses[] = {spv::Capability::Addresses}; +static const spv::Capability pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL[] = {spv::Capability::ArbitraryPrecisionFixedPointINTEL}; +static const spv::Capability pygen_variable_caps_AsmINTEL[] = {spv::Capability::AsmINTEL}; +static const spv::Capability pygen_variable_caps_AtomicStorage[] = {spv::Capability::AtomicStorage}; +static const spv::Capability pygen_variable_caps_BindlessTextureNV[] = {spv::Capability::BindlessTextureNV}; +static const spv::Capability pygen_variable_caps_CacheControlsINTEL[] = {spv::Capability::CacheControlsINTEL}; +static const spv::Capability pygen_variable_caps_ClipDistance[] = {spv::Capability::ClipDistance}; +static const spv::Capability pygen_variable_caps_ComputeDerivativeGroupLinearNV[] = {spv::Capability::ComputeDerivativeGroupLinearNV}; +static const spv::Capability pygen_variable_caps_ComputeDerivativeGroupQuadsNV[] = {spv::Capability::ComputeDerivativeGroupQuadsNV}; +static const spv::Capability pygen_variable_caps_CoreBuiltinsARM[] = {spv::Capability::CoreBuiltinsARM}; +static const spv::Capability pygen_variable_caps_CullDistance[] = {spv::Capability::CullDistance}; +static const spv::Capability pygen_variable_caps_DenormFlushToZero[] = {spv::Capability::DenormFlushToZero}; +static const spv::Capability pygen_variable_caps_DenormPreserve[] = {spv::Capability::DenormPreserve}; +static const spv::Capability pygen_variable_caps_DeviceEnqueue[] = {spv::Capability::DeviceEnqueue}; +static const spv::Capability pygen_variable_caps_DeviceGroup[] = {spv::Capability::DeviceGroup}; +static const spv::Capability pygen_variable_caps_DrawParameters[] = {spv::Capability::DrawParameters}; +static const spv::Capability pygen_variable_caps_DrawParametersMeshShadingNVMeshShadingEXT[] = {spv::Capability::DrawParameters, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_FPGAArgumentInterfacesINTEL[] = {spv::Capability::FPGAArgumentInterfacesINTEL}; +static const spv::Capability pygen_variable_caps_FPGABufferLocationINTEL[] = {spv::Capability::FPGABufferLocationINTEL}; +static const spv::Capability pygen_variable_caps_FPGAClusterAttributesINTEL[] = {spv::Capability::FPGAClusterAttributesINTEL}; +static const spv::Capability pygen_variable_caps_FPGAClusterAttributesV2INTEL[] = {spv::Capability::FPGAClusterAttributesV2INTEL}; +static const spv::Capability pygen_variable_caps_FPGADSPControlINTEL[] = {spv::Capability::FPGADSPControlINTEL}; +static const spv::Capability pygen_variable_caps_FPGAInvocationPipeliningAttributesINTEL[] = {spv::Capability::FPGAInvocationPipeliningAttributesINTEL}; +static const spv::Capability pygen_variable_caps_FPGAKernelAttributesINTEL[] = {spv::Capability::FPGAKernelAttributesINTEL}; +static const spv::Capability pygen_variable_caps_FPGAKernelAttributesv2INTEL[] = {spv::Capability::FPGAKernelAttributesv2INTEL}; +static const spv::Capability pygen_variable_caps_FPGALatencyControlINTEL[] = {spv::Capability::FPGALatencyControlINTEL}; +static const spv::Capability pygen_variable_caps_FPGALoopControlsINTEL[] = {spv::Capability::FPGALoopControlsINTEL}; +static const spv::Capability pygen_variable_caps_FPGAMemoryAccessesINTEL[] = {spv::Capability::FPGAMemoryAccessesINTEL}; +static const spv::Capability pygen_variable_caps_FPGAMemoryAttributesINTEL[] = {spv::Capability::FPGAMemoryAttributesINTEL}; +static const spv::Capability pygen_variable_caps_FPMaxErrorINTEL[] = {spv::Capability::FPMaxErrorINTEL}; +static const spv::Capability pygen_variable_caps_FloatControls2[] = {spv::Capability::FloatControls2}; +static const spv::Capability pygen_variable_caps_FloatControls2FPFastMathModeINTEL[] = {spv::Capability::FloatControls2, spv::Capability::FPFastMathModeINTEL}; +static const spv::Capability pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR[] = {spv::Capability::FragmentBarycentricNV, spv::Capability::FragmentBarycentricKHR}; +static const spv::Capability pygen_variable_caps_FragmentDensityEXTShadingRateNV[] = {spv::Capability::FragmentDensityEXT, spv::Capability::ShadingRateNV}; +static const spv::Capability pygen_variable_caps_FragmentFullyCoveredEXT[] = {spv::Capability::FragmentFullyCoveredEXT}; +static const spv::Capability pygen_variable_caps_FragmentShaderPixelInterlockEXT[] = {spv::Capability::FragmentShaderPixelInterlockEXT}; +static const spv::Capability pygen_variable_caps_FragmentShaderSampleInterlockEXT[] = {spv::Capability::FragmentShaderSampleInterlockEXT}; +static const spv::Capability pygen_variable_caps_FragmentShaderShadingRateInterlockEXT[] = {spv::Capability::FragmentShaderShadingRateInterlockEXT}; +static const spv::Capability pygen_variable_caps_FragmentShadingRateKHR[] = {spv::Capability::FragmentShadingRateKHR}; +static const spv::Capability pygen_variable_caps_FunctionFloatControlINTEL[] = {spv::Capability::FunctionFloatControlINTEL}; +static const spv::Capability pygen_variable_caps_FunctionPointersINTEL[] = {spv::Capability::FunctionPointersINTEL}; +static const spv::Capability pygen_variable_caps_GenericPointer[] = {spv::Capability::GenericPointer}; +static const spv::Capability pygen_variable_caps_Geometry[] = {spv::Capability::Geometry}; +static const spv::Capability pygen_variable_caps_GeometryMeshShadingNVMeshShadingEXT[] = {spv::Capability::Geometry, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_GeometryShaderLayerShaderViewportIndexLayerEXTMeshShadingNVMeshShadingEXT[] = {spv::Capability::Geometry, spv::Capability::ShaderLayer, spv::Capability::ShaderViewportIndexLayerEXT, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_GeometryTessellation[] = {spv::Capability::Geometry, spv::Capability::Tessellation}; +static const spv::Capability pygen_variable_caps_GeometryTessellationMeshShadingNVMeshShadingEXT[] = {spv::Capability::Geometry, spv::Capability::Tessellation, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_GeometryTessellationRayTracingNVRayTracingKHRMeshShadingNVMeshShadingEXT[] = {spv::Capability::Geometry, spv::Capability::Tessellation, spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_GeometryShaderPassthroughNV[] = {spv::Capability::GeometryShaderPassthroughNV}; +static const spv::Capability pygen_variable_caps_GeometryStreams[] = {spv::Capability::GeometryStreams}; +static const spv::Capability pygen_variable_caps_GlobalVariableFPGADecorationsINTEL[] = {spv::Capability::GlobalVariableFPGADecorationsINTEL}; +static const spv::Capability pygen_variable_caps_GlobalVariableHostAccessINTEL[] = {spv::Capability::GlobalVariableHostAccessINTEL}; +static const spv::Capability pygen_variable_caps_GroupNonUniform[] = {spv::Capability::GroupNonUniform}; +static const spv::Capability pygen_variable_caps_GroupNonUniformClustered[] = {spv::Capability::GroupNonUniformClustered}; +static const spv::Capability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {spv::Capability::GroupNonUniformPartitionedNV}; +static const spv::Capability pygen_variable_caps_IOPipesINTEL[] = {spv::Capability::IOPipesINTEL}; +static const spv::Capability pygen_variable_caps_ImageBasic[] = {spv::Capability::ImageBasic}; +static const spv::Capability pygen_variable_caps_ImageBuffer[] = {spv::Capability::ImageBuffer}; +static const spv::Capability pygen_variable_caps_ImageBufferShaderNonUniform[] = {spv::Capability::ImageBuffer, spv::Capability::ShaderNonUniform}; +static const spv::Capability pygen_variable_caps_ImageGatherExtended[] = {spv::Capability::ImageGatherExtended}; +static const spv::Capability pygen_variable_caps_IndirectReferencesINTEL[] = {spv::Capability::IndirectReferencesINTEL}; +static const spv::Capability pygen_variable_caps_InputAttachment[] = {spv::Capability::InputAttachment}; +static const spv::Capability pygen_variable_caps_InputAttachmentShaderNonUniform[] = {spv::Capability::InputAttachment, spv::Capability::ShaderNonUniform}; +static const spv::Capability pygen_variable_caps_Int64[] = {spv::Capability::Int64}; +static const spv::Capability pygen_variable_caps_Int64ImageEXT[] = {spv::Capability::Int64ImageEXT}; +static const spv::Capability pygen_variable_caps_Int8[] = {spv::Capability::Int8}; +static const spv::Capability pygen_variable_caps_Kernel[] = {spv::Capability::Kernel}; +static const spv::Capability pygen_variable_caps_KernelFloatControls2[] = {spv::Capability::Kernel, spv::Capability::FloatControls2}; +static const spv::Capability pygen_variable_caps_KernelGroupNonUniform[] = {spv::Capability::Kernel, spv::Capability::GroupNonUniform}; +static const spv::Capability pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR[] = {spv::Capability::Kernel, spv::Capability::GroupNonUniform, spv::Capability::SubgroupBallotKHR}; +static const spv::Capability pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot[] = {spv::Capability::Kernel, spv::Capability::GroupNonUniformArithmetic, spv::Capability::GroupNonUniformBallot}; +static const spv::Capability pygen_variable_caps_KernelAttributesINTEL[] = {spv::Capability::KernelAttributesINTEL}; +static const spv::Capability pygen_variable_caps_Linkage[] = {spv::Capability::Linkage}; +static const spv::Capability pygen_variable_caps_LoopFuseINTEL[] = {spv::Capability::LoopFuseINTEL}; +static const spv::Capability pygen_variable_caps_Matrix[] = {spv::Capability::Matrix}; +static const spv::Capability pygen_variable_caps_MemoryAccessAliasingINTEL[] = {spv::Capability::MemoryAccessAliasingINTEL}; +static const spv::Capability pygen_variable_caps_MeshShadingEXT[] = {spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_MeshShadingNV[] = {spv::Capability::MeshShadingNV}; +static const spv::Capability pygen_variable_caps_MeshShadingNVMeshShadingEXT[] = {spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_MinLod[] = {spv::Capability::MinLod}; +static const spv::Capability pygen_variable_caps_MultiView[] = {spv::Capability::MultiView}; +static const spv::Capability pygen_variable_caps_MultiViewport[] = {spv::Capability::MultiViewport}; +static const spv::Capability pygen_variable_caps_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXTMeshShadingNVMeshShadingEXT[] = {spv::Capability::MultiViewport, spv::Capability::ShaderViewportIndex, spv::Capability::ShaderViewportIndexLayerEXT, spv::Capability::MeshShadingNV, spv::Capability::MeshShadingEXT}; +static const spv::Capability pygen_variable_caps_OptNoneINTEL[] = {spv::Capability::OptNoneINTEL}; +static const spv::Capability pygen_variable_caps_PerViewAttributesNVMeshShadingNV[] = {spv::Capability::PerViewAttributesNV, spv::Capability::MeshShadingNV}; +static const spv::Capability pygen_variable_caps_PhysicalStorageBufferAddresses[] = {spv::Capability::PhysicalStorageBufferAddresses}; +static const spv::Capability pygen_variable_caps_Pipes[] = {spv::Capability::Pipes}; +static const spv::Capability pygen_variable_caps_QuadControlKHR[] = {spv::Capability::QuadControlKHR}; +static const spv::Capability pygen_variable_caps_RayCullMaskKHR[] = {spv::Capability::RayCullMaskKHR}; +static const spv::Capability pygen_variable_caps_RayQueryKHR[] = {spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_RayQueryKHRRayTracingKHR[] = {spv::Capability::RayQueryKHR, spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingDisplacementMicromapNV[] = {spv::Capability::RayTracingDisplacementMicromapNV}; +static const spv::Capability pygen_variable_caps_RayTracingKHR[] = {spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingMotionBlurNV[] = {spv::Capability::RayTracingMotionBlurNV}; +static const spv::Capability pygen_variable_caps_RayTracingNV[] = {spv::Capability::RayTracingNV}; +static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR}; +static const spv::Capability pygen_variable_caps_RayTracingOpacityMicromapEXT[] = {spv::Capability::RayTracingOpacityMicromapEXT}; +static const spv::Capability pygen_variable_caps_RayTracingPositionFetchKHR[] = {spv::Capability::RayTracingPositionFetchKHR}; +static const spv::Capability pygen_variable_caps_RayTraversalPrimitiveCullingKHR[] = {spv::Capability::RayTraversalPrimitiveCullingKHR}; +static const spv::Capability pygen_variable_caps_RegisterLimitsINTEL[] = {spv::Capability::RegisterLimitsINTEL}; +static const spv::Capability pygen_variable_caps_RoundToInfinityINTEL[] = {spv::Capability::RoundToInfinityINTEL}; +static const spv::Capability pygen_variable_caps_RoundingModeRTE[] = {spv::Capability::RoundingModeRTE}; +static const spv::Capability pygen_variable_caps_RoundingModeRTZ[] = {spv::Capability::RoundingModeRTZ}; +static const spv::Capability pygen_variable_caps_RuntimeAlignedAttributeINTEL[] = {spv::Capability::RuntimeAlignedAttributeINTEL}; +static const spv::Capability pygen_variable_caps_SampleMaskOverrideCoverageNV[] = {spv::Capability::SampleMaskOverrideCoverageNV}; +static const spv::Capability pygen_variable_caps_SampleMaskPostDepthCoverage[] = {spv::Capability::SampleMaskPostDepthCoverage}; +static const spv::Capability pygen_variable_caps_SampleRateShading[] = {spv::Capability::SampleRateShading}; +static const spv::Capability pygen_variable_caps_Sampled1D[] = {spv::Capability::Sampled1D}; +static const spv::Capability pygen_variable_caps_SampledBuffer[] = {spv::Capability::SampledBuffer}; +static const spv::Capability pygen_variable_caps_SampledBufferShaderNonUniform[] = {spv::Capability::SampledBuffer, spv::Capability::ShaderNonUniform}; +static const spv::Capability pygen_variable_caps_SampledCubeArray[] = {spv::Capability::SampledCubeArray}; +static const spv::Capability pygen_variable_caps_SampledRect[] = {spv::Capability::SampledRect}; +static const spv::Capability pygen_variable_caps_Shader[] = {spv::Capability::Shader}; +static const spv::Capability pygen_variable_caps_ShaderKernel[] = {spv::Capability::Shader, spv::Capability::Kernel}; +static const spv::Capability pygen_variable_caps_ShaderUniformDecoration[] = {spv::Capability::Shader, spv::Capability::UniformDecoration}; +static const spv::Capability pygen_variable_caps_ShaderVectorComputeINTEL[] = {spv::Capability::Shader, spv::Capability::VectorComputeINTEL}; +static const spv::Capability pygen_variable_caps_ShaderEnqueueAMDX[] = {spv::Capability::ShaderEnqueueAMDX}; +static const spv::Capability pygen_variable_caps_ShaderInvocationReorderNV[] = {spv::Capability::ShaderInvocationReorderNV}; +static const spv::Capability pygen_variable_caps_ShaderNonUniform[] = {spv::Capability::ShaderNonUniform}; +static const spv::Capability pygen_variable_caps_ShaderSMBuiltinsNV[] = {spv::Capability::ShaderSMBuiltinsNV}; +static const spv::Capability pygen_variable_caps_ShaderStereoViewNV[] = {spv::Capability::ShaderStereoViewNV}; +static const spv::Capability pygen_variable_caps_ShaderViewportIndexLayerNV[] = {spv::Capability::ShaderViewportIndexLayerNV}; +static const spv::Capability pygen_variable_caps_ShaderViewportMaskNV[] = {spv::Capability::ShaderViewportMaskNV}; +static const spv::Capability pygen_variable_caps_ShaderViewportMaskNVMeshShadingNV[] = {spv::Capability::ShaderViewportMaskNV, spv::Capability::MeshShadingNV}; +static const spv::Capability pygen_variable_caps_ShadingRateNVFragmentDensityEXT[] = {spv::Capability::ShadingRateNV, spv::Capability::FragmentDensityEXT}; +static const spv::Capability pygen_variable_caps_SignedZeroInfNanPreserve[] = {spv::Capability::SignedZeroInfNanPreserve}; +static const spv::Capability pygen_variable_caps_StencilExportEXT[] = {spv::Capability::StencilExportEXT}; +static const spv::Capability pygen_variable_caps_StorageBuffer16BitAccessStorageUniformBufferBlock16[] = {spv::Capability::StorageBuffer16BitAccess, spv::Capability::StorageUniformBufferBlock16}; +static const spv::Capability pygen_variable_caps_StorageBuffer8BitAccess[] = {spv::Capability::StorageBuffer8BitAccess}; +static const spv::Capability pygen_variable_caps_StorageImageExtendedFormats[] = {spv::Capability::StorageImageExtendedFormats}; +static const spv::Capability pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot[] = {spv::Capability::SubgroupBallotKHR, spv::Capability::GroupNonUniformBallot}; +static const spv::Capability pygen_variable_caps_SubgroupDispatch[] = {spv::Capability::SubgroupDispatch}; +static const spv::Capability pygen_variable_caps_Tessellation[] = {spv::Capability::Tessellation}; +static const spv::Capability pygen_variable_caps_TileImageColorReadAccessEXT[] = {spv::Capability::TileImageColorReadAccessEXT}; +static const spv::Capability pygen_variable_caps_TileImageDepthReadAccessEXT[] = {spv::Capability::TileImageDepthReadAccessEXT}; +static const spv::Capability pygen_variable_caps_TileImageStencilReadAccessEXT[] = {spv::Capability::TileImageStencilReadAccessEXT}; +static const spv::Capability pygen_variable_caps_TransformFeedback[] = {spv::Capability::TransformFeedback}; +static const spv::Capability pygen_variable_caps_USMStorageClassesINTEL[] = {spv::Capability::USMStorageClassesINTEL}; +static const spv::Capability pygen_variable_caps_VariablePointersStorageBuffer[] = {spv::Capability::VariablePointersStorageBuffer}; +static const spv::Capability pygen_variable_caps_VectorAnyINTEL[] = {spv::Capability::VectorAnyINTEL}; +static const spv::Capability pygen_variable_caps_VectorComputeINTEL[] = {spv::Capability::VectorComputeINTEL}; +static const spv::Capability pygen_variable_caps_VulkanMemoryModel[] = {spv::Capability::VulkanMemoryModel}; +static const spv::Capability pygen_variable_caps_WorkgroupMemoryExplicitLayoutKHR[] = {spv::Capability::WorkgroupMemoryExplicitLayoutKHR}; + +static const spvtools::Extension pygen_variable_exts_SPV_AMDX_shader_enqueue[] = {spvtools::Extension::kSPV_AMDX_shader_enqueue}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_gpu_shader_half_float_fetch[] = {spvtools::Extension::kSPV_AMD_gpu_shader_half_float_fetch}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_ballot[] = {spvtools::Extension::kSPV_AMD_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_tests[] = {spvtools::Extension::kSPV_AMD_shader_early_and_late_fragment_tests}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export[] = {spvtools::Extension::kSPV_AMD_shader_early_and_late_fragment_tests, spvtools::Extension::kSPV_EXT_shader_stencil_export}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter[] = {spvtools::Extension::kSPV_AMD_shader_explicit_vertex_parameter}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_fragment_mask[] = {spvtools::Extension::kSPV_AMD_shader_fragment_mask}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_image_load_store_lod[] = {spvtools::Extension::kSPV_AMD_shader_image_load_store_lod}; +static const spvtools::Extension pygen_variable_exts_SPV_AMD_texture_gather_bias_lod[] = {spvtools::Extension::kSPV_AMD_texture_gather_bias_lod}; +static const spvtools::Extension pygen_variable_exts_SPV_ARM_core_builtins[] = {spvtools::Extension::kSPV_ARM_core_builtins}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_demote_to_helper_invocation[] = {spvtools::Extension::kSPV_EXT_demote_to_helper_invocation}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_descriptor_indexing[] = {spvtools::Extension::kSPV_EXT_descriptor_indexing}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_fully_covered[] = {spvtools::Extension::kSPV_EXT_fragment_fully_covered}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate[] = {spvtools::Extension::kSPV_EXT_fragment_invocation_density, spvtools::Extension::kSPV_NV_shading_rate}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_interlock[] = {spvtools::Extension::kSPV_EXT_fragment_shader_interlock}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_mesh_shader[] = {spvtools::Extension::kSPV_EXT_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_mesh_shaderSPV_KHR_shader_draw_parametersSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_EXT_mesh_shader, spvtools::Extension::kSPV_KHR_shader_draw_parameters, spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_EXT_mesh_shader, spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_opacity_micromap[] = {spvtools::Extension::kSPV_EXT_opacity_micromap}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer[] = {spvtools::Extension::kSPV_EXT_physical_storage_buffer, spvtools::Extension::kSPV_KHR_physical_storage_buffer}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float16_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float16_add}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_min_max[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_min_max}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_image_int64[] = {spvtools::Extension::kSPV_EXT_shader_image_int64}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_stencil_export[] = {spvtools::Extension::kSPV_EXT_shader_stencil_export}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_tile_image[] = {spvtools::Extension::kSPV_EXT_shader_tile_image}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer, spvtools::Extension::kSPV_NV_viewport_array2}; +static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1}; +static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_user_type[] = {spvtools::Extension::kSPV_GOOGLE_user_type}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_arbitrary_precision_fixed_point[] = {spvtools::Extension::kSPV_INTEL_arbitrary_precision_fixed_point}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_arbitrary_precision_floating_point[] = {spvtools::Extension::kSPV_INTEL_arbitrary_precision_floating_point}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_arbitrary_precision_integers[] = {spvtools::Extension::kSPV_INTEL_arbitrary_precision_integers}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_bfloat16_conversion[] = {spvtools::Extension::kSPV_INTEL_bfloat16_conversion}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_blocking_pipes[] = {spvtools::Extension::kSPV_INTEL_blocking_pipes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_cache_controls[] = {spvtools::Extension::kSPV_INTEL_cache_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_debug_module[] = {spvtools::Extension::kSPV_INTEL_debug_module}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation[] = {spvtools::Extension::kSPV_INTEL_device_side_avc_motion_estimation}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_float_controls2[] = {spvtools::Extension::kSPV_INTEL_float_controls2}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fp_fast_math_mode[] = {spvtools::Extension::kSPV_INTEL_fp_fast_math_mode}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fp_max_error[] = {spvtools::Extension::kSPV_INTEL_fp_max_error}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_argument_interfaces[] = {spvtools::Extension::kSPV_INTEL_fpga_argument_interfaces}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_buffer_location[] = {spvtools::Extension::kSPV_INTEL_fpga_buffer_location}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_cluster_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_cluster_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_dsp_control[] = {spvtools::Extension::kSPV_INTEL_fpga_dsp_control}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_invocation_pipelining_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_latency_control[] = {spvtools::Extension::kSPV_INTEL_fpga_latency_control}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_loop_controls[] = {spvtools::Extension::kSPV_INTEL_fpga_loop_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_memory_accesses[] = {spvtools::Extension::kSPV_INTEL_fpga_memory_accesses}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_memory_attributes[] = {spvtools::Extension::kSPV_INTEL_fpga_memory_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_fpga_reg[] = {spvtools::Extension::kSPV_INTEL_fpga_reg}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_function_pointers[] = {spvtools::Extension::kSPV_INTEL_function_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_global_variable_fpga_decorations[] = {spvtools::Extension::kSPV_INTEL_global_variable_fpga_decorations}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_global_variable_host_access[] = {spvtools::Extension::kSPV_INTEL_global_variable_host_access}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_inline_assembly[] = {spvtools::Extension::kSPV_INTEL_inline_assembly}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_io_pipes[] = {spvtools::Extension::kSPV_INTEL_io_pipes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_kernel_attributes[] = {spvtools::Extension::kSPV_INTEL_kernel_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_long_composites[] = {spvtools::Extension::kSPV_INTEL_long_composites}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_loop_fuse[] = {spvtools::Extension::kSPV_INTEL_loop_fuse}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_masked_gather_scatter[] = {spvtools::Extension::kSPV_INTEL_masked_gather_scatter}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_maximum_registers[] = {spvtools::Extension::kSPV_INTEL_maximum_registers}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_media_block_io[] = {spvtools::Extension::kSPV_INTEL_media_block_io}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_memory_access_aliasing[] = {spvtools::Extension::kSPV_INTEL_memory_access_aliasing}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_optnone[] = {spvtools::Extension::kSPV_INTEL_optnone}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_runtime_aligned[] = {spvtools::Extension::kSPV_INTEL_runtime_aligned}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_shader_integer_functions2[] = {spvtools::Extension::kSPV_INTEL_shader_integer_functions2}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_split_barrier[] = {spvtools::Extension::kSPV_INTEL_split_barrier}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_subgroups[] = {spvtools::Extension::kSPV_INTEL_subgroups}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_unstructured_loop_controls[] = {spvtools::Extension::kSPV_INTEL_unstructured_loop_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_usm_storage_classes[] = {spvtools::Extension::kSPV_INTEL_usm_storage_classes}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_variable_length_array[] = {spvtools::Extension::kSPV_INTEL_variable_length_array}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_vector_compute[] = {spvtools::Extension::kSPV_INTEL_vector_compute}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_16bit_storage[] = {spvtools::Extension::kSPV_KHR_16bit_storage}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_8bit_storage[] = {spvtools::Extension::kSPV_KHR_8bit_storage}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_bit_instructions[] = {spvtools::Extension::kSPV_KHR_bit_instructions}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_cooperative_matrix[] = {spvtools::Extension::kSPV_KHR_cooperative_matrix}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_device_group[] = {spvtools::Extension::kSPV_KHR_device_group}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_expect_assume[] = {spvtools::Extension::kSPV_KHR_expect_assume}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_float_controls[] = {spvtools::Extension::kSPV_KHR_float_controls}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_float_controls2[] = {spvtools::Extension::kSPV_KHR_float_controls2}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric[] = {spvtools::Extension::kSPV_KHR_fragment_shader_barycentric, spvtools::Extension::kSPV_NV_fragment_shader_barycentric}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_fragment_shading_rate[] = {spvtools::Extension::kSPV_KHR_fragment_shading_rate}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_integer_dot_product[] = {spvtools::Extension::kSPV_KHR_integer_dot_product}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_linkonce_odr[] = {spvtools::Extension::kSPV_KHR_linkonce_odr}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_maximal_reconvergence[] = {spvtools::Extension::kSPV_KHR_maximal_reconvergence}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_multiview[] = {spvtools::Extension::kSPV_KHR_multiview}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration[] = {spvtools::Extension::kSPV_KHR_no_integer_wrap_decoration}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_post_depth_coverage[] = {spvtools::Extension::kSPV_KHR_post_depth_coverage}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_quad_control[] = {spvtools::Extension::kSPV_KHR_quad_control}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_cull_mask[] = {spvtools::Extension::kSPV_KHR_ray_cull_mask}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_query}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_querySPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_query, spvtools::Extension::kSPV_KHR_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_NV_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing_position_fetch[] = {spvtools::Extension::kSPV_KHR_ray_tracing_position_fetch}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_atomic_counter_ops[] = {spvtools::Extension::kSPV_KHR_shader_atomic_counter_ops}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parameters[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_storage_buffer_storage_classSPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_storage_buffer_storage_class, spvtools::Extension::kSPV_KHR_variable_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_rotate[] = {spvtools::Extension::kSPV_KHR_subgroup_rotate}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_uniform_control_flow[] = {spvtools::Extension::kSPV_KHR_subgroup_uniform_control_flow}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_uniform_group_instructions[] = {spvtools::Extension::kSPV_KHR_uniform_group_instructions}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_variable_pointers}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_vulkan_memory_model[] = {spvtools::Extension::kSPV_KHR_vulkan_memory_model}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout[] = {spvtools::Extension::kSPV_KHR_workgroup_memory_explicit_layout}; +static const spvtools::Extension pygen_variable_exts_SPV_NVX_multiview_per_view_attributes[] = {spvtools::Extension::kSPV_NVX_multiview_per_view_attributes}; +static const spvtools::Extension pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NVX_multiview_per_view_attributes, spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_bindless_texture[] = {spvtools::Extension::kSPV_NV_bindless_texture}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_compute_shader_derivatives[] = {spvtools::Extension::kSPV_NV_compute_shader_derivatives}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_displacement_micromap[] = {spvtools::Extension::kSPV_NV_displacement_micromap}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_geometry_shader_passthrough[] = {spvtools::Extension::kSPV_NV_geometry_shader_passthrough}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shaderSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_NV_mesh_shader, spvtools::Extension::kSPV_NV_viewport_array2}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing_motion_blur[] = {spvtools::Extension::kSPV_NV_ray_tracing_motion_blur}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_sample_mask_override_coverage[] = {spvtools::Extension::kSPV_NV_sample_mask_override_coverage}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_atomic_fp16_vector[] = {spvtools::Extension::kSPV_NV_shader_atomic_fp16_vector}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footprint[] = {spvtools::Extension::kSPV_NV_shader_image_footprint}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_invocation_reorder[] = {spvtools::Extension::kSPV_NV_shader_invocation_reorder}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_sm_builtins[] = {spvtools::Extension::kSPV_NV_shader_sm_builtins}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_subgroup_partitioned[] = {spvtools::Extension::kSPV_NV_shader_subgroup_partitioned}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_stereo_view_rendering[] = {spvtools::Extension::kSPV_NV_stereo_view_rendering}; +static const spvtools::Extension pygen_variable_exts_SPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_NV_viewport_array2}; +static const spvtools::Extension pygen_variable_exts_SPV_QCOM_image_processing[] = {spvtools::Extension::kSPV_QCOM_image_processing}; +static const spvtools::Extension pygen_variable_exts_SPV_QCOM_image_processing2[] = {spvtools::Extension::kSPV_QCOM_image_processing2}; + +static const spv_operand_desc_t pygen_variable_ImageOperandsEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Bias", 0x0001, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Lod", 0x0002, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Grad", 0x0004, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConstOffset", 0x0008, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Offset", 0x0010, 1, pygen_variable_caps_ImageGatherExtended, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ConstOffsets", 0x0020, 1, pygen_variable_caps_ImageGatherExtended, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Sample", 0x0040, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MinLod", 0x0080, 1, pygen_variable_caps_MinLod, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MakeTexelAvailable", 0x0100, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeTexelAvailableKHR", 0x0100, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeTexelVisible", 0x0200, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeTexelVisibleKHR", 0x0200, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonPrivateTexel", 0x0400, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonPrivateTexelKHR", 0x0400, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VolatileTexel", 0x0800, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VolatileTexelKHR", 0x0800, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"SignExtend", 0x1000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"ZeroExtend", 0x2000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"Nontemporal", 0x4000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"Offsets", 0x10000, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FPFastMathModeEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NotNaN", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NotInf", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NSZ", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AllowRecip", 0x0008, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Fast", 0x0010, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AllowContract", 0x10000, 2, pygen_variable_caps_FloatControls2FPFastMathModeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AllowContractFastINTEL", 0x10000, 2, pygen_variable_caps_FloatControls2FPFastMathModeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AllowReassoc", 0x20000, 2, pygen_variable_caps_FloatControls2FPFastMathModeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AllowReassocINTEL", 0x20000, 2, pygen_variable_caps_FloatControls2FPFastMathModeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AllowTransform", 0x40000, 1, pygen_variable_caps_FloatControls2, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_SelectionControlEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Flatten", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DontFlatten", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_LoopControlEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Unroll", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DontUnroll", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DependencyInfinite", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"DependencyLength", 0x0008, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"MinIterations", 0x0010, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"MaxIterations", 0x0020, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"IterationMultiple", 0x0040, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"PeelCount", 0x0080, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"PartialCount", 0x0100, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"InitiationIntervalINTEL", 0x10000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxConcurrencyINTEL", 0x20000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"DependencyArrayINTEL", 0x40000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"PipelineEnableINTEL", 0x80000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"LoopCoalesceINTEL", 0x100000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxInterleavingINTEL", 0x200000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"SpeculatedIterationsINTEL", 0x400000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"NoFusionINTEL", 0x800000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"LoopCountINTEL", 0x1000000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxReinvocationDelayINTEL", 0x2000000, 1, pygen_variable_caps_FPGALoopControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FunctionControlEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Inline", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DontInline", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Pure", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Const", 0x0008, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OptNoneINTEL", 0x10000, 1, pygen_variable_caps_OptNoneINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_MemorySemanticsEntries[] = { + {"Relaxed", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Acquire", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Release", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AcquireRelease", 0x0008, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SequentiallyConsistent", 0x0010, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UniformMemory", 0x0040, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SubgroupMemory", 0x0080, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WorkgroupMemory", 0x0100, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CrossWorkgroupMemory", 0x0200, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicCounterMemory", 0x0400, 1, pygen_variable_caps_AtomicStorage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageMemory", 0x0800, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OutputMemory", 0x1000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"OutputMemoryKHR", 0x1000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeAvailable", 0x2000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeAvailableKHR", 0x2000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeVisible", 0x4000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakeVisibleKHR", 0x4000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"Volatile", 0x8000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_MemoryAccessEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Volatile", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Aligned", 0x0002, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Nontemporal", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MakePointerAvailable", 0x0008, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakePointerAvailableKHR", 0x0008, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakePointerVisible", 0x0010, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"MakePointerVisibleKHR", 0x0010, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonPrivatePointer", 0x0020, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonPrivatePointerKHR", 0x0020, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"AliasScopeINTELMask", 0x10000, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"NoAliasINTELMask", 0x20000, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_KernelProfilingInfoEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CmdExecTime", 0x0001, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_RayFlagsEntries[] = { + {"NoneKHR", 0x0000, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"OpaqueKHR", 0x0001, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"NoOpaqueKHR", 0x0002, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"TerminateOnFirstHitKHR", 0x0004, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SkipClosestHitShaderKHR", 0x0008, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullBackFacingTrianglesKHR", 0x0010, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullFrontFacingTrianglesKHR", 0x0020, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullOpaqueKHR", 0x0040, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullNoOpaqueKHR", 0x0080, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SkipTrianglesKHR", 0x0100, 1, pygen_variable_caps_RayTraversalPrimitiveCullingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SkipAABBsKHR", 0x0200, 1, pygen_variable_caps_RayTraversalPrimitiveCullingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ForceOpacityMicromap2StateEXT", 0x0400, 1, pygen_variable_caps_RayTracingOpacityMicromapEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FragmentShadingRateEntries[] = { + {"Vertical2Pixels", 0x0001, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"Vertical4Pixels", 0x0002, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"Horizontal2Pixels", 0x0004, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"Horizontal4Pixels", 0x0008, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_SourceLanguageEntries[] = { + {"Unknown", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ESSL", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GLSL", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OpenCL_C", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OpenCL_CPP", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"HLSL", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CPP_for_OpenCL", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SYCL", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"HERO_C", 8, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NZSL", 9, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WGSL", 10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Slang", 11, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Zig", 12, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ExecutionModelEntries[] = { + {"Vertex", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TessellationControl", 1, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TessellationEvaluation", 2, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Geometry", 3, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Fragment", 4, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GLCompute", 5, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Kernel", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TaskNV", 5267, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MeshNV", 5268, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayGenerationNV", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayGenerationKHR", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"IntersectionNV", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"IntersectionKHR", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AnyHitNV", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AnyHitKHR", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ClosestHitNV", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ClosestHitKHR", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MissNV", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MissKHR", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CallableNV", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CallableKHR", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"TaskEXT", 5364, 1, pygen_variable_caps_MeshShadingEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MeshEXT", 5365, 1, pygen_variable_caps_MeshShadingEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_AddressingModelEntries[] = { + {"Logical", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Physical32", 1, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Physical64", 2, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PhysicalStorageBuffer64", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBuffer64EXT", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_MemoryModelEntries[] = { + {"Simple", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GLSL450", 1, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OpenCL", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Vulkan", 3, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VulkanKHR", 3, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = { + {"Invocations", 0, 1, pygen_variable_caps_Geometry, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpacingEqual", 1, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpacingFractionalEven", 2, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpacingFractionalOdd", 3, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VertexOrderCw", 4, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VertexOrderCcw", 5, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PixelCenterInteger", 6, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OriginUpperLeft", 7, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OriginLowerLeft", 8, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EarlyFragmentTests", 9, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PointMode", 10, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Xfb", 11, 1, pygen_variable_caps_TransformFeedback, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DepthReplacing", 12, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DepthGreater", 14, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DepthLess", 15, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DepthUnchanged", 16, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LocalSize", 17, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LocalSizeHint", 18, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InputPoints", 19, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InputLines", 20, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InputLinesAdjacency", 21, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Triangles", 22, 2, pygen_variable_caps_GeometryTessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InputTrianglesAdjacency", 23, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Quads", 24, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Isolines", 25, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OutputVertices", 26, 4, pygen_variable_caps_GeometryTessellationMeshShadingNVMeshShadingEXT, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OutputPoints", 27, 3, pygen_variable_caps_GeometryMeshShadingNVMeshShadingEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OutputLineStrip", 28, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"OutputTriangleStrip", 29, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VecTypeHint", 30, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ContractionOff", 31, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Initializer", 33, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"Finalizer", 34, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"SubgroupSize", 35, 1, pygen_variable_caps_SubgroupDispatch, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"SubgroupsPerWorkgroup", 36, 1, pygen_variable_caps_SubgroupDispatch, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"SubgroupsPerWorkgroupId", 37, 1, pygen_variable_caps_SubgroupDispatch, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"LocalSizeId", 38, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"LocalSizeHintId", 39, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"NonCoherentColorAttachmentReadEXT", 4169, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"NonCoherentDepthAttachmentReadEXT", 4170, 1, pygen_variable_caps_TileImageDepthReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"NonCoherentStencilAttachmentReadEXT", 4171, 1, pygen_variable_caps_TileImageStencilReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupUniformControlFlowKHR", 4421, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_subgroup_uniform_control_flow, {}, 0xffffffffu, 0xffffffffu}, + {"PostDepthCoverage", 4446, 1, pygen_variable_caps_SampleMaskPostDepthCoverage, 1, pygen_variable_exts_SPV_KHR_post_depth_coverage, {}, 0xffffffffu, 0xffffffffu}, + {"DenormPreserve", 4459, 1, pygen_variable_caps_DenormPreserve, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"DenormFlushToZero", 4460, 1, pygen_variable_caps_DenormFlushToZero, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"SignedZeroInfNanPreserve", 4461, 1, pygen_variable_caps_SignedZeroInfNanPreserve, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RoundingModeRTE", 4462, 1, pygen_variable_caps_RoundingModeRTE, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RoundingModeRTZ", 4463, 1, pygen_variable_caps_RoundingModeRTZ, 1, pygen_variable_exts_SPV_KHR_float_controls, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"EarlyAndLateFragmentTestsAMD", 5017, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_tests, {}, 0xffffffffu, 0xffffffffu}, + {"StencilRefReplacingEXT", 5027, 1, pygen_variable_caps_StencilExportEXT, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"CoalescingAMDX", 5069, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MaxNodeRecursionAMDX", 5071, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"StaticNumWorkgroupsAMDX", 5072, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"ShaderIndexAMDX", 5073, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"MaxNumWorkgroupsAMDX", 5077, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"StencilRefUnchangedFrontAMD", 5079, 1, pygen_variable_caps_StencilExportEXT, 2, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"StencilRefGreaterFrontAMD", 5080, 1, pygen_variable_caps_StencilExportEXT, 2, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"StencilRefLessFrontAMD", 5081, 1, pygen_variable_caps_StencilExportEXT, 2, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"StencilRefUnchangedBackAMD", 5082, 1, pygen_variable_caps_StencilExportEXT, 2, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"StencilRefGreaterBackAMD", 5083, 1, pygen_variable_caps_StencilExportEXT, 2, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"StencilRefLessBackAMD", 5084, 1, pygen_variable_caps_StencilExportEXT, 2, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"QuadDerivativesKHR", 5088, 1, pygen_variable_caps_QuadControlKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RequireFullQuadsKHR", 5089, 1, pygen_variable_caps_QuadControlKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"OutputLinesNV", 5269, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"OutputLinesEXT", 5269, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"OutputPrimitivesNV", 5270, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"OutputPrimitivesEXT", 5270, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"DerivativeGroupQuadsNV", 5289, 1, pygen_variable_caps_ComputeDerivativeGroupQuadsNV, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, + {"DerivativeGroupLinearNV", 5290, 1, pygen_variable_caps_ComputeDerivativeGroupLinearNV, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, + {"OutputTrianglesNV", 5298, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"OutputTrianglesEXT", 5298, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PixelInterlockOrderedEXT", 5366, 1, pygen_variable_caps_FragmentShaderPixelInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"PixelInterlockUnorderedEXT", 5367, 1, pygen_variable_caps_FragmentShaderPixelInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"SampleInterlockOrderedEXT", 5368, 1, pygen_variable_caps_FragmentShaderSampleInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"SampleInterlockUnorderedEXT", 5369, 1, pygen_variable_caps_FragmentShaderSampleInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"ShadingRateInterlockOrderedEXT", 5370, 1, pygen_variable_caps_FragmentShaderShadingRateInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"ShadingRateInterlockUnorderedEXT", 5371, 1, pygen_variable_caps_FragmentShaderShadingRateInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"SharedLocalMemorySizeINTEL", 5618, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"RoundingModeRTPINTEL", 5620, 1, pygen_variable_caps_RoundToInfinityINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"RoundingModeRTNINTEL", 5621, 1, pygen_variable_caps_RoundToInfinityINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"FloatingPointModeALTINTEL", 5622, 1, pygen_variable_caps_RoundToInfinityINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"FloatingPointModeIEEEINTEL", 5623, 1, pygen_variable_caps_RoundToInfinityINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxWorkgroupSizeINTEL", 5893, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxWorkDimINTEL", 5894, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"NoGlobalOffsetINTEL", 5895, 1, pygen_variable_caps_KernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"NumSIMDWorkitemsINTEL", 5896, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"SchedulerTargetFmaxMhzINTEL", 5903, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaximallyReconvergesKHR", 6023, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_maximal_reconvergence, {}, 0xffffffffu, 0xffffffffu}, + {"FPFastMathDefault", 6028, 1, pygen_variable_caps_FloatControls2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"StreamingInterfaceINTEL", 6154, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"RegisterMapInterfaceINTEL", 6160, 1, pygen_variable_caps_FPGAKernelAttributesv2INTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"NamedBarrierCountINTEL", 6417, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaximumRegistersINTEL", 6461, 1, pygen_variable_caps_RegisterLimitsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaximumRegistersIdINTEL", 6462, 1, pygen_variable_caps_RegisterLimitsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, +}; + +static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = { + {"UniformConstant", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Input", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Uniform", 2, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Output", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Workgroup", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CrossWorkgroup", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Private", 6, 2, pygen_variable_caps_ShaderVectorComputeINTEL, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Function", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Generic", 8, 1, pygen_variable_caps_GenericPointer, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PushConstant", 9, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicCounter", 10, 1, pygen_variable_caps_AtomicStorage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Image", 11, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"StorageBuffer", 12, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_KHR_storage_buffer_storage_classSPV_KHR_variable_pointers, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"TileImageEXT", 4172, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"NodePayloadAMDX", 5068, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"NodeOutputPayloadAMDX", 5076, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CallableDataNV", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"CallableDataKHR", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingCallableDataNV", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingCallableDataKHR", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayPayloadNV", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayPayloadKHR", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitAttributeNV", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitAttributeKHR", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayPayloadNV", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayPayloadKHR", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderRecordBufferNV", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderRecordBufferKHR", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"PhysicalStorageBuffer", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"HitObjectAttributeNV", 5385, 1, pygen_variable_caps_ShaderInvocationReorderNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"TaskPayloadWorkgroupEXT", 5402, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"CodeSectionINTEL", 5605, 1, pygen_variable_caps_FunctionPointersINTEL, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}, + {"DeviceOnlyINTEL", 5936, 1, pygen_variable_caps_USMStorageClassesINTEL, 1, pygen_variable_exts_SPV_INTEL_usm_storage_classes, {}, 0xffffffffu, 0xffffffffu}, + {"HostOnlyINTEL", 5937, 1, pygen_variable_caps_USMStorageClassesINTEL, 1, pygen_variable_exts_SPV_INTEL_usm_storage_classes, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DimEntries[] = { + {"1D", 0, 1, pygen_variable_caps_Sampled1D, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"2D", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"3D", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Cube", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rect", 4, 1, pygen_variable_caps_SampledRect, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Buffer", 5, 1, pygen_variable_caps_SampledBuffer, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SubpassData", 6, 1, pygen_variable_caps_InputAttachment, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TileImageDataEXT", 4173, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_SamplerAddressingModeEntries[] = { + {"None", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ClampToEdge", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Clamp", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Repeat", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RepeatMirrored", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_SamplerFilterModeEntries[] = { + {"Nearest", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Linear", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ImageFormatEntries[] = { + {"Unknown", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba32f", 1, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba16f", 2, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R32f", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba8", 4, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba8Snorm", 5, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg32f", 6, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg16f", 7, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R11fG11fB10f", 8, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R16f", 9, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba16", 10, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgb10A2", 11, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg16", 12, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg8", 13, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R16", 14, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R8", 15, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba16Snorm", 16, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg16Snorm", 17, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg8Snorm", 18, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R16Snorm", 19, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R8Snorm", 20, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba32i", 21, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba16i", 22, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba8i", 23, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R32i", 24, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg32i", 25, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg16i", 26, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg8i", 27, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R16i", 28, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R8i", 29, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba32ui", 30, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba16ui", 31, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgba8ui", 32, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R32ui", 33, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rgb10a2ui", 34, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg32ui", 35, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg16ui", 36, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rg8ui", 37, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R16ui", 38, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R8ui", 39, 1, pygen_variable_caps_StorageImageExtendedFormats, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R64ui", 40, 1, pygen_variable_caps_Int64ImageEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"R64i", 41, 1, pygen_variable_caps_Int64ImageEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ImageChannelOrderEntries[] = { + {"R", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"A", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RG", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RA", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RGB", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RGBA", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BGRA", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ARGB", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Intensity", 8, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Luminance", 9, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Rx", 10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RGx", 11, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RGBx", 12, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Depth", 13, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DepthStencil", 14, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"sRGB", 15, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"sRGBx", 16, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"sRGBA", 17, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"sBGRA", 18, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ABGR", 19, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ImageChannelDataTypeEntries[] = { + {"SnormInt8", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SnormInt16", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnormInt8", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnormInt16", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnormShort565", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnormShort555", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnormInt101010", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SignedInt8", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SignedInt16", 8, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SignedInt32", 9, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnsignedInt8", 10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnsignedInt16", 11, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnsignedInt32", 12, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"HalfFloat", 13, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Float", 14, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnormInt24", 15, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnormInt101010_2", 16, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnsignedIntRaw10EXT", 19, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UnsignedIntRaw12EXT", 20, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FPRoundingModeEntries[] = { + {"RTE", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RTZ", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RTP", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RTN", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FPDenormModeEntries[] = { + {"Preserve", 0, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"FlushToZero", 1, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_QuantizationModesEntries[] = { + {"TRN", 0, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"TRN_ZERO", 1, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RND", 2, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RND_ZERO", 3, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RND_INF", 4, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RND_MIN_INF", 5, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RND_CONV", 6, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RND_CONV_ODD", 7, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FPOperationModeEntries[] = { + {"IEEE", 0, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ALT", 1, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_OverflowModesEntries[] = { + {"WRAP", 0, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SAT", 1, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SAT_ZERO", 2, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SAT_SYM", 3, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_LinkageTypeEntries[] = { + {"Export", 0, 1, pygen_variable_caps_Linkage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Import", 1, 1, pygen_variable_caps_Linkage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LinkOnceODR", 2, 1, pygen_variable_caps_Linkage, 1, pygen_variable_exts_SPV_KHR_linkonce_odr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_AccessQualifierEntries[] = { + {"ReadOnly", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WriteOnly", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ReadWrite", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_HostAccessQualifierEntries[] = { + {"NoneINTEL", 0, 1, pygen_variable_caps_GlobalVariableHostAccessINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ReadINTEL", 1, 1, pygen_variable_caps_GlobalVariableHostAccessINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"WriteINTEL", 2, 1, pygen_variable_caps_GlobalVariableHostAccessINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ReadWriteINTEL", 3, 1, pygen_variable_caps_GlobalVariableHostAccessINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_FunctionParameterAttributeEntries[] = { + {"Zext", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Sext", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ByVal", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Sret", 3, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NoAlias", 4, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NoCapture", 5, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NoWrite", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NoReadWrite", 7, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"RuntimeAlignedINTEL", 5940, 1, pygen_variable_caps_RuntimeAlignedAttributeINTEL, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DecorationEntries[] = { + {"RelaxedPrecision", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SpecId", 1, 2, pygen_variable_caps_ShaderKernel, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Block", 2, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BufferBlock", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), SPV_SPIRV_VERSION_WORD(1,3)}, + {"RowMajor", 4, 1, pygen_variable_caps_Matrix, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ColMajor", 5, 1, pygen_variable_caps_Matrix, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ArrayStride", 6, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MatrixStride", 7, 1, pygen_variable_caps_Matrix, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GLSLShared", 8, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GLSLPacked", 9, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CPacked", 10, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"BuiltIn", 11, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_BUILT_IN}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NoPerspective", 13, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Flat", 14, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Patch", 15, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Centroid", 16, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Sample", 17, 1, pygen_variable_caps_SampleRateShading, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Invariant", 18, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Restrict", 19, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Aliased", 20, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Volatile", 21, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Constant", 22, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Coherent", 23, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NonWritable", 24, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NonReadable", 25, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Uniform", 26, 2, pygen_variable_caps_ShaderUniformDecoration, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UniformId", 27, 2, pygen_variable_caps_ShaderUniformDecoration, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"SaturatedConversion", 28, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Stream", 29, 1, pygen_variable_caps_GeometryStreams, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Location", 30, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Component", 31, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Index", 32, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Binding", 33, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DescriptorSet", 34, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Offset", 35, 1, pygen_variable_caps_Shader, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"XfbBuffer", 36, 1, pygen_variable_caps_TransformFeedback, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"XfbStride", 37, 1, pygen_variable_caps_TransformFeedback, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FuncParamAttr", 38, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FPRoundingMode", 39, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_FP_ROUNDING_MODE}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FPFastMathMode", 40, 2, pygen_variable_caps_KernelFloatControls2, 0, nullptr, {SPV_OPERAND_TYPE_FP_FAST_MATH_MODE}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LinkageAttributes", 41, 1, pygen_variable_caps_Linkage, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LINKAGE_TYPE}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NoContraction", 42, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InputAttachmentIndex", 43, 1, pygen_variable_caps_InputAttachment, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Alignment", 44, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MaxByteOffset", 45, 1, pygen_variable_caps_Addresses, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"AlignmentId", 46, 1, pygen_variable_caps_Kernel, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"MaxByteOffsetId", 47, 1, pygen_variable_caps_Addresses, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,2), 0xffffffffu}, + {"NoSignedWrap", 4469, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"NoUnsignedWrap", 4470, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_no_integer_wrap_decoration, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"WeightTextureQCOM", 4487, 0, nullptr, 1, pygen_variable_exts_SPV_QCOM_image_processing, {}, 0xffffffffu, 0xffffffffu}, + {"BlockMatchTextureQCOM", 4488, 0, nullptr, 1, pygen_variable_exts_SPV_QCOM_image_processing, {}, 0xffffffffu, 0xffffffffu}, + {"BlockMatchSamplerQCOM", 4499, 0, nullptr, 1, pygen_variable_exts_SPV_QCOM_image_processing2, {}, 0xffffffffu, 0xffffffffu}, + {"ExplicitInterpAMD", 4999, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"NodeSharesPayloadLimitsWithAMDX", 5019, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"NodeMaxPayloadsAMDX", 5020, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"TrackFinishWritingAMDX", 5078, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"PayloadNodeNameAMDX", 5091, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"OverrideCoverageNV", 5248, 1, pygen_variable_caps_SampleMaskOverrideCoverageNV, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu}, + {"PassthroughNV", 5250, 1, pygen_variable_caps_GeometryShaderPassthroughNV, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu}, + {"ViewportRelativeNV", 5252, 1, pygen_variable_caps_ShaderViewportMaskNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SecondaryViewportRelativeNV", 5256, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"PerPrimitiveNV", 5271, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PerPrimitiveEXT", 5271, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PerViewNV", 5272, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PerTaskNV", 5273, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PerVertexKHR", 5285, 2, pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"PerVertexNV", 5285, 2, pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"NonUniform", 5300, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"NonUniformEXT", 5300, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RestrictPointer", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RestrictPointerEXT", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"AliasedPointer", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"AliasedPointerEXT", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"HitObjectShaderRecordBufferNV", 5386, 1, pygen_variable_caps_ShaderInvocationReorderNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"BindlessSamplerNV", 5398, 1, pygen_variable_caps_BindlessTextureNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"BindlessImageNV", 5399, 1, pygen_variable_caps_BindlessTextureNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"BoundSamplerNV", 5400, 1, pygen_variable_caps_BindlessTextureNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"BoundImageNV", 5401, 1, pygen_variable_caps_BindlessTextureNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SIMTCallINTEL", 5599, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"ReferencedIndirectlyINTEL", 5602, 1, pygen_variable_caps_IndirectReferencesINTEL, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}, + {"ClobberINTEL", 5607, 1, pygen_variable_caps_AsmINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"SideEffectsINTEL", 5608, 1, pygen_variable_caps_AsmINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"VectorComputeVariableINTEL", 5624, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"FuncParamIOKindINTEL", 5625, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"VectorComputeFunctionINTEL", 5626, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"StackCallINTEL", 5627, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"GlobalVariableOffsetINTEL", 5628, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"CounterBuffer", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"HlslCounterBufferGOOGLE", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"UserSemantic", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"HlslSemanticGOOGLE", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"UserTypeGOOGLE", 5636, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_user_type, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"FunctionRoundingModeINTEL", 5822, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_FP_ROUNDING_MODE}, 0xffffffffu, 0xffffffffu}, + {"FunctionDenormModeINTEL", 5823, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_FPDENORM_MODE}, 0xffffffffu, 0xffffffffu}, + {"RegisterINTEL", 5825, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"MemoryINTEL", 5826, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"NumbanksINTEL", 5827, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"BankwidthINTEL", 5828, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxPrivateCopiesINTEL", 5829, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"SinglepumpINTEL", 5830, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"DoublepumpINTEL", 5831, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"MaxReplicatesINTEL", 5832, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"SimpleDualPortINTEL", 5833, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"MergeINTEL", 5834, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"BankBitsINTEL", 5835, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"ForcePow2DepthINTEL", 5836, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"StridesizeINTEL", 5883, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"WordsizeINTEL", 5884, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"TrueDualPortINTEL", 5885, 1, pygen_variable_caps_FPGAMemoryAttributesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"BurstCoalesceINTEL", 5899, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CacheSizeINTEL", 5900, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"DontStaticallyCoalesceINTEL", 5901, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"PrefetchINTEL", 5902, 1, pygen_variable_caps_FPGAMemoryAccessesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"StallEnableINTEL", 5905, 1, pygen_variable_caps_FPGAClusterAttributesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"FuseLoopsInFunctionINTEL", 5907, 1, pygen_variable_caps_LoopFuseINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MathOpDSPModeINTEL", 5909, 1, pygen_variable_caps_FPGADSPControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"AliasScopeINTEL", 5914, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"NoAliasINTEL", 5915, 1, pygen_variable_caps_MemoryAccessAliasingINTEL, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"InitiationIntervalINTEL", 5917, 1, pygen_variable_caps_FPGAInvocationPipeliningAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaxConcurrencyINTEL", 5918, 1, pygen_variable_caps_FPGAInvocationPipeliningAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"PipelineEnableINTEL", 5919, 1, pygen_variable_caps_FPGAInvocationPipeliningAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"BufferLocationINTEL", 5921, 1, pygen_variable_caps_FPGABufferLocationINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"IOPipeStorageINTEL", 5944, 1, pygen_variable_caps_IOPipesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"FunctionFloatingPointModeINTEL", 6080, 1, pygen_variable_caps_FunctionFloatControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_FPOPERATION_MODE}, 0xffffffffu, 0xffffffffu}, + {"SingleElementVectorINTEL", 6085, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"VectorComputeCallableFunctionINTEL", 6087, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MediaBlockIOINTEL", 6140, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"StallFreeINTEL", 6151, 1, pygen_variable_caps_FPGAClusterAttributesV2INTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"FPMaxErrorDecorationINTEL", 6170, 1, pygen_variable_caps_FPMaxErrorINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_FLOAT}, 0xffffffffu, 0xffffffffu}, + {"LatencyControlLabelINTEL", 6172, 1, pygen_variable_caps_FPGALatencyControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"LatencyControlConstraintINTEL", 6173, 1, pygen_variable_caps_FPGALatencyControlINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"ConduitKernelArgumentINTEL", 6175, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RegisterMapKernelArgumentINTEL", 6176, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MMHostInterfaceAddressWidthINTEL", 6177, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MMHostInterfaceDataWidthINTEL", 6178, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MMHostInterfaceLatencyINTEL", 6179, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MMHostInterfaceReadWriteModeINTEL", 6180, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 0xffffffffu, 0xffffffffu}, + {"MMHostInterfaceMaxBurstINTEL", 6181, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MMHostInterfaceWaitRequestINTEL", 6182, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"StableKernelArgumentINTEL", 6183, 1, pygen_variable_caps_FPGAArgumentInterfacesINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"HostAccessINTEL", 6188, 1, pygen_variable_caps_GlobalVariableHostAccessINTEL, 0, nullptr, {SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER, SPV_OPERAND_TYPE_LITERAL_STRING}, 0xffffffffu, 0xffffffffu}, + {"InitModeINTEL", 6190, 1, pygen_variable_caps_GlobalVariableFPGADecorationsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER}, 0xffffffffu, 0xffffffffu}, + {"ImplementInRegisterMapINTEL", 6191, 1, pygen_variable_caps_GlobalVariableFPGADecorationsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"CacheControlLoadINTEL", 6442, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL}, 0xffffffffu, 0xffffffffu}, + {"CacheControlStoreINTEL", 6443, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_STORE_CACHE_CONTROL}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = { + {"Position", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PointSize", 1, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ClipDistance", 3, 1, pygen_variable_caps_ClipDistance, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CullDistance", 4, 1, pygen_variable_caps_CullDistance, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VertexId", 5, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InstanceId", 6, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PrimitiveId", 7, 6, pygen_variable_caps_GeometryTessellationRayTracingNVRayTracingKHRMeshShadingNVMeshShadingEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InvocationId", 8, 2, pygen_variable_caps_GeometryTessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Layer", 9, 5, pygen_variable_caps_GeometryShaderLayerShaderViewportIndexLayerEXTMeshShadingNVMeshShadingEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ViewportIndex", 10, 5, pygen_variable_caps_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXTMeshShadingNVMeshShadingEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TessLevelOuter", 11, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TessLevelInner", 12, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TessCoord", 13, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PatchVertices", 14, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FragCoord", 15, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"PointCoord", 16, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FrontFacing", 17, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SampleId", 18, 1, pygen_variable_caps_SampleRateShading, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SamplePosition", 19, 1, pygen_variable_caps_SampleRateShading, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SampleMask", 20, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"FragDepth", 22, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"HelperInvocation", 23, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NumWorkgroups", 24, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WorkgroupSize", 25, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WorkgroupId", 26, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LocalInvocationId", 27, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GlobalInvocationId", 28, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LocalInvocationIndex", 29, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WorkDim", 30, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GlobalSize", 31, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"EnqueuedWorkgroupSize", 32, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GlobalOffset", 33, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GlobalLinearId", 34, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SubgroupSize", 36, 3, pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SubgroupMaxSize", 37, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NumSubgroups", 38, 2, pygen_variable_caps_KernelGroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"NumEnqueuedSubgroups", 39, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SubgroupId", 40, 2, pygen_variable_caps_KernelGroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SubgroupLocalInvocationId", 41, 3, pygen_variable_caps_KernelGroupNonUniformSubgroupBallotKHR, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"VertexIndex", 42, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InstanceIndex", 43, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CoreIDARM", 4160, 1, pygen_variable_caps_CoreBuiltinsARM, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CoreCountARM", 4161, 1, pygen_variable_caps_CoreBuiltinsARM, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CoreMaxIDARM", 4162, 1, pygen_variable_caps_CoreBuiltinsARM, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WarpIDARM", 4163, 1, pygen_variable_caps_CoreBuiltinsARM, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WarpMaxIDARM", 4164, 1, pygen_variable_caps_CoreBuiltinsARM, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SubgroupEqMask", 4416, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupEqMaskKHR", 4416, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupGeMask", 4417, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupGeMaskKHR", 4417, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupGtMask", 4418, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupGtMaskKHR", 4418, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupLeMask", 4419, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupLeMaskKHR", 4419, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupLtMask", 4420, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"SubgroupLtMaskKHR", 4420, 2, pygen_variable_caps_SubgroupBallotKHRGroupNonUniformBallot, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"BaseVertex", 4424, 1, pygen_variable_caps_DrawParameters, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"BaseInstance", 4425, 1, pygen_variable_caps_DrawParameters, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"DrawIndex", 4426, 3, pygen_variable_caps_DrawParametersMeshShadingNVMeshShadingEXT, 3, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_KHR_shader_draw_parametersSPV_NV_mesh_shader, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"PrimitiveShadingRateKHR", 4432, 1, pygen_variable_caps_FragmentShadingRateKHR, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"DeviceIndex", 4438, 1, pygen_variable_caps_DeviceGroup, 1, pygen_variable_exts_SPV_KHR_device_group, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"ViewIndex", 4440, 1, pygen_variable_caps_MultiView, 1, pygen_variable_exts_SPV_KHR_multiview, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"ShadingRateKHR", 4444, 1, pygen_variable_caps_FragmentShadingRateKHR, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNoPerspAMD", 4992, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNoPerspCentroidAMD", 4993, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNoPerspSampleAMD", 4994, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordSmoothAMD", 4995, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordSmoothCentroidAMD", 4996, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordSmoothSampleAMD", 4997, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordPullModelAMD", 4998, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu}, + {"FragStencilRefEXT", 5014, 1, pygen_variable_caps_StencilExportEXT, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"CoalescedInputCountAMDX", 5021, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderIndexAMDX", 5073, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ViewportMaskNV", 5253, 2, pygen_variable_caps_ShaderViewportMaskNVMeshShadingNV, 2, pygen_variable_exts_SPV_NV_mesh_shaderSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, + {"SecondaryPositionNV", 5257, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {}, 0xffffffffu, 0xffffffffu}, + {"SecondaryViewportMaskNV", 5258, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {}, 0xffffffffu, 0xffffffffu}, + {"PositionPerViewNV", 5261, 2, pygen_variable_caps_PerViewAttributesNVMeshShadingNV, 2, pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"ViewportMaskPerViewNV", 5262, 2, pygen_variable_caps_PerViewAttributesNVMeshShadingNV, 2, pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"FullyCoveredEXT", 5264, 1, pygen_variable_caps_FragmentFullyCoveredEXT, 1, pygen_variable_exts_SPV_EXT_fragment_fully_covered, {}, 0xffffffffu, 0xffffffffu}, + {"TaskCountNV", 5274, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PrimitiveCountNV", 5275, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PrimitiveIndicesNV", 5276, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"ClipDistancePerViewNV", 5277, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"CullDistancePerViewNV", 5278, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"LayerPerViewNV", 5279, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"MeshViewCountNV", 5280, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"MeshViewIndicesNV", 5281, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordKHR", 5286, 2, pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNV", 5286, 2, pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNoPerspKHR", 5287, 2, pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"BaryCoordNoPerspNV", 5287, 2, pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"FragSizeEXT", 5292, 2, pygen_variable_caps_FragmentDensityEXTShadingRateNV, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentSizeNV", 5292, 2, pygen_variable_caps_ShadingRateNVFragmentDensityEXT, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"FragInvocationCountEXT", 5293, 2, pygen_variable_caps_FragmentDensityEXTShadingRateNV, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"InvocationsPerPixelNV", 5293, 2, pygen_variable_caps_ShadingRateNVFragmentDensityEXT, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"PrimitivePointIndicesEXT", 5294, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PrimitiveLineIndicesEXT", 5295, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PrimitiveTriangleIndicesEXT", 5296, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"CullPrimitiveEXT", 5299, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchIdNV", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchIdKHR", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchSizeNV", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchSizeKHR", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayOriginNV", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayOriginKHR", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayDirectionNV", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayDirectionKHR", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayOriginNV", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayOriginKHR", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayDirectionNV", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayDirectionKHR", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTminNV", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTminKHR", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTmaxNV", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTmaxKHR", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"InstanceCustomIndexNV", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"InstanceCustomIndexKHR", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectToWorldNV", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectToWorldKHR", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldToObjectNV", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldToObjectKHR", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitTNV", 5332, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitKindNV", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitKindKHR", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"CurrentRayTimeNV", 5334, 1, pygen_variable_caps_RayTracingMotionBlurNV, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, {}, 0xffffffffu, 0xffffffffu}, + {"HitTriangleVertexPositionsKHR", 5335, 1, pygen_variable_caps_RayTracingPositionFetchKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"HitMicroTriangleVertexPositionsNV", 5337, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"HitMicroTriangleVertexBarycentricsNV", 5344, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayFlagsNV", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayFlagsKHR", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayGeometryIndexKHR", 5352, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WarpsPerSMNV", 5374, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"SMCountNV", 5375, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"WarpIDNV", 5376, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"SMIDNV", 5377, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"HitKindFrontFacingMicroTriangleNV", 5405, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"HitKindBackFacingMicroTriangleNV", 5406, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CullMaskKHR", 6021, 1, pygen_variable_caps_RayCullMaskKHR, 1, pygen_variable_exts_SPV_KHR_ray_cull_mask, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_ScopeEntries[] = { + {"CrossDevice", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Device", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Workgroup", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Subgroup", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Invocation", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"QueueFamily", 5, 1, pygen_variable_caps_VulkanMemoryModel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"QueueFamilyKHR", 5, 1, pygen_variable_caps_VulkanMemoryModel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ShaderCallKHR", 6, 1, pygen_variable_caps_RayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_GroupOperationEntries[] = { + {"Reduce", 0, 3, pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InclusiveScan", 1, 3, pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ExclusiveScan", 2, 3, pygen_variable_caps_KernelGroupNonUniformArithmeticGroupNonUniformBallot, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ClusteredReduce", 3, 1, pygen_variable_caps_GroupNonUniformClustered, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"PartitionedReduceNV", 6, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu}, + {"PartitionedInclusiveScanNV", 7, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu}, + {"PartitionedExclusiveScanNV", 8, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_KernelEnqueueFlagsEntries[] = { + {"NoWait", 0, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WaitKernel", 1, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"WaitWorkGroup", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { + {"Matrix", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Shader", 1, 1, pygen_variable_caps_Matrix, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Geometry", 2, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Tessellation", 3, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Addresses", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Linkage", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Kernel", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Vector16", 7, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Float16Buffer", 8, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Float16", 9, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Float64", 10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Int64", 11, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Int64Atomics", 12, 1, pygen_variable_caps_Int64, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageBasic", 13, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageReadWrite", 14, 1, pygen_variable_caps_ImageBasic, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageMipmap", 15, 1, pygen_variable_caps_ImageBasic, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Pipes", 17, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Groups", 18, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_ballot, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DeviceEnqueue", 19, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"LiteralSampler", 20, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"AtomicStorage", 21, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Int16", 22, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TessellationPointSize", 23, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GeometryPointSize", 24, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageGatherExtended", 25, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"StorageImageMultisample", 27, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"UniformBufferArrayDynamicIndexing", 28, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SampledImageArrayDynamicIndexing", 29, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"StorageBufferArrayDynamicIndexing", 30, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"StorageImageArrayDynamicIndexing", 31, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ClipDistance", 32, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"CullDistance", 33, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageCubeArray", 34, 1, pygen_variable_caps_SampledCubeArray, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SampleRateShading", 35, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageRect", 36, 1, pygen_variable_caps_SampledRect, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SampledRect", 37, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GenericPointer", 38, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Int8", 39, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InputAttachment", 40, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SparseResidency", 41, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MinLod", 42, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Sampled1D", 43, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"Image1D", 44, 1, pygen_variable_caps_Sampled1D, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SampledCubeArray", 45, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SampledBuffer", 46, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageBuffer", 47, 1, pygen_variable_caps_SampledBuffer, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageMSArray", 48, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"StorageImageExtendedFormats", 49, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"ImageQuery", 50, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"DerivativeControl", 51, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"InterpolationFunction", 52, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"TransformFeedback", 53, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"GeometryStreams", 54, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"StorageImageReadWithoutFormat", 55, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"StorageImageWriteWithoutFormat", 56, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"MultiViewport", 57, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, + {"SubgroupDispatch", 58, 1, pygen_variable_caps_DeviceEnqueue, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"NamedBarrier", 59, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"PipeStorage", 60, 1, pygen_variable_caps_Pipes, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,1), 0xffffffffu}, + {"GroupNonUniform", 61, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformVote", 62, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformArithmetic", 63, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformBallot", 64, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformShuffle", 65, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformShuffleRelative", 66, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformClustered", 67, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"GroupNonUniformQuad", 68, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"ShaderLayer", 69, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ShaderViewportIndex", 70, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformDecoration", 71, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"CoreBuiltinsARM", 4165, 0, nullptr, 1, pygen_variable_exts_SPV_ARM_core_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"TileImageColorReadAccessEXT", 4166, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu}, + {"TileImageDepthReadAccessEXT", 4167, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu}, + {"TileImageStencilReadAccessEXT", 4168, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentShadingRateKHR", 4422, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupBallotKHR", 4423, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, 0xffffffffu, 0xffffffffu}, + {"DrawParameters", 4427, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"WorkgroupMemoryExplicitLayoutKHR", 4428, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout, {}, 0xffffffffu, 0xffffffffu}, + {"WorkgroupMemoryExplicitLayout8BitAccessKHR", 4429, 1, pygen_variable_caps_WorkgroupMemoryExplicitLayoutKHR, 1, pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout, {}, 0xffffffffu, 0xffffffffu}, + {"WorkgroupMemoryExplicitLayout16BitAccessKHR", 4430, 1, pygen_variable_caps_WorkgroupMemoryExplicitLayoutKHR, 1, pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupVoteKHR", 4431, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, {}, 0xffffffffu, 0xffffffffu}, + {"StorageBuffer16BitAccess", 4433, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"StorageUniformBufferBlock16", 4433, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"UniformAndStorageBuffer16BitAccess", 4434, 2, pygen_variable_caps_StorageBuffer16BitAccessStorageUniformBufferBlock16, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"StorageUniform16", 4434, 2, pygen_variable_caps_StorageBuffer16BitAccessStorageUniformBufferBlock16, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"StoragePushConstant16", 4435, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"StorageInputOutput16", 4436, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_16bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"DeviceGroup", 4437, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_device_group, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"MultiView", 4439, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_multiview, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"VariablePointersStorageBuffer", 4441, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_variable_pointers, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"VariablePointers", 4442, 1, pygen_variable_caps_VariablePointersStorageBuffer, 1, pygen_variable_exts_SPV_KHR_variable_pointers, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, + {"AtomicStorageOps", 4445, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_atomic_counter_ops, {}, 0xffffffffu, 0xffffffffu}, + {"SampleMaskPostDepthCoverage", 4447, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_post_depth_coverage, {}, 0xffffffffu, 0xffffffffu}, + {"StorageBuffer8BitAccess", 4448, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformAndStorageBuffer8BitAccess", 4449, 1, pygen_variable_caps_StorageBuffer8BitAccess, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StoragePushConstant8", 4450, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"DenormPreserve", 4464, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"DenormFlushToZero", 4465, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"SignedZeroInfNanPreserve", 4466, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RoundingModeRTE", 4467, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RoundingModeRTZ", 4468, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}, + {"RayQueryProvisionalKHR", 4471, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_query, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryKHR", 4472, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_query, {}, 0xffffffffu, 0xffffffffu}, + {"RayTraversalPrimitiveCullingKHR", 4478, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_querySPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTracingKHR", 4479, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"TextureSampleWeightedQCOM", 4484, 0, nullptr, 1, pygen_variable_exts_SPV_QCOM_image_processing, {}, 0xffffffffu, 0xffffffffu}, + {"TextureBoxFilterQCOM", 4485, 0, nullptr, 1, pygen_variable_exts_SPV_QCOM_image_processing, {}, 0xffffffffu, 0xffffffffu}, + {"TextureBlockMatchQCOM", 4486, 0, nullptr, 1, pygen_variable_exts_SPV_QCOM_image_processing, {}, 0xffffffffu, 0xffffffffu}, + {"TextureBlockMatch2QCOM", 4498, 0, nullptr, 1, pygen_variable_exts_SPV_QCOM_image_processing2, {}, 0xffffffffu, 0xffffffffu}, + {"Float16ImageAMD", 5008, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_gpu_shader_half_float_fetch, {}, 0xffffffffu, 0xffffffffu}, + {"ImageGatherBiasLodAMD", 5009, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_texture_gather_bias_lod, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentMaskAMD", 5010, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, {}, 0xffffffffu, 0xffffffffu}, + {"StencilExportEXT", 5013, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, + {"ImageReadWriteLodAMD", 5015, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_image_load_store_lod, {}, 0xffffffffu, 0xffffffffu}, + {"Int64ImageEXT", 5016, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_image_int64, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderClockKHR", 5055, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_clock, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderEnqueueAMDX", 5067, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMDX_shader_enqueue, {}, 0xffffffffu, 0xffffffffu}, + {"QuadControlKHR", 5087, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_quad_control, {}, 0xffffffffu, 0xffffffffu}, + {"SampleMaskOverrideCoverageNV", 5249, 1, pygen_variable_caps_SampleRateShading, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu}, + {"GeometryShaderPassthroughNV", 5251, 1, pygen_variable_caps_Geometry, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderViewportIndexLayerEXT", 5254, 1, pygen_variable_caps_MultiViewport, 2, pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderViewportIndexLayerNV", 5254, 1, pygen_variable_caps_MultiViewport, 2, pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderViewportMaskNV", 5255, 1, pygen_variable_caps_ShaderViewportIndexLayerNV, 1, pygen_variable_exts_SPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderStereoViewNV", 5259, 1, pygen_variable_caps_ShaderViewportMaskNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {}, 0xffffffffu, 0xffffffffu}, + {"PerViewAttributesNV", 5260, 1, pygen_variable_caps_MultiView, 1, pygen_variable_exts_SPV_NVX_multiview_per_view_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentFullyCoveredEXT", 5265, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_fully_covered, {}, 0xffffffffu, 0xffffffffu}, + {"MeshShadingNV", 5266, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"ImageFootprintNV", 5282, 0, nullptr, 1, pygen_variable_exts_SPV_NV_shader_image_footprint, {}, 0xffffffffu, 0xffffffffu}, + {"MeshShadingEXT", 5283, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentBarycentricKHR", 5284, 0, nullptr, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentBarycentricNV", 5284, 0, nullptr, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, + {"ComputeDerivativeGroupQuadsNV", 5288, 0, nullptr, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentDensityEXT", 5291, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"ShadingRateNV", 5291, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformPartitionedNV", 5297, 0, nullptr, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderNonUniform", 5301, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ShaderNonUniformEXT", 5301, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RuntimeDescriptorArray", 5302, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RuntimeDescriptorArrayEXT", 5302, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"InputAttachmentArrayDynamicIndexing", 5303, 1, pygen_variable_caps_InputAttachment, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"InputAttachmentArrayDynamicIndexingEXT", 5303, 1, pygen_variable_caps_InputAttachment, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformTexelBufferArrayDynamicIndexing", 5304, 1, pygen_variable_caps_SampledBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformTexelBufferArrayDynamicIndexingEXT", 5304, 1, pygen_variable_caps_SampledBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageTexelBufferArrayDynamicIndexing", 5305, 1, pygen_variable_caps_ImageBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageTexelBufferArrayDynamicIndexingEXT", 5305, 1, pygen_variable_caps_ImageBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformBufferArrayNonUniformIndexing", 5306, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformBufferArrayNonUniformIndexingEXT", 5306, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"SampledImageArrayNonUniformIndexing", 5307, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"SampledImageArrayNonUniformIndexingEXT", 5307, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageBufferArrayNonUniformIndexing", 5308, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageBufferArrayNonUniformIndexingEXT", 5308, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageImageArrayNonUniformIndexing", 5309, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageImageArrayNonUniformIndexingEXT", 5309, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"InputAttachmentArrayNonUniformIndexing", 5310, 2, pygen_variable_caps_InputAttachmentShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"InputAttachmentArrayNonUniformIndexingEXT", 5310, 2, pygen_variable_caps_InputAttachmentShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformTexelBufferArrayNonUniformIndexing", 5311, 2, pygen_variable_caps_SampledBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"UniformTexelBufferArrayNonUniformIndexingEXT", 5311, 2, pygen_variable_caps_SampledBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageTexelBufferArrayNonUniformIndexing", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"StorageTexelBufferArrayNonUniformIndexingEXT", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"RayTracingPositionFetchKHR", 5336, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing_position_fetch, {}, 0xffffffffu, 0xffffffffu}, + {"RayTracingNV", 5340, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTracingMotionBlurNV", 5341, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, {}, 0xffffffffu, 0xffffffffu}, + {"VulkanMemoryModel", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VulkanMemoryModelKHR", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VulkanMemoryModelDeviceScope", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"VulkanMemoryModelDeviceScopeKHR", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferAddresses", 5347, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"PhysicalStorageBufferAddressesEXT", 5347, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, + {"ComputeDerivativeGroupLinearNV", 5350, 0, nullptr, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, + {"RayTracingProvisionalKHR", 5353, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixNV", 5357, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentShaderSampleInterlockEXT", 5363, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentShaderShadingRateInterlockEXT", 5372, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderSMBuiltinsNV", 5373, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, + {"FragmentShaderPixelInterlockEXT", 5378, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, + {"DemoteToHelperInvocation", 5379, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DemoteToHelperInvocationEXT", 5379, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_demote_to_helper_invocation, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DisplacementMicromapNV", 5380, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_displacement_micromap, {}, 0xffffffffu, 0xffffffffu}, + {"RayTracingOpacityMicromapEXT", 5381, 2, pygen_variable_caps_RayQueryKHRRayTracingKHR, 1, pygen_variable_exts_SPV_EXT_opacity_micromap, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderInvocationReorderNV", 5383, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_NV_shader_invocation_reorder, {}, 0xffffffffu, 0xffffffffu}, + {"BindlessTextureNV", 5390, 0, nullptr, 1, pygen_variable_exts_SPV_NV_bindless_texture, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryPositionFetchKHR", 5391, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing_position_fetch, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat16VectorNV", 5404, 0, nullptr, 1, pygen_variable_exts_SPV_NV_shader_atomic_fp16_vector, {}, 0xffffffffu, 0xffffffffu}, + {"RayTracingDisplacementMicromapNV", 5409, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_NV_displacement_micromap, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupShuffleINTEL", 5568, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupBufferBlockIOINTEL", 5569, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageBlockIOINTEL", 5570, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupImageMediaBlockIOINTEL", 5579, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_media_block_io, {}, 0xffffffffu, 0xffffffffu}, + {"RoundToInfinityINTEL", 5582, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_float_controls2, {}, 0xffffffffu, 0xffffffffu}, + {"FloatingPointModeINTEL", 5583, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_float_controls2, {}, 0xffffffffu, 0xffffffffu}, + {"IntegerFunctions2INTEL", 5584, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_INTEL_shader_integer_functions2, {}, 0xffffffffu, 0xffffffffu}, + {"FunctionPointersINTEL", 5603, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}, + {"IndirectReferencesINTEL", 5604, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_function_pointers, {}, 0xffffffffu, 0xffffffffu}, + {"AsmINTEL", 5606, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_inline_assembly, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat32MinMaxEXT", 5612, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_min_max, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat64MinMaxEXT", 5613, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_min_max, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat16MinMaxEXT", 5616, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_min_max, {}, 0xffffffffu, 0xffffffffu}, + {"VectorComputeINTEL", 5617, 1, pygen_variable_caps_VectorAnyINTEL, 1, pygen_variable_exts_SPV_INTEL_vector_compute, {}, 0xffffffffu, 0xffffffffu}, + {"VectorAnyINTEL", 5619, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_vector_compute, {}, 0xffffffffu, 0xffffffffu}, + {"ExpectAssumeKHR", 5629, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_expect_assume, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMotionEstimationINTEL", 5696, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMotionEstimationIntraINTEL", 5697, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu}, + {"SubgroupAvcMotionEstimationChromaINTEL", 5698, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_device_side_avc_motion_estimation, {}, 0xffffffffu, 0xffffffffu}, + {"VariableLengthArrayINTEL", 5817, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_variable_length_array, {}, 0xffffffffu, 0xffffffffu}, + {"FunctionFloatControlINTEL", 5821, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_float_controls2, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAMemoryAttributesINTEL", 5824, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FPFastMathModeINTEL", 5837, 1, pygen_variable_caps_Kernel, 1, pygen_variable_exts_SPV_INTEL_fp_fast_math_mode, {}, 0xffffffffu, 0xffffffffu}, + {"ArbitraryPrecisionIntegersINTEL", 5844, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_arbitrary_precision_integers, {}, 0xffffffffu, 0xffffffffu}, + {"ArbitraryPrecisionFloatingPointINTEL", 5845, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_arbitrary_precision_floating_point, {}, 0xffffffffu, 0xffffffffu}, + {"UnstructuredLoopControlsINTEL", 5886, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_unstructured_loop_controls, {}, 0xffffffffu, 0xffffffffu}, + {"FPGALoopControlsINTEL", 5888, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_loop_controls, {}, 0xffffffffu, 0xffffffffu}, + {"KernelAttributesINTEL", 5892, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAKernelAttributesINTEL", 5897, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAMemoryAccessesINTEL", 5898, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_memory_accesses, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAClusterAttributesINTEL", 5904, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_cluster_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"LoopFuseINTEL", 5906, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_loop_fuse, {}, 0xffffffffu, 0xffffffffu}, + {"FPGADSPControlINTEL", 5908, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_dsp_control, {}, 0xffffffffu, 0xffffffffu}, + {"MemoryAccessAliasingINTEL", 5910, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_memory_access_aliasing, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAInvocationPipeliningAttributesINTEL", 5916, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_invocation_pipelining_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FPGABufferLocationINTEL", 5920, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_buffer_location, {}, 0xffffffffu, 0xffffffffu}, + {"ArbitraryPrecisionFixedPointINTEL", 5922, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_arbitrary_precision_fixed_point, {}, 0xffffffffu, 0xffffffffu}, + {"USMStorageClassesINTEL", 5935, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_usm_storage_classes, {}, 0xffffffffu, 0xffffffffu}, + {"RuntimeAlignedAttributeINTEL", 5939, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_runtime_aligned, {}, 0xffffffffu, 0xffffffffu}, + {"IOPipesINTEL", 5943, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_io_pipes, {}, 0xffffffffu, 0xffffffffu}, + {"BlockingPipesINTEL", 5945, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_blocking_pipes, {}, 0xffffffffu, 0xffffffffu}, + {"FPGARegINTEL", 5948, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_reg, {}, 0xffffffffu, 0xffffffffu}, + {"DotProductInputAll", 6016, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DotProductInputAllKHR", 6016, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DotProductInput4x8Bit", 6017, 1, pygen_variable_caps_Int8, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DotProductInput4x8BitKHR", 6017, 1, pygen_variable_caps_Int8, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DotProductInput4x8BitPacked", 6018, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DotProductInput4x8BitPackedKHR", 6018, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DotProduct", 6019, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"DotProductKHR", 6019, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"RayCullMaskKHR", 6020, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_ray_cull_mask, {}, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixKHR", 6022, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_cooperative_matrix, {}, 0xffffffffu, 0xffffffffu}, + {"BitInstructions", 6025, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_bit_instructions, {}, 0xffffffffu, 0xffffffffu}, + {"GroupNonUniformRotateKHR", 6026, 1, pygen_variable_caps_GroupNonUniform, 1, pygen_variable_exts_SPV_KHR_subgroup_rotate, {}, 0xffffffffu, 0xffffffffu}, + {"FloatControls2", 6029, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls2, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat32AddEXT", 6033, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat64AddEXT", 6034, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float_add, {}, 0xffffffffu, 0xffffffffu}, + {"LongCompositesINTEL", 6089, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_long_composites, {}, 0xffffffffu, 0xffffffffu}, + {"OptNoneINTEL", 6094, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_optnone, {}, 0xffffffffu, 0xffffffffu}, + {"AtomicFloat16AddEXT", 6095, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float16_add, {}, 0xffffffffu, 0xffffffffu}, + {"DebugInfoModuleINTEL", 6114, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_debug_module, {}, 0xffffffffu, 0xffffffffu}, + {"BFloat16ConversionINTEL", 6115, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_bfloat16_conversion, {}, 0xffffffffu, 0xffffffffu}, + {"SplitBarrierINTEL", 6141, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_split_barrier, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAClusterAttributesV2INTEL", 6150, 1, pygen_variable_caps_FPGAClusterAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_fpga_cluster_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAKernelAttributesv2INTEL", 6161, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 1, pygen_variable_exts_SPV_INTEL_kernel_attributes, {}, 0xffffffffu, 0xffffffffu}, + {"FPMaxErrorINTEL", 6169, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fp_max_error, {}, 0xffffffffu, 0xffffffffu}, + {"FPGALatencyControlINTEL", 6171, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_latency_control, {}, 0xffffffffu, 0xffffffffu}, + {"FPGAArgumentInterfacesINTEL", 6174, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_fpga_argument_interfaces, {}, 0xffffffffu, 0xffffffffu}, + {"GlobalVariableHostAccessINTEL", 6187, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_global_variable_host_access, {}, 0xffffffffu, 0xffffffffu}, + {"GlobalVariableFPGADecorationsINTEL", 6189, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_global_variable_fpga_decorations, {}, 0xffffffffu, 0xffffffffu}, + {"GroupUniformArithmeticKHR", 6400, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_uniform_group_instructions, {}, 0xffffffffu, 0xffffffffu}, + {"MaskedGatherScatterINTEL", 6427, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_masked_gather_scatter, {}, 0xffffffffu, 0xffffffffu}, + {"CacheControlsINTEL", 6441, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_cache_controls, {}, 0xffffffffu, 0xffffffffu}, + {"RegisterLimitsINTEL", 6460, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_maximum_registers, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_RayQueryIntersectionEntries[] = { + {"RayQueryCandidateIntersectionKHR", 0, 1, pygen_variable_caps_RayQueryKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryCommittedIntersectionKHR", 1, 1, pygen_variable_caps_RayQueryKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_RayQueryCommittedIntersectionTypeEntries[] = { + {"RayQueryCommittedIntersectionNoneKHR", 0, 1, pygen_variable_caps_RayQueryKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryCommittedIntersectionTriangleKHR", 1, 1, pygen_variable_caps_RayQueryKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryCommittedIntersectionGeneratedKHR", 2, 1, pygen_variable_caps_RayQueryKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_RayQueryCandidateIntersectionTypeEntries[] = { + {"RayQueryCandidateIntersectionTriangleKHR", 0, 1, pygen_variable_caps_RayQueryKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayQueryCandidateIntersectionAABBKHR", 1, 1, pygen_variable_caps_RayQueryKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_PackedVectorFormatEntries[] = { + {"PackedVectorFormat4x8Bit", 0, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, + {"PackedVectorFormat4x8BitKHR", 0, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CooperativeMatrixOperandsEntries[] = { + {"NoneKHR", 0x0000, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MatrixASignedComponentsKHR", 0x0001, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MatrixBSignedComponentsKHR", 0x0002, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MatrixCSignedComponentsKHR", 0x0004, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MatrixResultSignedComponentsKHR", 0x0008, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"SaturatingAccumulationKHR", 0x0010, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CooperativeMatrixLayoutEntries[] = { + {"RowMajorKHR", 0, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ColumnMajorKHR", 1, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CooperativeMatrixUseEntries[] = { + {"MatrixAKHR", 0, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MatrixBKHR", 1, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MatrixAccumulatorKHR", 2, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_InitializationModeQualifierEntries[] = { + {"InitOnDeviceReprogramINTEL", 0, 1, pygen_variable_caps_GlobalVariableFPGADecorationsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"InitOnDeviceResetINTEL", 1, 1, pygen_variable_caps_GlobalVariableFPGADecorationsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_LoadCacheControlEntries[] = { + {"UncachedINTEL", 0, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CachedINTEL", 1, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"StreamingINTEL", 2, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"InvalidateAfterReadINTEL", 3, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ConstCachedINTEL", 4, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_StoreCacheControlEntries[] = { + {"UncachedINTEL", 0, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"WriteThroughINTEL", 1, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"WriteBackINTEL", 2, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"StreamingINTEL", 3, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_NamedMaximumNumberOfRegistersEntries[] = { + {"AutoINTEL", 0, 1, pygen_variable_caps_RegisterLimitsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugInfoFlagsEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsProtected", 0x01, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsPrivate", 0x02, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsPublic", 0x03, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsLocal", 0x04, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsDefinition", 0x08, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagFwdDecl", 0x10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagArtificial", 0x20, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagExplicit", 0x40, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagPrototyped", 0x80, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagObjectPointer", 0x100, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagStaticMember", 0x200, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIndirectVariable", 0x400, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagLValueReference", 0x800, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagRValueReference", 0x1000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsOptimized", 0x2000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugBaseTypeAttributeEncodingEntries[] = { + {"Unspecified", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Address", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Boolean", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Float", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Signed", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SignedChar", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Unsigned", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnsignedChar", 8, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugCompositeTypeEntries[] = { + {"Class", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Structure", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Union", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugTypeQualifierEntries[] = { + {"ConstType", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VolatileType", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RestrictType", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_DebugOperationEntries[] = { + {"Deref", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Plus", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Minus", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PlusUconst", 3, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitPiece", 4, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Swap", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Xderef", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StackValue", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Constu", 8, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugInfoFlagsEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsProtected", 0x01, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsPrivate", 0x02, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsPublic", 0x03, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsLocal", 0x04, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsDefinition", 0x08, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagFwdDecl", 0x10, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagArtificial", 0x20, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagExplicit", 0x40, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagPrototyped", 0x80, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagObjectPointer", 0x100, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagStaticMember", 0x200, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIndirectVariable", 0x400, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagLValueReference", 0x800, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagRValueReference", 0x1000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsOptimized", 0x2000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagIsEnumClass", 0x4000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagTypePassByValue", 0x8000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"FlagTypePassByReference", 0x10000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugBaseTypeAttributeEncodingEntries[] = { + {"Unspecified", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Address", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Boolean", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Float", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Signed", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"SignedChar", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Unsigned", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"UnsignedChar", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugCompositeTypeEntries[] = { + {"Class", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Structure", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Union", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugTypeQualifierEntries[] = { + {"ConstType", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"VolatileType", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RestrictType", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"AtomicType", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugOperationEntries[] = { + {"Deref", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Plus", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Minus", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"PlusUconst", 3, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"BitPiece", 4, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Swap", 5, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Xderef", 6, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"StackValue", 7, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Constu", 8, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"Fragment", 9, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_t pygen_variable_CLDEBUG100_DebugImportedEntityEntries[] = { + {"ImportedModule", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"ImportedDeclaration", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu} +}; + +static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = { + {SPV_OPERAND_TYPE_IMAGE, ARRAY_SIZE(pygen_variable_ImageOperandsEntries), pygen_variable_ImageOperandsEntries}, + {SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, ARRAY_SIZE(pygen_variable_FPFastMathModeEntries), pygen_variable_FPFastMathModeEntries}, + {SPV_OPERAND_TYPE_SELECTION_CONTROL, ARRAY_SIZE(pygen_variable_SelectionControlEntries), pygen_variable_SelectionControlEntries}, + {SPV_OPERAND_TYPE_LOOP_CONTROL, ARRAY_SIZE(pygen_variable_LoopControlEntries), pygen_variable_LoopControlEntries}, + {SPV_OPERAND_TYPE_FUNCTION_CONTROL, ARRAY_SIZE(pygen_variable_FunctionControlEntries), pygen_variable_FunctionControlEntries}, + {SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, ARRAY_SIZE(pygen_variable_MemorySemanticsEntries), pygen_variable_MemorySemanticsEntries}, + {SPV_OPERAND_TYPE_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries}, + {SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, ARRAY_SIZE(pygen_variable_KernelProfilingInfoEntries), pygen_variable_KernelProfilingInfoEntries}, + {SPV_OPERAND_TYPE_RAY_FLAGS, ARRAY_SIZE(pygen_variable_RayFlagsEntries), pygen_variable_RayFlagsEntries}, + {SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, ARRAY_SIZE(pygen_variable_FragmentShadingRateEntries), pygen_variable_FragmentShadingRateEntries}, + {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, ARRAY_SIZE(pygen_variable_SourceLanguageEntries), pygen_variable_SourceLanguageEntries}, + {SPV_OPERAND_TYPE_EXECUTION_MODEL, ARRAY_SIZE(pygen_variable_ExecutionModelEntries), pygen_variable_ExecutionModelEntries}, + {SPV_OPERAND_TYPE_ADDRESSING_MODEL, ARRAY_SIZE(pygen_variable_AddressingModelEntries), pygen_variable_AddressingModelEntries}, + {SPV_OPERAND_TYPE_MEMORY_MODEL, ARRAY_SIZE(pygen_variable_MemoryModelEntries), pygen_variable_MemoryModelEntries}, + {SPV_OPERAND_TYPE_EXECUTION_MODE, ARRAY_SIZE(pygen_variable_ExecutionModeEntries), pygen_variable_ExecutionModeEntries}, + {SPV_OPERAND_TYPE_STORAGE_CLASS, ARRAY_SIZE(pygen_variable_StorageClassEntries), pygen_variable_StorageClassEntries}, + {SPV_OPERAND_TYPE_DIMENSIONALITY, ARRAY_SIZE(pygen_variable_DimEntries), pygen_variable_DimEntries}, + {SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, ARRAY_SIZE(pygen_variable_SamplerAddressingModeEntries), pygen_variable_SamplerAddressingModeEntries}, + {SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, ARRAY_SIZE(pygen_variable_SamplerFilterModeEntries), pygen_variable_SamplerFilterModeEntries}, + {SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, ARRAY_SIZE(pygen_variable_ImageFormatEntries), pygen_variable_ImageFormatEntries}, + {SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, ARRAY_SIZE(pygen_variable_ImageChannelOrderEntries), pygen_variable_ImageChannelOrderEntries}, + {SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, ARRAY_SIZE(pygen_variable_ImageChannelDataTypeEntries), pygen_variable_ImageChannelDataTypeEntries}, + {SPV_OPERAND_TYPE_FP_ROUNDING_MODE, ARRAY_SIZE(pygen_variable_FPRoundingModeEntries), pygen_variable_FPRoundingModeEntries}, + {SPV_OPERAND_TYPE_FPDENORM_MODE, ARRAY_SIZE(pygen_variable_FPDenormModeEntries), pygen_variable_FPDenormModeEntries}, + {SPV_OPERAND_TYPE_QUANTIZATION_MODES, ARRAY_SIZE(pygen_variable_QuantizationModesEntries), pygen_variable_QuantizationModesEntries}, + {SPV_OPERAND_TYPE_FPOPERATION_MODE, ARRAY_SIZE(pygen_variable_FPOperationModeEntries), pygen_variable_FPOperationModeEntries}, + {SPV_OPERAND_TYPE_OVERFLOW_MODES, ARRAY_SIZE(pygen_variable_OverflowModesEntries), pygen_variable_OverflowModesEntries}, + {SPV_OPERAND_TYPE_LINKAGE_TYPE, ARRAY_SIZE(pygen_variable_LinkageTypeEntries), pygen_variable_LinkageTypeEntries}, + {SPV_OPERAND_TYPE_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries}, + {SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_HostAccessQualifierEntries), pygen_variable_HostAccessQualifierEntries}, + {SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE, ARRAY_SIZE(pygen_variable_FunctionParameterAttributeEntries), pygen_variable_FunctionParameterAttributeEntries}, + {SPV_OPERAND_TYPE_DECORATION, ARRAY_SIZE(pygen_variable_DecorationEntries), pygen_variable_DecorationEntries}, + {SPV_OPERAND_TYPE_BUILT_IN, ARRAY_SIZE(pygen_variable_BuiltInEntries), pygen_variable_BuiltInEntries}, + {SPV_OPERAND_TYPE_SCOPE_ID, ARRAY_SIZE(pygen_variable_ScopeEntries), pygen_variable_ScopeEntries}, + {SPV_OPERAND_TYPE_GROUP_OPERATION, ARRAY_SIZE(pygen_variable_GroupOperationEntries), pygen_variable_GroupOperationEntries}, + {SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS, ARRAY_SIZE(pygen_variable_KernelEnqueueFlagsEntries), pygen_variable_KernelEnqueueFlagsEntries}, + {SPV_OPERAND_TYPE_CAPABILITY, ARRAY_SIZE(pygen_variable_CapabilityEntries), pygen_variable_CapabilityEntries}, + {SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION, ARRAY_SIZE(pygen_variable_RayQueryIntersectionEntries), pygen_variable_RayQueryIntersectionEntries}, + {SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE, ARRAY_SIZE(pygen_variable_RayQueryCommittedIntersectionTypeEntries), pygen_variable_RayQueryCommittedIntersectionTypeEntries}, + {SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE, ARRAY_SIZE(pygen_variable_RayQueryCandidateIntersectionTypeEntries), pygen_variable_RayQueryCandidateIntersectionTypeEntries}, + {SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT, ARRAY_SIZE(pygen_variable_PackedVectorFormatEntries), pygen_variable_PackedVectorFormatEntries}, + {SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, ARRAY_SIZE(pygen_variable_CooperativeMatrixOperandsEntries), pygen_variable_CooperativeMatrixOperandsEntries}, + {SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT, ARRAY_SIZE(pygen_variable_CooperativeMatrixLayoutEntries), pygen_variable_CooperativeMatrixLayoutEntries}, + {SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE, ARRAY_SIZE(pygen_variable_CooperativeMatrixUseEntries), pygen_variable_CooperativeMatrixUseEntries}, + {SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER, ARRAY_SIZE(pygen_variable_InitializationModeQualifierEntries), pygen_variable_InitializationModeQualifierEntries}, + {SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL, ARRAY_SIZE(pygen_variable_LoadCacheControlEntries), pygen_variable_LoadCacheControlEntries}, + {SPV_OPERAND_TYPE_STORE_CACHE_CONTROL, ARRAY_SIZE(pygen_variable_StoreCacheControlEntries), pygen_variable_StoreCacheControlEntries}, + {SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, ARRAY_SIZE(pygen_variable_DebugBaseTypeAttributeEncodingEntries), pygen_variable_DebugBaseTypeAttributeEncodingEntries}, + {SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, ARRAY_SIZE(pygen_variable_DebugCompositeTypeEntries), pygen_variable_DebugCompositeTypeEntries}, + {SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, ARRAY_SIZE(pygen_variable_DebugTypeQualifierEntries), pygen_variable_DebugTypeQualifierEntries}, + {SPV_OPERAND_TYPE_DEBUG_OPERATION, ARRAY_SIZE(pygen_variable_DebugOperationEntries), pygen_variable_DebugOperationEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugInfoFlagsEntries), pygen_variable_CLDEBUG100_DebugInfoFlagsEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugBaseTypeAttributeEncodingEntries), pygen_variable_CLDEBUG100_DebugBaseTypeAttributeEncodingEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugCompositeTypeEntries), pygen_variable_CLDEBUG100_DebugCompositeTypeEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugTypeQualifierEntries), pygen_variable_CLDEBUG100_DebugTypeQualifierEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugOperationEntries), pygen_variable_CLDEBUG100_DebugOperationEntries}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugImportedEntityEntries), pygen_variable_CLDEBUG100_DebugImportedEntityEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_IMAGE, ARRAY_SIZE(pygen_variable_ImageOperandsEntries), pygen_variable_ImageOperandsEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT, ARRAY_SIZE(pygen_variable_PackedVectorFormatEntries), pygen_variable_PackedVectorFormatEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS, ARRAY_SIZE(pygen_variable_CooperativeMatrixOperandsEntries), pygen_variable_CooperativeMatrixOperandsEntries} +}; diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/CMakeLists.txt b/thirdparty/glslang/External/spirv-tools/source/opt/CMakeLists.txt new file mode 100644 index 000000000000..4e7d92d5eaca --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/CMakeLists.txt @@ -0,0 +1,291 @@ +# Copyright (c) 2016 Google Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set(SPIRV_TOOLS_OPT_SOURCES + fix_func_call_arguments.h + aggressive_dead_code_elim_pass.h + amd_ext_to_khr.h + analyze_live_input_pass.h + basic_block.h + block_merge_pass.h + block_merge_util.h + build_module.h + ccp_pass.h + cfg_cleanup_pass.h + cfg.h + code_sink.h + combine_access_chains.h + compact_ids_pass.h + composite.h + const_folding_rules.h + constants.h + control_dependence.h + convert_to_sampled_image_pass.h + convert_to_half_pass.h + copy_prop_arrays.h + dataflow.h + dead_branch_elim_pass.h + dead_insert_elim_pass.h + dead_variable_elimination.h + decoration_manager.h + debug_info_manager.h + def_use_manager.h + desc_sroa.h + desc_sroa_util.h + dominator_analysis.h + dominator_tree.h + eliminate_dead_constant_pass.h + eliminate_dead_functions_pass.h + eliminate_dead_functions_util.h + eliminate_dead_io_components_pass.h + eliminate_dead_members_pass.h + eliminate_dead_output_stores_pass.h + empty_pass.h + feature_manager.h + fix_storage_class.h + flatten_decoration_pass.h + fold.h + folding_rules.h + fold_spec_constant_op_and_composite_pass.h + freeze_spec_constant_value_pass.h + function.h + graphics_robust_access_pass.h + if_conversion.h + inline_exhaustive_pass.h + inline_opaque_pass.h + inline_pass.h + inst_bindless_check_pass.h + inst_buff_addr_check_pass.h + inst_debug_printf_pass.h + instruction.h + instruction_list.h + instrument_pass.h + interface_var_sroa.h + invocation_interlock_placement_pass.h + interp_fixup_pass.h + ir_builder.h + ir_context.h + ir_loader.h + licm_pass.h + liveness.h + local_access_chain_convert_pass.h + local_redundancy_elimination.h + local_single_block_elim_pass.h + local_single_store_elim_pass.h + log.h + loop_dependence.h + loop_descriptor.h + loop_fission.h + loop_fusion.h + loop_fusion_pass.h + loop_peeling.h + loop_unroller.h + loop_utils.h + loop_unswitch_pass.h + mem_pass.h + merge_return_pass.h + modify_maximal_reconvergence.h + module.h + null_pass.h + passes.h + pass.h + pass_manager.h + private_to_local_pass.h + propagator.h + reduce_load_size.h + redundancy_elimination.h + reflect.h + register_pressure.h + relax_float_ops_pass.h + remove_dontinline_pass.h + remove_duplicates_pass.h + remove_unused_interface_variables_pass.h + replace_desc_array_access_using_var_index.h + replace_invalid_opc.h + scalar_analysis.h + scalar_analysis_nodes.h + scalar_replacement_pass.h + set_spec_constant_default_value_pass.h + simplification_pass.h + spread_volatile_semantics.h + ssa_rewrite_pass.h + strength_reduction_pass.h + strip_debug_info_pass.h + strip_nonsemantic_info_pass.h + struct_cfg_analysis.h + switch_descriptorset_pass.h + tree_iterator.h + trim_capabilities_pass.h + type_manager.h + types.h + unify_const_pass.h + upgrade_memory_model.h + value_number_table.h + vector_dce.h + workaround1209.h + wrap_opkill.h + + fix_func_call_arguments.cpp + aggressive_dead_code_elim_pass.cpp + amd_ext_to_khr.cpp + analyze_live_input_pass.cpp + basic_block.cpp + block_merge_pass.cpp + block_merge_util.cpp + build_module.cpp + ccp_pass.cpp + cfg_cleanup_pass.cpp + cfg.cpp + code_sink.cpp + combine_access_chains.cpp + compact_ids_pass.cpp + composite.cpp + const_folding_rules.cpp + constants.cpp + control_dependence.cpp + convert_to_sampled_image_pass.cpp + convert_to_half_pass.cpp + copy_prop_arrays.cpp + dataflow.cpp + dead_branch_elim_pass.cpp + dead_insert_elim_pass.cpp + dead_variable_elimination.cpp + decoration_manager.cpp + debug_info_manager.cpp + def_use_manager.cpp + desc_sroa.cpp + desc_sroa_util.cpp + dominator_analysis.cpp + dominator_tree.cpp + eliminate_dead_constant_pass.cpp + eliminate_dead_functions_pass.cpp + eliminate_dead_functions_util.cpp + eliminate_dead_io_components_pass.cpp + eliminate_dead_members_pass.cpp + eliminate_dead_output_stores_pass.cpp + feature_manager.cpp + fix_storage_class.cpp + flatten_decoration_pass.cpp + fold.cpp + folding_rules.cpp + fold_spec_constant_op_and_composite_pass.cpp + freeze_spec_constant_value_pass.cpp + function.cpp + graphics_robust_access_pass.cpp + if_conversion.cpp + inline_exhaustive_pass.cpp + inline_opaque_pass.cpp + inline_pass.cpp + inst_bindless_check_pass.cpp + inst_buff_addr_check_pass.cpp + inst_debug_printf_pass.cpp + instruction.cpp + instruction_list.cpp + instrument_pass.cpp + interface_var_sroa.cpp + invocation_interlock_placement_pass.cpp + interp_fixup_pass.cpp + ir_context.cpp + ir_loader.cpp + licm_pass.cpp + liveness.cpp + local_access_chain_convert_pass.cpp + local_redundancy_elimination.cpp + local_single_block_elim_pass.cpp + local_single_store_elim_pass.cpp + loop_dependence.cpp + loop_dependence_helpers.cpp + loop_descriptor.cpp + loop_fission.cpp + loop_fusion.cpp + loop_fusion_pass.cpp + loop_peeling.cpp + loop_utils.cpp + loop_unroller.cpp + loop_unswitch_pass.cpp + mem_pass.cpp + merge_return_pass.cpp + modify_maximal_reconvergence.cpp + module.cpp + optimizer.cpp + pass.cpp + pass_manager.cpp + private_to_local_pass.cpp + propagator.cpp + reduce_load_size.cpp + redundancy_elimination.cpp + register_pressure.cpp + relax_float_ops_pass.cpp + remove_dontinline_pass.cpp + remove_duplicates_pass.cpp + remove_unused_interface_variables_pass.cpp + replace_desc_array_access_using_var_index.cpp + replace_invalid_opc.cpp + scalar_analysis.cpp + scalar_analysis_simplification.cpp + scalar_replacement_pass.cpp + set_spec_constant_default_value_pass.cpp + simplification_pass.cpp + spread_volatile_semantics.cpp + ssa_rewrite_pass.cpp + strength_reduction_pass.cpp + strip_debug_info_pass.cpp + strip_nonsemantic_info_pass.cpp + struct_cfg_analysis.cpp + switch_descriptorset_pass.cpp + trim_capabilities_pass.cpp + type_manager.cpp + types.cpp + unify_const_pass.cpp + upgrade_memory_model.cpp + value_number_table.cpp + vector_dce.cpp + workaround1209.cpp + wrap_opkill.cpp +) + +if(MSVC AND (NOT ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))) + # Enable parallel builds across four cores for this lib + add_definitions(/MP4) +endif() + +spvtools_pch(SPIRV_TOOLS_OPT_SOURCES pch_source_opt) + +add_library(SPIRV-Tools-opt ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_TOOLS_OPT_SOURCES}) + +spvtools_default_compile_options(SPIRV-Tools-opt) +target_include_directories(SPIRV-Tools-opt + PUBLIC + $ + $ + $ + PRIVATE ${spirv-tools_BINARY_DIR} +) +# We need the assembling and disassembling functionalities in the main library. +target_link_libraries(SPIRV-Tools-opt + PUBLIC ${SPIRV_TOOLS_FULL_VISIBILITY}) + +set_property(TARGET SPIRV-Tools-opt PROPERTY FOLDER "SPIRV-Tools libraries") +spvtools_check_symbol_exports(SPIRV-Tools-opt) + +if(ENABLE_SPIRV_TOOLS_INSTALL) + install(TARGETS SPIRV-Tools-opt EXPORT SPIRV-Tools-optTargets) + export(EXPORT SPIRV-Tools-optTargets FILE SPIRV-Tools-optTargets.cmake) + + spvtools_config_package_dir(SPIRV-Tools-opt PACKAGE_DIR) + install(EXPORT SPIRV-Tools-optTargets FILE SPIRV-Tools-optTargets.cmake + DESTINATION ${PACKAGE_DIR}) + + spvtools_generate_config_file(SPIRV-Tools-opt) + install(FILES ${CMAKE_BINARY_DIR}/SPIRV-Tools-optConfig.cmake DESTINATION ${PACKAGE_DIR}) +endif(ENABLE_SPIRV_TOOLS_INSTALL) diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp new file mode 100644 index 000000000000..4737da5f9cf7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp @@ -0,0 +1,1123 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// Copyright (c) 2018-2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/aggressive_dead_code_elim_pass.h" + +#include +#include + +#include "source/cfa.h" +#include "source/opt/eliminate_dead_functions_util.h" +#include "source/opt/ir_builder.h" +#include "source/opt/reflect.h" +#include "source/spirv_constant.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { +namespace { + +constexpr uint32_t kTypePointerStorageClassInIdx = 0; +constexpr uint32_t kEntryPointFunctionIdInIdx = 1; +constexpr uint32_t kSelectionMergeMergeBlockIdInIdx = 0; +constexpr uint32_t kLoopMergeContinueBlockIdInIdx = 1; +constexpr uint32_t kCopyMemoryTargetAddrInIdx = 0; +constexpr uint32_t kCopyMemorySourceAddrInIdx = 1; +constexpr uint32_t kLoadSourceAddrInIdx = 0; +constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; +constexpr uint32_t kGlobalVariableVariableIndex = 12; + +// Sorting functor to present annotation instructions in an easy-to-process +// order. The functor orders by opcode first and falls back on unique id +// ordering if both instructions have the same opcode. +// +// Desired priority: +// spv::Op::OpGroupDecorate +// spv::Op::OpGroupMemberDecorate +// spv::Op::OpDecorate +// spv::Op::OpMemberDecorate +// spv::Op::OpDecorateId +// spv::Op::OpDecorateStringGOOGLE +// spv::Op::OpDecorationGroup +struct DecorationLess { + bool operator()(const Instruction* lhs, const Instruction* rhs) const { + assert(lhs && rhs); + spv::Op lhsOp = lhs->opcode(); + spv::Op rhsOp = rhs->opcode(); + if (lhsOp != rhsOp) { +#define PRIORITY_CASE(opcode) \ + if (lhsOp == opcode && rhsOp != opcode) return true; \ + if (rhsOp == opcode && lhsOp != opcode) return false; + // OpGroupDecorate and OpGroupMember decorate are highest priority to + // eliminate dead targets early and simplify subsequent checks. + PRIORITY_CASE(spv::Op::OpGroupDecorate) + PRIORITY_CASE(spv::Op::OpGroupMemberDecorate) + PRIORITY_CASE(spv::Op::OpDecorate) + PRIORITY_CASE(spv::Op::OpMemberDecorate) + PRIORITY_CASE(spv::Op::OpDecorateId) + PRIORITY_CASE(spv::Op::OpDecorateStringGOOGLE) + // OpDecorationGroup is lowest priority to ensure use/def chains remain + // usable for instructions that target this group. + PRIORITY_CASE(spv::Op::OpDecorationGroup) +#undef PRIORITY_CASE + } + + // Fall back to maintain total ordering (compare unique ids). + return *lhs < *rhs; + } +}; + +} // namespace + +bool AggressiveDCEPass::IsVarOfStorage(uint32_t varId, + spv::StorageClass storageClass) { + if (varId == 0) return false; + const Instruction* varInst = get_def_use_mgr()->GetDef(varId); + const spv::Op op = varInst->opcode(); + if (op != spv::Op::OpVariable) return false; + const uint32_t varTypeId = varInst->type_id(); + const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); + if (varTypeInst->opcode() != spv::Op::OpTypePointer) return false; + return spv::StorageClass(varTypeInst->GetSingleWordInOperand( + kTypePointerStorageClassInIdx)) == storageClass; +} + +bool AggressiveDCEPass::IsLocalVar(uint32_t varId, Function* func) { + if (IsVarOfStorage(varId, spv::StorageClass::Function)) { + return true; + } + + if (!IsVarOfStorage(varId, spv::StorageClass::Private) && + !IsVarOfStorage(varId, spv::StorageClass::Workgroup)) { + return false; + } + + // For a variable in the Private or WorkGroup storage class, the variable will + // get a new instance for every call to an entry point. If the entry point + // does not have a call, then no other function can read or write to that + // instance of the variable. + return IsEntryPointWithNoCalls(func); +} + +void AggressiveDCEPass::AddStores(Function* func, uint32_t ptrId) { + get_def_use_mgr()->ForEachUser(ptrId, [this, ptrId, func](Instruction* user) { + // If the user is not a part of |func|, skip it. + BasicBlock* blk = context()->get_instr_block(user); + if (blk && blk->GetParent() != func) return; + + switch (user->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpCopyObject: + this->AddStores(func, user->result_id()); + break; + case spv::Op::OpLoad: + break; + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + if (user->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx) == ptrId) { + AddToWorklist(user); + } + break; + // If default, assume it stores e.g. frexp, modf, function call + case spv::Op::OpStore: + default: + AddToWorklist(user); + break; + } + }); +} + +bool AggressiveDCEPass::AllExtensionsSupported() const { + // If any extension not in allowlist, return false + for (auto& ei : get_module()->extensions()) { + const std::string extName = ei.GetInOperand(0).AsString(); + if (extensions_allowlist_.find(extName) == extensions_allowlist_.end()) + return false; + } + // Only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise + // around unknown extended instruction sets even if they are non-semantic + for (auto& inst : context()->module()->ext_inst_imports()) { + assert(inst.opcode() == spv::Op::OpExtInstImport && + "Expecting an import of an extension's instruction set."); + const std::string extension_name = inst.GetInOperand(0).AsString(); + if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && + (extension_name != "NonSemantic.Shader.DebugInfo.100") && + (extension_name != "NonSemantic.DebugPrintf")) { + return false; + } + } + return true; +} + +bool AggressiveDCEPass::IsTargetDead(Instruction* inst) { + const uint32_t tId = inst->GetSingleWordInOperand(0); + Instruction* tInst = get_def_use_mgr()->GetDef(tId); + if (IsAnnotationInst(tInst->opcode())) { + // This must be a decoration group. We go through annotations in a specific + // order. So if this is not used by any group or group member decorates, it + // is dead. + assert(tInst->opcode() == spv::Op::OpDecorationGroup); + bool dead = true; + get_def_use_mgr()->ForEachUser(tInst, [&dead](Instruction* user) { + if (user->opcode() == spv::Op::OpGroupDecorate || + user->opcode() == spv::Op::OpGroupMemberDecorate) + dead = false; + }); + return dead; + } + return !IsLive(tInst); +} + +void AggressiveDCEPass::ProcessLoad(Function* func, uint32_t varId) { + // Only process locals + if (!IsLocalVar(varId, func)) return; + // Return if already processed + if (live_local_vars_.find(varId) != live_local_vars_.end()) return; + // Mark all stores to varId as live + AddStores(func, varId); + // Cache varId as processed + live_local_vars_.insert(varId); +} + +void AggressiveDCEPass::AddBranch(uint32_t labelId, BasicBlock* bp) { + std::unique_ptr newBranch( + new Instruction(context(), spv::Op::OpBranch, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); + context()->AnalyzeDefUse(&*newBranch); + context()->set_instr_block(&*newBranch, bp); + bp->AddInstruction(std::move(newBranch)); +} + +void AggressiveDCEPass::AddBreaksAndContinuesToWorklist( + Instruction* mergeInst) { + assert(mergeInst->opcode() == spv::Op::OpSelectionMerge || + mergeInst->opcode() == spv::Op::OpLoopMerge); + + BasicBlock* header = context()->get_instr_block(mergeInst); + const uint32_t mergeId = mergeInst->GetSingleWordInOperand(0); + get_def_use_mgr()->ForEachUser(mergeId, [header, this](Instruction* user) { + if (!user->IsBranch()) return; + BasicBlock* block = context()->get_instr_block(user); + if (BlockIsInConstruct(header, block)) { + // This is a break from the loop. + AddToWorklist(user); + // Add branch's merge if there is one. + Instruction* userMerge = GetMergeInstruction(user); + if (userMerge != nullptr) AddToWorklist(userMerge); + } + }); + + if (mergeInst->opcode() != spv::Op::OpLoopMerge) { + return; + } + + // For loops we need to find the continues as well. + const uint32_t contId = + mergeInst->GetSingleWordInOperand(kLoopMergeContinueBlockIdInIdx); + get_def_use_mgr()->ForEachUser(contId, [&contId, this](Instruction* user) { + spv::Op op = user->opcode(); + if (op == spv::Op::OpBranchConditional || op == spv::Op::OpSwitch) { + // A conditional branch or switch can only be a continue if it does not + // have a merge instruction or its merge block is not the continue block. + Instruction* hdrMerge = GetMergeInstruction(user); + if (hdrMerge != nullptr && + hdrMerge->opcode() == spv::Op::OpSelectionMerge) { + uint32_t hdrMergeId = + hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); + if (hdrMergeId == contId) return; + // Need to mark merge instruction too + AddToWorklist(hdrMerge); + } + } else if (op == spv::Op::OpBranch) { + // An unconditional branch can only be a continue if it is not + // branching to its own merge block. + BasicBlock* blk = context()->get_instr_block(user); + Instruction* hdrBranch = GetHeaderBranch(blk); + if (hdrBranch == nullptr) return; + Instruction* hdrMerge = GetMergeInstruction(hdrBranch); + if (hdrMerge->opcode() == spv::Op::OpLoopMerge) return; + uint32_t hdrMergeId = + hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); + if (contId == hdrMergeId) return; + } else { + return; + } + AddToWorklist(user); + }); +} + +bool AggressiveDCEPass::AggressiveDCE(Function* func) { + std::list structured_order; + cfg()->ComputeStructuredOrder(func, &*func->begin(), &structured_order); + live_local_vars_.clear(); + InitializeWorkList(func, structured_order); + ProcessWorkList(func); + return KillDeadInstructions(func, structured_order); +} + +bool AggressiveDCEPass::KillDeadInstructions( + const Function* func, std::list& structured_order) { + bool modified = false; + for (auto bi = structured_order.begin(); bi != structured_order.end();) { + uint32_t merge_block_id = 0; + (*bi)->ForEachInst([this, &modified, &merge_block_id](Instruction* inst) { + if (IsLive(inst)) return; + if (inst->opcode() == spv::Op::OpLabel) return; + // If dead instruction is selection merge, remember merge block + // for new branch at end of block + if (inst->opcode() == spv::Op::OpSelectionMerge || + inst->opcode() == spv::Op::OpLoopMerge) + merge_block_id = inst->GetSingleWordInOperand(0); + to_kill_.push_back(inst); + modified = true; + }); + // If a structured if or loop was deleted, add a branch to its merge + // block, and traverse to the merge block and continue processing there. + // We know the block still exists because the label is not deleted. + if (merge_block_id != 0) { + AddBranch(merge_block_id, *bi); + for (++bi; (*bi)->id() != merge_block_id; ++bi) { + } + + auto merge_terminator = (*bi)->terminator(); + if (merge_terminator->opcode() == spv::Op::OpUnreachable) { + // The merge was unreachable. This is undefined behaviour so just + // return (or return an undef). Then mark the new return as live. + auto func_ret_type_inst = get_def_use_mgr()->GetDef(func->type_id()); + if (func_ret_type_inst->opcode() == spv::Op::OpTypeVoid) { + merge_terminator->SetOpcode(spv::Op::OpReturn); + } else { + // Find an undef for the return value and make sure it gets kept by + // the pass. + auto undef_id = Type2Undef(func->type_id()); + auto undef = get_def_use_mgr()->GetDef(undef_id); + live_insts_.Set(undef->unique_id()); + merge_terminator->SetOpcode(spv::Op::OpReturnValue); + merge_terminator->SetInOperands({{SPV_OPERAND_TYPE_ID, {undef_id}}}); + get_def_use_mgr()->AnalyzeInstUse(merge_terminator); + } + live_insts_.Set(merge_terminator->unique_id()); + } + } else { + Instruction* inst = (*bi)->terminator(); + if (!IsLive(inst)) { + // If the terminator is not live, this block has no live instructions, + // and it will be unreachable. + AddUnreachable(*bi); + } + ++bi; + } + } + return modified; +} + +void AggressiveDCEPass::ProcessWorkList(Function* func) { + while (!worklist_.empty()) { + Instruction* live_inst = worklist_.front(); + worklist_.pop(); + AddOperandsToWorkList(live_inst); + MarkBlockAsLive(live_inst); + MarkLoadedVariablesAsLive(func, live_inst); + AddDecorationsToWorkList(live_inst); + AddDebugInstructionsToWorkList(live_inst); + } +} + +void AggressiveDCEPass::AddDebugScopeToWorkList(const Instruction* inst) { + auto scope = inst->GetDebugScope(); + auto lex_scope_id = scope.GetLexicalScope(); + if (lex_scope_id != kNoDebugScope) + AddToWorklist(get_def_use_mgr()->GetDef(lex_scope_id)); + auto inlined_at_id = scope.GetInlinedAt(); + if (inlined_at_id != kNoInlinedAt) + AddToWorklist(get_def_use_mgr()->GetDef(inlined_at_id)); +} + +void AggressiveDCEPass::AddDebugInstructionsToWorkList( + const Instruction* inst) { + for (auto& line_inst : inst->dbg_line_insts()) { + if (line_inst.IsDebugLineInst()) { + AddOperandsToWorkList(&line_inst); + } + AddDebugScopeToWorkList(&line_inst); + } + AddDebugScopeToWorkList(inst); +} + +void AggressiveDCEPass::AddDecorationsToWorkList(const Instruction* inst) { + // Add OpDecorateId instructions that apply to this instruction to the work + // list. We use the decoration manager to look through the group + // decorations to get to the OpDecorate* instructions themselves. + auto decorations = + get_decoration_mgr()->GetDecorationsFor(inst->result_id(), false); + for (Instruction* dec : decorations) { + // We only care about OpDecorateId instructions because the are the only + // decorations that will reference an id that will have to be kept live + // because of that use. + if (dec->opcode() != spv::Op::OpDecorateId) { + continue; + } + if (spv::Decoration(dec->GetSingleWordInOperand(1)) == + spv::Decoration::HlslCounterBufferGOOGLE) { + // These decorations should not force the use id to be live. It will be + // removed if either the target or the in operand are dead. + continue; + } + AddToWorklist(dec); + } +} + +void AggressiveDCEPass::MarkLoadedVariablesAsLive(Function* func, + Instruction* inst) { + std::vector live_variables = GetLoadedVariables(inst); + for (uint32_t var_id : live_variables) { + ProcessLoad(func, var_id); + } +} + +std::vector AggressiveDCEPass::GetLoadedVariables(Instruction* inst) { + if (inst->opcode() == spv::Op::OpFunctionCall) { + return GetLoadedVariablesFromFunctionCall(inst); + } + uint32_t var_id = GetLoadedVariableFromNonFunctionCalls(inst); + if (var_id == 0) { + return {}; + } + return {var_id}; +} + +uint32_t AggressiveDCEPass::GetLoadedVariableFromNonFunctionCalls( + Instruction* inst) { + std::vector live_variables; + if (inst->IsAtomicWithLoad()) { + return GetVariableId(inst->GetSingleWordInOperand(kLoadSourceAddrInIdx)); + } + + switch (inst->opcode()) { + case spv::Op::OpLoad: + case spv::Op::OpImageTexelPointer: + return GetVariableId(inst->GetSingleWordInOperand(kLoadSourceAddrInIdx)); + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + return GetVariableId( + inst->GetSingleWordInOperand(kCopyMemorySourceAddrInIdx)); + default: + break; + } + + switch (inst->GetCommonDebugOpcode()) { + case CommonDebugInfoDebugDeclare: + return inst->GetSingleWordOperand(kDebugDeclareOperandVariableIndex); + case CommonDebugInfoDebugValue: { + analysis::DebugInfoManager* debug_info_mgr = + context()->get_debug_info_mgr(); + return debug_info_mgr->GetVariableIdOfDebugValueUsedForDeclare(inst); + } + default: + break; + } + return 0; +} + +std::vector AggressiveDCEPass::GetLoadedVariablesFromFunctionCall( + const Instruction* inst) { + assert(inst->opcode() == spv::Op::OpFunctionCall); + std::vector live_variables; + // NOTE: we should only be checking function call parameters here, not the + // function itself, however, `IsPtr` will trivially return false for + // OpFunction + inst->ForEachInId([this, &live_variables](const uint32_t* operand_id) { + if (!IsPtr(*operand_id)) return; + uint32_t var_id = GetVariableId(*operand_id); + live_variables.push_back(var_id); + }); + return live_variables; +} + +uint32_t AggressiveDCEPass::GetVariableId(uint32_t ptr_id) { + assert(IsPtr(ptr_id) && + "Cannot get the variable when input is not a pointer."); + uint32_t varId = 0; + (void)GetPtr(ptr_id, &varId); + return varId; +} + +void AggressiveDCEPass::MarkBlockAsLive(Instruction* inst) { + BasicBlock* basic_block = context()->get_instr_block(inst); + if (basic_block == nullptr) { + return; + } + + // If we intend to keep this instruction, we need the block label and + // block terminator to have a valid block for the instruction. + AddToWorklist(basic_block->GetLabelInst()); + + // We need to mark the successors blocks that follow as live. If this is + // header of the merge construct, the construct may be folded, but we will + // definitely need the merge label. If it is not a construct, the terminator + // must be live, and the successor blocks will be marked as live when + // processing the terminator. + uint32_t merge_id = basic_block->MergeBlockIdIfAny(); + if (merge_id == 0) { + AddToWorklist(basic_block->terminator()); + } else { + AddToWorklist(context()->get_def_use_mgr()->GetDef(merge_id)); + } + + // Mark the structured control flow constructs that contains this block as + // live. If |inst| is an instruction in the loop header, then it is part of + // the loop, so the loop construct must be live. We exclude the label because + // it does not matter how many times it is executed. This could be extended + // to more instructions, but we will need it for now. + if (inst->opcode() != spv::Op::OpLabel) + MarkLoopConstructAsLiveIfLoopHeader(basic_block); + + Instruction* next_branch_inst = GetBranchForNextHeader(basic_block); + if (next_branch_inst != nullptr) { + AddToWorklist(next_branch_inst); + Instruction* mergeInst = GetMergeInstruction(next_branch_inst); + AddToWorklist(mergeInst); + } + + if (inst->opcode() == spv::Op::OpLoopMerge || + inst->opcode() == spv::Op::OpSelectionMerge) { + AddBreaksAndContinuesToWorklist(inst); + } +} +void AggressiveDCEPass::MarkLoopConstructAsLiveIfLoopHeader( + BasicBlock* basic_block) { + // If this is the header for a loop, then loop structure needs to keep as well + // because the loop header is also part of the loop. + Instruction* merge_inst = basic_block->GetLoopMergeInst(); + if (merge_inst != nullptr) { + AddToWorklist(basic_block->terminator()); + AddToWorklist(merge_inst); + } +} + +void AggressiveDCEPass::AddOperandsToWorkList(const Instruction* inst) { + inst->ForEachInId([this](const uint32_t* iid) { + Instruction* inInst = get_def_use_mgr()->GetDef(*iid); + AddToWorklist(inInst); + }); + if (inst->type_id() != 0) { + AddToWorklist(get_def_use_mgr()->GetDef(inst->type_id())); + } +} + +void AggressiveDCEPass::InitializeWorkList( + Function* func, std::list& structured_order) { + AddToWorklist(&func->DefInst()); + MarkFunctionParameterAsLive(func); + MarkFirstBlockAsLive(func); + + // Add instructions with external side effects to the worklist. Also add + // branches that are not attached to a structured construct. + // TODO(s-perron): The handling of branch seems to be adhoc. This needs to be + // cleaned up. + for (auto& bi : structured_order) { + for (auto ii = bi->begin(); ii != bi->end(); ++ii) { + spv::Op op = ii->opcode(); + if (ii->IsBranch()) { + continue; + } + switch (op) { + case spv::Op::OpStore: { + uint32_t var_id = 0; + (void)GetPtr(&*ii, &var_id); + if (!IsLocalVar(var_id, func)) AddToWorklist(&*ii); + } break; + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: { + uint32_t var_id = 0; + uint32_t target_addr_id = + ii->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx); + (void)GetPtr(target_addr_id, &var_id); + if (!IsLocalVar(var_id, func)) AddToWorklist(&*ii); + } break; + case spv::Op::OpLoopMerge: + case spv::Op::OpSelectionMerge: + case spv::Op::OpUnreachable: + break; + default: { + // Function calls, atomics, function params, function returns, etc. + if (!ii->IsOpcodeSafeToDelete()) { + AddToWorklist(&*ii); + } + } break; + } + } + } +} + +void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { + // Keep all execution modes. + for (auto& exec : get_module()->execution_modes()) { + AddToWorklist(&exec); + } + // Keep all entry points. + for (auto& entry : get_module()->entry_points()) { + if (!preserve_interface_) { + live_insts_.Set(entry.unique_id()); + // The actual function is live always. + AddToWorklist( + get_def_use_mgr()->GetDef(entry.GetSingleWordInOperand(1u))); + for (uint32_t i = 3; i < entry.NumInOperands(); ++i) { + auto* var = get_def_use_mgr()->GetDef(entry.GetSingleWordInOperand(i)); + auto storage_class = var->GetSingleWordInOperand(0u); + // Vulkan support outputs without an associated input, but not inputs + // without an associated output. Don't remove outputs unless explicitly + // allowed. + if (!remove_outputs_ && + spv::StorageClass(storage_class) == spv::StorageClass::Output) { + AddToWorklist(var); + } + } + } else { + AddToWorklist(&entry); + } + } + for (auto& anno : get_module()->annotations()) { + if (anno.opcode() == spv::Op::OpDecorate) { + // Keep workgroup size. + if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::BuiltIn && + spv::BuiltIn(anno.GetSingleWordInOperand(2u)) == + spv::BuiltIn::WorkgroupSize) { + AddToWorklist(&anno); + } + + if (context()->preserve_bindings()) { + // Keep all bindings. + if ((spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::DescriptorSet) || + (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::Binding)) { + AddToWorklist(&anno); + } + } + + if (context()->preserve_spec_constants()) { + // Keep all specialization constant instructions + if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::SpecId) { + AddToWorklist(&anno); + } + } + } + } + + // For each DebugInfo GlobalVariable keep all operands except the Variable. + // Later, if the variable is killed with KillInst(), we will set the operand + // to DebugInfoNone. Create and save DebugInfoNone now for this possible + // later use. This is slightly unoptimal, but it avoids generating it during + // instruction killing when the module is not consistent. + bool debug_global_seen = false; + for (auto& dbg : get_module()->ext_inst_debuginfo()) { + if (dbg.GetCommonDebugOpcode() != CommonDebugInfoDebugGlobalVariable) + continue; + debug_global_seen = true; + dbg.ForEachInId([this](const uint32_t* iid) { + Instruction* in_inst = get_def_use_mgr()->GetDef(*iid); + if (in_inst->opcode() == spv::Op::OpVariable) return; + AddToWorklist(in_inst); + }); + } + if (debug_global_seen) { + auto dbg_none = context()->get_debug_info_mgr()->GetDebugInfoNone(); + AddToWorklist(dbg_none); + } + + // Add top level DebugInfo to worklist + for (auto& dbg : get_module()->ext_inst_debuginfo()) { + auto op = dbg.GetShader100DebugOpcode(); + if (op == NonSemanticShaderDebugInfo100DebugCompilationUnit || + op == NonSemanticShaderDebugInfo100DebugEntryPoint || + op == NonSemanticShaderDebugInfo100DebugSourceContinued) { + AddToWorklist(&dbg); + } + } +} + +Pass::Status AggressiveDCEPass::ProcessImpl() { + // Current functionality assumes shader capability + // TODO(greg-lunarg): Handle additional capabilities + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return Status::SuccessWithoutChange; + + // Current functionality assumes relaxed logical addressing (see + // instruction.h) + // TODO(greg-lunarg): Handle non-logical addressing + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) + return Status::SuccessWithoutChange; + + // The variable pointer extension is no longer needed to use the capability, + // so we have to look for the capability. + if (context()->get_feature_mgr()->HasCapability( + spv::Capability::VariablePointersStorageBuffer)) + return Status::SuccessWithoutChange; + + // If any extensions in the module are not explicitly supported, + // return unmodified. + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; + + // Eliminate Dead functions. + bool modified = EliminateDeadFunctions(); + + InitializeModuleScopeLiveInstructions(); + + // Run |AggressiveDCE| on the remaining functions. The order does not matter, + // since |AggressiveDCE| is intra-procedural. This can mean that function + // will become dead if all function call to them are removed. These dead + // function will still be in the module after this pass. We expect this to be + // rare. + for (Function& fp : *context()->module()) { + modified |= AggressiveDCE(&fp); + } + + // If the decoration manager is kept live then the context will try to keep it + // up to date. ADCE deals with group decorations by changing the operands in + // |OpGroupDecorate| instruction directly without informing the decoration + // manager. This can put it in an invalid state which will cause an error + // when the context tries to update it. To avoid this problem invalidate + // the decoration manager upfront. + // + // We kill it at now because it is used when processing the entry point + // functions. + context()->InvalidateAnalyses(IRContext::Analysis::kAnalysisDecorations); + + // Process module-level instructions. Now that all live instructions have + // been marked, it is safe to remove dead global values. + modified |= ProcessGlobalValues(); + + assert((to_kill_.empty() || modified) && + "A dead instruction was identified, but no change recorded."); + + // Kill all dead instructions. + for (auto inst : to_kill_) { + context()->KillInst(inst); + } + + // Cleanup all CFG including all unreachable blocks. + for (Function& fp : *context()->module()) { + modified |= CFGCleanup(&fp); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool AggressiveDCEPass::EliminateDeadFunctions() { + // Identify live functions first. Those that are not live + // are dead. + std::unordered_set live_function_set; + ProcessFunction mark_live = [&live_function_set](Function* fp) { + live_function_set.insert(fp); + return false; + }; + context()->ProcessReachableCallTree(mark_live); + + bool modified = false; + for (auto funcIter = get_module()->begin(); + funcIter != get_module()->end();) { + if (live_function_set.count(&*funcIter) == 0) { + modified = true; + funcIter = + eliminatedeadfunctionsutil::EliminateFunction(context(), &funcIter); + } else { + ++funcIter; + } + } + + return modified; +} + +bool AggressiveDCEPass::ProcessGlobalValues() { + // Remove debug and annotation statements referencing dead instructions. + // This must be done before killing the instructions, otherwise there are + // dead objects in the def/use database. + bool modified = false; + Instruction* instruction = &*get_module()->debug2_begin(); + while (instruction) { + if (instruction->opcode() != spv::Op::OpName) { + instruction = instruction->NextNode(); + continue; + } + + if (IsTargetDead(instruction)) { + instruction = context()->KillInst(instruction); + modified = true; + } else { + instruction = instruction->NextNode(); + } + } + + // This code removes all unnecessary decorations safely (see #1174). It also + // does so in a more efficient manner than deleting them only as the targets + // are deleted. + std::vector annotations; + for (auto& inst : get_module()->annotations()) annotations.push_back(&inst); + std::sort(annotations.begin(), annotations.end(), DecorationLess()); + for (auto annotation : annotations) { + switch (annotation->opcode()) { + case spv::Op::OpDecorate: + case spv::Op::OpMemberDecorate: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorateStringGOOGLE: + if (IsTargetDead(annotation)) { + context()->KillInst(annotation); + modified = true; + } + break; + case spv::Op::OpDecorateId: + if (IsTargetDead(annotation)) { + context()->KillInst(annotation); + modified = true; + } else { + if (spv::Decoration(annotation->GetSingleWordInOperand(1)) == + spv::Decoration::HlslCounterBufferGOOGLE) { + // HlslCounterBuffer will reference an id other than the target. + // If that id is dead, then the decoration can be removed as well. + uint32_t counter_buffer_id = annotation->GetSingleWordInOperand(2); + Instruction* counter_buffer_inst = + get_def_use_mgr()->GetDef(counter_buffer_id); + if (!IsLive(counter_buffer_inst)) { + context()->KillInst(annotation); + modified = true; + } + } + } + break; + case spv::Op::OpGroupDecorate: { + // Go through the targets of this group decorate. Remove each dead + // target. If all targets are dead, remove this decoration. + bool dead = true; + bool removed_operand = false; + for (uint32_t i = 1; i < annotation->NumOperands();) { + Instruction* opInst = + get_def_use_mgr()->GetDef(annotation->GetSingleWordOperand(i)); + if (!IsLive(opInst)) { + // Don't increment |i|. + annotation->RemoveOperand(i); + modified = true; + removed_operand = true; + } else { + i++; + dead = false; + } + } + if (dead) { + context()->KillInst(annotation); + modified = true; + } else if (removed_operand) { + context()->UpdateDefUse(annotation); + } + break; + } + case spv::Op::OpGroupMemberDecorate: { + // Go through the targets of this group member decorate. Remove each + // dead target (and member index). If all targets are dead, remove this + // decoration. + bool dead = true; + bool removed_operand = false; + for (uint32_t i = 1; i < annotation->NumOperands();) { + Instruction* opInst = + get_def_use_mgr()->GetDef(annotation->GetSingleWordOperand(i)); + if (!IsLive(opInst)) { + // Don't increment |i|. + annotation->RemoveOperand(i + 1); + annotation->RemoveOperand(i); + modified = true; + removed_operand = true; + } else { + i += 2; + dead = false; + } + } + if (dead) { + context()->KillInst(annotation); + modified = true; + } else if (removed_operand) { + context()->UpdateDefUse(annotation); + } + break; + } + case spv::Op::OpDecorationGroup: + // By the time we hit decoration groups we've checked everything that + // can target them. So if they have no uses they must be dead. + if (get_def_use_mgr()->NumUsers(annotation) == 0) { + context()->KillInst(annotation); + modified = true; + } + break; + default: + assert(false); + break; + } + } + + for (auto& dbg : get_module()->ext_inst_debuginfo()) { + if (IsLive(&dbg)) continue; + // Save GlobalVariable if its variable is live, otherwise null out variable + // index + if (dbg.GetCommonDebugOpcode() == CommonDebugInfoDebugGlobalVariable) { + auto var_id = dbg.GetSingleWordOperand(kGlobalVariableVariableIndex); + Instruction* var_inst = get_def_use_mgr()->GetDef(var_id); + if (IsLive(var_inst)) continue; + context()->ForgetUses(&dbg); + dbg.SetOperand( + kGlobalVariableVariableIndex, + {context()->get_debug_info_mgr()->GetDebugInfoNone()->result_id()}); + context()->AnalyzeUses(&dbg); + continue; + } + to_kill_.push_back(&dbg); + modified = true; + } + + // Since ADCE is disabled for non-shaders, we don't check for export linkage + // attributes here. + for (auto& val : get_module()->types_values()) { + if (!IsLive(&val)) { + // Save forwarded pointer if pointer is live since closure does not mark + // this live as it does not have a result id. This is a little too + // conservative since it is not known if the structure type that needed + // it is still live. TODO(greg-lunarg): Only save if needed. + if (val.opcode() == spv::Op::OpTypeForwardPointer) { + uint32_t ptr_ty_id = val.GetSingleWordInOperand(0); + Instruction* ptr_ty_inst = get_def_use_mgr()->GetDef(ptr_ty_id); + if (IsLive(ptr_ty_inst)) continue; + } + to_kill_.push_back(&val); + modified = true; + } + } + + if (!preserve_interface_) { + // Remove the dead interface variables from the entry point interface list. + for (auto& entry : get_module()->entry_points()) { + std::vector new_operands; + for (uint32_t i = 0; i < entry.NumInOperands(); ++i) { + if (i < 3) { + // Execution model, function id and name are always valid. + new_operands.push_back(entry.GetInOperand(i)); + } else { + auto* var = + get_def_use_mgr()->GetDef(entry.GetSingleWordInOperand(i)); + if (IsLive(var)) { + new_operands.push_back(entry.GetInOperand(i)); + } + } + } + if (new_operands.size() != entry.NumInOperands()) { + entry.SetInOperands(std::move(new_operands)); + get_def_use_mgr()->UpdateDefUse(&entry); + } + } + } + + return modified; +} + +Pass::Status AggressiveDCEPass::Process() { + // Initialize extensions allowlist + InitExtensions(); + return ProcessImpl(); +} + +void AggressiveDCEPass::InitExtensions() { + extensions_allowlist_.clear(); + + // clang-format off + extensions_allowlist_.insert({ + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_8bit_storage", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + // SPV_KHR_variable_pointers + // Currently do not support extended pointer expressions + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", + "SPV_EXT_shader_stencil_export", + "SPV_EXT_shader_viewport_index_layer", + "SPV_AMD_shader_image_load_store_lod", + "SPV_AMD_shader_fragment_mask", + "SPV_EXT_fragment_fully_covered", + "SPV_AMD_gpu_shader_half_float_fetch", + "SPV_GOOGLE_decorate_string", + "SPV_GOOGLE_hlsl_functionality1", + "SPV_GOOGLE_user_type", + "SPV_NV_shader_subgroup_partitioned", + "SPV_EXT_demote_to_helper_invocation", + "SPV_EXT_descriptor_indexing", + "SPV_NV_fragment_shader_barycentric", + "SPV_NV_compute_shader_derivatives", + "SPV_NV_shader_image_footprint", + "SPV_NV_shading_rate", + "SPV_NV_mesh_shader", + "SPV_EXT_mesh_shader", + "SPV_NV_ray_tracing", + "SPV_KHR_ray_tracing", + "SPV_KHR_ray_query", + "SPV_EXT_fragment_invocation_density", + "SPV_EXT_physical_storage_buffer", + "SPV_KHR_physical_storage_buffer", + "SPV_KHR_terminate_invocation", + "SPV_KHR_shader_clock", + "SPV_KHR_vulkan_memory_model", + "SPV_KHR_subgroup_uniform_control_flow", + "SPV_KHR_integer_dot_product", + "SPV_EXT_shader_image_int64", + "SPV_KHR_non_semantic_info", + "SPV_KHR_uniform_group_instructions", + "SPV_KHR_fragment_shader_barycentric", + "SPV_NV_bindless_texture", + "SPV_EXT_shader_atomic_float_add", + "SPV_EXT_fragment_shader_interlock", + "SPV_NV_compute_shader_derivatives" + }); + // clang-format on +} + +Instruction* AggressiveDCEPass::GetHeaderBranch(BasicBlock* blk) { + if (blk == nullptr) { + return nullptr; + } + BasicBlock* header_block = GetHeaderBlock(blk); + if (header_block == nullptr) { + return nullptr; + } + return header_block->terminator(); +} + +BasicBlock* AggressiveDCEPass::GetHeaderBlock(BasicBlock* blk) const { + if (blk == nullptr) { + return nullptr; + } + + BasicBlock* header_block = nullptr; + if (blk->IsLoopHeader()) { + header_block = blk; + } else { + uint32_t header = + context()->GetStructuredCFGAnalysis()->ContainingConstruct(blk->id()); + header_block = context()->get_instr_block(header); + } + return header_block; +} + +Instruction* AggressiveDCEPass::GetMergeInstruction(Instruction* inst) { + BasicBlock* bb = context()->get_instr_block(inst); + if (bb == nullptr) { + return nullptr; + } + return bb->GetMergeInst(); +} + +Instruction* AggressiveDCEPass::GetBranchForNextHeader(BasicBlock* blk) { + if (blk == nullptr) { + return nullptr; + } + + if (blk->IsLoopHeader()) { + uint32_t header = + context()->GetStructuredCFGAnalysis()->ContainingConstruct(blk->id()); + blk = context()->get_instr_block(header); + } + return GetHeaderBranch(blk); +} + +void AggressiveDCEPass::MarkFunctionParameterAsLive(const Function* func) { + func->ForEachParam( + [this](const Instruction* param) { + AddToWorklist(const_cast(param)); + }, + false); +} + +bool AggressiveDCEPass::BlockIsInConstruct(BasicBlock* header_block, + BasicBlock* bb) { + if (bb == nullptr || header_block == nullptr) { + return false; + } + + uint32_t current_header = bb->id(); + while (current_header != 0) { + if (current_header == header_block->id()) return true; + current_header = context()->GetStructuredCFGAnalysis()->ContainingConstruct( + current_header); + } + return false; +} + +bool AggressiveDCEPass::IsEntryPointWithNoCalls(Function* func) { + auto cached_result = entry_point_with_no_calls_cache_.find(func->result_id()); + if (cached_result != entry_point_with_no_calls_cache_.end()) { + return cached_result->second; + } + bool result = IsEntryPoint(func) && !HasCall(func); + entry_point_with_no_calls_cache_[func->result_id()] = result; + return result; +} + +bool AggressiveDCEPass::IsEntryPoint(Function* func) { + for (const Instruction& entry_point : get_module()->entry_points()) { + uint32_t entry_point_id = + entry_point.GetSingleWordInOperand(kEntryPointFunctionIdInIdx); + if (entry_point_id == func->result_id()) { + return true; + } + } + return false; +} + +bool AggressiveDCEPass::HasCall(Function* func) { + return !func->WhileEachInst([](Instruction* inst) { + return inst->opcode() != spv::Op::OpFunctionCall; + }); +} + +void AggressiveDCEPass::MarkFirstBlockAsLive(Function* func) { + BasicBlock* first_block = &*func->begin(); + MarkBlockAsLive(first_block->GetLabelInst()); +} + +void AggressiveDCEPass::AddUnreachable(BasicBlock*& block) { + InstructionBuilder builder( + context(), block, + IRContext::kAnalysisInstrToBlockMapping | IRContext::kAnalysisDefUse); + builder.AddUnreachable(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h new file mode 100644 index 000000000000..fbe08ad03da0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h @@ -0,0 +1,265 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_AGGRESSIVE_DEAD_CODE_ELIM_PASS_H_ +#define SOURCE_OPT_AGGRESSIVE_DEAD_CODE_ELIM_PASS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" +#include "source/util/bit_vector.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class AggressiveDCEPass : public MemPass { + using cbb_ptr = const BasicBlock*; + + public: + using GetBlocksFunction = + std::function*(const BasicBlock*)>; + + AggressiveDCEPass(bool preserve_interface = false, + bool remove_outputs = false) + : preserve_interface_(preserve_interface), + remove_outputs_(remove_outputs) {} + + const char* name() const override { return "eliminate-dead-code-aggressive"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Preserve entry point interface if true. All variables in interface + // will be marked live and will not be eliminated. This mode is needed by + // GPU-Assisted Validation instrumentation where a change in the interface + // is not allowed. + bool preserve_interface_; + + // Output variables can be removed from the interface if this is true. + // This is safe if the caller knows that the corresponding input variable + // in the following shader has been removed. It is false by default. + bool remove_outputs_; + + // Return true if |varId| is a variable of |storageClass|. |varId| must either + // be 0 or the result of an instruction. + bool IsVarOfStorage(uint32_t varId, spv::StorageClass storageClass); + + // Return true if the instance of the variable |varId| can only be access in + // |func|. For example, a function scope variable, or a private variable + // where |func| is an entry point with no function calls. + bool IsLocalVar(uint32_t varId, Function* func); + + // Return true if |inst| is marked live. + bool IsLive(const Instruction* inst) const { + return live_insts_.Get(inst->unique_id()); + } + + // Adds entry points, execution modes and workgroup size decorations to the + // worklist for processing with the first function. + void InitializeModuleScopeLiveInstructions(); + + // Add |inst| to worklist_ and live_insts_. + void AddToWorklist(Instruction* inst) { + if (!live_insts_.Set(inst->unique_id())) { + worklist_.push(inst); + } + } + + // Add all store instruction which use |ptrId|, directly or indirectly, + // to the live instruction worklist. + void AddStores(Function* func, uint32_t ptrId); + + // Initialize extensions allowlist + void InitExtensions(); + + // Return true if all extensions in this module are supported by this pass. + bool AllExtensionsSupported() const; + + // Returns true if the target of |inst| is dead. An instruction is dead if + // its result id is used in decoration or debug instructions only. |inst| is + // assumed to be OpName, OpMemberName or an annotation instruction. + bool IsTargetDead(Instruction* inst); + + // If |varId| is local, mark all stores of varId as live. + void ProcessLoad(Function* func, uint32_t varId); + + // Add branch to |labelId| to end of block |bp|. + void AddBranch(uint32_t labelId, BasicBlock* bp); + + // Add all break and continue branches in the construct associated with + // |mergeInst| to worklist if not already live + void AddBreaksAndContinuesToWorklist(Instruction* mergeInst); + + // Eliminates dead debug2 and annotation instructions. Marks dead globals for + // removal (e.g. types, constants and variables). + bool ProcessGlobalValues(); + + // Erases functions that are unreachable from the entry points of the module. + bool EliminateDeadFunctions(); + + // For function |func|, mark all Stores to non-function-scope variables + // and block terminating instructions as live. Recursively mark the values + // they use. When complete, mark any non-live instructions to be deleted. + // Returns true if the function has been modified. + // + // Note: This function does not delete useless control structures. All + // existing control structures will remain. This can leave not-insignificant + // sequences of ultimately useless code. + // TODO(): Remove useless control constructs. + bool AggressiveDCE(Function* func); + + Pass::Status ProcessImpl(); + + // Adds instructions which must be kept because of they have side-effects + // that ADCE cannot model to the work list. + void InitializeWorkList(Function* func, + std::list& structured_order); + + // Process each instruction in the work list by marking any instruction that + // that it depends on as live, and adding it to the work list. The work list + // will be empty at the end. + void ProcessWorkList(Function* func); + + // Kills any instructions in |func| that have not been marked as live. + bool KillDeadInstructions(const Function* func, + std::list& structured_order); + + // Adds the instructions that define the operands of |inst| to the work list. + void AddOperandsToWorkList(const Instruction* inst); + + // Marks all of the labels and branch that inst requires as live. + void MarkBlockAsLive(Instruction* inst); + + // Marks any variables from which |inst| may require data as live. + void MarkLoadedVariablesAsLive(Function* func, Instruction* inst); + + // Returns the id of the variable that |ptr_id| point to. |ptr_id| must be a + // value whose type is a pointer. + uint32_t GetVariableId(uint32_t ptr_id); + + // Returns all of the ids for the variables from which |inst| will load data. + std::vector GetLoadedVariables(Instruction* inst); + + // Returns all of the ids for the variables from which |inst| will load data. + // The opcode of |inst| must be OpFunctionCall. + std::vector GetLoadedVariablesFromFunctionCall( + const Instruction* inst); + + // Returns the id of the variable from which |inst| will load data. |inst| + // must not be an OpFunctionCall. Returns 0 if no data is read or the + // variable cannot be determined. Note that in logical addressing mode the + // latter is not possible for function and private storage class because there + // cannot be variable pointers pointing to those storage classes. + uint32_t GetLoadedVariableFromNonFunctionCalls(Instruction* inst); + + // Adds all decorations of |inst| to the work list. + void AddDecorationsToWorkList(const Instruction* inst); + + // Adds DebugScope instruction associated with |inst| to the work list. + void AddDebugScopeToWorkList(const Instruction* inst); + + // Adds all debug instruction associated with |inst| to the work list. + void AddDebugInstructionsToWorkList(const Instruction* inst); + + // Marks all of the OpFunctionParameter instructions in |func| as live. + void MarkFunctionParameterAsLive(const Function* func); + + // Returns the terminator instruction in the header for the innermost + // construct that contains |blk|. Returns nullptr if no such header exists. + Instruction* GetHeaderBranch(BasicBlock* blk); + + // Returns the header for the innermost construct that contains |blk|. A loop + // header will be its own header. Returns nullptr if no such header exists. + BasicBlock* GetHeaderBlock(BasicBlock* blk) const; + + // Returns the same as |GetHeaderBlock| except if |blk| is a loop header it + // will return the header of the next enclosing construct. Returns nullptr if + // no such header exists. + Instruction* GetBranchForNextHeader(BasicBlock* blk); + + // Returns the merge instruction in the same basic block as |inst|. Returns + // nullptr if one does not exist. + Instruction* GetMergeInstruction(Instruction* inst); + + // Returns true if |bb| is in the construct with header |header_block|. + bool BlockIsInConstruct(BasicBlock* header_block, BasicBlock* bb); + + // Returns true if |func| is an entry point that does not have any function + // calls. + bool IsEntryPointWithNoCalls(Function* func); + + // Returns true if |func| is an entry point. + bool IsEntryPoint(Function* func); + + // Returns true if |func| contains a function call. + bool HasCall(Function* func); + + // Marks the first block, which is the entry block, in |func| as live. + void MarkFirstBlockAsLive(Function* func); + + // Adds an OpUnreachable instruction at the end of |block|. + void AddUnreachable(BasicBlock*& block); + + // Marks the OpLoopMerge and the terminator in |basic_block| as live if + // |basic_block| is a loop header. + void MarkLoopConstructAsLiveIfLoopHeader(BasicBlock* basic_block); + + // The cached results for |IsEntryPointWithNoCalls|. It maps the function's + // result id to the return value. + std::unordered_map entry_point_with_no_calls_cache_; + + // Live Instruction Worklist. An instruction is added to this list + // if it might have a side effect, either directly or indirectly. + // If we don't know, then add it to this list. Instructions are + // removed from this list as the algorithm traces side effects, + // building up the live instructions set |live_insts_|. + std::queue worklist_; + + // Live Instructions + utils::BitVector live_insts_; + + // Live Local Variables + std::unordered_set live_local_vars_; + + // List of instructions to delete. Deletion is delayed until debug and + // annotation instructions are processed. + std::vector to_kill_; + + // Extensions supported by this pass. + std::unordered_set extensions_allowlist_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_AGGRESSIVE_DEAD_CODE_ELIM_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/amd_ext_to_khr.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/amd_ext_to_khr.cpp new file mode 100644 index 000000000000..a314567f8c16 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/amd_ext_to_khr.cpp @@ -0,0 +1,980 @@ +// Copyright (c) 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/amd_ext_to_khr.h" + +#include +#include + +#include "ir_builder.h" +#include "source/opt/ir_context.h" +#include "spv-amd-shader-ballot.insts.inc" +#include "type_manager.h" + +namespace spvtools { +namespace opt { +namespace { + +enum AmdShaderBallotExtOpcodes { + AmdShaderBallotSwizzleInvocationsAMD = 1, + AmdShaderBallotSwizzleInvocationsMaskedAMD = 2, + AmdShaderBallotWriteInvocationAMD = 3, + AmdShaderBallotMbcntAMD = 4 +}; + +enum AmdShaderTrinaryMinMaxExtOpCodes { + FMin3AMD = 1, + UMin3AMD = 2, + SMin3AMD = 3, + FMax3AMD = 4, + UMax3AMD = 5, + SMax3AMD = 6, + FMid3AMD = 7, + UMid3AMD = 8, + SMid3AMD = 9 +}; + +enum AmdGcnShader { CubeFaceCoordAMD = 2, CubeFaceIndexAMD = 1, TimeAMD = 3 }; + +analysis::Type* GetUIntType(IRContext* ctx) { + analysis::Integer int_type(32, false); + return ctx->get_type_mgr()->GetRegisteredType(&int_type); +} + +// Returns a folding rule that replaces |op(a,b,c)| by |op(op(a,b),c)|, where +// |op| is either min or max. |opcode| is the binary opcode in the GLSLstd450 +// extended instruction set that corresponds to the trinary instruction being +// replaced. +template +bool ReplaceTrinaryMinMax(IRContext* ctx, Instruction* inst, + const std::vector&) { + uint32_t glsl405_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + if (glsl405_ext_inst_id == 0) { + ctx->AddExtInstImport("GLSL.std.450"); + glsl405_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + } + + InstructionBuilder ir_builder( + ctx, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + uint32_t op1 = inst->GetSingleWordInOperand(2); + uint32_t op2 = inst->GetSingleWordInOperand(3); + uint32_t op3 = inst->GetSingleWordInOperand(4); + + Instruction* temp = ir_builder.AddNaryExtendedInstruction( + inst->type_id(), glsl405_ext_inst_id, opcode, {op1, op2}); + + Instruction::OperandList new_operands; + new_operands.push_back({SPV_OPERAND_TYPE_ID, {glsl405_ext_inst_id}}); + new_operands.push_back({SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast(opcode)}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {temp->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {op3}}); + + inst->SetInOperands(std::move(new_operands)); + ctx->UpdateDefUse(inst); + return true; +} + +// Returns a folding rule that replaces |mid(a,b,c)| by |clamp(a, min(b,c), +// max(b,c)|. The three parameters are the opcode that correspond to the min, +// max, and clamp operations for the type of the instruction being replaced. +template +bool ReplaceTrinaryMid(IRContext* ctx, Instruction* inst, + const std::vector&) { + uint32_t glsl405_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + if (glsl405_ext_inst_id == 0) { + ctx->AddExtInstImport("GLSL.std.450"); + glsl405_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + } + + InstructionBuilder ir_builder( + ctx, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + uint32_t op1 = inst->GetSingleWordInOperand(2); + uint32_t op2 = inst->GetSingleWordInOperand(3); + uint32_t op3 = inst->GetSingleWordInOperand(4); + + Instruction* min = ir_builder.AddNaryExtendedInstruction( + inst->type_id(), glsl405_ext_inst_id, static_cast(min_opcode), + {op2, op3}); + Instruction* max = ir_builder.AddNaryExtendedInstruction( + inst->type_id(), glsl405_ext_inst_id, static_cast(max_opcode), + {op2, op3}); + + Instruction::OperandList new_operands; + new_operands.push_back({SPV_OPERAND_TYPE_ID, {glsl405_ext_inst_id}}); + new_operands.push_back({SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast(clamp_opcode)}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {op1}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {min->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {max->result_id()}}); + + inst->SetInOperands(std::move(new_operands)); + ctx->UpdateDefUse(inst); + return true; +} + +// Returns a folding rule that will replace the opcode with |opcode| and add +// the capabilities required. The folding rule assumes it is folding an +// OpGroup*NonUniformAMD instruction from the SPV_AMD_shader_ballot extension. +template +bool ReplaceGroupNonuniformOperationOpCode( + IRContext* ctx, Instruction* inst, + const std::vector&) { + switch (new_opcode) { + case spv::Op::OpGroupNonUniformIAdd: + case spv::Op::OpGroupNonUniformFAdd: + case spv::Op::OpGroupNonUniformUMin: + case spv::Op::OpGroupNonUniformSMin: + case spv::Op::OpGroupNonUniformFMin: + case spv::Op::OpGroupNonUniformUMax: + case spv::Op::OpGroupNonUniformSMax: + case spv::Op::OpGroupNonUniformFMax: + break; + default: + assert( + false && + "Should be replacing with a group non uniform arithmetic operation."); + } + + switch (inst->opcode()) { + case spv::Op::OpGroupIAddNonUniformAMD: + case spv::Op::OpGroupFAddNonUniformAMD: + case spv::Op::OpGroupUMinNonUniformAMD: + case spv::Op::OpGroupSMinNonUniformAMD: + case spv::Op::OpGroupFMinNonUniformAMD: + case spv::Op::OpGroupUMaxNonUniformAMD: + case spv::Op::OpGroupSMaxNonUniformAMD: + case spv::Op::OpGroupFMaxNonUniformAMD: + break; + default: + assert(false && + "Should be replacing a group non uniform arithmetic operation."); + } + + ctx->AddCapability(spv::Capability::GroupNonUniformArithmetic); + inst->SetOpcode(new_opcode); + return true; +} + +// Returns a folding rule that will replace the SwizzleInvocationsAMD extended +// instruction in the SPV_AMD_shader_ballot extension. +// +// The instruction +// +// %offset = OpConstantComposite %v3uint %x %y %z %w +// %result = OpExtInst %type %1 SwizzleInvocationsAMD %data %offset +// +// is replaced with +// +// potentially new constants and types +// +// clang-format off +// %uint_max = OpConstant %uint 0xFFFFFFFF +// %v4uint = OpTypeVector %uint 4 +// %ballot_value = OpConstantComposite %v4uint %uint_max %uint_max %uint_max %uint_max +// %null = OpConstantNull %type +// clang-format on +// +// and the following code in the function body +// +// clang-format off +// %id = OpLoad %uint %SubgroupLocalInvocationId +// %quad_idx = OpBitwiseAnd %uint %id %uint_3 +// %quad_ldr = OpBitwiseXor %uint %id %quad_idx +// %my_offset = OpVectorExtractDynamic %uint %offset %quad_idx +// %target_inv = OpIAdd %uint %quad_ldr %my_offset +// %is_active = OpGroupNonUniformBallotBitExtract %bool %uint_3 %ballot_value %target_inv +// %shuffle = OpGroupNonUniformShuffle %type %uint_3 %data %target_inv +// %result = OpSelect %type %is_active %shuffle %null +// clang-format on +// +// Also adding the capabilities and builtins that are needed. +bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, + const std::vector&) { + analysis::TypeManager* type_mgr = ctx->get_type_mgr(); + analysis::ConstantManager* const_mgr = ctx->get_constant_mgr(); + + ctx->AddExtension("SPV_KHR_shader_ballot"); + ctx->AddCapability(spv::Capability::GroupNonUniformBallot); + ctx->AddCapability(spv::Capability::GroupNonUniformShuffle); + + InstructionBuilder ir_builder( + ctx, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + uint32_t data_id = inst->GetSingleWordInOperand(2); + uint32_t offset_id = inst->GetSingleWordInOperand(3); + + // Get the subgroup invocation id. + uint32_t var_id = ctx->GetBuiltinInputVarId( + uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); + assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); + Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); + Instruction* var_ptr_type = + ctx->get_def_use_mgr()->GetDef(var_inst->type_id()); + uint32_t uint_type_id = var_ptr_type->GetSingleWordInOperand(1); + + Instruction* id = ir_builder.AddLoad(uint_type_id, var_id); + + uint32_t quad_mask = ir_builder.GetUintConstantId(3); + + // This gives the offset in the group of 4 of this invocation. + Instruction* quad_idx = ir_builder.AddBinaryOp( + uint_type_id, spv::Op::OpBitwiseAnd, id->result_id(), quad_mask); + + // Get the invocation id of the first invocation in the group of 4. + Instruction* quad_ldr = + ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpBitwiseXor, + id->result_id(), quad_idx->result_id()); + + // Get the offset of the target invocation from the offset vector. + Instruction* my_offset = + ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpVectorExtractDynamic, + offset_id, quad_idx->result_id()); + + // Determine the index of the invocation to read from. + Instruction* target_inv = + ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpIAdd, + quad_ldr->result_id(), my_offset->result_id()); + + // Do the group operations + uint32_t uint_max_id = ir_builder.GetUintConstantId(0xFFFFFFFF); + uint32_t subgroup_scope = + ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); + const auto* ballot_value_const = const_mgr->GetConstant( + type_mgr->GetUIntVectorType(4), + {uint_max_id, uint_max_id, uint_max_id, uint_max_id}); + Instruction* ballot_value = + const_mgr->GetDefiningInstruction(ballot_value_const); + Instruction* is_active = ir_builder.AddNaryOp( + type_mgr->GetBoolTypeId(), spv::Op::OpGroupNonUniformBallotBitExtract, + {subgroup_scope, ballot_value->result_id(), target_inv->result_id()}); + Instruction* shuffle = + ir_builder.AddNaryOp(inst->type_id(), spv::Op::OpGroupNonUniformShuffle, + {subgroup_scope, data_id, target_inv->result_id()}); + + // Create the null constant to use in the select. + const auto* null = const_mgr->GetConstant(type_mgr->GetType(inst->type_id()), + std::vector()); + Instruction* null_inst = const_mgr->GetDefiningInstruction(null); + + // Build the select. + inst->SetOpcode(spv::Op::OpSelect); + Instruction::OperandList new_operands; + new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_active->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {shuffle->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {null_inst->result_id()}}); + + inst->SetInOperands(std::move(new_operands)); + ctx->UpdateDefUse(inst); + return true; +} + +// Returns a folding rule that will replace the SwizzleInvocationsMaskedAMD +// extended instruction in the SPV_AMD_shader_ballot extension. +// +// The instruction +// +// %mask = OpConstantComposite %v3uint %uint_x %uint_y %uint_z +// %result = OpExtInst %uint %1 SwizzleInvocationsMaskedAMD %data %mask +// +// is replaced with +// +// potentially new constants and types +// +// clang-format off +// %uint_mask_extend = OpConstant %uint 0xFFFFFFE0 +// %uint_max = OpConstant %uint 0xFFFFFFFF +// %v4uint = OpTypeVector %uint 4 +// %ballot_value = OpConstantComposite %v4uint %uint_max %uint_max %uint_max %uint_max +// clang-format on +// +// and the following code in the function body +// +// clang-format off +// %id = OpLoad %uint %SubgroupLocalInvocationId +// %and_mask = OpBitwiseOr %uint %uint_x %uint_mask_extend +// %and = OpBitwiseAnd %uint %id %and_mask +// %or = OpBitwiseOr %uint %and %uint_y +// %target_inv = OpBitwiseXor %uint %or %uint_z +// %is_active = OpGroupNonUniformBallotBitExtract %bool %uint_3 %ballot_value %target_inv +// %shuffle = OpGroupNonUniformShuffle %type %uint_3 %data %target_inv +// %result = OpSelect %type %is_active %shuffle %uint_0 +// clang-format on +// +// Also adding the capabilities and builtins that are needed. +bool ReplaceSwizzleInvocationsMasked( + IRContext* ctx, Instruction* inst, + const std::vector&) { + analysis::TypeManager* type_mgr = ctx->get_type_mgr(); + analysis::DefUseManager* def_use_mgr = ctx->get_def_use_mgr(); + analysis::ConstantManager* const_mgr = ctx->get_constant_mgr(); + + ctx->AddCapability(spv::Capability::GroupNonUniformBallot); + ctx->AddCapability(spv::Capability::GroupNonUniformShuffle); + + InstructionBuilder ir_builder( + ctx, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + // Get the operands to inst, and the components of the mask + uint32_t data_id = inst->GetSingleWordInOperand(2); + + Instruction* mask_inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(3)); + assert(mask_inst->opcode() == spv::Op::OpConstantComposite && + "The mask is suppose to be a vector constant."); + assert(mask_inst->NumInOperands() == 3 && + "The mask is suppose to have 3 components."); + + uint32_t uint_x = mask_inst->GetSingleWordInOperand(0); + uint32_t uint_y = mask_inst->GetSingleWordInOperand(1); + uint32_t uint_z = mask_inst->GetSingleWordInOperand(2); + + // Get the subgroup invocation id. + uint32_t var_id = ctx->GetBuiltinInputVarId( + uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); + ctx->AddExtension("SPV_KHR_shader_ballot"); + assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); + Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); + Instruction* var_ptr_type = + ctx->get_def_use_mgr()->GetDef(var_inst->type_id()); + uint32_t uint_type_id = var_ptr_type->GetSingleWordInOperand(1); + + Instruction* id = ir_builder.AddLoad(uint_type_id, var_id); + + // Do the bitwise operations. + uint32_t mask_extended = ir_builder.GetUintConstantId(0xFFFFFFE0); + Instruction* and_mask = ir_builder.AddBinaryOp( + uint_type_id, spv::Op::OpBitwiseOr, uint_x, mask_extended); + Instruction* and_result = + ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpBitwiseAnd, + id->result_id(), and_mask->result_id()); + Instruction* or_result = ir_builder.AddBinaryOp( + uint_type_id, spv::Op::OpBitwiseOr, and_result->result_id(), uint_y); + Instruction* target_inv = ir_builder.AddBinaryOp( + uint_type_id, spv::Op::OpBitwiseXor, or_result->result_id(), uint_z); + + // Do the group operations + uint32_t uint_max_id = ir_builder.GetUintConstantId(0xFFFFFFFF); + uint32_t subgroup_scope = + ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); + const auto* ballot_value_const = const_mgr->GetConstant( + type_mgr->GetUIntVectorType(4), + {uint_max_id, uint_max_id, uint_max_id, uint_max_id}); + Instruction* ballot_value = + const_mgr->GetDefiningInstruction(ballot_value_const); + Instruction* is_active = ir_builder.AddNaryOp( + type_mgr->GetBoolTypeId(), spv::Op::OpGroupNonUniformBallotBitExtract, + {subgroup_scope, ballot_value->result_id(), target_inv->result_id()}); + Instruction* shuffle = + ir_builder.AddNaryOp(inst->type_id(), spv::Op::OpGroupNonUniformShuffle, + {subgroup_scope, data_id, target_inv->result_id()}); + + // Create the null constant to use in the select. + const auto* null = const_mgr->GetConstant(type_mgr->GetType(inst->type_id()), + std::vector()); + Instruction* null_inst = const_mgr->GetDefiningInstruction(null); + + // Build the select. + inst->SetOpcode(spv::Op::OpSelect); + Instruction::OperandList new_operands; + new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_active->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {shuffle->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {null_inst->result_id()}}); + + inst->SetInOperands(std::move(new_operands)); + ctx->UpdateDefUse(inst); + return true; +} + +// Returns a folding rule that will replace the WriteInvocationAMD extended +// instruction in the SPV_AMD_shader_ballot extension. +// +// The instruction +// +// clang-format off +// %result = OpExtInst %type %1 WriteInvocationAMD %input_value %write_value %invocation_index +// clang-format on +// +// with +// +// %id = OpLoad %uint %SubgroupLocalInvocationId +// %cmp = OpIEqual %bool %id %invocation_index +// %result = OpSelect %type %cmp %write_value %input_value +// +// Also adding the capabilities and builtins that are needed. +bool ReplaceWriteInvocation(IRContext* ctx, Instruction* inst, + const std::vector&) { + uint32_t var_id = ctx->GetBuiltinInputVarId( + uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); + ctx->AddCapability(spv::Capability::SubgroupBallotKHR); + ctx->AddExtension("SPV_KHR_shader_ballot"); + assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); + Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); + Instruction* var_ptr_type = + ctx->get_def_use_mgr()->GetDef(var_inst->type_id()); + + InstructionBuilder ir_builder( + ctx, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + Instruction* t = + ir_builder.AddLoad(var_ptr_type->GetSingleWordInOperand(1), var_id); + analysis::Bool bool_type; + uint32_t bool_type_id = ctx->get_type_mgr()->GetTypeInstruction(&bool_type); + Instruction* cmp = + ir_builder.AddBinaryOp(bool_type_id, spv::Op::OpIEqual, t->result_id(), + inst->GetSingleWordInOperand(4)); + + // Build a select. + inst->SetOpcode(spv::Op::OpSelect); + Instruction::OperandList new_operands; + new_operands.push_back({SPV_OPERAND_TYPE_ID, {cmp->result_id()}}); + new_operands.push_back(inst->GetInOperand(3)); + new_operands.push_back(inst->GetInOperand(2)); + + inst->SetInOperands(std::move(new_operands)); + ctx->UpdateDefUse(inst); + return true; +} + +// Returns a folding rule that will replace the MbcntAMD extended instruction in +// the SPV_AMD_shader_ballot extension. +// +// The instruction +// +// %result = OpExtInst %uint %1 MbcntAMD %mask +// +// with +// +// Get SubgroupLtMask and convert the first 64-bits into a uint64_t because +// AMD's shader compiler expects a 64-bit integer mask. +// +// %var = OpLoad %v4uint %SubgroupLtMaskKHR +// %shuffle = OpVectorShuffle %v2uint %var %var 0 1 +// %cast = OpBitcast %ulong %shuffle +// +// Perform the mask and count the bits. +// +// %and = OpBitwiseAnd %ulong %cast %mask +// %result = OpBitCount %uint %and +// +// Also adding the capabilities and builtins that are needed. +bool ReplaceMbcnt(IRContext* context, Instruction* inst, + const std::vector&) { + analysis::TypeManager* type_mgr = context->get_type_mgr(); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + + uint32_t var_id = + context->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::SubgroupLtMask)); + assert(var_id != 0 && "Could not get SubgroupLtMask variable."); + context->AddCapability(spv::Capability::GroupNonUniformBallot); + Instruction* var_inst = def_use_mgr->GetDef(var_id); + Instruction* var_ptr_type = def_use_mgr->GetDef(var_inst->type_id()); + Instruction* var_type = + def_use_mgr->GetDef(var_ptr_type->GetSingleWordInOperand(1)); + assert(var_type->opcode() == spv::Op::OpTypeVector && + "Variable is suppose to be a vector of 4 ints"); + + // Get the type for the shuffle. + analysis::Vector temp_type(GetUIntType(context), 2); + const analysis::Type* shuffle_type = + context->get_type_mgr()->GetRegisteredType(&temp_type); + uint32_t shuffle_type_id = type_mgr->GetTypeInstruction(shuffle_type); + + uint32_t mask_id = inst->GetSingleWordInOperand(2); + Instruction* mask_inst = def_use_mgr->GetDef(mask_id); + + // Testing with amd's shader compiler shows that a 64-bit mask is expected. + assert(type_mgr->GetType(mask_inst->type_id())->AsInteger() != nullptr); + assert(type_mgr->GetType(mask_inst->type_id())->AsInteger()->width() == 64); + + InstructionBuilder ir_builder( + context, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + Instruction* load = ir_builder.AddLoad(var_type->result_id(), var_id); + Instruction* shuffle = ir_builder.AddVectorShuffle( + shuffle_type_id, load->result_id(), load->result_id(), {0, 1}); + Instruction* bitcast = ir_builder.AddUnaryOp( + mask_inst->type_id(), spv::Op::OpBitcast, shuffle->result_id()); + Instruction* t = + ir_builder.AddBinaryOp(mask_inst->type_id(), spv::Op::OpBitwiseAnd, + bitcast->result_id(), mask_id); + + inst->SetOpcode(spv::Op::OpBitCount); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {t->result_id()}}}); + context->UpdateDefUse(inst); + return true; +} + +// A folding rule that will replace the CubeFaceCoordAMD extended +// instruction in the SPV_AMD_gcn_shader_ballot. Returns true if the folding is +// successful. +// +// The instruction +// +// %result = OpExtInst %v2float %1 CubeFaceCoordAMD %input +// +// with +// +// %x = OpCompositeExtract %float %input 0 +// %y = OpCompositeExtract %float %input 1 +// %z = OpCompositeExtract %float %input 2 +// %nx = OpFNegate %float %x +// %ny = OpFNegate %float %y +// %nz = OpFNegate %float %z +// %ax = OpExtInst %float %n_1 FAbs %x +// %ay = OpExtInst %float %n_1 FAbs %y +// %az = OpExtInst %float %n_1 FAbs %z +// %amax_x_y = OpExtInst %float %n_1 FMax %ay %ax +// %amax = OpExtInst %float %n_1 FMax %az %amax_x_y +// %cubema = OpFMul %float %float_2 %amax +// %is_z_max = OpFOrdGreaterThanEqual %bool %az %amax_x_y +// %not_is_z_max = OpLogicalNot %bool %is_z_max +// %y_gt_x = OpFOrdGreaterThanEqual %bool %ay %ax +// %is_y_max = OpLogicalAnd %bool %not_is_z_max %y_gt_x +// %is_z_neg = OpFOrdLessThan %bool %z %float_0 +// %cubesc_case_1 = OpSelect %float %is_z_neg %nx %x +// %is_x_neg = OpFOrdLessThan %bool %x %float_0 +// %cubesc_case_2 = OpSelect %float %is_x_neg %z %nz +// %sel = OpSelect %float %is_y_max %x %cubesc_case_2 +// %cubesc = OpSelect %float %is_z_max %cubesc_case_1 %sel +// %is_y_neg = OpFOrdLessThan %bool %y %float_0 +// %cubetc_case_1 = OpSelect %float %is_y_neg %nz %z +// %cubetc = OpSelect %float %is_y_max %cubetc_case_1 %ny +// %cube = OpCompositeConstruct %v2float %cubesc %cubetc +// %denom = OpCompositeConstruct %v2float %cubema %cubema +// %div = OpFDiv %v2float %cube %denom +// %result = OpFAdd %v2float %div %const +// +// Also adding the capabilities and builtins that are needed. +bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, + const std::vector&) { + analysis::TypeManager* type_mgr = ctx->get_type_mgr(); + analysis::ConstantManager* const_mgr = ctx->get_constant_mgr(); + + uint32_t float_type_id = type_mgr->GetFloatTypeId(); + const analysis::Type* v2_float_type = type_mgr->GetFloatVectorType(2); + uint32_t v2_float_type_id = type_mgr->GetId(v2_float_type); + uint32_t bool_id = type_mgr->GetBoolTypeId(); + + InstructionBuilder ir_builder( + ctx, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + uint32_t input_id = inst->GetSingleWordInOperand(2); + uint32_t glsl405_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + if (glsl405_ext_inst_id == 0) { + ctx->AddExtInstImport("GLSL.std.450"); + glsl405_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + } + + // Get the constants that will be used. + uint32_t f0_const_id = const_mgr->GetFloatConstId(0.0); + uint32_t f2_const_id = const_mgr->GetFloatConstId(2.0); + uint32_t f0_5_const_id = const_mgr->GetFloatConstId(0.5); + const analysis::Constant* vec_const = + const_mgr->GetConstant(v2_float_type, {f0_5_const_id, f0_5_const_id}); + uint32_t vec_const_id = + const_mgr->GetDefiningInstruction(vec_const)->result_id(); + + // Extract the input values. + Instruction* x = ir_builder.AddCompositeExtract(float_type_id, input_id, {0}); + Instruction* y = ir_builder.AddCompositeExtract(float_type_id, input_id, {1}); + Instruction* z = ir_builder.AddCompositeExtract(float_type_id, input_id, {2}); + + // Negate the input values. + Instruction* nx = + ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, x->result_id()); + Instruction* ny = + ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, y->result_id()); + Instruction* nz = + ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, z->result_id()); + + // Get the abolsute values of the inputs. + Instruction* ax = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {x->result_id()}); + Instruction* ay = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {y->result_id()}); + Instruction* az = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {z->result_id()}); + + // Find which values are negative. Used in later computations. + Instruction* is_z_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, z->result_id(), f0_const_id); + Instruction* is_y_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, y->result_id(), f0_const_id); + Instruction* is_x_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, x->result_id(), f0_const_id); + + // Compute cubema + Instruction* amax_x_y = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FMax, + {ax->result_id(), ay->result_id()}); + Instruction* amax = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FMax, + {az->result_id(), amax_x_y->result_id()}); + Instruction* cubema = ir_builder.AddBinaryOp(float_type_id, spv::Op::OpFMul, + f2_const_id, amax->result_id()); + + // Do the comparisons needed for computing cubesc and cubetc. + Instruction* is_z_max = + ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, + az->result_id(), amax_x_y->result_id()); + Instruction* not_is_z_max = ir_builder.AddUnaryOp( + bool_id, spv::Op::OpLogicalNot, is_z_max->result_id()); + Instruction* y_gr_x = + ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, + ay->result_id(), ax->result_id()); + Instruction* is_y_max = + ir_builder.AddBinaryOp(bool_id, spv::Op::OpLogicalAnd, + not_is_z_max->result_id(), y_gr_x->result_id()); + + // Select the correct value for cubesc. + Instruction* cubesc_case_1 = ir_builder.AddSelect( + float_type_id, is_z_neg->result_id(), nx->result_id(), x->result_id()); + Instruction* cubesc_case_2 = ir_builder.AddSelect( + float_type_id, is_x_neg->result_id(), z->result_id(), nz->result_id()); + Instruction* sel = + ir_builder.AddSelect(float_type_id, is_y_max->result_id(), x->result_id(), + cubesc_case_2->result_id()); + Instruction* cubesc = + ir_builder.AddSelect(float_type_id, is_z_max->result_id(), + cubesc_case_1->result_id(), sel->result_id()); + + // Select the correct value for cubetc. + Instruction* cubetc_case_1 = ir_builder.AddSelect( + float_type_id, is_y_neg->result_id(), nz->result_id(), z->result_id()); + Instruction* cubetc = + ir_builder.AddSelect(float_type_id, is_y_max->result_id(), + cubetc_case_1->result_id(), ny->result_id()); + + // Do the division + Instruction* cube = ir_builder.AddCompositeConstruct( + v2_float_type_id, {cubesc->result_id(), cubetc->result_id()}); + Instruction* denom = ir_builder.AddCompositeConstruct( + v2_float_type_id, {cubema->result_id(), cubema->result_id()}); + Instruction* div = ir_builder.AddBinaryOp( + v2_float_type_id, spv::Op::OpFDiv, cube->result_id(), denom->result_id()); + + // Get the final result by adding 0.5 to |div|. + inst->SetOpcode(spv::Op::OpFAdd); + Instruction::OperandList new_operands; + new_operands.push_back({SPV_OPERAND_TYPE_ID, {div->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {vec_const_id}}); + + inst->SetInOperands(std::move(new_operands)); + ctx->UpdateDefUse(inst); + return true; +} + +// A folding rule that will replace the CubeFaceIndexAMD extended +// instruction in the SPV_AMD_gcn_shader_ballot. Returns true if the folding +// is successful. +// +// The instruction +// +// %result = OpExtInst %float %1 CubeFaceIndexAMD %input +// +// with +// +// %x = OpCompositeExtract %float %input 0 +// %y = OpCompositeExtract %float %input 1 +// %z = OpCompositeExtract %float %input 2 +// %ax = OpExtInst %float %n_1 FAbs %x +// %ay = OpExtInst %float %n_1 FAbs %y +// %az = OpExtInst %float %n_1 FAbs %z +// %is_z_neg = OpFOrdLessThan %bool %z %float_0 +// %is_y_neg = OpFOrdLessThan %bool %y %float_0 +// %is_x_neg = OpFOrdLessThan %bool %x %float_0 +// %amax_x_y = OpExtInst %float %n_1 FMax %ax %ay +// %is_z_max = OpFOrdGreaterThanEqual %bool %az %amax_x_y +// %y_gt_x = OpFOrdGreaterThanEqual %bool %ay %ax +// %case_z = OpSelect %float %is_z_neg %float_5 %float4 +// %case_y = OpSelect %float %is_y_neg %float_3 %float2 +// %case_x = OpSelect %float %is_x_neg %float_1 %float0 +// %sel = OpSelect %float %y_gt_x %case_y %case_x +// %result = OpSelect %float %is_z_max %case_z %sel +// +// Also adding the capabilities and builtins that are needed. +bool ReplaceCubeFaceIndex(IRContext* ctx, Instruction* inst, + const std::vector&) { + analysis::TypeManager* type_mgr = ctx->get_type_mgr(); + analysis::ConstantManager* const_mgr = ctx->get_constant_mgr(); + + uint32_t float_type_id = type_mgr->GetFloatTypeId(); + uint32_t bool_id = type_mgr->GetBoolTypeId(); + + InstructionBuilder ir_builder( + ctx, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + uint32_t input_id = inst->GetSingleWordInOperand(2); + uint32_t glsl405_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + if (glsl405_ext_inst_id == 0) { + ctx->AddExtInstImport("GLSL.std.450"); + glsl405_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + } + + // Get the constants that will be used. + uint32_t f0_const_id = const_mgr->GetFloatConstId(0.0); + uint32_t f1_const_id = const_mgr->GetFloatConstId(1.0); + uint32_t f2_const_id = const_mgr->GetFloatConstId(2.0); + uint32_t f3_const_id = const_mgr->GetFloatConstId(3.0); + uint32_t f4_const_id = const_mgr->GetFloatConstId(4.0); + uint32_t f5_const_id = const_mgr->GetFloatConstId(5.0); + + // Extract the input values. + Instruction* x = ir_builder.AddCompositeExtract(float_type_id, input_id, {0}); + Instruction* y = ir_builder.AddCompositeExtract(float_type_id, input_id, {1}); + Instruction* z = ir_builder.AddCompositeExtract(float_type_id, input_id, {2}); + + // Get the absolute values of the inputs. + Instruction* ax = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {x->result_id()}); + Instruction* ay = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {y->result_id()}); + Instruction* az = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {z->result_id()}); + + // Find which values are negative. Used in later computations. + Instruction* is_z_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, z->result_id(), f0_const_id); + Instruction* is_y_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, y->result_id(), f0_const_id); + Instruction* is_x_neg = ir_builder.AddBinaryOp( + bool_id, spv::Op::OpFOrdLessThan, x->result_id(), f0_const_id); + + // Find the max value. + Instruction* amax_x_y = ir_builder.AddNaryExtendedInstruction( + float_type_id, glsl405_ext_inst_id, GLSLstd450FMax, + {ax->result_id(), ay->result_id()}); + Instruction* is_z_max = + ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, + az->result_id(), amax_x_y->result_id()); + Instruction* y_gr_x = + ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, + ay->result_id(), ax->result_id()); + + // Get the value for each case. + Instruction* case_z = ir_builder.AddSelect( + float_type_id, is_z_neg->result_id(), f5_const_id, f4_const_id); + Instruction* case_y = ir_builder.AddSelect( + float_type_id, is_y_neg->result_id(), f3_const_id, f2_const_id); + Instruction* case_x = ir_builder.AddSelect( + float_type_id, is_x_neg->result_id(), f1_const_id, f0_const_id); + + // Select the correct case. + Instruction* sel = + ir_builder.AddSelect(float_type_id, y_gr_x->result_id(), + case_y->result_id(), case_x->result_id()); + + // Get the final result by adding 0.5 to |div|. + inst->SetOpcode(spv::Op::OpSelect); + Instruction::OperandList new_operands; + new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_z_max->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {case_z->result_id()}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {sel->result_id()}}); + + inst->SetInOperands(std::move(new_operands)); + ctx->UpdateDefUse(inst); + return true; +} + +// A folding rule that will replace the TimeAMD extended instruction in the +// SPV_AMD_gcn_shader_ballot. It returns true if the folding is successful. +// It returns False, otherwise. +// +// The instruction +// +// %result = OpExtInst %uint64 %1 TimeAMD +// +// with +// +// %result = OpReadClockKHR %uint64 %uint_3 +// +// NOTE: TimeAMD uses subgroup scope (it is not a real time clock). +bool ReplaceTimeAMD(IRContext* ctx, Instruction* inst, + const std::vector&) { + InstructionBuilder ir_builder( + ctx, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + ctx->AddExtension("SPV_KHR_shader_clock"); + ctx->AddCapability(spv::Capability::ShaderClockKHR); + + inst->SetOpcode(spv::Op::OpReadClockKHR); + Instruction::OperandList args; + uint32_t subgroup_scope_id = + ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); + args.push_back({SPV_OPERAND_TYPE_ID, {subgroup_scope_id}}); + inst->SetInOperands(std::move(args)); + ctx->UpdateDefUse(inst); + + return true; +} + +class AmdExtFoldingRules : public FoldingRules { + public: + explicit AmdExtFoldingRules(IRContext* ctx) : FoldingRules(ctx) {} + + protected: + virtual void AddFoldingRules() override { + rules_[spv::Op::OpGroupIAddNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupFAddNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupUMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupSMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupFMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupUMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupSMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[spv::Op::OpGroupFMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + + uint32_t extension_id = + context()->module()->GetExtInstImportId("SPV_AMD_shader_ballot"); + + if (extension_id != 0) { + ext_rules_[{extension_id, AmdShaderBallotSwizzleInvocationsAMD}] + .push_back(ReplaceSwizzleInvocations); + ext_rules_[{extension_id, AmdShaderBallotSwizzleInvocationsMaskedAMD}] + .push_back(ReplaceSwizzleInvocationsMasked); + ext_rules_[{extension_id, AmdShaderBallotWriteInvocationAMD}].push_back( + ReplaceWriteInvocation); + ext_rules_[{extension_id, AmdShaderBallotMbcntAMD}].push_back( + ReplaceMbcnt); + } + + extension_id = context()->module()->GetExtInstImportId( + "SPV_AMD_shader_trinary_minmax"); + + if (extension_id != 0) { + ext_rules_[{extension_id, FMin3AMD}].push_back( + ReplaceTrinaryMinMax); + ext_rules_[{extension_id, UMin3AMD}].push_back( + ReplaceTrinaryMinMax); + ext_rules_[{extension_id, SMin3AMD}].push_back( + ReplaceTrinaryMinMax); + ext_rules_[{extension_id, FMax3AMD}].push_back( + ReplaceTrinaryMinMax); + ext_rules_[{extension_id, UMax3AMD}].push_back( + ReplaceTrinaryMinMax); + ext_rules_[{extension_id, SMax3AMD}].push_back( + ReplaceTrinaryMinMax); + ext_rules_[{extension_id, FMid3AMD}].push_back( + ReplaceTrinaryMid); + ext_rules_[{extension_id, UMid3AMD}].push_back( + ReplaceTrinaryMid); + ext_rules_[{extension_id, SMid3AMD}].push_back( + ReplaceTrinaryMid); + } + + extension_id = + context()->module()->GetExtInstImportId("SPV_AMD_gcn_shader"); + + if (extension_id != 0) { + ext_rules_[{extension_id, CubeFaceCoordAMD}].push_back( + ReplaceCubeFaceCoord); + ext_rules_[{extension_id, CubeFaceIndexAMD}].push_back( + ReplaceCubeFaceIndex); + ext_rules_[{extension_id, TimeAMD}].push_back(ReplaceTimeAMD); + } + } +}; + +class AmdExtConstFoldingRules : public ConstantFoldingRules { + public: + AmdExtConstFoldingRules(IRContext* ctx) : ConstantFoldingRules(ctx) {} + + protected: + virtual void AddFoldingRules() override {} +}; + +} // namespace + +Pass::Status AmdExtensionToKhrPass::Process() { + bool changed = false; + + // Traverse the body of the functions to replace instructions that require + // the extensions. + InstructionFolder folder( + context(), + std::unique_ptr(new AmdExtFoldingRules(context())), + MakeUnique(context())); + for (Function& func : *get_module()) { + func.ForEachInst([&changed, &folder](Instruction* inst) { + if (folder.FoldInstruction(inst)) { + changed = true; + } + }); + } + + // Now that instruction that require the extensions have been removed, we can + // remove the extension instructions. + std::set ext_to_remove = {"SPV_AMD_shader_ballot", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader"}; + + std::vector to_be_killed; + for (Instruction& inst : context()->module()->extensions()) { + if (inst.opcode() == spv::Op::OpExtension) { + if (ext_to_remove.count(inst.GetInOperand(0).AsString()) != 0) { + to_be_killed.push_back(&inst); + } + } + } + + for (Instruction& inst : context()->ext_inst_imports()) { + if (inst.opcode() == spv::Op::OpExtInstImport) { + if (ext_to_remove.count(inst.GetInOperand(0).AsString()) != 0) { + to_be_killed.push_back(&inst); + } + } + } + + for (Instruction* inst : to_be_killed) { + context()->KillInst(inst); + changed = true; + } + + // The replacements that take place use instructions that are missing before + // SPIR-V 1.3. If we changed something, we will have to make sure the version + // is at least SPIR-V 1.3 to make sure those instruction can be used. + if (changed) { + uint32_t version = get_module()->version(); + if (version < 0x00010300 /*1.3*/) { + get_module()->set_version(0x00010300); + } + } + return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/amd_ext_to_khr.h b/thirdparty/glslang/External/spirv-tools/source/opt/amd_ext_to_khr.h new file mode 100644 index 000000000000..6a39d953a110 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/amd_ext_to_khr.h @@ -0,0 +1,51 @@ +// Copyright (c) 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_AMD_EXT_TO_KHR_H_ +#define SOURCE_OPT_AMD_EXT_TO_KHR_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// Replaces the extensions VK_AMD_shader_ballot, VK_AMD_gcn_shader, and +// VK_AMD_shader_trinary_minmax with equivalent code using core instructions and +// capabilities. +class AmdExtensionToKhrPass : public Pass { + public: + const char* name() const override { return "amd-ext-to-khr"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisScalarEvolution | + IRContext::kAnalysisRegisterPressure | + IRContext::kAnalysisValueNumberTable | + IRContext::kAnalysisStructuredCFG | + IRContext::kAnalysisBuiltinVarId | + IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | + IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; + } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_AMD_EXT_TO_KHR_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/analyze_live_input_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/analyze_live_input_pass.cpp new file mode 100644 index 000000000000..529e68467180 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/analyze_live_input_pass.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/analyze_live_input_pass.h" + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +Pass::Status AnalyzeLiveInputPass::Process() { + // Current functionality assumes shader capability + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return Status::SuccessWithoutChange; + Pass::Status status = DoLiveInputAnalysis(); + return status; +} + +Pass::Status AnalyzeLiveInputPass::DoLiveInputAnalysis() { + // Current functionality only supports frag, tesc, tese or geom shaders. + // Report failure for any other stage. + auto stage = context()->GetStage(); + if (stage != spv::ExecutionModel::Fragment && + stage != spv::ExecutionModel::TessellationControl && + stage != spv::ExecutionModel::TessellationEvaluation && + stage != spv::ExecutionModel::Geometry) + return Status::Failure; + context()->get_liveness_mgr()->GetLiveness(live_locs_, live_builtins_); + return Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/analyze_live_input_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/analyze_live_input_pass.h new file mode 100644 index 000000000000..ab292effe151 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/analyze_live_input_pass.h @@ -0,0 +1,57 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ +#define SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ + +#include + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class AnalyzeLiveInputPass : public Pass { + public: + explicit AnalyzeLiveInputPass(std::unordered_set* live_locs, + std::unordered_set* live_builtins) + : live_locs_(live_locs), live_builtins_(live_builtins) {} + + const char* name() const override { return "analyze-live-input"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Do live input analysis + Status DoLiveInputAnalysis(); + + std::unordered_set* live_locs_; + std::unordered_set* live_builtins_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/basic_block.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/basic_block.cpp new file mode 100644 index 000000000000..a9fc8e2f7bb4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/basic_block.cpp @@ -0,0 +1,284 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/basic_block.h" + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/reflect.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kLoopMergeContinueBlockIdInIdx = 1; +constexpr uint32_t kLoopMergeMergeBlockIdInIdx = 0; +constexpr uint32_t kSelectionMergeMergeBlockIdInIdx = 0; +} // namespace + +BasicBlock* BasicBlock::Clone(IRContext* context) const { + BasicBlock* clone = new BasicBlock( + std::unique_ptr(GetLabelInst()->Clone(context))); + for (const auto& inst : insts_) { + // Use the incoming context + clone->AddInstruction(std::unique_ptr(inst.Clone(context))); + } + + if (context->AreAnalysesValid( + IRContext::Analysis::kAnalysisInstrToBlockMapping)) { + for (auto& inst : *clone) { + context->set_instr_block(&inst, clone); + } + } + + return clone; +} + +const Instruction* BasicBlock::GetMergeInst() const { + const Instruction* result = nullptr; + // If it exists, the merge instruction immediately precedes the + // terminator. + auto iter = ctail(); + if (iter != cbegin()) { + --iter; + const auto opcode = iter->opcode(); + if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) { + result = &*iter; + } + } + return result; +} + +Instruction* BasicBlock::GetMergeInst() { + Instruction* result = nullptr; + // If it exists, the merge instruction immediately precedes the + // terminator. + auto iter = tail(); + if (iter != begin()) { + --iter; + const auto opcode = iter->opcode(); + if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) { + result = &*iter; + } + } + return result; +} + +const Instruction* BasicBlock::GetLoopMergeInst() const { + if (auto* merge = GetMergeInst()) { + if (merge->opcode() == spv::Op::OpLoopMerge) { + return merge; + } + } + return nullptr; +} + +Instruction* BasicBlock::GetLoopMergeInst() { + if (auto* merge = GetMergeInst()) { + if (merge->opcode() == spv::Op::OpLoopMerge) { + return merge; + } + } + return nullptr; +} + +void BasicBlock::KillAllInsts(bool killLabel) { + ForEachInst([killLabel](Instruction* ip) { + if (killLabel || ip->opcode() != spv::Op::OpLabel) { + ip->context()->KillInst(ip); + } + }); +} + +void BasicBlock::ForEachSuccessorLabel( + const std::function& f) const { + WhileEachSuccessorLabel([f](const uint32_t l) { + f(l); + return true; + }); +} + +bool BasicBlock::WhileEachSuccessorLabel( + const std::function& f) const { + const auto br = &insts_.back(); + switch (br->opcode()) { + case spv::Op::OpBranch: + return f(br->GetOperand(0).words[0]); + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: { + bool is_first = true; + return br->WhileEachInId([&is_first, &f](const uint32_t* idp) { + if (!is_first) return f(*idp); + is_first = false; + return true; + }); + } + default: + return true; + } +} + +void BasicBlock::ForEachSuccessorLabel( + const std::function& f) { + auto br = &insts_.back(); + switch (br->opcode()) { + case spv::Op::OpBranch: { + uint32_t tmp_id = br->GetOperand(0).words[0]; + f(&tmp_id); + if (tmp_id != br->GetOperand(0).words[0]) br->SetOperand(0, {tmp_id}); + } break; + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: { + bool is_first = true; + br->ForEachInId([&is_first, &f](uint32_t* idp) { + if (!is_first) f(idp); + is_first = false; + }); + } break; + default: + break; + } +} + +bool BasicBlock::IsSuccessor(const BasicBlock* block) const { + uint32_t succId = block->id(); + bool isSuccessor = false; + ForEachSuccessorLabel([&isSuccessor, succId](const uint32_t label) { + if (label == succId) isSuccessor = true; + }); + return isSuccessor; +} + +void BasicBlock::ForMergeAndContinueLabel( + const std::function& f) { + auto ii = insts_.end(); + --ii; + if (ii == insts_.begin()) return; + --ii; + if (ii->opcode() == spv::Op::OpSelectionMerge || + ii->opcode() == spv::Op::OpLoopMerge) { + ii->ForEachInId([&f](const uint32_t* idp) { f(*idp); }); + } +} + +uint32_t BasicBlock::MergeBlockIdIfAny() const { + auto merge_ii = cend(); + --merge_ii; + uint32_t mbid = 0; + if (merge_ii != cbegin()) { + --merge_ii; + if (merge_ii->opcode() == spv::Op::OpLoopMerge) { + mbid = merge_ii->GetSingleWordInOperand(kLoopMergeMergeBlockIdInIdx); + } else if (merge_ii->opcode() == spv::Op::OpSelectionMerge) { + mbid = merge_ii->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); + } + } + + return mbid; +} + +uint32_t BasicBlock::MergeBlockId() const { + uint32_t mbid = MergeBlockIdIfAny(); + assert(mbid && "Expected block to have a corresponding merge block"); + return mbid; +} + +uint32_t BasicBlock::ContinueBlockIdIfAny() const { + auto merge_ii = cend(); + --merge_ii; + uint32_t cbid = 0; + if (merge_ii != cbegin()) { + --merge_ii; + if (merge_ii->opcode() == spv::Op::OpLoopMerge) { + cbid = merge_ii->GetSingleWordInOperand(kLoopMergeContinueBlockIdInIdx); + } + } + return cbid; +} + +uint32_t BasicBlock::ContinueBlockId() const { + uint32_t cbid = ContinueBlockIdIfAny(); + assert(cbid && "Expected block to have a corresponding continue target"); + return cbid; +} + +std::ostream& operator<<(std::ostream& str, const BasicBlock& block) { + str << block.PrettyPrint(); + return str; +} + +void BasicBlock::Dump() const { + std::cerr << "Basic block #" << id() << "\n" << *this << "\n "; +} + +std::string BasicBlock::PrettyPrint(uint32_t options) const { + std::ostringstream str; + ForEachInst([&str, options](const Instruction* inst) { + str << inst->PrettyPrint(options); + if (!spvOpcodeIsBlockTerminator(inst->opcode())) { + str << std::endl; + } + }); + return str.str(); +} + +BasicBlock* BasicBlock::SplitBasicBlock(IRContext* context, uint32_t label_id, + iterator iter) { + assert(!insts_.empty()); + + std::unique_ptr new_block_temp = MakeUnique( + MakeUnique(context, spv::Op::OpLabel, 0, label_id, + std::initializer_list{})); + BasicBlock* new_block = new_block_temp.get(); + function_->InsertBasicBlockAfter(std::move(new_block_temp), this); + + new_block->insts_.Splice(new_block->end(), &insts_, iter, end()); + assert(new_block->GetParent() == GetParent() && + "The parent should already be set appropriately."); + + context->AnalyzeDefUse(new_block->GetLabelInst()); + + // Update the phi nodes in the successor blocks to reference the new block id. + const_cast(new_block)->ForEachSuccessorLabel( + [new_block, this, context](const uint32_t label) { + BasicBlock* target_bb = context->get_instr_block(label); + target_bb->ForEachPhiInst( + [this, new_block, context](Instruction* phi_inst) { + bool changed = false; + for (uint32_t i = 1; i < phi_inst->NumInOperands(); i += 2) { + if (phi_inst->GetSingleWordInOperand(i) == this->id()) { + changed = true; + phi_inst->SetInOperand(i, {new_block->id()}); + } + } + + if (changed) { + context->UpdateDefUse(phi_inst); + } + }); + }); + + if (context->AreAnalysesValid(IRContext::kAnalysisInstrToBlockMapping)) { + context->set_instr_block(new_block->GetLabelInst(), new_block); + new_block->ForEachInst([new_block, context](Instruction* inst) { + context->set_instr_block(inst, new_block); + }); + } + + return new_block; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/basic_block.h b/thirdparty/glslang/External/spirv-tools/source/opt/basic_block.h new file mode 100644 index 000000000000..24d5fceb346d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/basic_block.h @@ -0,0 +1,342 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file defines the language constructs for representing a SPIR-V +// module in memory. + +#ifndef SOURCE_OPT_BASIC_BLOCK_H_ +#define SOURCE_OPT_BASIC_BLOCK_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/instruction_list.h" +#include "source/opt/iterator.h" + +namespace spvtools { +namespace opt { + +class Function; +class IRContext; + +// A SPIR-V basic block. +class BasicBlock { + public: + using iterator = InstructionList::iterator; + using const_iterator = InstructionList::const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = + std::reverse_iterator; + + // Creates a basic block with the given starting |label|. + inline explicit BasicBlock(std::unique_ptr label); + + explicit BasicBlock(const BasicBlock& bb) = delete; + + // Creates a clone of the basic block in the given |context| + // + // The parent function will default to null and needs to be explicitly set by + // the user. + // + // If the inst-to-block map in |context| is valid, then the new instructions + // will be inserted into the map. + BasicBlock* Clone(IRContext*) const; + + // Sets the enclosing function for this basic block. + void SetParent(Function* function) { function_ = function; } + + // Return the enclosing function + inline Function* GetParent() const { return function_; } + + // Appends an instruction to this basic block. + inline void AddInstruction(std::unique_ptr i); + + // Appends all of block's instructions (except label) to this block + inline void AddInstructions(BasicBlock* bp); + + // The pointer to the label starting this basic block. + std::unique_ptr& GetLabel() { return label_; } + + // The label starting this basic block. + Instruction* GetLabelInst() { return label_.get(); } + const Instruction* GetLabelInst() const { return label_.get(); } + + // Returns the merge instruction in this basic block, if it exists. + // Otherwise return null. May be used whenever tail() can be used. + const Instruction* GetMergeInst() const; + Instruction* GetMergeInst(); + + // Returns the OpLoopMerge instruction in this basic block, if it exists. + // Otherwise return null. May be used whenever tail() can be used. + const Instruction* GetLoopMergeInst() const; + Instruction* GetLoopMergeInst(); + + // Returns the id of the label at the top of this block + inline uint32_t id() const { return label_->result_id(); } + + iterator begin() { return insts_.begin(); } + iterator end() { return insts_.end(); } + const_iterator begin() const { return insts_.cbegin(); } + const_iterator end() const { return insts_.cend(); } + const_iterator cbegin() const { return insts_.cbegin(); } + const_iterator cend() const { return insts_.cend(); } + + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(cend()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(cbegin()); + } + const_reverse_iterator crbegin() const { + return const_reverse_iterator(cend()); + } + const_reverse_iterator crend() const { + return const_reverse_iterator(cbegin()); + } + + // Returns an iterator pointing to the last instruction. This may only + // be used if this block has an instruction other than the OpLabel + // that defines it. + iterator tail() { + assert(!insts_.empty()); + return --end(); + } + + // Returns a const iterator, but othewrise similar to tail(). + const_iterator ctail() const { + assert(!insts_.empty()); + return --insts_.cend(); + } + + // Returns true if the basic block has at least one successor. + inline bool hasSuccessor() const { return ctail()->IsBranch(); } + + // Runs the given function |f| on each instruction in this basic block, and + // optionally on the debug line instructions that might precede them. + inline void ForEachInst(const std::function& f, + bool run_on_debug_line_insts = false); + inline void ForEachInst(const std::function& f, + bool run_on_debug_line_insts = false) const; + + // Runs the given function |f| on each instruction in this basic block, and + // optionally on the debug line instructions that might precede them. If |f| + // returns false, iteration is terminated and this function returns false. + inline bool WhileEachInst(const std::function& f, + bool run_on_debug_line_insts = false); + inline bool WhileEachInst(const std::function& f, + bool run_on_debug_line_insts = false) const; + + // Runs the given function |f| on each Phi instruction in this basic block, + // and optionally on the debug line instructions that might precede them. + inline void ForEachPhiInst(const std::function& f, + bool run_on_debug_line_insts = false); + + // Runs the given function |f| on each Phi instruction in this basic block, + // and optionally on the debug line instructions that might precede them. If + // |f| returns false, iteration is terminated and this function return false. + inline bool WhileEachPhiInst(const std::function& f, + bool run_on_debug_line_insts = false); + + // Runs the given function |f| on each label id of each successor block + void ForEachSuccessorLabel( + const std::function& f) const; + + // Runs the given function |f| on each label id of each successor block. If + // |f| returns false, iteration is terminated and this function returns false. + bool WhileEachSuccessorLabel( + const std::function& f) const; + + // Runs the given function |f| on each label id of each successor block. + // Modifying the pointed value will change the branch taken by the basic + // block. It is the caller responsibility to update or invalidate the CFG. + void ForEachSuccessorLabel(const std::function& f); + + // Returns true if |block| is a direct successor of |this|. + bool IsSuccessor(const BasicBlock* block) const; + + // Runs the given function |f| on the merge and continue label, if any + void ForMergeAndContinueLabel(const std::function& f); + + // Returns true if this basic block has any Phi instructions. + bool HasPhiInstructions() { + return !WhileEachPhiInst([](Instruction*) { return false; }); + } + + // Return true if this block is a loop header block. + bool IsLoopHeader() const { return GetLoopMergeInst() != nullptr; } + + // Returns the ID of the merge block declared by a merge instruction in this + // block, if any. If none, returns zero. + uint32_t MergeBlockIdIfAny() const; + + // Returns MergeBlockIdIfAny() and asserts that it is non-zero. + uint32_t MergeBlockId() const; + + // Returns the ID of the continue block declared by a merge instruction in + // this block, if any. If none, returns zero. + uint32_t ContinueBlockIdIfAny() const; + + // Returns ContinueBlockIdIfAny() and asserts that it is non-zero. + uint32_t ContinueBlockId() const; + + // Returns the terminator instruction. Assumes the terminator exists. + Instruction* terminator() { return &*tail(); } + const Instruction* terminator() const { return &*ctail(); } + + // Returns true if this basic block exits this function and returns to its + // caller. + bool IsReturn() const { return ctail()->IsReturn(); } + + // Returns true if this basic block exits this function or aborts execution. + bool IsReturnOrAbort() const { return ctail()->IsReturnOrAbort(); } + + // Kill all instructions in this block. Whether or not to kill the label is + // indicated by |killLabel|. + void KillAllInsts(bool killLabel); + + // Splits this basic block into two. Returns a new basic block with label + // |label_id| containing the instructions from |iter| onwards. Instructions + // prior to |iter| remain in this basic block. The new block will be added + // to the function immediately after the original block. + BasicBlock* SplitBasicBlock(IRContext* context, uint32_t label_id, + iterator iter); + + // Pretty-prints this basic block into a std::string by printing every + // instruction in it. + // + // |options| are the disassembly options. SPV_BINARY_TO_TEXT_OPTION_NO_HEADER + // is always added to |options|. + std::string PrettyPrint(uint32_t options = 0u) const; + + // Dump this basic block on stderr. Useful when running interactive + // debuggers. + void Dump() const; + + private: + // The enclosing function. + Function* function_; + // The label starting this basic block. + std::unique_ptr label_; + // Instructions inside this basic block, but not the OpLabel. + InstructionList insts_; +}; + +// Pretty-prints |block| to |str|. Returns |str|. +std::ostream& operator<<(std::ostream& str, const BasicBlock& block); + +inline BasicBlock::BasicBlock(std::unique_ptr label) + : function_(nullptr), label_(std::move(label)) {} + +inline void BasicBlock::AddInstruction(std::unique_ptr i) { + insts_.push_back(std::move(i)); +} + +inline void BasicBlock::AddInstructions(BasicBlock* bp) { + auto bEnd = end(); + (void)bEnd.MoveBefore(&bp->insts_); +} + +inline bool BasicBlock::WhileEachInst( + const std::function& f, bool run_on_debug_line_insts) { + if (label_) { + if (!label_->WhileEachInst(f, run_on_debug_line_insts)) return false; + } + if (insts_.empty()) { + return true; + } + + Instruction* inst = &insts_.front(); + while (inst != nullptr) { + Instruction* next_instruction = inst->NextNode(); + if (!inst->WhileEachInst(f, run_on_debug_line_insts)) return false; + inst = next_instruction; + } + return true; +} + +inline bool BasicBlock::WhileEachInst( + const std::function& f, + bool run_on_debug_line_insts) const { + if (label_) { + if (!static_cast(label_.get()) + ->WhileEachInst(f, run_on_debug_line_insts)) + return false; + } + for (const auto& inst : insts_) { + if (!static_cast(&inst)->WhileEachInst( + f, run_on_debug_line_insts)) + return false; + } + return true; +} + +inline void BasicBlock::ForEachInst(const std::function& f, + bool run_on_debug_line_insts) { + WhileEachInst( + [&f](Instruction* inst) { + f(inst); + return true; + }, + run_on_debug_line_insts); +} + +inline void BasicBlock::ForEachInst( + const std::function& f, + bool run_on_debug_line_insts) const { + WhileEachInst( + [&f](const Instruction* inst) { + f(inst); + return true; + }, + run_on_debug_line_insts); +} + +inline bool BasicBlock::WhileEachPhiInst( + const std::function& f, bool run_on_debug_line_insts) { + if (insts_.empty()) { + return true; + } + + Instruction* inst = &insts_.front(); + while (inst != nullptr) { + Instruction* next_instruction = inst->NextNode(); + if (inst->opcode() != spv::Op::OpPhi) break; + if (!inst->WhileEachInst(f, run_on_debug_line_insts)) return false; + inst = next_instruction; + } + return true; +} + +inline void BasicBlock::ForEachPhiInst( + const std::function& f, bool run_on_debug_line_insts) { + WhileEachPhiInst( + [&f](Instruction* inst) { + f(inst); + return true; + }, + run_on_debug_line_insts); +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_BASIC_BLOCK_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_pass.cpp new file mode 100644 index 000000000000..d6c33e52b565 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_pass.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/block_merge_pass.h" + +#include "source/opt/block_merge_util.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +bool BlockMergePass::MergeBlocks(Function* func) { + bool modified = false; + for (auto bi = func->begin(); bi != func->end();) { + // Don't bother trying to merge unreachable blocks. + if (context()->IsReachable(*bi) && + blockmergeutil::CanMergeWithSuccessor(context(), &*bi)) { + blockmergeutil::MergeWithSuccessor(context(), func, bi); + // Reprocess block. + modified = true; + } else { + ++bi; + } + } + return modified; +} + +Pass::Status BlockMergePass::Process() { + // Process all entry point functions. + ProcessFunction pfn = [this](Function* fp) { return MergeBlocks(fp); }; + bool modified = context()->ProcessReachableCallTree(pfn); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +BlockMergePass::BlockMergePass() = default; + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_pass.h new file mode 100644 index 000000000000..aabf789fda6b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_pass.h @@ -0,0 +1,62 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_BLOCK_MERGE_PASS_H_ +#define SOURCE_OPT_BLOCK_MERGE_PASS_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class BlockMergePass : public Pass { + public: + BlockMergePass(); + const char* name() const override { return "merge-blocks"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + + // Search |func| for blocks which have a single Branch to a block + // with no other predecessors. Merge these blocks into a single block. + bool MergeBlocks(Function* func); + +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_BLOCK_MERGE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_util.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_util.cpp new file mode 100644 index 000000000000..42f695f2352a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_util.cpp @@ -0,0 +1,233 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "block_merge_util.h" + +namespace spvtools { +namespace opt { +namespace blockmergeutil { +namespace { + +// Returns true if |block| contains a merge instruction. +bool IsHeader(BasicBlock* block) { return block->GetMergeInst() != nullptr; } + +// Returns true if |id| contains a merge instruction. +bool IsHeader(IRContext* context, uint32_t id) { + return IsHeader( + context->get_instr_block(context->get_def_use_mgr()->GetDef(id))); +} + +// Returns true if |id| is the merge target of a merge instruction. +bool IsMerge(IRContext* context, uint32_t id) { + return !context->get_def_use_mgr()->WhileEachUse( + id, [](Instruction* user, uint32_t index) { + spv::Op op = user->opcode(); + if ((op == spv::Op::OpLoopMerge || op == spv::Op::OpSelectionMerge) && + index == 0u) { + return false; + } + return true; + }); +} + +// Returns true if |block| is the merge target of a merge instruction. +bool IsMerge(IRContext* context, BasicBlock* block) { + return IsMerge(context, block->id()); +} + +// Returns true if |id| is the continue target of a merge instruction. +bool IsContinue(IRContext* context, uint32_t id) { + return !context->get_def_use_mgr()->WhileEachUse( + id, [](Instruction* user, uint32_t index) { + spv::Op op = user->opcode(); + if (op == spv::Op::OpLoopMerge && index == 1u) { + return false; + } + return true; + }); +} + +// Removes any OpPhi instructions in |block|, which should have exactly one +// predecessor, replacing uses of OpPhi ids with the ids associated with the +// predecessor. +void EliminateOpPhiInstructions(IRContext* context, BasicBlock* block) { + block->ForEachPhiInst([context](Instruction* phi) { + assert(2 == phi->NumInOperands() && + "A block can only have one predecessor for block merging to make " + "sense."); + context->ReplaceAllUsesWith(phi->result_id(), + phi->GetSingleWordInOperand(0)); + context->KillInst(phi); + }); +} + +} // Anonymous namespace + +bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block) { + // Find block with single successor which has no other predecessors. + auto ii = block->end(); + --ii; + Instruction* br = &*ii; + if (br->opcode() != spv::Op::OpBranch) { + return false; + } + + const uint32_t lab_id = br->GetSingleWordInOperand(0); + if (context->cfg()->preds(lab_id).size() != 1) { + return false; + } + + bool pred_is_merge = IsMerge(context, block); + bool succ_is_merge = IsMerge(context, lab_id); + if (pred_is_merge && succ_is_merge) { + // Cannot merge two merges together. + return false; + } + + // Note: This means that the instructions in a break block will execute as if + // they were still diverged according to the loop iteration. This restricts + // potential transformations an implementation may perform on the IR to match + // shader author expectations. Similarly, instructions in the loop construct + // cannot be moved into the continue construct unless it can be proven that + // invocations are always converged. + if (succ_is_merge && context->get_feature_mgr()->HasExtension( + kSPV_KHR_maximal_reconvergence)) { + return false; + } + + if (pred_is_merge && IsContinue(context, lab_id)) { + // Cannot merge a continue target with a merge block. + return false; + } + + Instruction* merge_inst = block->GetMergeInst(); + const bool pred_is_header = IsHeader(block); + if (pred_is_header && lab_id != merge_inst->GetSingleWordInOperand(0u)) { + bool succ_is_header = IsHeader(context, lab_id); + if (pred_is_header && succ_is_header) { + // Cannot merge two headers together when the successor is not the merge + // block of the predecessor. + return false; + } + + // If this is a header block and the successor is not its merge, we must + // be careful about which blocks we are willing to merge together. + // OpLoopMerge must be followed by a conditional or unconditional branch. + // The merge must be a loop merge because a selection merge cannot be + // followed by an unconditional branch. + BasicBlock* succ_block = context->get_instr_block(lab_id); + spv::Op succ_term_op = succ_block->terminator()->opcode(); + assert(merge_inst->opcode() == spv::Op::OpLoopMerge); + if (succ_term_op != spv::Op::OpBranch && + succ_term_op != spv::Op::OpBranchConditional) { + return false; + } + } + + if (succ_is_merge || IsContinue(context, lab_id)) { + auto* struct_cfg = context->GetStructuredCFGAnalysis(); + auto switch_block_id = struct_cfg->ContainingSwitch(block->id()); + if (switch_block_id) { + auto switch_merge_id = struct_cfg->SwitchMergeBlock(switch_block_id); + const auto* switch_inst = + &*block->GetParent()->FindBlock(switch_block_id)->tail(); + for (uint32_t i = 1; i < switch_inst->NumInOperands(); i += 2) { + auto target_id = switch_inst->GetSingleWordInOperand(i); + if (target_id == block->id() && target_id != switch_merge_id) { + // Case constructs must be structurally dominated by the OpSwitch. + // Since the successor is the merge/continue for another construct, + // merging the blocks would break that requirement. + return false; + } + } + } + } + + return true; +} + +void MergeWithSuccessor(IRContext* context, Function* func, + Function::iterator bi) { + assert(CanMergeWithSuccessor(context, &*bi) && + "Precondition failure for MergeWithSuccessor: it must be legal to " + "merge the block and its successor."); + + auto ii = bi->end(); + --ii; + Instruction* br = &*ii; + const uint32_t lab_id = br->GetSingleWordInOperand(0); + Instruction* merge_inst = bi->GetMergeInst(); + bool pred_is_header = IsHeader(&*bi); + + // Merge blocks. + context->KillInst(br); + auto sbi = bi; + for (; sbi != func->end(); ++sbi) + if (sbi->id() == lab_id) break; + // If bi is sbi's only predecessor, it dominates sbi and thus + // sbi must follow bi in func's ordering. + assert(sbi != func->end()); + + if (sbi->tail()->opcode() == spv::Op::OpSwitch && + sbi->MergeBlockIdIfAny() != 0) { + context->InvalidateAnalyses(IRContext::Analysis::kAnalysisStructuredCFG); + } + + // Update the inst-to-block mapping for the instructions in sbi. + for (auto& inst : *sbi) { + context->set_instr_block(&inst, &*bi); + } + + EliminateOpPhiInstructions(context, &*sbi); + + // Now actually move the instructions. + bi->AddInstructions(&*sbi); + + if (merge_inst) { + if (pred_is_header && lab_id == merge_inst->GetSingleWordInOperand(0u)) { + // Merging the header and merge blocks, so remove the structured control + // flow declaration. + context->KillInst(merge_inst); + } else { + // Move OpLine/OpNoLine information to merge_inst. This solves + // the validation error that OpLine is placed between OpLoopMerge + // and OpBranchConditional. + auto terminator = bi->terminator(); + auto& vec = terminator->dbg_line_insts(); + if (vec.size() > 0) { + merge_inst->ClearDbgLineInsts(); + auto& new_vec = merge_inst->dbg_line_insts(); + new_vec.insert(new_vec.end(), vec.begin(), vec.end()); + terminator->ClearDbgLineInsts(); + for (auto& l_inst : new_vec) + context->get_def_use_mgr()->AnalyzeInstDefUse(&l_inst); + } + // Clear debug scope of terminator to avoid DebugScope + // emitted between terminator and merge. + terminator->SetDebugScope(DebugScope(kNoDebugScope, kNoInlinedAt)); + // Move the merge instruction to just before the terminator. + merge_inst->InsertBefore(terminator); + } + } + context->ReplaceAllUsesWith(lab_id, bi->id()); + context->KillInst(sbi->GetLabelInst()); + (void)sbi.Erase(); +} + +} // namespace blockmergeutil +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_util.h b/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_util.h new file mode 100644 index 000000000000..e71e3d6ad2f1 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/block_merge_util.h @@ -0,0 +1,44 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_BLOCK_MERGE_UTIL_H_ +#define SOURCE_OPT_BLOCK_MERGE_UTIL_H_ + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +// Provides functions for determining when it is safe to merge blocks, and for +// actually merging blocks, for use by various analyses and passes. +namespace blockmergeutil { + +// Returns true if and only if |block| has exactly one successor and merging +// this successor into |block| has no impact on the semantics or validity of the +// SPIR-V module. +bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block); + +// Requires that |bi| has a successor that can be safely merged into |bi|, and +// performs the merge. +void MergeWithSuccessor(IRContext* context, Function* func, + Function::iterator bi); + +} // namespace blockmergeutil +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_BLOCK_MERGE_UTIL_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/build_module.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/build_module.cpp new file mode 100644 index 000000000000..3b606dc2b5ed --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/build_module.cpp @@ -0,0 +1,88 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/build_module.h" + +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/ir_loader.h" +#include "source/table.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace { + +// Sets the module header for IrLoader. Meets the interface requirement of +// spvBinaryParse(). +spv_result_t SetSpvHeader(void* builder, spv_endianness_t, uint32_t magic, + uint32_t version, uint32_t generator, + uint32_t id_bound, uint32_t reserved) { + reinterpret_cast(builder)->SetModuleHeader( + magic, version, generator, id_bound, reserved); + return SPV_SUCCESS; +} + +// Processes a parsed instruction for IrLoader. Meets the interface requirement +// of spvBinaryParse(). +spv_result_t SetSpvInst(void* builder, const spv_parsed_instruction_t* inst) { + if (reinterpret_cast(builder)->AddInstruction(inst)) { + return SPV_SUCCESS; + } + return SPV_ERROR_INVALID_BINARY; +} + +} // namespace + +std::unique_ptr BuildModule(spv_target_env env, + MessageConsumer consumer, + const uint32_t* binary, + const size_t size) { + return BuildModule(env, consumer, binary, size, true); +} + +std::unique_ptr BuildModule(spv_target_env env, + MessageConsumer consumer, + const uint32_t* binary, + const size_t size, + bool extra_line_tracking) { + auto context = spvContextCreate(env); + SetContextMessageConsumer(context, consumer); + + auto irContext = MakeUnique(env, consumer); + opt::IrLoader loader(consumer, irContext->module()); + loader.SetExtraLineTracking(extra_line_tracking); + + spv_result_t status = spvBinaryParse(context, &loader, binary, size, + SetSpvHeader, SetSpvInst, nullptr); + loader.EndModule(); + + spvContextDestroy(context); + + return status == SPV_SUCCESS ? std::move(irContext) : nullptr; +} + +std::unique_ptr BuildModule(spv_target_env env, + MessageConsumer consumer, + const std::string& text, + uint32_t assemble_options) { + SpirvTools t(env); + t.SetMessageConsumer(consumer); + std::vector binary; + if (!t.Assemble(text, &binary, assemble_options)) return nullptr; + return BuildModule(env, consumer, binary.data(), binary.size()); +} + +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/build_module.h b/thirdparty/glslang/External/spirv-tools/source/opt/build_module.h new file mode 100644 index 000000000000..29eaf66139e6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/build_module.h @@ -0,0 +1,54 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_BUILD_MODULE_H_ +#define SOURCE_OPT_BUILD_MODULE_H_ + +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "spirv-tools/libspirv.hpp" + +namespace spvtools { + +// Builds an Module returns the owning IRContext from the given SPIR-V +// |binary|. |size| specifies number of words in |binary|. The |binary| will be +// decoded according to the given target |env|. Returns nullptr if errors occur +// and sends the errors to |consumer|. When |extra_line_tracking| is true, +// extra OpLine instructions are injected to better presere line numbers while +// later transforms mutate the module. +std::unique_ptr BuildModule(spv_target_env env, + MessageConsumer consumer, + const uint32_t* binary, size_t size, + bool extra_line_tracking); + +// Like above, with extra line tracking turned on. +std::unique_ptr BuildModule(spv_target_env env, + MessageConsumer consumer, + const uint32_t* binary, + size_t size); + +// Builds an Module and returns the owning IRContext from the given +// SPIR-V assembly |text|. The |text| will be encoded according to the given +// target |env|. Returns nullptr if errors occur and sends the errors to +// |consumer|. +std::unique_ptr BuildModule( + spv_target_env env, MessageConsumer consumer, const std::string& text, + uint32_t assemble_options = SpirvTools::kDefaultAssembleOption); + +} // namespace spvtools + +#endif // SOURCE_OPT_BUILD_MODULE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ccp_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/ccp_pass.cpp new file mode 100644 index 000000000000..46bfc907de7a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ccp_pass.cpp @@ -0,0 +1,377 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file implements conditional constant propagation as described in +// +// Constant propagation with conditional branches, +// Wegman and Zadeck, ACM TOPLAS 13(2):181-210. + +#include "source/opt/ccp_pass.h" + +#include +#include + +#include "source/opt/fold.h" +#include "source/opt/function.h" +#include "source/opt/propagator.h" + +namespace spvtools { +namespace opt { +namespace { +// This SSA id is never defined nor referenced in the IR. It is a special ID +// which represents varying values. When an ID is found to have a varying +// value, its entry in the |values_| table maps to kVaryingSSAId. +constexpr uint32_t kVaryingSSAId = std::numeric_limits::max(); +} // namespace + +bool CCPPass::IsVaryingValue(uint32_t id) const { return id == kVaryingSSAId; } + +SSAPropagator::PropStatus CCPPass::MarkInstructionVarying(Instruction* instr) { + assert(instr->result_id() != 0 && + "Instructions with no result cannot be marked varying."); + values_[instr->result_id()] = kVaryingSSAId; + return SSAPropagator::kVarying; +} + +SSAPropagator::PropStatus CCPPass::VisitPhi(Instruction* phi) { + uint32_t meet_val_id = 0; + + // Implement the lattice meet operation. The result of this Phi instruction is + // interesting only if the meet operation over arguments coming through + // executable edges yields the same constant value. + for (uint32_t i = 2; i < phi->NumOperands(); i += 2) { + if (!propagator_->IsPhiArgExecutable(phi, i)) { + // Ignore arguments coming through non-executable edges. + continue; + } + uint32_t phi_arg_id = phi->GetSingleWordOperand(i); + auto it = values_.find(phi_arg_id); + if (it != values_.end()) { + // We found an argument with a constant value. Apply the meet operation + // with the previous arguments. + if (it->second == kVaryingSSAId) { + // The "constant" value is actually a placeholder for varying. Return + // varying for this phi. + return MarkInstructionVarying(phi); + } else if (meet_val_id == 0) { + // This is the first argument we find. Initialize the result to its + // constant value id. + meet_val_id = it->second; + } else if (it->second == meet_val_id) { + // The argument is the same constant value already computed. Continue + // looking. + continue; + } else { + // We either found a varying value, or another constant value different + // from the previous computed meet value. This Phi will never be + // constant. + return MarkInstructionVarying(phi); + } + } else { + // The incoming value has no recorded value and is therefore not + // interesting. A not interesting value joined with any other value is the + // other value. + continue; + } + } + + // If there are no incoming executable edges, the meet ID will still be 0. In + // that case, return not interesting to evaluate the Phi node again. + if (meet_val_id == 0) { + return SSAPropagator::kNotInteresting; + } + + // All the operands have the same constant value represented by |meet_val_id|. + // Set the Phi's result to that value and declare it interesting. + values_[phi->result_id()] = meet_val_id; + return SSAPropagator::kInteresting; +} + +uint32_t CCPPass::ComputeLatticeMeet(Instruction* instr, uint32_t val2) { + // Given two values val1 and val2, the meet operation in the constant + // lattice uses the following rules: + // + // meet(val1, UNDEFINED) = val1 + // meet(val1, VARYING) = VARYING + // meet(val1, val2) = val1 if val1 == val2 + // meet(val1, val2) = VARYING if val1 != val2 + // + // When two different values meet, the result is always varying because CCP + // does not allow lateral transitions in the lattice. This prevents + // infinite cycles during propagation. + auto val1_it = values_.find(instr->result_id()); + if (val1_it == values_.end()) { + return val2; + } + + uint32_t val1 = val1_it->second; + if (IsVaryingValue(val1)) { + return val1; + } else if (IsVaryingValue(val2)) { + return val2; + } else if (val1 != val2) { + return kVaryingSSAId; + } + return val2; +} + +SSAPropagator::PropStatus CCPPass::VisitAssignment(Instruction* instr) { + assert(instr->result_id() != 0 && + "Expecting an instruction that produces a result"); + + // If this is a copy operation, and the RHS is a known constant, assign its + // value to the LHS. + if (instr->opcode() == spv::Op::OpCopyObject) { + uint32_t rhs_id = instr->GetSingleWordInOperand(0); + auto it = values_.find(rhs_id); + if (it != values_.end()) { + if (IsVaryingValue(it->second)) { + return MarkInstructionVarying(instr); + } else { + uint32_t new_val = ComputeLatticeMeet(instr, it->second); + values_[instr->result_id()] = new_val; + return IsVaryingValue(new_val) ? SSAPropagator::kVarying + : SSAPropagator::kInteresting; + } + } + return SSAPropagator::kNotInteresting; + } + + // Instructions with a RHS that cannot produce a constant are always varying. + if (!instr->IsFoldable()) { + return MarkInstructionVarying(instr); + } + + // See if the RHS of the assignment folds into a constant value. + auto map_func = [this](uint32_t id) { + auto it = values_.find(id); + if (it == values_.end() || IsVaryingValue(it->second)) { + return id; + } + return it->second; + }; + Instruction* folded_inst = + context()->get_instruction_folder().FoldInstructionToConstant(instr, + map_func); + + if (folded_inst != nullptr) { + // We do not want to change the body of the function by adding new + // instructions. When folding we can only generate new constants. + assert((folded_inst->IsConstant() || + IsSpecConstantInst(folded_inst->opcode())) && + "CCP is only interested in constant values."); + uint32_t new_val = ComputeLatticeMeet(instr, folded_inst->result_id()); + values_[instr->result_id()] = new_val; + return IsVaryingValue(new_val) ? SSAPropagator::kVarying + : SSAPropagator::kInteresting; + } + + // Conservatively mark this instruction as varying if any input id is varying. + if (!instr->WhileEachInId([this](uint32_t* op_id) { + auto iter = values_.find(*op_id); + if (iter != values_.end() && IsVaryingValue(iter->second)) return false; + return true; + })) { + return MarkInstructionVarying(instr); + } + + // If not, see if there is a least one unknown operand to the instruction. If + // so, we might be able to fold it later. + if (!instr->WhileEachInId([this](uint32_t* op_id) { + auto it = values_.find(*op_id); + if (it == values_.end()) return false; + return true; + })) { + return SSAPropagator::kNotInteresting; + } + + // Otherwise, we will never be able to fold this instruction, so mark it + // varying. + return MarkInstructionVarying(instr); +} + +SSAPropagator::PropStatus CCPPass::VisitBranch(Instruction* instr, + BasicBlock** dest_bb) const { + assert(instr->IsBranch() && "Expected a branch instruction."); + + *dest_bb = nullptr; + uint32_t dest_label = 0; + if (instr->opcode() == spv::Op::OpBranch) { + // An unconditional jump always goes to its unique destination. + dest_label = instr->GetSingleWordInOperand(0); + } else if (instr->opcode() == spv::Op::OpBranchConditional) { + // For a conditional branch, determine whether the predicate selector has a + // known value in |values_|. If it does, set the destination block + // according to the selector's boolean value. + uint32_t pred_id = instr->GetSingleWordOperand(0); + auto it = values_.find(pred_id); + if (it == values_.end() || IsVaryingValue(it->second)) { + // The predicate has an unknown value, either branch could be taken. + return SSAPropagator::kVarying; + } + + // Get the constant value for the predicate selector from the value table. + // Use it to decide which branch will be taken. + uint32_t pred_val_id = it->second; + const analysis::Constant* c = const_mgr_->FindDeclaredConstant(pred_val_id); + assert(c && "Expected to find a constant declaration for a known value."); + // Undef values should have returned as varying above. + assert(c->AsBoolConstant() || c->AsNullConstant()); + if (c->AsNullConstant()) { + dest_label = instr->GetSingleWordOperand(2u); + } else { + const analysis::BoolConstant* val = c->AsBoolConstant(); + dest_label = val->value() ? instr->GetSingleWordOperand(1) + : instr->GetSingleWordOperand(2); + } + } else { + // For an OpSwitch, extract the value taken by the switch selector and check + // which of the target literals it matches. The branch associated with that + // literal is the taken branch. + assert(instr->opcode() == spv::Op::OpSwitch); + if (instr->GetOperand(0).words.size() != 1) { + // If the selector is wider than 32-bits, return varying. TODO(dnovillo): + // Add support for wider constants. + return SSAPropagator::kVarying; + } + uint32_t select_id = instr->GetSingleWordOperand(0); + auto it = values_.find(select_id); + if (it == values_.end() || IsVaryingValue(it->second)) { + // The selector has an unknown value, any of the branches could be taken. + return SSAPropagator::kVarying; + } + + // Get the constant value for the selector from the value table. Use it to + // decide which branch will be taken. + uint32_t select_val_id = it->second; + const analysis::Constant* c = + const_mgr_->FindDeclaredConstant(select_val_id); + assert(c && "Expected to find a constant declaration for a known value."); + // TODO: support 64-bit integer switches. + uint32_t constant_cond = 0; + if (const analysis::IntConstant* val = c->AsIntConstant()) { + constant_cond = val->words()[0]; + } else { + // Undef values should have returned varying above. + assert(c->AsNullConstant()); + constant_cond = 0; + } + + // Start assuming that the selector will take the default value; + dest_label = instr->GetSingleWordOperand(1); + for (uint32_t i = 2; i < instr->NumOperands(); i += 2) { + if (constant_cond == instr->GetSingleWordOperand(i)) { + dest_label = instr->GetSingleWordOperand(i + 1); + break; + } + } + } + + assert(dest_label && "Destination label should be set at this point."); + *dest_bb = context()->cfg()->block(dest_label); + return SSAPropagator::kInteresting; +} + +SSAPropagator::PropStatus CCPPass::VisitInstruction(Instruction* instr, + BasicBlock** dest_bb) { + *dest_bb = nullptr; + if (instr->opcode() == spv::Op::OpPhi) { + return VisitPhi(instr); + } else if (instr->IsBranch()) { + return VisitBranch(instr, dest_bb); + } else if (instr->result_id()) { + return VisitAssignment(instr); + } + return SSAPropagator::kVarying; +} + +bool CCPPass::ReplaceValues() { + // Even if we make no changes to the function's IR, propagation may have + // created new constants. Even if those constants cannot be replaced in + // the IR, the constant definition itself is a change. To reflect this, + // we check whether the next ID to be given by the module is different than + // the original bound ID. If that happens, new instructions were added to the + // module during propagation. + // + // See https://github.com/KhronosGroup/SPIRV-Tools/issues/3636 and + // https://github.com/KhronosGroup/SPIRV-Tools/issues/3991 for details. + bool changed_ir = (context()->module()->IdBound() > original_id_bound_); + + for (const auto& it : values_) { + uint32_t id = it.first; + uint32_t cst_id = it.second; + if (!IsVaryingValue(cst_id) && id != cst_id) { + context()->KillNamesAndDecorates(id); + changed_ir |= context()->ReplaceAllUsesWith(id, cst_id); + } + } + + return changed_ir; +} + +bool CCPPass::PropagateConstants(Function* fp) { + if (fp->IsDeclaration()) { + return false; + } + + // Mark function parameters as varying. + fp->ForEachParam([this](const Instruction* inst) { + values_[inst->result_id()] = kVaryingSSAId; + }); + + const auto visit_fn = [this](Instruction* instr, BasicBlock** dest_bb) { + return VisitInstruction(instr, dest_bb); + }; + + propagator_ = + std::unique_ptr(new SSAPropagator(context(), visit_fn)); + + if (propagator_->Run(fp)) { + return ReplaceValues(); + } + + return false; +} + +void CCPPass::Initialize() { + const_mgr_ = context()->get_constant_mgr(); + + // Populate the constant table with values from constant declarations in the + // module. The values of each OpConstant declaration is the identity + // assignment (i.e., each constant is its own value). + for (const auto& inst : get_module()->types_values()) { + // Record compile time constant ids. Treat all other global values as + // varying. + if (inst.IsConstant()) { + values_[inst.result_id()] = inst.result_id(); + } else { + values_[inst.result_id()] = kVaryingSSAId; + } + } + + original_id_bound_ = context()->module()->IdBound(); +} + +Pass::Status CCPPass::Process() { + Initialize(); + + // Process all entry point functions. + ProcessFunction pfn = [this](Function* fp) { return PropagateConstants(fp); }; + bool modified = context()->ProcessReachableCallTree(pfn); + return modified ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ccp_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/ccp_pass.h new file mode 100644 index 000000000000..77ea9f80daa4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ccp_pass.h @@ -0,0 +1,133 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_CCP_PASS_H_ +#define SOURCE_OPT_CCP_PASS_H_ + +#include +#include + +#include "source/opt/constants.h" +#include "source/opt/function.h" +#include "source/opt/ir_context.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" +#include "source/opt/propagator.h" + +namespace spvtools { +namespace opt { + +class CCPPass : public MemPass { + public: + CCPPass() = default; + + const char* name() const override { return "ccp"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + // Initializes the pass. + void Initialize(); + + // Runs constant propagation on the given function |fp|. Returns true if any + // constants were propagated and the IR modified. + bool PropagateConstants(Function* fp); + + // Visits a single instruction |instr|. If the instruction is a conditional + // branch that always jumps to the same basic block, it sets the destination + // block in |dest_bb|. + SSAPropagator::PropStatus VisitInstruction(Instruction* instr, + BasicBlock** dest_bb); + + // Visits an OpPhi instruction |phi|. This applies the meet operator for the + // CCP lattice. Essentially, if all the operands in |phi| have the same + // constant value C, the result for |phi| gets assigned the value C. + SSAPropagator::PropStatus VisitPhi(Instruction* phi); + + // Visits an SSA assignment instruction |instr|. If the RHS of |instr| folds + // into a constant value C, then the LHS of |instr| is assigned the value C in + // |values_|. + SSAPropagator::PropStatus VisitAssignment(Instruction* instr); + + // Visits a branch instruction |instr|. If the branch is conditional + // (OpBranchConditional or OpSwitch), and the value of its selector is known, + // |dest_bb| will be set to the corresponding destination block. Unconditional + // branches always set |dest_bb| to the single destination block. + SSAPropagator::PropStatus VisitBranch(Instruction* instr, + BasicBlock** dest_bb) const; + + // Replaces all operands used in |fp| with the corresponding constant values + // in |values_|. Returns true if any operands were replaced, and false + // otherwise. + bool ReplaceValues(); + + // Marks |instr| as varying by registering a varying value for its result + // into the |values_| table. Returns SSAPropagator::kVarying. + SSAPropagator::PropStatus MarkInstructionVarying(Instruction* instr); + + // Returns true if |id| is the special SSA id that corresponds to a varying + // value. + bool IsVaryingValue(uint32_t id) const; + + // Constant manager for the parent IR context. Used to record new constants + // generated during propagation. + analysis::ConstantManager* const_mgr_; + + // Returns a new value for |instr| by computing the meet operation between + // its existing value and |val2|. + // + // Given two values val1 and val2, the meet operation in the constant + // lattice uses the following rules: + // + // meet(val1, UNDEFINED) = val1 + // meet(val1, VARYING) = VARYING + // meet(val1, val2) = val1 if val1 == val2 + // meet(val1, val2) = VARYING if val1 != val2 + // + // When two different values meet, the result is always varying because CCP + // does not allow lateral transitions in the lattice. This prevents + // infinite cycles during propagation. + uint32_t ComputeLatticeMeet(Instruction* instr, uint32_t val2); + + // Constant value table. Each entry in this map + // represents the compile-time constant value for |id| as declared by + // |const_decl_id|. Each |const_decl_id| in this table is an OpConstant + // declaration for the current module. + // + // Additionally, this table keeps track of SSA IDs with varying values. If an + // SSA ID is found to have a varying value, it will have an entry in this + // table that maps to the special SSA id kVaryingSSAId. These values are + // never replaced in the IR, they are used by CCP during propagation. + std::unordered_map values_; + + // Propagator engine used. + std::unique_ptr propagator_; + + // Value for the module's ID bound before running CCP. Used to detect whether + // propagation created new instructions. + uint32_t original_id_bound_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_CCP_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/cfg.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/cfg.cpp new file mode 100644 index 000000000000..4c4bb25689b4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/cfg.cpp @@ -0,0 +1,354 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/cfg.h" + +#include +#include + +#include "source/cfa.h" +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { +namespace { + +using cbb_ptr = const opt::BasicBlock*; + +// Universal Limit of ResultID + 1 +constexpr int kMaxResultId = 0x400000; + +} // namespace + +CFG::CFG(Module* module) + : module_(module), + pseudo_entry_block_(std::unique_ptr( + new Instruction(module->context(), spv::Op::OpLabel, 0, 0, {}))), + pseudo_exit_block_(std::unique_ptr(new Instruction( + module->context(), spv::Op::OpLabel, 0, kMaxResultId, {}))) { + for (auto& fn : *module) { + for (auto& blk : fn) { + RegisterBlock(&blk); + } + } +} + +void CFG::AddEdges(BasicBlock* blk) { + uint32_t blk_id = blk->id(); + // Force the creation of an entry, not all basic block have predecessors + // (such as the entry blocks and some unreachables). + label2preds_[blk_id]; + const auto* const_blk = blk; + const_blk->ForEachSuccessorLabel( + [blk_id, this](const uint32_t succ_id) { AddEdge(blk_id, succ_id); }); +} + +void CFG::RemoveNonExistingEdges(uint32_t blk_id) { + std::vector updated_pred_list; + for (uint32_t id : preds(blk_id)) { + const BasicBlock* pred_blk = block(id); + bool has_branch = false; + pred_blk->ForEachSuccessorLabel([&has_branch, blk_id](uint32_t succ) { + if (succ == blk_id) { + has_branch = true; + } + }); + if (has_branch) updated_pred_list.push_back(id); + } + + label2preds_.at(blk_id) = std::move(updated_pred_list); +} + +void CFG::ComputeStructuredOrder(Function* func, BasicBlock* root, + std::list* order) { + ComputeStructuredOrder(func, root, nullptr, order); +} + +void CFG::ComputeStructuredOrder(Function* func, BasicBlock* root, + BasicBlock* end, + std::list* order) { + assert(module_->context()->get_feature_mgr()->HasCapability( + spv::Capability::Shader) && + "This only works on structured control flow"); + + // Compute structured successors and do DFS. + ComputeStructuredSuccessors(func); + auto ignore_block = [](cbb_ptr) {}; + auto terminal = [end](cbb_ptr bb) { return bb == end; }; + + auto get_structured_successors = [this](const BasicBlock* b) { + return &(block2structured_succs_[b]); + }; + + // TODO(greg-lunarg): Get rid of const_cast by making moving const + // out of the cfa.h prototypes and into the invoking code. + auto post_order = [&](cbb_ptr b) { + order->push_front(const_cast(b)); + }; + CFA::DepthFirstTraversal(root, get_structured_successors, + ignore_block, post_order, terminal); +} + +void CFG::ForEachBlockInPostOrder(BasicBlock* bb, + const std::function& f) { + std::vector po; + std::unordered_set seen; + ComputePostOrderTraversal(bb, &po, &seen); + + for (BasicBlock* current_bb : po) { + if (!IsPseudoExitBlock(current_bb) && !IsPseudoEntryBlock(current_bb)) { + f(current_bb); + } + } +} + +void CFG::ForEachBlockInReversePostOrder( + BasicBlock* bb, const std::function& f) { + WhileEachBlockInReversePostOrder(bb, [f](BasicBlock* b) { + f(b); + return true; + }); +} + +bool CFG::WhileEachBlockInReversePostOrder( + BasicBlock* bb, const std::function& f) { + std::vector po; + std::unordered_set seen; + ComputePostOrderTraversal(bb, &po, &seen); + + for (auto current_bb = po.rbegin(); current_bb != po.rend(); ++current_bb) { + if (!IsPseudoExitBlock(*current_bb) && !IsPseudoEntryBlock(*current_bb)) { + if (!f(*current_bb)) { + return false; + } + } + } + return true; +} + +void CFG::ComputeStructuredSuccessors(Function* func) { + block2structured_succs_.clear(); + for (auto& blk : *func) { + // If no predecessors in function, make successor to pseudo entry. + if (label2preds_[blk.id()].size() == 0) + block2structured_succs_[&pseudo_entry_block_].push_back(&blk); + + // If header, make merge block first successor and continue block second + // successor if there is one. + uint32_t mbid = blk.MergeBlockIdIfAny(); + if (mbid != 0) { + block2structured_succs_[&blk].push_back(block(mbid)); + uint32_t cbid = blk.ContinueBlockIdIfAny(); + if (cbid != 0) { + block2structured_succs_[&blk].push_back(block(cbid)); + } + } + + // Add true successors. + const auto& const_blk = blk; + const_blk.ForEachSuccessorLabel([&blk, this](const uint32_t sbid) { + block2structured_succs_[&blk].push_back(block(sbid)); + }); + } +} + +void CFG::ComputePostOrderTraversal(BasicBlock* bb, + std::vector* order, + std::unordered_set* seen) { + std::vector stack; + stack.push_back(bb); + while (!stack.empty()) { + bb = stack.back(); + seen->insert(bb); + static_cast(bb)->WhileEachSuccessorLabel( + [&seen, &stack, this](const uint32_t sbid) { + BasicBlock* succ_bb = id2block_[sbid]; + if (!seen->count(succ_bb)) { + stack.push_back(succ_bb); + return false; + } + return true; + }); + if (stack.back() == bb) { + order->push_back(bb); + stack.pop_back(); + } + } +} + +BasicBlock* CFG::SplitLoopHeader(BasicBlock* bb) { + assert(bb->GetLoopMergeInst() && "Expecting bb to be the header of a loop."); + + Function* fn = bb->GetParent(); + IRContext* context = module_->context(); + + // Get the new header id up front. If we are out of ids, then we cannot split + // the loop. + uint32_t new_header_id = context->TakeNextId(); + if (new_header_id == 0) { + return nullptr; + } + + // Find the insertion point for the new bb. + Function::iterator header_it = std::find_if( + fn->begin(), fn->end(), + [bb](BasicBlock& block_in_func) { return &block_in_func == bb; }); + assert(header_it != fn->end()); + + const std::vector& pred = preds(bb->id()); + // Find the back edge + BasicBlock* latch_block = nullptr; + Function::iterator latch_block_iter = header_it; + for (; latch_block_iter != fn->end(); ++latch_block_iter) { + // If blocks are in the proper order, then the only branch that appears + // after the header is the latch. + if (std::find(pred.begin(), pred.end(), latch_block_iter->id()) != + pred.end()) { + break; + } + } + assert(latch_block_iter != fn->end() && "Could not find the latch."); + latch_block = &*latch_block_iter; + + RemoveSuccessorEdges(bb); + + // Create the new header bb basic bb. + // Leave the phi instructions behind. + auto iter = bb->begin(); + while (iter->opcode() == spv::Op::OpPhi) { + ++iter; + } + + BasicBlock* new_header = bb->SplitBasicBlock(context, new_header_id, iter); + context->AnalyzeDefUse(new_header->GetLabelInst()); + + // Update cfg + RegisterBlock(new_header); + + // Update bb mappings. + context->set_instr_block(new_header->GetLabelInst(), new_header); + new_header->ForEachInst([new_header, context](Instruction* inst) { + context->set_instr_block(inst, new_header); + }); + + // If |bb| was the latch block, the branch back to the header is not in + // |new_header|. + if (latch_block == bb) { + if (new_header->ContinueBlockId() == bb->id()) { + new_header->GetLoopMergeInst()->SetInOperand(1, {new_header_id}); + } + latch_block = new_header; + } + + // Adjust the OpPhi instructions as needed. + bb->ForEachPhiInst([latch_block, bb, new_header, context](Instruction* phi) { + std::vector preheader_phi_ops; + std::vector header_phi_ops; + + // Identify where the original inputs to original OpPhi belong: header or + // preheader. + for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) { + uint32_t def_id = phi->GetSingleWordInOperand(i); + uint32_t branch_id = phi->GetSingleWordInOperand(i + 1); + if (branch_id == latch_block->id()) { + header_phi_ops.push_back({SPV_OPERAND_TYPE_ID, {def_id}}); + header_phi_ops.push_back({SPV_OPERAND_TYPE_ID, {branch_id}}); + } else { + preheader_phi_ops.push_back(def_id); + preheader_phi_ops.push_back(branch_id); + } + } + + // Create a phi instruction if and only if the preheader_phi_ops has more + // than one pair. + if (preheader_phi_ops.size() > 2) { + InstructionBuilder builder( + context, &*bb->begin(), + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + Instruction* new_phi = builder.AddPhi(phi->type_id(), preheader_phi_ops); + + // Add the OpPhi to the header bb. + header_phi_ops.push_back({SPV_OPERAND_TYPE_ID, {new_phi->result_id()}}); + header_phi_ops.push_back({SPV_OPERAND_TYPE_ID, {bb->id()}}); + } else { + // An OpPhi with a single entry is just a copy. In this case use the same + // instruction in the new header. + header_phi_ops.push_back({SPV_OPERAND_TYPE_ID, {preheader_phi_ops[0]}}); + header_phi_ops.push_back({SPV_OPERAND_TYPE_ID, {bb->id()}}); + } + + phi->RemoveFromList(); + std::unique_ptr phi_owner(phi); + phi->SetInOperands(std::move(header_phi_ops)); + new_header->begin()->InsertBefore(std::move(phi_owner)); + context->set_instr_block(phi, new_header); + context->AnalyzeUses(phi); + }); + + // Add a branch to the new header. + InstructionBuilder branch_builder( + context, bb, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + bb->AddInstruction( + MakeUnique(context, spv::Op::OpBranch, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {new_header->id()}}})); + context->AnalyzeUses(bb->terminator()); + context->set_instr_block(bb->terminator(), bb); + label2preds_[new_header->id()].push_back(bb->id()); + + // Update the latch to branch to the new header. + latch_block->ForEachSuccessorLabel([bb, new_header_id](uint32_t* id) { + if (*id == bb->id()) { + *id = new_header_id; + } + }); + Instruction* latch_branch = latch_block->terminator(); + context->AnalyzeUses(latch_branch); + label2preds_[new_header->id()].push_back(latch_block->id()); + + auto& block_preds = label2preds_[bb->id()]; + auto latch_pos = + std::find(block_preds.begin(), block_preds.end(), latch_block->id()); + assert(latch_pos != block_preds.end() && "The cfg was invalid."); + block_preds.erase(latch_pos); + + // Update the loop descriptors + if (context->AreAnalysesValid(IRContext::kAnalysisLoopAnalysis)) { + LoopDescriptor* loop_desc = context->GetLoopDescriptor(bb->GetParent()); + Loop* loop = (*loop_desc)[bb->id()]; + + loop->AddBasicBlock(new_header_id); + loop->SetHeaderBlock(new_header); + loop_desc->SetBasicBlockToLoop(new_header_id, loop); + + loop->RemoveBasicBlock(bb->id()); + loop->SetPreHeaderBlock(bb); + + Loop* parent_loop = loop->GetParent(); + if (parent_loop != nullptr) { + parent_loop->AddBasicBlock(bb->id()); + loop_desc->SetBasicBlockToLoop(bb->id(), parent_loop); + } else { + loop_desc->SetBasicBlockToLoop(bb->id(), nullptr); + } + } + return new_header; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/cfg.h b/thirdparty/glslang/External/spirv-tools/source/opt/cfg.h new file mode 100644 index 000000000000..fa4fef2d5a9b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/cfg.h @@ -0,0 +1,189 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_CFG_H_ +#define SOURCE_OPT_CFG_H_ + +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" + +namespace spvtools { +namespace opt { + +class CFG { + public: + explicit CFG(Module* module); + + // Return the list of predecessors for basic block with label |blkid|. + // TODO(dnovillo): Move this to BasicBlock. + const std::vector& preds(uint32_t blk_id) const { + assert(label2preds_.count(blk_id)); + return label2preds_.at(blk_id); + } + + // Return a pointer to the basic block instance corresponding to the label + // |blk_id|. + BasicBlock* block(uint32_t blk_id) const { return id2block_.at(blk_id); } + + // Return the pseudo entry and exit blocks. + const BasicBlock* pseudo_entry_block() const { return &pseudo_entry_block_; } + BasicBlock* pseudo_entry_block() { return &pseudo_entry_block_; } + + const BasicBlock* pseudo_exit_block() const { return &pseudo_exit_block_; } + BasicBlock* pseudo_exit_block() { return &pseudo_exit_block_; } + + // Return true if |block_ptr| is the pseudo-entry block. + bool IsPseudoEntryBlock(BasicBlock* block_ptr) const { + return block_ptr == &pseudo_entry_block_; + } + + // Return true if |block_ptr| is the pseudo-exit block. + bool IsPseudoExitBlock(BasicBlock* block_ptr) const { + return block_ptr == &pseudo_exit_block_; + } + + // Compute structured block order into |order| for |func| starting at |root|. + // This order has the property that dominators come before all blocks they + // dominate, merge blocks come after all blocks that are in the control + // constructs of their header, and continue blocks come after all of the + // blocks in the body of their loop. + void ComputeStructuredOrder(Function* func, BasicBlock* root, + std::list* order); + + // Compute structured block order into |order| for |func| starting at |root| + // and ending at |end|. This order has the property that dominators come + // before all blocks they dominate, merge blocks come after all blocks that + // are in the control constructs of their header, and continue blocks come + // after all the blocks in the body of their loop. + void ComputeStructuredOrder(Function* func, BasicBlock* root, BasicBlock* end, + std::list* order); + + // Applies |f| to all blocks that can be reach from |bb| in post order. + void ForEachBlockInPostOrder(BasicBlock* bb, + const std::function& f); + + // Applies |f| to all blocks that can be reach from |bb| in reverse post + // order. + void ForEachBlockInReversePostOrder( + BasicBlock* bb, const std::function& f); + + // Applies |f| to all blocks that can be reach from |bb| in reverse post + // order. Return false if |f| return false on any basic block, and stops + // processing. + bool WhileEachBlockInReversePostOrder( + BasicBlock* bb, const std::function& f); + + // Registers |blk| as a basic block in the cfg, this also updates the + // predecessor lists of each successor of |blk|. |blk| must have a terminator + // instruction at the end of the block. + void RegisterBlock(BasicBlock* blk) { + assert(blk->begin() != blk->end() && + "Basic blocks must have a terminator before registering."); + assert(blk->tail()->IsBlockTerminator() && + "Basic blocks must have a terminator before registering."); + uint32_t blk_id = blk->id(); + id2block_[blk_id] = blk; + AddEdges(blk); + } + + // Removes from the CFG any mapping for the basic block id |blk_id|. + void ForgetBlock(const BasicBlock* blk) { + id2block_.erase(blk->id()); + label2preds_.erase(blk->id()); + RemoveSuccessorEdges(blk); + } + + void RemoveEdge(uint32_t pred_blk_id, uint32_t succ_blk_id) { + auto pred_it = label2preds_.find(succ_blk_id); + if (pred_it == label2preds_.end()) return; + auto& preds_list = pred_it->second; + auto it = std::find(preds_list.begin(), preds_list.end(), pred_blk_id); + if (it != preds_list.end()) preds_list.erase(it); + } + + // Registers |blk| to all of its successors. + void AddEdges(BasicBlock* blk); + + // Registers the basic block id |pred_blk_id| as being a predecessor of the + // basic block id |succ_blk_id|. + void AddEdge(uint32_t pred_blk_id, uint32_t succ_blk_id) { + label2preds_[succ_blk_id].push_back(pred_blk_id); + } + + // Removes any edges that no longer exist from the predecessor mapping for + // the basic block id |blk_id|. + void RemoveNonExistingEdges(uint32_t blk_id); + + // Remove all edges that leave |bb|. + void RemoveSuccessorEdges(const BasicBlock* bb) { + bb->ForEachSuccessorLabel( + [bb, this](uint32_t succ_id) { RemoveEdge(bb->id(), succ_id); }); + } + + // Divides |block| into two basic blocks. The first block will have the same + // id as |block| and will become a preheader for the loop. The other block + // is a new block that will be the new loop header. + // + // Returns a pointer to the new loop header. Returns |nullptr| if the new + // loop pointer could not be created. + BasicBlock* SplitLoopHeader(BasicBlock* bb); + + private: + // Compute structured successors for function |func|. A block's structured + // successors are the blocks it branches to together with its declared merge + // block and continue block if it has them. When order matters, the merge + // block and continue block always appear first. This assures correct depth + // first search in the presence of early returns and kills. If the successor + // vector contain duplicates of the merge or continue blocks, they are safely + // ignored by DFS. + void ComputeStructuredSuccessors(Function* func); + + // Computes the post-order traversal of the cfg starting at |bb| skipping + // nodes in |seen|. The order of the traversal is appended to |order|, and + // all nodes in the traversal are added to |seen|. + void ComputePostOrderTraversal(BasicBlock* bb, + std::vector* order, + std::unordered_set* seen); + + // Module for this CFG. + Module* module_; + + // Map from block to its structured successor blocks. See + // ComputeStructuredSuccessors() for definition. + std::unordered_map> + block2structured_succs_; + + // Extra block whose successors are all blocks with no predecessors + // in function. + BasicBlock pseudo_entry_block_; + + // Augmented CFG Exit Block. + BasicBlock pseudo_exit_block_; + + // Map from block's label id to its predecessor blocks ids + std::unordered_map> label2preds_; + + // Map from block's label id to block. + std::unordered_map id2block_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_CFG_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/cfg_cleanup_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/cfg_cleanup_pass.cpp new file mode 100644 index 000000000000..26fed89fb14a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/cfg_cleanup_pass.cpp @@ -0,0 +1,35 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file implements a pass to cleanup the CFG to remove superfluous +// constructs (e.g., unreachable basic blocks, empty control flow structures, +// etc) + +#include "source/opt/cfg_cleanup_pass.h" + +#include "source/opt/function.h" + +namespace spvtools { +namespace opt { + +Pass::Status CFGCleanupPass::Process() { + // Process all entry point functions. + ProcessFunction pfn = [this](Function* fp) { return CFGCleanup(fp); }; + bool modified = context()->ProcessReachableCallTree(pfn); + return modified ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/cfg_cleanup_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/cfg_cleanup_pass.h new file mode 100644 index 000000000000..509542890416 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/cfg_cleanup_pass.h @@ -0,0 +1,41 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_CFG_CLEANUP_PASS_H_ +#define SOURCE_OPT_CFG_CLEANUP_PASS_H_ + +#include "source/opt/function.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +class CFGCleanupPass : public MemPass { + public: + CFGCleanupPass() = default; + + const char* name() const override { return "cfg-cleanup"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_CFG_CLEANUP_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/code_sink.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/code_sink.cpp new file mode 100644 index 000000000000..90231791e7d2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/code_sink.cpp @@ -0,0 +1,325 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "code_sink.h" + +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" +#include "source/util/bit_vector.h" + +namespace spvtools { +namespace opt { + +Pass::Status CodeSinkingPass::Process() { + bool modified = false; + for (Function& function : *get_module()) { + cfg()->ForEachBlockInPostOrder(function.entry().get(), + [&modified, this](BasicBlock* bb) { + if (SinkInstructionsInBB(bb)) { + modified = true; + } + }); + } + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool CodeSinkingPass::SinkInstructionsInBB(BasicBlock* bb) { + bool modified = false; + for (auto inst = bb->rbegin(); inst != bb->rend(); ++inst) { + if (SinkInstruction(&*inst)) { + inst = bb->rbegin(); + modified = true; + } + } + return modified; +} + +bool CodeSinkingPass::SinkInstruction(Instruction* inst) { + if (inst->opcode() != spv::Op::OpLoad && + inst->opcode() != spv::Op::OpAccessChain) { + return false; + } + + if (ReferencesMutableMemory(inst)) { + return false; + } + + if (BasicBlock* target_bb = FindNewBasicBlockFor(inst)) { + Instruction* pos = &*target_bb->begin(); + while (pos->opcode() == spv::Op::OpPhi) { + pos = pos->NextNode(); + } + + inst->InsertBefore(pos); + context()->set_instr_block(inst, target_bb); + return true; + } + return false; +} + +BasicBlock* CodeSinkingPass::FindNewBasicBlockFor(Instruction* inst) { + assert(inst->result_id() != 0 && "Instruction should have a result."); + BasicBlock* original_bb = context()->get_instr_block(inst); + BasicBlock* bb = original_bb; + + std::unordered_set bbs_with_uses; + get_def_use_mgr()->ForEachUse( + inst, [&bbs_with_uses, this](Instruction* use, uint32_t idx) { + if (use->opcode() != spv::Op::OpPhi) { + BasicBlock* use_bb = context()->get_instr_block(use); + if (use_bb) { + bbs_with_uses.insert(use_bb->id()); + } + } else { + bbs_with_uses.insert(use->GetSingleWordOperand(idx + 1)); + } + }); + + while (true) { + // If |inst| is used in |bb|, then |inst| cannot be moved any further. + if (bbs_with_uses.count(bb->id())) { + break; + } + + // If |bb| has one successor (succ_bb), and |bb| is the only predecessor + // of succ_bb, then |inst| can be moved to succ_bb. If succ_bb, has move + // then one predecessor, then moving |inst| into succ_bb could cause it to + // be executed more often, so the search has to stop. + if (bb->terminator()->opcode() == spv::Op::OpBranch) { + uint32_t succ_bb_id = bb->terminator()->GetSingleWordInOperand(0); + if (cfg()->preds(succ_bb_id).size() == 1) { + bb = context()->get_instr_block(succ_bb_id); + continue; + } else { + break; + } + } + + // The remaining checks need to know the merge node. If there is no merge + // instruction or an OpLoopMerge, then it is a break or continue. We could + // figure it out, but not worth doing it now. + Instruction* merge_inst = bb->GetMergeInst(); + if (merge_inst == nullptr || + merge_inst->opcode() != spv::Op::OpSelectionMerge) { + break; + } + + // Check all of the successors of |bb| it see which lead to a use of |inst| + // before reaching the merge node. + bool used_in_multiple_blocks = false; + uint32_t bb_used_in = 0; + bb->ForEachSuccessorLabel([this, bb, &bb_used_in, &used_in_multiple_blocks, + &bbs_with_uses](uint32_t* succ_bb_id) { + if (IntersectsPath(*succ_bb_id, bb->MergeBlockIdIfAny(), bbs_with_uses)) { + if (bb_used_in == 0) { + bb_used_in = *succ_bb_id; + } else { + used_in_multiple_blocks = true; + } + } + }); + + // If more than one successor, which is not the merge block, uses |inst| + // then we have to leave |inst| in bb because there is none of the + // successors dominate all uses of |inst|. + if (used_in_multiple_blocks) { + break; + } + + if (bb_used_in == 0) { + // If |inst| is not used before reaching the merge node, then we can move + // |inst| to the merge node. + bb = context()->get_instr_block(bb->MergeBlockIdIfAny()); + } else { + // If the only successor that leads to a used of |inst| has more than 1 + // predecessor, then moving |inst| could cause it to be executed more + // often, so we cannot move it. + if (cfg()->preds(bb_used_in).size() != 1) { + break; + } + + // If |inst| is used after the merge block, then |bb_used_in| does not + // dominate all of the uses. So we cannot move |inst| any further. + if (IntersectsPath(bb->MergeBlockIdIfAny(), original_bb->id(), + bbs_with_uses)) { + break; + } + + // Otherwise, |bb_used_in| dominates all uses, so move |inst| into that + // block. + bb = context()->get_instr_block(bb_used_in); + } + continue; + } + return (bb != original_bb ? bb : nullptr); +} + +bool CodeSinkingPass::ReferencesMutableMemory(Instruction* inst) { + if (!inst->IsLoad()) { + return false; + } + + Instruction* base_ptr = inst->GetBaseAddress(); + if (base_ptr->opcode() != spv::Op::OpVariable) { + return true; + } + + if (base_ptr->IsReadOnlyPointer()) { + return false; + } + + if (HasUniformMemorySync()) { + return true; + } + + if (spv::StorageClass(base_ptr->GetSingleWordInOperand(0)) != + spv::StorageClass::Uniform) { + return true; + } + + return HasPossibleStore(base_ptr); +} + +bool CodeSinkingPass::HasUniformMemorySync() { + if (checked_for_uniform_sync_) { + return has_uniform_sync_; + } + + bool has_sync = false; + get_module()->ForEachInst([this, &has_sync](Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpMemoryBarrier: { + uint32_t mem_semantics_id = inst->GetSingleWordInOperand(1); + if (IsSyncOnUniform(mem_semantics_id)) { + has_sync = true; + } + break; + } + case spv::Op::OpControlBarrier: + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicStore: + case spv::Op::OpAtomicExchange: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicFMinEXT: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicFMaxEXT: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + case spv::Op::OpAtomicFlagTestAndSet: + case spv::Op::OpAtomicFlagClear: { + uint32_t mem_semantics_id = inst->GetSingleWordInOperand(2); + if (IsSyncOnUniform(mem_semantics_id)) { + has_sync = true; + } + break; + } + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: + if (IsSyncOnUniform(inst->GetSingleWordInOperand(2)) || + IsSyncOnUniform(inst->GetSingleWordInOperand(3))) { + has_sync = true; + } + break; + default: + break; + } + }); + has_uniform_sync_ = has_sync; + return has_sync; +} + +bool CodeSinkingPass::IsSyncOnUniform(uint32_t mem_semantics_id) const { + const analysis::Constant* mem_semantics_const = + context()->get_constant_mgr()->FindDeclaredConstant(mem_semantics_id); + assert(mem_semantics_const != nullptr && + "Expecting memory semantics id to be a constant."); + assert(mem_semantics_const->AsIntConstant() && + "Memory semantics should be an integer."); + uint32_t mem_semantics_int = mem_semantics_const->GetU32(); + + // If it does not affect uniform memory, then it is does not apply to uniform + // memory. + if ((mem_semantics_int & uint32_t(spv::MemorySemanticsMask::UniformMemory)) == + 0) { + return false; + } + + // Check if there is an acquire or release. If so not, this it does not add + // any memory constraints. + return (mem_semantics_int & + uint32_t(spv::MemorySemanticsMask::Acquire | + spv::MemorySemanticsMask::AcquireRelease | + spv::MemorySemanticsMask::Release)) != 0; +} + +bool CodeSinkingPass::HasPossibleStore(Instruction* var_inst) { + assert(var_inst->opcode() == spv::Op::OpVariable || + var_inst->opcode() == spv::Op::OpAccessChain || + var_inst->opcode() == spv::Op::OpPtrAccessChain); + + return get_def_use_mgr()->WhileEachUser(var_inst, [this](Instruction* use) { + switch (use->opcode()) { + case spv::Op::OpStore: + return true; + case spv::Op::OpAccessChain: + case spv::Op::OpPtrAccessChain: + return HasPossibleStore(use); + default: + return false; + } + }); +} + +bool CodeSinkingPass::IntersectsPath(uint32_t start, uint32_t end, + const std::unordered_set& set) { + std::vector worklist; + worklist.push_back(start); + std::unordered_set already_done; + already_done.insert(start); + + while (!worklist.empty()) { + BasicBlock* bb = context()->get_instr_block(worklist.back()); + worklist.pop_back(); + + if (bb->id() == end) { + continue; + } + + if (set.count(bb->id())) { + return true; + } + + bb->ForEachSuccessorLabel([&already_done, &worklist](uint32_t* succ_bb_id) { + if (already_done.insert(*succ_bb_id).second) { + worklist.push_back(*succ_bb_id); + } + }); + } + return false; +} + +// namespace opt + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/code_sink.h b/thirdparty/glslang/External/spirv-tools/source/opt/code_sink.h new file mode 100644 index 000000000000..d24df030dff2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/code_sink.h @@ -0,0 +1,107 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_CODE_SINK_H_ +#define SOURCE_OPT_CODE_SINK_H_ + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// This pass does code sinking for OpAccessChain and OpLoad on variables in +// uniform storage or in read only memory. Code sinking is a transformation +// where an instruction is moved into a more deeply nested construct. +// +// The goal is to move these instructions as close as possible to their uses +// without having to execute them more often or to replicate the instruction. +// Moving the instruction in this way can lead to shorter live ranges, which can +// lead to less register pressure. It can also cause instructions to be +// executed less often because they could be moved into one path of a selection +// construct. +// +// This optimization can cause register pressure to rise if the operands of the +// instructions go dead after the instructions being moved. That is why we only +// move certain OpLoad and OpAccessChain instructions. They generally have +// constants, loop induction variables, and global pointers as operands. The +// operands are live for a longer time in most cases. +class CodeSinkingPass : public Pass { + public: + const char* name() const override { return "code-sink"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Sinks the instructions in |bb| as much as possible. Returns true if + // something changes. + bool SinkInstructionsInBB(BasicBlock* bb); + + // Tries the sink |inst| as much as possible. Returns true if the instruction + // is moved. + bool SinkInstruction(Instruction* inst); + + // Returns the basic block in which to move |inst| to move is as close as + // possible to the uses of |inst| without increasing the number of times + // |inst| will be executed. Return |nullptr| if there is no need to move + // |inst|. + BasicBlock* FindNewBasicBlockFor(Instruction* inst); + + // Return true if |inst| reference memory and it is possible that the data in + // the memory changes at some point. + bool ReferencesMutableMemory(Instruction* inst); + + // Returns true if the module contains an instruction that has a memory + // semantics id as an operand, and the memory semantics enforces a + // synchronization of uniform memory. See section 3.25 of the SPIR-V + // specification. + bool HasUniformMemorySync(); + + // Returns true if there may be a store to the variable |var_inst|. + bool HasPossibleStore(Instruction* var_inst); + + // Returns true if one of the basic blocks in |set| exists on a path from the + // basic block |start| to |end|. + bool IntersectsPath(uint32_t start, uint32_t end, + const std::unordered_set& set); + + // Returns true if |mem_semantics_id| is the id of a constant that, when + // interpreted as a memory semantics mask enforces synchronization of uniform + // memory. See section 3.25 of the SPIR-V specification. + bool IsSyncOnUniform(uint32_t mem_semantics_id) const; + + // True if a check has for uniform storage has taken place. + bool checked_for_uniform_sync_; + + // Cache of whether or not the module has a memory sync on uniform storage. + // only valid if |check_for_uniform_sync_| is true. + bool has_uniform_sync_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_CODE_SINK_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/combine_access_chains.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/combine_access_chains.cpp new file mode 100644 index 000000000000..99ec79625216 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/combine_access_chains.cpp @@ -0,0 +1,296 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/combine_access_chains.h" + +#include + +#include "source/opt/constants.h" +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +Pass::Status CombineAccessChains::Process() { + bool modified = false; + + for (auto& function : *get_module()) { + modified |= ProcessFunction(function); + } + + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool CombineAccessChains::ProcessFunction(Function& function) { + if (function.IsDeclaration()) { + return false; + } + + bool modified = false; + + cfg()->ForEachBlockInReversePostOrder( + function.entry().get(), [&modified, this](BasicBlock* block) { + block->ForEachInst([&modified, this](Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + modified |= CombineAccessChain(inst); + break; + default: + break; + } + }); + }); + + return modified; +} + +uint32_t CombineAccessChains::GetConstantValue( + const analysis::Constant* constant_inst) { + if (constant_inst->type()->AsInteger()->width() <= 32) { + if (constant_inst->type()->AsInteger()->IsSigned()) { + return static_cast(constant_inst->GetS32()); + } else { + return constant_inst->GetU32(); + } + } else { + assert(false); + return 0u; + } +} + +uint32_t CombineAccessChains::GetArrayStride(const Instruction* inst) { + uint32_t array_stride = 0; + context()->get_decoration_mgr()->WhileEachDecoration( + inst->type_id(), uint32_t(spv::Decoration::ArrayStride), + [&array_stride](const Instruction& decoration) { + assert(decoration.opcode() != spv::Op::OpDecorateId); + if (decoration.opcode() == spv::Op::OpDecorate) { + array_stride = decoration.GetSingleWordInOperand(1); + } else { + array_stride = decoration.GetSingleWordInOperand(2); + } + return false; + }); + return array_stride; +} + +const analysis::Type* CombineAccessChains::GetIndexedType(Instruction* inst) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + + Instruction* base_ptr = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); + const analysis::Type* type = type_mgr->GetType(base_ptr->type_id()); + assert(type->AsPointer()); + type = type->AsPointer()->pointee_type(); + std::vector element_indices; + uint32_t starting_index = 1; + if (IsPtrAccessChain(inst->opcode())) { + // Skip the first index of OpPtrAccessChain as it does not affect type + // resolution. + starting_index = 2; + } + for (uint32_t i = starting_index; i < inst->NumInOperands(); ++i) { + Instruction* index_inst = + def_use_mgr->GetDef(inst->GetSingleWordInOperand(i)); + const analysis::Constant* index_constant = + context()->get_constant_mgr()->GetConstantFromInst(index_inst); + if (index_constant) { + uint32_t index_value = GetConstantValue(index_constant); + element_indices.push_back(index_value); + } else { + // This index must not matter to resolve the type in valid SPIR-V. + element_indices.push_back(0); + } + } + type = type_mgr->GetMemberType(type, element_indices); + return type; +} + +bool CombineAccessChains::CombineIndices(Instruction* ptr_input, + Instruction* inst, + std::vector* new_operands) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::ConstantManager* constant_mgr = context()->get_constant_mgr(); + + Instruction* last_index_inst = def_use_mgr->GetDef( + ptr_input->GetSingleWordInOperand(ptr_input->NumInOperands() - 1)); + const analysis::Constant* last_index_constant = + constant_mgr->GetConstantFromInst(last_index_inst); + + Instruction* element_inst = + def_use_mgr->GetDef(inst->GetSingleWordInOperand(1)); + const analysis::Constant* element_constant = + constant_mgr->GetConstantFromInst(element_inst); + + // Combine the last index of the AccessChain (|ptr_inst|) with the element + // operand of the PtrAccessChain (|inst|). + const bool combining_element_operands = + IsPtrAccessChain(inst->opcode()) && + IsPtrAccessChain(ptr_input->opcode()) && ptr_input->NumInOperands() == 2; + uint32_t new_value_id = 0; + const analysis::Type* type = GetIndexedType(ptr_input); + if (last_index_constant && element_constant) { + // Combine the constants. + uint32_t new_value = GetConstantValue(last_index_constant) + + GetConstantValue(element_constant); + const analysis::Constant* new_value_constant = + constant_mgr->GetConstant(last_index_constant->type(), {new_value}); + Instruction* new_value_inst = + constant_mgr->GetDefiningInstruction(new_value_constant); + new_value_id = new_value_inst->result_id(); + } else if (!type->AsStruct() || combining_element_operands) { + // Generate an addition of the two indices. + InstructionBuilder builder( + context(), inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + Instruction* addition = builder.AddIAdd(last_index_inst->type_id(), + last_index_inst->result_id(), + element_inst->result_id()); + new_value_id = addition->result_id(); + } else { + // Indexing into structs must be constant, so bail out here. + return false; + } + new_operands->push_back({SPV_OPERAND_TYPE_ID, {new_value_id}}); + return true; +} + +bool CombineAccessChains::CreateNewInputOperands( + Instruction* ptr_input, Instruction* inst, + std::vector* new_operands) { + // Start by copying all the input operands of the feeder access chain. + for (uint32_t i = 0; i != ptr_input->NumInOperands() - 1; ++i) { + new_operands->push_back(ptr_input->GetInOperand(i)); + } + + // Deal with the last index of the feeder access chain. + if (IsPtrAccessChain(inst->opcode())) { + // The last index of the feeder should be combined with the element operand + // of |inst|. + if (!CombineIndices(ptr_input, inst, new_operands)) return false; + } else { + // The indices aren't being combined so now add the last index operand of + // |ptr_input|. + new_operands->push_back( + ptr_input->GetInOperand(ptr_input->NumInOperands() - 1)); + } + + // Copy the remaining index operands. + uint32_t starting_index = IsPtrAccessChain(inst->opcode()) ? 2 : 1; + for (uint32_t i = starting_index; i < inst->NumInOperands(); ++i) { + new_operands->push_back(inst->GetInOperand(i)); + } + + return true; +} + +bool CombineAccessChains::CombineAccessChain(Instruction* inst) { + assert((inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpAccessChain || + inst->opcode() == spv::Op::OpInBoundsAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) && + "Wrong opcode. Expected an access chain."); + + Instruction* ptr_input = + context()->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0)); + if (ptr_input->opcode() != spv::Op::OpAccessChain && + ptr_input->opcode() != spv::Op::OpInBoundsAccessChain && + ptr_input->opcode() != spv::Op::OpPtrAccessChain && + ptr_input->opcode() != spv::Op::OpInBoundsPtrAccessChain) { + return false; + } + + if (Has64BitIndices(inst) || Has64BitIndices(ptr_input)) return false; + + // Handles the following cases: + // 1. |ptr_input| is an index-less access chain. Replace the pointer + // in |inst| with |ptr_input|'s pointer. + // 2. |inst| is a index-less access chain. Change |inst| to an + // OpCopyObject. + // 3. |inst| is not a pointer access chain. + // |inst|'s indices are appended to |ptr_input|'s indices. + // 4. |ptr_input| is not pointer access chain. + // |inst| is a pointer access chain. + // |inst|'s element operand is combined with the last index in + // |ptr_input| to form a new operand. + // 5. |ptr_input| is a pointer access chain. + // Like the above scenario, |inst|'s element operand is combined + // with |ptr_input|'s last index. This results is either a + // combined element operand or combined regular index. + + // TODO(alan-baker): Support this properly. Requires analyzing the + // size/alignment of the type and converting the stride into an element + // index. + uint32_t array_stride = GetArrayStride(ptr_input); + if (array_stride != 0) return false; + + if (ptr_input->NumInOperands() == 1) { + // The input is effectively a no-op. + inst->SetInOperand(0, {ptr_input->GetSingleWordInOperand(0)}); + context()->AnalyzeUses(inst); + } else if (inst->NumInOperands() == 1) { + // |inst| is a no-op, change it to a copy. Instruction simplification will + // clean it up. + inst->SetOpcode(spv::Op::OpCopyObject); + } else { + std::vector new_operands; + if (!CreateNewInputOperands(ptr_input, inst, &new_operands)) return false; + + // Update the instruction. + inst->SetOpcode(UpdateOpcode(inst->opcode(), ptr_input->opcode())); + inst->SetInOperands(std::move(new_operands)); + context()->AnalyzeUses(inst); + } + return true; +} + +spv::Op CombineAccessChains::UpdateOpcode(spv::Op base_opcode, + spv::Op input_opcode) { + auto IsInBounds = [](spv::Op opcode) { + return opcode == spv::Op::OpInBoundsPtrAccessChain || + opcode == spv::Op::OpInBoundsAccessChain; + }; + + if (input_opcode == spv::Op::OpInBoundsPtrAccessChain) { + if (!IsInBounds(base_opcode)) return spv::Op::OpPtrAccessChain; + } else if (input_opcode == spv::Op::OpInBoundsAccessChain) { + if (!IsInBounds(base_opcode)) return spv::Op::OpAccessChain; + } + + return input_opcode; +} + +bool CombineAccessChains::IsPtrAccessChain(spv::Op opcode) { + return opcode == spv::Op::OpPtrAccessChain || + opcode == spv::Op::OpInBoundsPtrAccessChain; +} + +bool CombineAccessChains::Has64BitIndices(Instruction* inst) { + for (uint32_t i = 1; i < inst->NumInOperands(); ++i) { + Instruction* index_inst = + context()->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(i)); + const analysis::Type* index_type = + context()->get_type_mgr()->GetType(index_inst->type_id()); + if (!index_type->AsInteger() || index_type->AsInteger()->width() != 32) + return true; + } + return false; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/combine_access_chains.h b/thirdparty/glslang/External/spirv-tools/source/opt/combine_access_chains.h new file mode 100644 index 000000000000..32ee50d30dce --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/combine_access_chains.h @@ -0,0 +1,83 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_COMBINE_ACCESS_CHAINS_H_ +#define SOURCE_OPT_COMBINE_ACCESS_CHAINS_H_ + +#include + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class CombineAccessChains : public Pass { + public: + const char* name() const override { return "combine-access-chains"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + // Combine access chains in |function|. Blocks are processed in reverse + // post-order. Returns true if the function is modified. + bool ProcessFunction(Function& function); + + // Combines an access chain (normal, in bounds or pointer) |inst| if its base + // pointer is another access chain. Returns true if the access chain was + // modified. + bool CombineAccessChain(Instruction* inst); + + // Returns the value of |constant_inst| as a uint32_t. + uint32_t GetConstantValue(const analysis::Constant* constant_inst); + + // Returns the array stride of |inst|'s type. + uint32_t GetArrayStride(const Instruction* inst); + + // Returns the type by resolving the index operands |inst|. |inst| must be an + // access chain instruction. + const analysis::Type* GetIndexedType(Instruction* inst); + + // Populates |new_operands| with the operands for the combined access chain. + // Returns false if the access chains cannot be combined. + bool CreateNewInputOperands(Instruction* ptr_input, Instruction* inst, + std::vector* new_operands); + + // Combines the last index of |ptr_input| with the element operand of |inst|. + // Adds the combined operand to |new_operands|. + bool CombineIndices(Instruction* ptr_input, Instruction* inst, + std::vector* new_operands); + + // Returns the opcode to use for the combined access chain. + spv::Op UpdateOpcode(spv::Op base_opcode, spv::Op input_opcode); + + // Returns true if |opcode| is a pointer access chain. + bool IsPtrAccessChain(spv::Op opcode); + + // Returns true if |inst| (an access chain) has 64-bit indices. + bool Has64BitIndices(Instruction* inst); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_COMBINE_ACCESS_CHAINS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/compact_ids_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/compact_ids_pass.cpp new file mode 100644 index 000000000000..5a2a54b17890 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/compact_ids_pass.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/compact_ids_pass.h" + +#include +#include + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { + +// Returns the remapped id of |id| from |result_id_mapping|. If the remapped +// id does not exist, adds a new one to |result_id_mapping| and returns it. +uint32_t GetRemappedId( + std::unordered_map* result_id_mapping, uint32_t id) { + auto it = result_id_mapping->find(id); + if (it == result_id_mapping->end()) { + const uint32_t new_id = + static_cast(result_id_mapping->size()) + 1; + const auto insertion_result = result_id_mapping->emplace(id, new_id); + it = insertion_result.first; + assert(insertion_result.second); + } + return it->second; +} + +} // namespace + +Pass::Status CompactIdsPass::Process() { + bool modified = false; + std::unordered_map result_id_mapping; + + // Disable automatic DebugInfo analysis for the life of the CompactIds pass. + // The DebugInfo manager requires the SPIR-V to be valid to run, but this is + // not true at all times in CompactIds as it remaps all ids. + context()->InvalidateAnalyses(IRContext::kAnalysisDebugInfo); + + context()->module()->ForEachInst( + [&result_id_mapping, &modified](Instruction* inst) { + auto operand = inst->begin(); + while (operand != inst->end()) { + const auto type = operand->type; + if (spvIsIdType(type)) { + assert(operand->words.size() == 1); + uint32_t& id = operand->words[0]; + uint32_t new_id = GetRemappedId(&result_id_mapping, id); + if (id != new_id) { + modified = true; + id = new_id; + // Update data cached in the instruction object. + if (type == SPV_OPERAND_TYPE_RESULT_ID) { + inst->SetResultId(id); + } else if (type == SPV_OPERAND_TYPE_TYPE_ID) { + inst->SetResultType(id); + } + } + } + ++operand; + } + + uint32_t scope_id = inst->GetDebugScope().GetLexicalScope(); + if (scope_id != kNoDebugScope) { + uint32_t new_id = GetRemappedId(&result_id_mapping, scope_id); + if (scope_id != new_id) { + inst->UpdateLexicalScope(new_id); + modified = true; + } + } + uint32_t inlinedat_id = inst->GetDebugInlinedAt(); + if (inlinedat_id != kNoInlinedAt) { + uint32_t new_id = GetRemappedId(&result_id_mapping, inlinedat_id); + if (inlinedat_id != new_id) { + inst->UpdateDebugInlinedAt(new_id); + modified = true; + } + } + }, + true); + + if (context()->module()->id_bound() != result_id_mapping.size() + 1) { + modified = true; + context()->module()->SetIdBound( + static_cast(result_id_mapping.size() + 1)); + // There are ids in the feature manager that could now be invalid + context()->ResetFeatureManager(); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/compact_ids_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/compact_ids_pass.h new file mode 100644 index 000000000000..d97ae0fa49f5 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/compact_ids_pass.h @@ -0,0 +1,42 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_COMPACT_IDS_PASS_H_ +#define SOURCE_OPT_COMPACT_IDS_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class CompactIdsPass : public Pass { + public: + const char* name() const override { return "compact-ids"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis; + } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_COMPACT_IDS_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/composite.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/composite.cpp new file mode 100644 index 000000000000..2b4dca25792f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/composite.cpp @@ -0,0 +1,52 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/composite.h" + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/iterator.h" +#include "spirv/1.2/GLSL.std.450.h" + +namespace spvtools { +namespace opt { + +bool ExtInsMatch(const std::vector& extIndices, + const Instruction* insInst, const uint32_t extOffset) { + uint32_t numIndices = static_cast(extIndices.size()) - extOffset; + if (numIndices != insInst->NumInOperands() - 2) return false; + for (uint32_t i = 0; i < numIndices; ++i) + if (extIndices[i + extOffset] != insInst->GetSingleWordInOperand(i + 2)) + return false; + return true; +} + +bool ExtInsConflict(const std::vector& extIndices, + const Instruction* insInst, const uint32_t extOffset) { + if (extIndices.size() - extOffset == insInst->NumInOperands() - 2) + return false; + uint32_t extNumIndices = static_cast(extIndices.size()) - extOffset; + uint32_t insNumIndices = insInst->NumInOperands() - 2; + uint32_t numIndices = std::min(extNumIndices, insNumIndices); + for (uint32_t i = 0; i < numIndices; ++i) + if (extIndices[i + extOffset] != insInst->GetSingleWordInOperand(i + 2)) + return false; + return true; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/composite.h b/thirdparty/glslang/External/spirv-tools/source/opt/composite.h new file mode 100644 index 000000000000..3cc036e4d7ff --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/composite.h @@ -0,0 +1,51 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_COMPOSITE_H_ +#define SOURCE_OPT_COMPOSITE_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// Return true if the extract indices in |extIndices| starting at |extOffset| +// match indices of insert |insInst|. +bool ExtInsMatch(const std::vector& extIndices, + const Instruction* insInst, const uint32_t extOffset); + +// Return true if indices in |extIndices| starting at |extOffset| and +// indices of insert |insInst| conflict, specifically, if the insert +// changes bits specified by the extract, but changes either more bits +// or less bits than the extract specifies, meaning the exact value being +// inserted cannot be used to replace the extract. +bool ExtInsConflict(const std::vector& extIndices, + const Instruction* insInst, const uint32_t extOffset); + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_COMPOSITE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/const_folding_rules.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/const_folding_rules.cpp new file mode 100644 index 000000000000..17900af245e2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/const_folding_rules.cpp @@ -0,0 +1,1963 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/const_folding_rules.h" + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kExtractCompositeIdInIdx = 0; + +// Returns the value obtained by extracting the |number_of_bits| least +// significant bits from |value|, and sign-extending it to 64-bits. +uint64_t SignExtendValue(uint64_t value, uint32_t number_of_bits) { + if (number_of_bits == 64) return value; + + uint64_t mask_for_sign_bit = 1ull << (number_of_bits - 1); + uint64_t mask_for_significant_bits = (mask_for_sign_bit << 1) - 1ull; + if (value & mask_for_sign_bit) { + // Set upper bits to 1 + value |= ~mask_for_significant_bits; + } else { + // Clear the upper bits + value &= mask_for_significant_bits; + } + return value; +} + +// Returns the value obtained by extracting the |number_of_bits| least +// significant bits from |value|, and zero-extending it to 64-bits. +uint64_t ZeroExtendValue(uint64_t value, uint32_t number_of_bits) { + if (number_of_bits == 64) return value; + + uint64_t mask_for_first_bit_to_clear = 1ull << (number_of_bits); + uint64_t mask_for_bits_to_keep = mask_for_first_bit_to_clear - 1; + value &= mask_for_bits_to_keep; + return value; +} + +// Returns a constant whose value is `value` and type is `type`. This constant +// will be generated by `const_mgr`. The type must be a scalar integer type. +const analysis::Constant* GenerateIntegerConstant( + const analysis::Integer* integer_type, uint64_t result, + analysis::ConstantManager* const_mgr) { + assert(integer_type != nullptr); + + std::vector words; + if (integer_type->width() == 64) { + // In the 64-bit case, two words are needed to represent the value. + words = {static_cast(result), + static_cast(result >> 32)}; + } else { + // In all other cases, only a single word is needed. + assert(integer_type->width() <= 32); + if (integer_type->IsSigned()) { + result = SignExtendValue(result, integer_type->width()); + } else { + result = ZeroExtendValue(result, integer_type->width()); + } + words = {static_cast(result)}; + } + return const_mgr->GetConstant(integer_type, words); +} + +// Returns a constants with the value NaN of the given type. Only works for +// 32-bit and 64-bit float point types. Returns |nullptr| if an error occurs. +const analysis::Constant* GetNan(const analysis::Type* type, + analysis::ConstantManager* const_mgr) { + const analysis::Float* float_type = type->AsFloat(); + if (float_type == nullptr) { + return nullptr; + } + + switch (float_type->width()) { + case 32: + return const_mgr->GetFloatConst(std::numeric_limits::quiet_NaN()); + case 64: + return const_mgr->GetDoubleConst( + std::numeric_limits::quiet_NaN()); + default: + return nullptr; + } +} + +// Returns a constants with the value INF of the given type. Only works for +// 32-bit and 64-bit float point types. Returns |nullptr| if an error occurs. +const analysis::Constant* GetInf(const analysis::Type* type, + analysis::ConstantManager* const_mgr) { + const analysis::Float* float_type = type->AsFloat(); + if (float_type == nullptr) { + return nullptr; + } + + switch (float_type->width()) { + case 32: + return const_mgr->GetFloatConst(std::numeric_limits::infinity()); + case 64: + return const_mgr->GetDoubleConst(std::numeric_limits::infinity()); + default: + return nullptr; + } +} + +// Returns true if |type| is Float or a vector of Float. +bool HasFloatingPoint(const analysis::Type* type) { + if (type->AsFloat()) { + return true; + } else if (const analysis::Vector* vec_type = type->AsVector()) { + return vec_type->element_type()->AsFloat() != nullptr; + } + + return false; +} + +// Returns a constants with the value |-val| of the given type. Only works for +// 32-bit and 64-bit float point types. Returns |nullptr| if an error occurs. +const analysis::Constant* NegateFPConst(const analysis::Type* result_type, + const analysis::Constant* val, + analysis::ConstantManager* const_mgr) { + const analysis::Float* float_type = result_type->AsFloat(); + assert(float_type != nullptr); + if (float_type->width() == 32) { + float fa = val->GetFloat(); + return const_mgr->GetFloatConst(-fa); + } else if (float_type->width() == 64) { + double da = val->GetDouble(); + return const_mgr->GetDoubleConst(-da); + } + return nullptr; +} + +// Returns a constants with the value |-val| of the given type. +const analysis::Constant* NegateIntConst(const analysis::Type* result_type, + const analysis::Constant* val, + analysis::ConstantManager* const_mgr) { + const analysis::Integer* int_type = result_type->AsInteger(); + assert(int_type != nullptr); + + if (val->AsNullConstant()) { + return val; + } + + uint64_t new_value = static_cast(-val->GetSignExtendedValue()); + return const_mgr->GetIntConst(new_value, int_type->width(), + int_type->IsSigned()); +} + +// Folds an OpcompositeExtract where input is a composite constant. +ConstantFoldingRule FoldExtractWithConstants() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + const analysis::Constant* c = constants[kExtractCompositeIdInIdx]; + if (c == nullptr) { + return nullptr; + } + + for (uint32_t i = 1; i < inst->NumInOperands(); ++i) { + uint32_t element_index = inst->GetSingleWordInOperand(i); + if (c->AsNullConstant()) { + // Return Null for the return type. + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + return const_mgr->GetConstant(type_mgr->GetType(inst->type_id()), {}); + } + + auto cc = c->AsCompositeConstant(); + assert(cc != nullptr); + auto components = cc->GetComponents(); + // Protect against invalid IR. Refuse to fold if the index is out + // of bounds. + if (element_index >= components.size()) return nullptr; + c = components[element_index]; + } + return c; + }; +} + +// Folds an OpcompositeInsert where input is a composite constant. +ConstantFoldingRule FoldInsertWithConstants() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Constant* object = constants[0]; + const analysis::Constant* composite = constants[1]; + if (object == nullptr || composite == nullptr) { + return nullptr; + } + + // If there is more than 1 index, then each additional constant used by the + // index will need to be recreated to use the inserted object. + std::vector chain; + std::vector components; + const analysis::Type* type = nullptr; + const uint32_t final_index = (inst->NumInOperands() - 1); + + // Work down hierarchy of all indexes + for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { + type = composite->type(); + + if (composite->AsNullConstant()) { + // Make new composite so it can be inserted in the index with the + // non-null value + if (const auto new_composite = + const_mgr->GetNullCompositeConstant(type)) { + // Keep track of any indexes along the way to last index + if (i != final_index) { + chain.push_back(new_composite); + } + components = new_composite->AsCompositeConstant()->GetComponents(); + } else { + // Unsupported input type (such as structs) + return nullptr; + } + } else { + // Keep track of any indexes along the way to last index + if (i != final_index) { + chain.push_back(composite); + } + components = composite->AsCompositeConstant()->GetComponents(); + } + const uint32_t index = inst->GetSingleWordInOperand(i); + composite = components[index]; + } + + // Final index in hierarchy is inserted with new object. + const uint32_t final_operand = inst->GetSingleWordInOperand(final_index); + std::vector ids; + for (size_t i = 0; i < components.size(); i++) { + const analysis::Constant* constant = + (i == final_operand) ? object : components[i]; + Instruction* member_inst = const_mgr->GetDefiningInstruction(constant); + ids.push_back(member_inst->result_id()); + } + const analysis::Constant* new_constant = const_mgr->GetConstant(type, ids); + + // Work backwards up the chain and replace each index with new constant. + for (size_t i = chain.size(); i > 0; i--) { + // Need to insert any previous instruction into the module first. + // Can't just insert in types_values_begin() because it will move above + // where the types are declared. + // Can't compare with location of inst because not all new added + // instructions are added to types_values_ + auto iter = context->types_values_end(); + Module::inst_iterator* pos = &iter; + const_mgr->BuildInstructionAndAddToModule(new_constant, pos); + + composite = chain[i - 1]; + components = composite->AsCompositeConstant()->GetComponents(); + type = composite->type(); + ids.clear(); + for (size_t k = 0; k < components.size(); k++) { + const uint32_t index = + inst->GetSingleWordInOperand(1 + static_cast(i)); + const analysis::Constant* constant = + (k == index) ? new_constant : components[k]; + const uint32_t constant_id = + const_mgr->FindDeclaredConstant(constant, 0); + ids.push_back(constant_id); + } + new_constant = const_mgr->GetConstant(type, ids); + } + + // If multiple constants were created, only need to return the top index. + return new_constant; + }; +} + +ConstantFoldingRule FoldVectorShuffleWithConstants() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + assert(inst->opcode() == spv::Op::OpVectorShuffle); + const analysis::Constant* c1 = constants[0]; + const analysis::Constant* c2 = constants[1]; + if (c1 == nullptr || c2 == nullptr) { + return nullptr; + } + + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* element_type = c1->type()->AsVector()->element_type(); + + std::vector c1_components; + if (const analysis::VectorConstant* vec_const = c1->AsVectorConstant()) { + c1_components = vec_const->GetComponents(); + } else { + assert(c1->AsNullConstant()); + const analysis::Constant* element = + const_mgr->GetConstant(element_type, {}); + c1_components.resize(c1->type()->AsVector()->element_count(), element); + } + std::vector c2_components; + if (const analysis::VectorConstant* vec_const = c2->AsVectorConstant()) { + c2_components = vec_const->GetComponents(); + } else { + assert(c2->AsNullConstant()); + const analysis::Constant* element = + const_mgr->GetConstant(element_type, {}); + c2_components.resize(c2->type()->AsVector()->element_count(), element); + } + + std::vector ids; + const uint32_t undef_literal_value = 0xffffffff; + for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { + uint32_t index = inst->GetSingleWordInOperand(i); + if (index == undef_literal_value) { + // Don't fold shuffle with undef literal value. + return nullptr; + } else if (index < c1_components.size()) { + Instruction* member_inst = + const_mgr->GetDefiningInstruction(c1_components[index]); + ids.push_back(member_inst->result_id()); + } else { + Instruction* member_inst = const_mgr->GetDefiningInstruction( + c2_components[index - c1_components.size()]); + ids.push_back(member_inst->result_id()); + } + } + + analysis::TypeManager* type_mgr = context->get_type_mgr(); + return const_mgr->GetConstant(type_mgr->GetType(inst->type_id()), ids); + }; +} + +ConstantFoldingRule FoldVectorTimesScalar() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + assert(inst->opcode() == spv::Op::OpVectorTimesScalar); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + + if (!inst->IsFloatingPointFoldingAllowed()) { + if (HasFloatingPoint(type_mgr->GetType(inst->type_id()))) { + return nullptr; + } + } + + const analysis::Constant* c1 = constants[0]; + const analysis::Constant* c2 = constants[1]; + + if (c1 && c1->IsZero()) { + return c1; + } + + if (c2 && c2->IsZero()) { + // Get or create the NullConstant for this type. + std::vector ids; + return const_mgr->GetConstant(type_mgr->GetType(inst->type_id()), ids); + } + + if (c1 == nullptr || c2 == nullptr) { + return nullptr; + } + + // Check result type. + const analysis::Type* result_type = type_mgr->GetType(inst->type_id()); + const analysis::Vector* vector_type = result_type->AsVector(); + assert(vector_type != nullptr); + const analysis::Type* element_type = vector_type->element_type(); + assert(element_type != nullptr); + const analysis::Float* float_type = element_type->AsFloat(); + assert(float_type != nullptr); + + // Check types of c1 and c2. + assert(c1->type()->AsVector() == vector_type); + assert(c1->type()->AsVector()->element_type() == element_type && + c2->type() == element_type); + + // Get a float vector that is the result of vector-times-scalar. + std::vector c1_components = + c1->GetVectorComponents(const_mgr); + std::vector ids; + if (float_type->width() == 32) { + float scalar = c2->GetFloat(); + for (uint32_t i = 0; i < c1_components.size(); ++i) { + utils::FloatProxy result(c1_components[i]->GetFloat() * scalar); + std::vector words = result.GetWords(); + const analysis::Constant* new_elem = + const_mgr->GetConstant(float_type, words); + ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } else if (float_type->width() == 64) { + double scalar = c2->GetDouble(); + for (uint32_t i = 0; i < c1_components.size(); ++i) { + utils::FloatProxy result(c1_components[i]->GetDouble() * + scalar); + std::vector words = result.GetWords(); + const analysis::Constant* new_elem = + const_mgr->GetConstant(float_type, words); + ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } + return nullptr; + }; +} + +// Returns to the constant that results from tranposing |matrix|. The result +// will have type |result_type|, and |matrix| must exist in |context|. The +// result constant will also exist in |context|. +const analysis::Constant* TransposeMatrix(const analysis::Constant* matrix, + analysis::Matrix* result_type, + IRContext* context) { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + if (matrix->AsNullConstant() != nullptr) { + return const_mgr->GetNullCompositeConstant(result_type); + } + + const auto& columns = matrix->AsMatrixConstant()->GetComponents(); + uint32_t number_of_rows = columns[0]->type()->AsVector()->element_count(); + + // Collect the ids of the elements in their new positions. + std::vector> result_elements(number_of_rows); + for (const analysis::Constant* column : columns) { + if (column->AsNullConstant()) { + column = const_mgr->GetNullCompositeConstant(column->type()); + } + const auto& column_components = column->AsVectorConstant()->GetComponents(); + + for (uint32_t row = 0; row < number_of_rows; ++row) { + result_elements[row].push_back( + const_mgr->GetDefiningInstruction(column_components[row]) + ->result_id()); + } + } + + // Create the constant for each row in the result, and collect the ids. + std::vector result_columns(number_of_rows); + for (uint32_t col = 0; col < number_of_rows; ++col) { + auto* element = const_mgr->GetConstant(result_type->element_type(), + result_elements[col]); + result_columns[col] = + const_mgr->GetDefiningInstruction(element)->result_id(); + } + + // Create the matrix constant from the row ids, and return it. + return const_mgr->GetConstant(result_type, result_columns); +} + +const analysis::Constant* FoldTranspose( + IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpTranspose); + + analysis::TypeManager* type_mgr = context->get_type_mgr(); + if (!inst->IsFloatingPointFoldingAllowed()) { + if (HasFloatingPoint(type_mgr->GetType(inst->type_id()))) { + return nullptr; + } + } + + const analysis::Constant* matrix = constants[0]; + if (matrix == nullptr) { + return nullptr; + } + + auto* result_type = type_mgr->GetType(inst->type_id()); + return TransposeMatrix(matrix, result_type->AsMatrix(), context); +} + +ConstantFoldingRule FoldVectorTimesMatrix() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + assert(inst->opcode() == spv::Op::OpVectorTimesMatrix); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + + if (!inst->IsFloatingPointFoldingAllowed()) { + if (HasFloatingPoint(type_mgr->GetType(inst->type_id()))) { + return nullptr; + } + } + + const analysis::Constant* c1 = constants[0]; + const analysis::Constant* c2 = constants[1]; + + if (c1 == nullptr || c2 == nullptr) { + return nullptr; + } + + // Check result type. + const analysis::Type* result_type = type_mgr->GetType(inst->type_id()); + const analysis::Vector* vector_type = result_type->AsVector(); + assert(vector_type != nullptr); + const analysis::Type* element_type = vector_type->element_type(); + assert(element_type != nullptr); + const analysis::Float* float_type = element_type->AsFloat(); + assert(float_type != nullptr); + + // Check types of c1 and c2. + assert(c1->type()->AsVector() == vector_type); + assert(c1->type()->AsVector()->element_type() == element_type && + c2->type()->AsMatrix()->element_type() == vector_type); + + uint32_t resultVectorSize = result_type->AsVector()->element_count(); + std::vector ids; + + if ((c1 && c1->IsZero()) || (c2 && c2->IsZero())) { + std::vector words(float_type->width() / 32, 0); + for (uint32_t i = 0; i < resultVectorSize; ++i) { + const analysis::Constant* new_elem = + const_mgr->GetConstant(float_type, words); + ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } + + // Get a float vector that is the result of vector-times-matrix. + std::vector c1_components = + c1->GetVectorComponents(const_mgr); + std::vector c2_components = + c2->AsMatrixConstant()->GetComponents(); + + if (float_type->width() == 32) { + for (uint32_t i = 0; i < resultVectorSize; ++i) { + float result_scalar = 0.0f; + if (!c2_components[i]->AsNullConstant()) { + const analysis::VectorConstant* c2_vec = + c2_components[i]->AsVectorConstant(); + for (uint32_t j = 0; j < c2_vec->GetComponents().size(); ++j) { + float c1_scalar = c1_components[j]->GetFloat(); + float c2_scalar = c2_vec->GetComponents()[j]->GetFloat(); + result_scalar += c1_scalar * c2_scalar; + } + } + utils::FloatProxy result(result_scalar); + std::vector words = result.GetWords(); + const analysis::Constant* new_elem = + const_mgr->GetConstant(float_type, words); + ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } else if (float_type->width() == 64) { + for (uint32_t i = 0; i < c2_components.size(); ++i) { + double result_scalar = 0.0; + if (!c2_components[i]->AsNullConstant()) { + const analysis::VectorConstant* c2_vec = + c2_components[i]->AsVectorConstant(); + for (uint32_t j = 0; j < c2_vec->GetComponents().size(); ++j) { + double c1_scalar = c1_components[j]->GetDouble(); + double c2_scalar = c2_vec->GetComponents()[j]->GetDouble(); + result_scalar += c1_scalar * c2_scalar; + } + } + utils::FloatProxy result(result_scalar); + std::vector words = result.GetWords(); + const analysis::Constant* new_elem = + const_mgr->GetConstant(float_type, words); + ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } + return nullptr; + }; +} + +ConstantFoldingRule FoldMatrixTimesVector() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + assert(inst->opcode() == spv::Op::OpMatrixTimesVector); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + + if (!inst->IsFloatingPointFoldingAllowed()) { + if (HasFloatingPoint(type_mgr->GetType(inst->type_id()))) { + return nullptr; + } + } + + const analysis::Constant* c1 = constants[0]; + const analysis::Constant* c2 = constants[1]; + + if (c1 == nullptr || c2 == nullptr) { + return nullptr; + } + + // Check result type. + const analysis::Type* result_type = type_mgr->GetType(inst->type_id()); + const analysis::Vector* vector_type = result_type->AsVector(); + assert(vector_type != nullptr); + const analysis::Type* element_type = vector_type->element_type(); + assert(element_type != nullptr); + const analysis::Float* float_type = element_type->AsFloat(); + assert(float_type != nullptr); + + // Check types of c1 and c2. + assert(c1->type()->AsMatrix()->element_type() == vector_type); + assert(c2->type()->AsVector()->element_type() == element_type); + + uint32_t resultVectorSize = result_type->AsVector()->element_count(); + std::vector ids; + + if ((c1 && c1->IsZero()) || (c2 && c2->IsZero())) { + std::vector words(float_type->width() / 32, 0); + for (uint32_t i = 0; i < resultVectorSize; ++i) { + const analysis::Constant* new_elem = + const_mgr->GetConstant(float_type, words); + ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } + + // Get a float vector that is the result of matrix-times-vector. + std::vector c1_components = + c1->AsMatrixConstant()->GetComponents(); + std::vector c2_components = + c2->GetVectorComponents(const_mgr); + + if (float_type->width() == 32) { + for (uint32_t i = 0; i < resultVectorSize; ++i) { + float result_scalar = 0.0f; + for (uint32_t j = 0; j < c1_components.size(); ++j) { + if (!c1_components[j]->AsNullConstant()) { + float c1_scalar = c1_components[j] + ->AsVectorConstant() + ->GetComponents()[i] + ->GetFloat(); + float c2_scalar = c2_components[j]->GetFloat(); + result_scalar += c1_scalar * c2_scalar; + } + } + utils::FloatProxy result(result_scalar); + std::vector words = result.GetWords(); + const analysis::Constant* new_elem = + const_mgr->GetConstant(float_type, words); + ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } else if (float_type->width() == 64) { + for (uint32_t i = 0; i < resultVectorSize; ++i) { + double result_scalar = 0.0; + for (uint32_t j = 0; j < c1_components.size(); ++j) { + if (!c1_components[j]->AsNullConstant()) { + double c1_scalar = c1_components[j] + ->AsVectorConstant() + ->GetComponents()[i] + ->GetDouble(); + double c2_scalar = c2_components[j]->GetDouble(); + result_scalar += c1_scalar * c2_scalar; + } + } + utils::FloatProxy result(result_scalar); + std::vector words = result.GetWords(); + const analysis::Constant* new_elem = + const_mgr->GetConstant(float_type, words); + ids.push_back(const_mgr->GetDefiningInstruction(new_elem)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } + return nullptr; + }; +} + +ConstantFoldingRule FoldCompositeWithConstants() { + // Folds an OpCompositeConstruct where all of the inputs are constants to a + // constant. A new constant is created if necessary. + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + const analysis::Type* new_type = type_mgr->GetType(inst->type_id()); + Instruction* type_inst = + context->get_def_use_mgr()->GetDef(inst->type_id()); + + std::vector ids; + for (uint32_t i = 0; i < constants.size(); ++i) { + const analysis::Constant* element_const = constants[i]; + if (element_const == nullptr) { + return nullptr; + } + + uint32_t component_type_id = 0; + if (type_inst->opcode() == spv::Op::OpTypeStruct) { + component_type_id = type_inst->GetSingleWordInOperand(i); + } else if (type_inst->opcode() == spv::Op::OpTypeArray) { + component_type_id = type_inst->GetSingleWordInOperand(0); + } + + uint32_t element_id = + const_mgr->FindDeclaredConstant(element_const, component_type_id); + if (element_id == 0) { + return nullptr; + } + ids.push_back(element_id); + } + return const_mgr->GetConstant(new_type, ids); + }; +} + +// The interface for a function that returns the result of applying a scalar +// floating-point binary operation on |a| and |b|. The type of the return value +// will be |type|. The input constants must also be of type |type|. +using UnaryScalarFoldingRule = std::function; + +// The interface for a function that returns the result of applying a scalar +// floating-point binary operation on |a| and |b|. The type of the return value +// will be |type|. The input constants must also be of type |type|. +using BinaryScalarFoldingRule = std::function; + +// Returns a |ConstantFoldingRule| that folds unary scalar ops +// using |scalar_rule| and unary vectors ops by applying +// |scalar_rule| to the elements of the vector. The |ConstantFoldingRule| +// that is returned assumes that |constants| contains 1 entry. If they are +// not |nullptr|, then their type is either |Float| or |Integer| or a |Vector| +// whose element type is |Float| or |Integer|. +ConstantFoldingRule FoldUnaryOp(UnaryScalarFoldingRule scalar_rule) { + return [scalar_rule](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + const analysis::Type* result_type = type_mgr->GetType(inst->type_id()); + const analysis::Vector* vector_type = result_type->AsVector(); + + const analysis::Constant* arg = + (inst->opcode() == spv::Op::OpExtInst) ? constants[1] : constants[0]; + + if (arg == nullptr) { + return nullptr; + } + + if (vector_type != nullptr) { + std::vector a_components; + std::vector results_components; + + a_components = arg->GetVectorComponents(const_mgr); + + // Fold each component of the vector. + for (uint32_t i = 0; i < a_components.size(); ++i) { + results_components.push_back(scalar_rule(vector_type->element_type(), + a_components[i], const_mgr)); + if (results_components[i] == nullptr) { + return nullptr; + } + } + + // Build the constant object and return it. + std::vector ids; + for (const analysis::Constant* member : results_components) { + ids.push_back(const_mgr->GetDefiningInstruction(member)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } else { + return scalar_rule(result_type, arg, const_mgr); + } + }; +} + +// Returns a |ConstantFoldingRule| that folds binary scalar ops +// using |scalar_rule| and binary vectors ops by applying +// |scalar_rule| to the elements of the vector. The folding rule assumes that op +// has two inputs. For regular instruction, those are in operands 0 and 1. For +// extended instruction, they are in operands 1 and 2. If an element in +// |constants| is not nullprt, then the constant's type is |Float|, |Integer|, +// or |Vector| whose element type is |Float| or |Integer|. +ConstantFoldingRule FoldBinaryOp(BinaryScalarFoldingRule scalar_rule) { + return [scalar_rule](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + assert(constants.size() == inst->NumInOperands()); + assert(constants.size() == (inst->opcode() == spv::Op::OpExtInst ? 3 : 2)); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + const analysis::Type* result_type = type_mgr->GetType(inst->type_id()); + const analysis::Vector* vector_type = result_type->AsVector(); + + const analysis::Constant* arg1 = + (inst->opcode() == spv::Op::OpExtInst) ? constants[1] : constants[0]; + const analysis::Constant* arg2 = + (inst->opcode() == spv::Op::OpExtInst) ? constants[2] : constants[1]; + + if (arg1 == nullptr || arg2 == nullptr) { + return nullptr; + } + + if (vector_type == nullptr) { + return scalar_rule(result_type, arg1, arg2, const_mgr); + } + + std::vector a_components; + std::vector b_components; + std::vector results_components; + + a_components = arg1->GetVectorComponents(const_mgr); + b_components = arg2->GetVectorComponents(const_mgr); + assert(a_components.size() == b_components.size()); + + // Fold each component of the vector. + for (uint32_t i = 0; i < a_components.size(); ++i) { + results_components.push_back(scalar_rule(vector_type->element_type(), + a_components[i], b_components[i], + const_mgr)); + if (results_components[i] == nullptr) { + return nullptr; + } + } + + // Build the constant object and return it. + std::vector ids; + for (const analysis::Constant* member : results_components) { + ids.push_back(const_mgr->GetDefiningInstruction(member)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + }; +} + +// Returns a |ConstantFoldingRule| that folds unary floating point scalar ops +// using |scalar_rule| and unary float point vectors ops by applying +// |scalar_rule| to the elements of the vector. The |ConstantFoldingRule| +// that is returned assumes that |constants| contains 1 entry. If they are +// not |nullptr|, then their type is either |Float| or |Integer| or a |Vector| +// whose element type is |Float| or |Integer|. +ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) { + auto folding_rule = FoldUnaryOp(scalar_rule); + return [folding_rule](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + if (!inst->IsFloatingPointFoldingAllowed()) { + return nullptr; + } + + return folding_rule(context, inst, constants); + }; +} + +// Returns the result of folding the constants in |constants| according the +// |scalar_rule|. If |result_type| is a vector, then |scalar_rule| is applied +// per component. +const analysis::Constant* FoldFPBinaryOp( + BinaryScalarFoldingRule scalar_rule, uint32_t result_type_id, + const std::vector& constants, + IRContext* context) { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + const analysis::Type* result_type = type_mgr->GetType(result_type_id); + const analysis::Vector* vector_type = result_type->AsVector(); + + if (constants[0] == nullptr || constants[1] == nullptr) { + return nullptr; + } + + if (vector_type != nullptr) { + std::vector a_components; + std::vector b_components; + std::vector results_components; + + a_components = constants[0]->GetVectorComponents(const_mgr); + b_components = constants[1]->GetVectorComponents(const_mgr); + + // Fold each component of the vector. + for (uint32_t i = 0; i < a_components.size(); ++i) { + results_components.push_back(scalar_rule(vector_type->element_type(), + a_components[i], b_components[i], + const_mgr)); + if (results_components[i] == nullptr) { + return nullptr; + } + } + + // Build the constant object and return it. + std::vector ids; + for (const analysis::Constant* member : results_components) { + ids.push_back(const_mgr->GetDefiningInstruction(member)->result_id()); + } + return const_mgr->GetConstant(vector_type, ids); + } else { + return scalar_rule(result_type, constants[0], constants[1], const_mgr); + } +} + +// Returns a |ConstantFoldingRule| that folds floating point scalars using +// |scalar_rule| and vectors of floating point by applying |scalar_rule| to the +// elements of the vector. The |ConstantFoldingRule| that is returned assumes +// that |constants| contains 2 entries. If they are not |nullptr|, then their +// type is either |Float| or a |Vector| whose element type is |Float|. +ConstantFoldingRule FoldFPBinaryOp(BinaryScalarFoldingRule scalar_rule) { + return [scalar_rule](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + if (!inst->IsFloatingPointFoldingAllowed()) { + return nullptr; + } + if (inst->opcode() == spv::Op::OpExtInst) { + return FoldFPBinaryOp(scalar_rule, inst->type_id(), + {constants[1], constants[2]}, context); + } + return FoldFPBinaryOp(scalar_rule, inst->type_id(), constants, context); + }; +} + +// This macro defines a |UnaryScalarFoldingRule| that performs float to +// integer conversion. +// TODO(greg-lunarg): Support for 64-bit integer types. +UnaryScalarFoldingRule FoldFToIOp() { + return [](const analysis::Type* result_type, const analysis::Constant* a, + analysis::ConstantManager* const_mgr) -> const analysis::Constant* { + assert(result_type != nullptr && a != nullptr); + const analysis::Integer* integer_type = result_type->AsInteger(); + const analysis::Float* float_type = a->type()->AsFloat(); + assert(float_type != nullptr); + assert(integer_type != nullptr); + if (integer_type->width() != 32) return nullptr; + if (float_type->width() == 32) { + float fa = a->GetFloat(); + uint32_t result = integer_type->IsSigned() + ? static_cast(static_cast(fa)) + : static_cast(fa); + std::vector words = {result}; + return const_mgr->GetConstant(result_type, words); + } else if (float_type->width() == 64) { + double fa = a->GetDouble(); + uint32_t result = integer_type->IsSigned() + ? static_cast(static_cast(fa)) + : static_cast(fa); + std::vector words = {result}; + return const_mgr->GetConstant(result_type, words); + } + return nullptr; + }; +} + +// This function defines a |UnaryScalarFoldingRule| that performs integer to +// float conversion. +// TODO(greg-lunarg): Support for 64-bit integer types. +UnaryScalarFoldingRule FoldIToFOp() { + return [](const analysis::Type* result_type, const analysis::Constant* a, + analysis::ConstantManager* const_mgr) -> const analysis::Constant* { + assert(result_type != nullptr && a != nullptr); + const analysis::Integer* integer_type = a->type()->AsInteger(); + const analysis::Float* float_type = result_type->AsFloat(); + assert(float_type != nullptr); + assert(integer_type != nullptr); + if (integer_type->width() != 32) return nullptr; + uint32_t ua = a->GetU32(); + if (float_type->width() == 32) { + float result_val = integer_type->IsSigned() + ? static_cast(static_cast(ua)) + : static_cast(ua); + utils::FloatProxy result(result_val); + std::vector words = {result.data()}; + return const_mgr->GetConstant(result_type, words); + } else if (float_type->width() == 64) { + double result_val = integer_type->IsSigned() + ? static_cast(static_cast(ua)) + : static_cast(ua); + utils::FloatProxy result(result_val); + std::vector words = result.GetWords(); + return const_mgr->GetConstant(result_type, words); + } + return nullptr; + }; +} + +// This defines a |UnaryScalarFoldingRule| that performs |OpQuantizeToF16|. +UnaryScalarFoldingRule FoldQuantizeToF16Scalar() { + return [](const analysis::Type* result_type, const analysis::Constant* a, + analysis::ConstantManager* const_mgr) -> const analysis::Constant* { + assert(result_type != nullptr && a != nullptr); + const analysis::Float* float_type = a->type()->AsFloat(); + assert(float_type != nullptr); + if (float_type->width() != 32) { + return nullptr; + } + + float fa = a->GetFloat(); + utils::HexFloat> orignal(fa); + utils::HexFloat> quantized(0); + utils::HexFloat> result(0.0f); + orignal.castTo(quantized, utils::round_direction::kToZero); + quantized.castTo(result, utils::round_direction::kToZero); + std::vector words = {result.getBits()}; + return const_mgr->GetConstant(result_type, words); + }; +} + +// This macro defines a |BinaryScalarFoldingRule| that applies |op|. The +// operator |op| must work for both float and double, and use syntax "f1 op f2". +#define FOLD_FPARITH_OP(op) \ + [](const analysis::Type* result_type_in_macro, const analysis::Constant* a, \ + const analysis::Constant* b, \ + analysis::ConstantManager* const_mgr_in_macro) \ + -> const analysis::Constant* { \ + assert(result_type_in_macro != nullptr && a != nullptr && b != nullptr); \ + assert(result_type_in_macro == a->type() && \ + result_type_in_macro == b->type()); \ + const analysis::Float* float_type_in_macro = \ + result_type_in_macro->AsFloat(); \ + assert(float_type_in_macro != nullptr); \ + if (float_type_in_macro->width() == 32) { \ + float fa = a->GetFloat(); \ + float fb = b->GetFloat(); \ + utils::FloatProxy result_in_macro(fa op fb); \ + std::vector words_in_macro = result_in_macro.GetWords(); \ + return const_mgr_in_macro->GetConstant(result_type_in_macro, \ + words_in_macro); \ + } else if (float_type_in_macro->width() == 64) { \ + double fa = a->GetDouble(); \ + double fb = b->GetDouble(); \ + utils::FloatProxy result_in_macro(fa op fb); \ + std::vector words_in_macro = result_in_macro.GetWords(); \ + return const_mgr_in_macro->GetConstant(result_type_in_macro, \ + words_in_macro); \ + } \ + return nullptr; \ + } + +// Define the folding rule for conversion between floating point and integer +ConstantFoldingRule FoldFToI() { return FoldFPUnaryOp(FoldFToIOp()); } +ConstantFoldingRule FoldIToF() { return FoldFPUnaryOp(FoldIToFOp()); } +ConstantFoldingRule FoldQuantizeToF16() { + return FoldFPUnaryOp(FoldQuantizeToF16Scalar()); +} + +// Define the folding rules for subtraction, addition, multiplication, and +// division for floating point values. +ConstantFoldingRule FoldFSub() { return FoldFPBinaryOp(FOLD_FPARITH_OP(-)); } +ConstantFoldingRule FoldFAdd() { return FoldFPBinaryOp(FOLD_FPARITH_OP(+)); } +ConstantFoldingRule FoldFMul() { return FoldFPBinaryOp(FOLD_FPARITH_OP(*)); } + +// Returns the constant that results from evaluating |numerator| / 0.0. Returns +// |nullptr| if the result could not be evaluated. +const analysis::Constant* FoldFPScalarDivideByZero( + const analysis::Type* result_type, const analysis::Constant* numerator, + analysis::ConstantManager* const_mgr) { + if (numerator == nullptr) { + return nullptr; + } + + if (numerator->IsZero()) { + return GetNan(result_type, const_mgr); + } + + const analysis::Constant* result = GetInf(result_type, const_mgr); + if (result == nullptr) { + return nullptr; + } + + if (numerator->AsFloatConstant()->GetValueAsDouble() < 0.0) { + result = NegateFPConst(result_type, result, const_mgr); + } + return result; +} + +// Returns the result of folding |numerator| / |denominator|. Returns |nullptr| +// if it cannot be folded. +const analysis::Constant* FoldScalarFPDivide( + const analysis::Type* result_type, const analysis::Constant* numerator, + const analysis::Constant* denominator, + analysis::ConstantManager* const_mgr) { + if (denominator == nullptr) { + return nullptr; + } + + if (denominator->IsZero()) { + return FoldFPScalarDivideByZero(result_type, numerator, const_mgr); + } + + uint32_t width = denominator->type()->AsFloat()->width(); + if (width != 32 && width != 64) { + return nullptr; + } + + const analysis::FloatConstant* denominator_float = + denominator->AsFloatConstant(); + if (denominator_float && denominator->GetValueAsDouble() == -0.0) { + const analysis::Constant* result = + FoldFPScalarDivideByZero(result_type, numerator, const_mgr); + if (result != nullptr) + result = NegateFPConst(result_type, result, const_mgr); + return result; + } else { + return FOLD_FPARITH_OP(/)(result_type, numerator, denominator, const_mgr); + } +} + +// Returns the constant folding rule to fold |OpFDiv| with two constants. +ConstantFoldingRule FoldFDiv() { return FoldFPBinaryOp(FoldScalarFPDivide); } + +bool CompareFloatingPoint(bool op_result, bool op_unordered, + bool need_ordered) { + if (need_ordered) { + // operands are ordered and Operand 1 is |op| Operand 2 + return !op_unordered && op_result; + } else { + // operands are unordered or Operand 1 is |op| Operand 2 + return op_unordered || op_result; + } +} + +// This macro defines a |BinaryScalarFoldingRule| that applies |op|. The +// operator |op| must work for both float and double, and use syntax "f1 op f2". +#define FOLD_FPCMP_OP(op, ord) \ + [](const analysis::Type* result_type, const analysis::Constant* a, \ + const analysis::Constant* b, \ + analysis::ConstantManager* const_mgr) -> const analysis::Constant* { \ + assert(result_type != nullptr && a != nullptr && b != nullptr); \ + assert(result_type->AsBool()); \ + assert(a->type() == b->type()); \ + const analysis::Float* float_type = a->type()->AsFloat(); \ + assert(float_type != nullptr); \ + if (float_type->width() == 32) { \ + float fa = a->GetFloat(); \ + float fb = b->GetFloat(); \ + bool result = CompareFloatingPoint( \ + fa op fb, std::isnan(fa) || std::isnan(fb), ord); \ + std::vector words = {uint32_t(result)}; \ + return const_mgr->GetConstant(result_type, words); \ + } else if (float_type->width() == 64) { \ + double fa = a->GetDouble(); \ + double fb = b->GetDouble(); \ + bool result = CompareFloatingPoint( \ + fa op fb, std::isnan(fa) || std::isnan(fb), ord); \ + std::vector words = {uint32_t(result)}; \ + return const_mgr->GetConstant(result_type, words); \ + } \ + return nullptr; \ + } + +// Define the folding rules for ordered and unordered comparison for floating +// point values. +ConstantFoldingRule FoldFOrdEqual() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(==, true)); +} +ConstantFoldingRule FoldFUnordEqual() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(==, false)); +} +ConstantFoldingRule FoldFOrdNotEqual() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(!=, true)); +} +ConstantFoldingRule FoldFUnordNotEqual() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(!=, false)); +} +ConstantFoldingRule FoldFOrdLessThan() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(<, true)); +} +ConstantFoldingRule FoldFUnordLessThan() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(<, false)); +} +ConstantFoldingRule FoldFOrdGreaterThan() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(>, true)); +} +ConstantFoldingRule FoldFUnordGreaterThan() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(>, false)); +} +ConstantFoldingRule FoldFOrdLessThanEqual() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(<=, true)); +} +ConstantFoldingRule FoldFUnordLessThanEqual() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(<=, false)); +} +ConstantFoldingRule FoldFOrdGreaterThanEqual() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(>=, true)); +} +ConstantFoldingRule FoldFUnordGreaterThanEqual() { + return FoldFPBinaryOp(FOLD_FPCMP_OP(>=, false)); +} + +// Folds an OpDot where all of the inputs are constants to a +// constant. A new constant is created if necessary. +ConstantFoldingRule FoldOpDotWithConstants() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + const analysis::Type* new_type = type_mgr->GetType(inst->type_id()); + assert(new_type->AsFloat() && "OpDot should have a float return type."); + const analysis::Float* float_type = new_type->AsFloat(); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return nullptr; + } + + // If one of the operands is 0, then the result is 0. + bool has_zero_operand = false; + + for (int i = 0; i < 2; ++i) { + if (constants[i]) { + if (constants[i]->AsNullConstant() || + constants[i]->AsVectorConstant()->IsZero()) { + has_zero_operand = true; + break; + } + } + } + + if (has_zero_operand) { + if (float_type->width() == 32) { + utils::FloatProxy result(0.0f); + std::vector words = result.GetWords(); + return const_mgr->GetConstant(float_type, words); + } + if (float_type->width() == 64) { + utils::FloatProxy result(0.0); + std::vector words = result.GetWords(); + return const_mgr->GetConstant(float_type, words); + } + return nullptr; + } + + if (constants[0] == nullptr || constants[1] == nullptr) { + return nullptr; + } + + std::vector a_components; + std::vector b_components; + + a_components = constants[0]->GetVectorComponents(const_mgr); + b_components = constants[1]->GetVectorComponents(const_mgr); + + utils::FloatProxy result(0.0); + std::vector words = result.GetWords(); + const analysis::Constant* result_const = + const_mgr->GetConstant(float_type, words); + for (uint32_t i = 0; i < a_components.size() && result_const != nullptr; + ++i) { + if (a_components[i] == nullptr || b_components[i] == nullptr) { + return nullptr; + } + + const analysis::Constant* component = FOLD_FPARITH_OP(*)( + new_type, a_components[i], b_components[i], const_mgr); + if (component == nullptr) { + return nullptr; + } + result_const = + FOLD_FPARITH_OP(+)(new_type, result_const, component, const_mgr); + } + return result_const; + }; +} + +ConstantFoldingRule FoldFNegate() { return FoldFPUnaryOp(NegateFPConst); } +ConstantFoldingRule FoldSNegate() { return FoldUnaryOp(NegateIntConst); } + +ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { + return [cmp_opcode](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return nullptr; + } + + uint32_t non_const_idx = (constants[0] ? 1 : 0); + uint32_t operand_id = inst->GetSingleWordInOperand(non_const_idx); + Instruction* operand_inst = def_use_mgr->GetDef(operand_id); + + analysis::TypeManager* type_mgr = context->get_type_mgr(); + const analysis::Type* operand_type = + type_mgr->GetType(operand_inst->type_id()); + + if (!operand_type->AsFloat()) { + return nullptr; + } + + if (operand_type->AsFloat()->width() != 32 && + operand_type->AsFloat()->width() != 64) { + return nullptr; + } + + if (operand_inst->opcode() != spv::Op::OpExtInst) { + return nullptr; + } + + if (operand_inst->GetSingleWordInOperand(1) != GLSLstd450FClamp) { + return nullptr; + } + + if (constants[1] == nullptr && constants[0] == nullptr) { + return nullptr; + } + + uint32_t max_id = operand_inst->GetSingleWordInOperand(4); + const analysis::Constant* max_const = + const_mgr->FindDeclaredConstant(max_id); + + uint32_t min_id = operand_inst->GetSingleWordInOperand(3); + const analysis::Constant* min_const = + const_mgr->FindDeclaredConstant(min_id); + + bool found_result = false; + bool result = false; + + switch (cmp_opcode) { + case spv::Op::OpFOrdLessThan: + case spv::Op::OpFUnordLessThan: + case spv::Op::OpFOrdGreaterThanEqual: + case spv::Op::OpFUnordGreaterThanEqual: + if (constants[0]) { + if (min_const) { + if (constants[0]->GetValueAsDouble() < + min_const->GetValueAsDouble()) { + found_result = true; + result = (cmp_opcode == spv::Op::OpFOrdLessThan || + cmp_opcode == spv::Op::OpFUnordLessThan); + } + } + if (max_const) { + if (constants[0]->GetValueAsDouble() >= + max_const->GetValueAsDouble()) { + found_result = true; + result = !(cmp_opcode == spv::Op::OpFOrdLessThan || + cmp_opcode == spv::Op::OpFUnordLessThan); + } + } + } + + if (constants[1]) { + if (max_const) { + if (max_const->GetValueAsDouble() < + constants[1]->GetValueAsDouble()) { + found_result = true; + result = (cmp_opcode == spv::Op::OpFOrdLessThan || + cmp_opcode == spv::Op::OpFUnordLessThan); + } + } + + if (min_const) { + if (min_const->GetValueAsDouble() >= + constants[1]->GetValueAsDouble()) { + found_result = true; + result = !(cmp_opcode == spv::Op::OpFOrdLessThan || + cmp_opcode == spv::Op::OpFUnordLessThan); + } + } + } + break; + case spv::Op::OpFOrdGreaterThan: + case spv::Op::OpFUnordGreaterThan: + case spv::Op::OpFOrdLessThanEqual: + case spv::Op::OpFUnordLessThanEqual: + if (constants[0]) { + if (min_const) { + if (constants[0]->GetValueAsDouble() <= + min_const->GetValueAsDouble()) { + found_result = true; + result = (cmp_opcode == spv::Op::OpFOrdLessThanEqual || + cmp_opcode == spv::Op::OpFUnordLessThanEqual); + } + } + if (max_const) { + if (constants[0]->GetValueAsDouble() > + max_const->GetValueAsDouble()) { + found_result = true; + result = !(cmp_opcode == spv::Op::OpFOrdLessThanEqual || + cmp_opcode == spv::Op::OpFUnordLessThanEqual); + } + } + } + + if (constants[1]) { + if (max_const) { + if (max_const->GetValueAsDouble() <= + constants[1]->GetValueAsDouble()) { + found_result = true; + result = (cmp_opcode == spv::Op::OpFOrdLessThanEqual || + cmp_opcode == spv::Op::OpFUnordLessThanEqual); + } + } + + if (min_const) { + if (min_const->GetValueAsDouble() > + constants[1]->GetValueAsDouble()) { + found_result = true; + result = !(cmp_opcode == spv::Op::OpFOrdLessThanEqual || + cmp_opcode == spv::Op::OpFUnordLessThanEqual); + } + } + } + break; + default: + return nullptr; + } + + if (!found_result) { + return nullptr; + } + + const analysis::Type* bool_type = + context->get_type_mgr()->GetType(inst->type_id()); + const analysis::Constant* result_const = + const_mgr->GetConstant(bool_type, {static_cast(result)}); + assert(result_const); + return result_const; + }; +} + +ConstantFoldingRule FoldFMix() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) + -> const analysis::Constant* { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + assert(inst->opcode() == spv::Op::OpExtInst && + "Expecting an extended instruction."); + assert(inst->GetSingleWordInOperand(0) == + context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && + "Expecting a GLSLstd450 extended instruction."); + assert(inst->GetSingleWordInOperand(1) == GLSLstd450FMix && + "Expecting and FMix instruction."); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return nullptr; + } + + // Make sure all FMix operands are constants. + for (uint32_t i = 1; i < 4; i++) { + if (constants[i] == nullptr) { + return nullptr; + } + } + + const analysis::Constant* one; + bool is_vector = false; + const analysis::Type* result_type = constants[1]->type(); + const analysis::Type* base_type = result_type; + if (base_type->AsVector()) { + is_vector = true; + base_type = base_type->AsVector()->element_type(); + } + assert(base_type->AsFloat() != nullptr && + "FMix is suppose to act on floats or vectors of floats."); + + if (base_type->AsFloat()->width() == 32) { + one = const_mgr->GetConstant(base_type, + utils::FloatProxy(1.0f).GetWords()); + } else { + one = const_mgr->GetConstant(base_type, + utils::FloatProxy(1.0).GetWords()); + } + + if (is_vector) { + uint32_t one_id = const_mgr->GetDefiningInstruction(one)->result_id(); + one = + const_mgr->GetConstant(result_type, std::vector(4, one_id)); + } + + const analysis::Constant* temp1 = FoldFPBinaryOp( + FOLD_FPARITH_OP(-), inst->type_id(), {one, constants[3]}, context); + if (temp1 == nullptr) { + return nullptr; + } + + const analysis::Constant* temp2 = FoldFPBinaryOp( + FOLD_FPARITH_OP(*), inst->type_id(), {constants[1], temp1}, context); + if (temp2 == nullptr) { + return nullptr; + } + const analysis::Constant* temp3 = + FoldFPBinaryOp(FOLD_FPARITH_OP(*), inst->type_id(), + {constants[2], constants[3]}, context); + if (temp3 == nullptr) { + return nullptr; + } + return FoldFPBinaryOp(FOLD_FPARITH_OP(+), inst->type_id(), {temp2, temp3}, + context); + }; +} + +const analysis::Constant* FoldMin(const analysis::Type* result_type, + const analysis::Constant* a, + const analysis::Constant* b, + analysis::ConstantManager*) { + if (const analysis::Integer* int_type = result_type->AsInteger()) { + if (int_type->width() == 32) { + if (int_type->IsSigned()) { + int32_t va = a->GetS32(); + int32_t vb = b->GetS32(); + return (va < vb ? a : b); + } else { + uint32_t va = a->GetU32(); + uint32_t vb = b->GetU32(); + return (va < vb ? a : b); + } + } else if (int_type->width() == 64) { + if (int_type->IsSigned()) { + int64_t va = a->GetS64(); + int64_t vb = b->GetS64(); + return (va < vb ? a : b); + } else { + uint64_t va = a->GetU64(); + uint64_t vb = b->GetU64(); + return (va < vb ? a : b); + } + } + } else if (const analysis::Float* float_type = result_type->AsFloat()) { + if (float_type->width() == 32) { + float va = a->GetFloat(); + float vb = b->GetFloat(); + return (va < vb ? a : b); + } else if (float_type->width() == 64) { + double va = a->GetDouble(); + double vb = b->GetDouble(); + return (va < vb ? a : b); + } + } + return nullptr; +} + +const analysis::Constant* FoldMax(const analysis::Type* result_type, + const analysis::Constant* a, + const analysis::Constant* b, + analysis::ConstantManager*) { + if (const analysis::Integer* int_type = result_type->AsInteger()) { + if (int_type->width() == 32) { + if (int_type->IsSigned()) { + int32_t va = a->GetS32(); + int32_t vb = b->GetS32(); + return (va > vb ? a : b); + } else { + uint32_t va = a->GetU32(); + uint32_t vb = b->GetU32(); + return (va > vb ? a : b); + } + } else if (int_type->width() == 64) { + if (int_type->IsSigned()) { + int64_t va = a->GetS64(); + int64_t vb = b->GetS64(); + return (va > vb ? a : b); + } else { + uint64_t va = a->GetU64(); + uint64_t vb = b->GetU64(); + return (va > vb ? a : b); + } + } + } else if (const analysis::Float* float_type = result_type->AsFloat()) { + if (float_type->width() == 32) { + float va = a->GetFloat(); + float vb = b->GetFloat(); + return (va > vb ? a : b); + } else if (float_type->width() == 64) { + double va = a->GetDouble(); + double vb = b->GetDouble(); + return (va > vb ? a : b); + } + } + return nullptr; +} + +// Fold an clamp instruction when all three operands are constant. +const analysis::Constant* FoldClamp1( + IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpExtInst && + "Expecting an extended instruction."); + assert(inst->GetSingleWordInOperand(0) == + context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && + "Expecting a GLSLstd450 extended instruction."); + + // Make sure all Clamp operands are constants. + for (uint32_t i = 1; i < 4; i++) { + if (constants[i] == nullptr) { + return nullptr; + } + } + + const analysis::Constant* temp = FoldFPBinaryOp( + FoldMax, inst->type_id(), {constants[1], constants[2]}, context); + if (temp == nullptr) { + return nullptr; + } + return FoldFPBinaryOp(FoldMin, inst->type_id(), {temp, constants[3]}, + context); +} + +// Fold a clamp instruction when |x <= min_val|. +const analysis::Constant* FoldClamp2( + IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpExtInst && + "Expecting an extended instruction."); + assert(inst->GetSingleWordInOperand(0) == + context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && + "Expecting a GLSLstd450 extended instruction."); + + const analysis::Constant* x = constants[1]; + const analysis::Constant* min_val = constants[2]; + + if (x == nullptr || min_val == nullptr) { + return nullptr; + } + + const analysis::Constant* temp = + FoldFPBinaryOp(FoldMax, inst->type_id(), {x, min_val}, context); + if (temp == min_val) { + // We can assume that |min_val| is less than |max_val|. Therefore, if the + // result of the max operation is |min_val|, we know the result of the min + // operation, even if |max_val| is not a constant. + return min_val; + } + return nullptr; +} + +// Fold a clamp instruction when |x >= max_val|. +const analysis::Constant* FoldClamp3( + IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpExtInst && + "Expecting an extended instruction."); + assert(inst->GetSingleWordInOperand(0) == + context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && + "Expecting a GLSLstd450 extended instruction."); + + const analysis::Constant* x = constants[1]; + const analysis::Constant* max_val = constants[3]; + + if (x == nullptr || max_val == nullptr) { + return nullptr; + } + + const analysis::Constant* temp = + FoldFPBinaryOp(FoldMin, inst->type_id(), {x, max_val}, context); + if (temp == max_val) { + // We can assume that |min_val| is less than |max_val|. Therefore, if the + // result of the max operation is |min_val|, we know the result of the min + // operation, even if |max_val| is not a constant. + return max_val; + } + return nullptr; +} + +UnaryScalarFoldingRule FoldFTranscendentalUnary(double (*fp)(double)) { + return + [fp](const analysis::Type* result_type, const analysis::Constant* a, + analysis::ConstantManager* const_mgr) -> const analysis::Constant* { + assert(result_type != nullptr && a != nullptr); + const analysis::Float* float_type = a->type()->AsFloat(); + assert(float_type != nullptr); + assert(float_type == result_type->AsFloat()); + if (float_type->width() == 32) { + float fa = a->GetFloat(); + float res = static_cast(fp(fa)); + utils::FloatProxy result(res); + std::vector words = result.GetWords(); + return const_mgr->GetConstant(result_type, words); + } else if (float_type->width() == 64) { + double fa = a->GetDouble(); + double res = fp(fa); + utils::FloatProxy result(res); + std::vector words = result.GetWords(); + return const_mgr->GetConstant(result_type, words); + } + return nullptr; + }; +} + +BinaryScalarFoldingRule FoldFTranscendentalBinary(double (*fp)(double, + double)) { + return + [fp](const analysis::Type* result_type, const analysis::Constant* a, + const analysis::Constant* b, + analysis::ConstantManager* const_mgr) -> const analysis::Constant* { + assert(result_type != nullptr && a != nullptr); + const analysis::Float* float_type = a->type()->AsFloat(); + assert(float_type != nullptr); + assert(float_type == result_type->AsFloat()); + assert(float_type == b->type()->AsFloat()); + if (float_type->width() == 32) { + float fa = a->GetFloat(); + float fb = b->GetFloat(); + float res = static_cast(fp(fa, fb)); + utils::FloatProxy result(res); + std::vector words = result.GetWords(); + return const_mgr->GetConstant(result_type, words); + } else if (float_type->width() == 64) { + double fa = a->GetDouble(); + double fb = b->GetDouble(); + double res = fp(fa, fb); + utils::FloatProxy result(res); + std::vector words = result.GetWords(); + return const_mgr->GetConstant(result_type, words); + } + return nullptr; + }; +} + +enum Sign { Signed, Unsigned }; + +// Returns a BinaryScalarFoldingRule that applies `op` to the scalars. +// The `signedness` is used to determine if the operands should be interpreted +// as signed or unsigned. If the operands are signed, the value will be sign +// extended before the value is passed to `op`. Otherwise the values will be +// zero extended. +template +BinaryScalarFoldingRule FoldBinaryIntegerOperation(uint64_t (*op)(uint64_t, + uint64_t)) { + return + [op](const analysis::Type* result_type, const analysis::Constant* a, + const analysis::Constant* b, + analysis::ConstantManager* const_mgr) -> const analysis::Constant* { + assert(result_type != nullptr && a != nullptr && b != nullptr); + const analysis::Integer* integer_type = result_type->AsInteger(); + assert(integer_type != nullptr); + assert(a->type()->kind() == analysis::Type::kInteger); + assert(b->type()->kind() == analysis::Type::kInteger); + assert(integer_type->width() == a->type()->AsInteger()->width()); + assert(integer_type->width() == b->type()->AsInteger()->width()); + + // In SPIR-V, all operations support unsigned types, but the way they + // are interpreted depends on the opcode. This is why we use the + // template argument to determine how to interpret the operands. + uint64_t ia = (signedness == Signed ? a->GetSignExtendedValue() + : a->GetZeroExtendedValue()); + uint64_t ib = (signedness == Signed ? b->GetSignExtendedValue() + : b->GetZeroExtendedValue()); + uint64_t result = op(ia, ib); + + const analysis::Constant* result_constant = + GenerateIntegerConstant(integer_type, result, const_mgr); + return result_constant; + }; +} + +// A scalar folding rule that folds OpSConvert. +const analysis::Constant* FoldScalarSConvert( + const analysis::Type* result_type, const analysis::Constant* a, + analysis::ConstantManager* const_mgr) { + assert(result_type != nullptr); + assert(a != nullptr); + assert(const_mgr != nullptr); + const analysis::Integer* integer_type = result_type->AsInteger(); + assert(integer_type && "The result type of an SConvert"); + int64_t value = a->GetSignExtendedValue(); + return GenerateIntegerConstant(integer_type, value, const_mgr); +} + +// A scalar folding rule that folds OpUConvert. +const analysis::Constant* FoldScalarUConvert( + const analysis::Type* result_type, const analysis::Constant* a, + analysis::ConstantManager* const_mgr) { + assert(result_type != nullptr); + assert(a != nullptr); + assert(const_mgr != nullptr); + const analysis::Integer* integer_type = result_type->AsInteger(); + assert(integer_type && "The result type of an UConvert"); + uint64_t value = a->GetZeroExtendedValue(); + + // If the operand was an unsigned value with less than 32-bit, it would have + // been sign extended earlier, and we need to clear those bits. + auto* operand_type = a->type()->AsInteger(); + value = ZeroExtendValue(value, operand_type->width()); + return GenerateIntegerConstant(integer_type, value, const_mgr); +} +} // namespace + +void ConstantFoldingRules::AddFoldingRules() { + // Add all folding rules to the list for the opcodes to which they apply. + // Note that the order in which rules are added to the list matters. If a rule + // applies to the instruction, the rest of the rules will not be attempted. + // Take that into consideration. + + rules_[spv::Op::OpCompositeConstruct].push_back(FoldCompositeWithConstants()); + + rules_[spv::Op::OpCompositeExtract].push_back(FoldExtractWithConstants()); + rules_[spv::Op::OpCompositeInsert].push_back(FoldInsertWithConstants()); + + rules_[spv::Op::OpConvertFToS].push_back(FoldFToI()); + rules_[spv::Op::OpConvertFToU].push_back(FoldFToI()); + rules_[spv::Op::OpConvertSToF].push_back(FoldIToF()); + rules_[spv::Op::OpConvertUToF].push_back(FoldIToF()); + rules_[spv::Op::OpSConvert].push_back(FoldUnaryOp(FoldScalarSConvert)); + rules_[spv::Op::OpUConvert].push_back(FoldUnaryOp(FoldScalarUConvert)); + + rules_[spv::Op::OpDot].push_back(FoldOpDotWithConstants()); + rules_[spv::Op::OpFAdd].push_back(FoldFAdd()); + rules_[spv::Op::OpFDiv].push_back(FoldFDiv()); + rules_[spv::Op::OpFMul].push_back(FoldFMul()); + rules_[spv::Op::OpFSub].push_back(FoldFSub()); + + rules_[spv::Op::OpFOrdEqual].push_back(FoldFOrdEqual()); + + rules_[spv::Op::OpFUnordEqual].push_back(FoldFUnordEqual()); + + rules_[spv::Op::OpFOrdNotEqual].push_back(FoldFOrdNotEqual()); + + rules_[spv::Op::OpFUnordNotEqual].push_back(FoldFUnordNotEqual()); + + rules_[spv::Op::OpFOrdLessThan].push_back(FoldFOrdLessThan()); + rules_[spv::Op::OpFOrdLessThan].push_back( + FoldFClampFeedingCompare(spv::Op::OpFOrdLessThan)); + + rules_[spv::Op::OpFUnordLessThan].push_back(FoldFUnordLessThan()); + rules_[spv::Op::OpFUnordLessThan].push_back( + FoldFClampFeedingCompare(spv::Op::OpFUnordLessThan)); + + rules_[spv::Op::OpFOrdGreaterThan].push_back(FoldFOrdGreaterThan()); + rules_[spv::Op::OpFOrdGreaterThan].push_back( + FoldFClampFeedingCompare(spv::Op::OpFOrdGreaterThan)); + + rules_[spv::Op::OpFUnordGreaterThan].push_back(FoldFUnordGreaterThan()); + rules_[spv::Op::OpFUnordGreaterThan].push_back( + FoldFClampFeedingCompare(spv::Op::OpFUnordGreaterThan)); + + rules_[spv::Op::OpFOrdLessThanEqual].push_back(FoldFOrdLessThanEqual()); + rules_[spv::Op::OpFOrdLessThanEqual].push_back( + FoldFClampFeedingCompare(spv::Op::OpFOrdLessThanEqual)); + + rules_[spv::Op::OpFUnordLessThanEqual].push_back(FoldFUnordLessThanEqual()); + rules_[spv::Op::OpFUnordLessThanEqual].push_back( + FoldFClampFeedingCompare(spv::Op::OpFUnordLessThanEqual)); + + rules_[spv::Op::OpFOrdGreaterThanEqual].push_back(FoldFOrdGreaterThanEqual()); + rules_[spv::Op::OpFOrdGreaterThanEqual].push_back( + FoldFClampFeedingCompare(spv::Op::OpFOrdGreaterThanEqual)); + + rules_[spv::Op::OpFUnordGreaterThanEqual].push_back( + FoldFUnordGreaterThanEqual()); + rules_[spv::Op::OpFUnordGreaterThanEqual].push_back( + FoldFClampFeedingCompare(spv::Op::OpFUnordGreaterThanEqual)); + + rules_[spv::Op::OpVectorShuffle].push_back(FoldVectorShuffleWithConstants()); + rules_[spv::Op::OpVectorTimesScalar].push_back(FoldVectorTimesScalar()); + rules_[spv::Op::OpVectorTimesMatrix].push_back(FoldVectorTimesMatrix()); + rules_[spv::Op::OpMatrixTimesVector].push_back(FoldMatrixTimesVector()); + rules_[spv::Op::OpTranspose].push_back(FoldTranspose); + + rules_[spv::Op::OpFNegate].push_back(FoldFNegate()); + rules_[spv::Op::OpSNegate].push_back(FoldSNegate()); + rules_[spv::Op::OpQuantizeToF16].push_back(FoldQuantizeToF16()); + + rules_[spv::Op::OpIAdd].push_back( + FoldBinaryOp(FoldBinaryIntegerOperation( + [](uint64_t a, uint64_t b) { return a + b; }))); + rules_[spv::Op::OpISub].push_back( + FoldBinaryOp(FoldBinaryIntegerOperation( + [](uint64_t a, uint64_t b) { return a - b; }))); + rules_[spv::Op::OpIMul].push_back( + FoldBinaryOp(FoldBinaryIntegerOperation( + [](uint64_t a, uint64_t b) { return a * b; }))); + rules_[spv::Op::OpUDiv].push_back( + FoldBinaryOp(FoldBinaryIntegerOperation( + [](uint64_t a, uint64_t b) { return (b != 0 ? a / b : 0); }))); + rules_[spv::Op::OpSDiv].push_back(FoldBinaryOp( + FoldBinaryIntegerOperation([](uint64_t a, uint64_t b) { + return (b != 0 ? static_cast(static_cast(a) / + static_cast(b)) + : 0); + }))); + rules_[spv::Op::OpUMod].push_back( + FoldBinaryOp(FoldBinaryIntegerOperation( + [](uint64_t a, uint64_t b) { return (b != 0 ? a % b : 0); }))); + + rules_[spv::Op::OpSRem].push_back(FoldBinaryOp( + FoldBinaryIntegerOperation([](uint64_t a, uint64_t b) { + return (b != 0 ? static_cast(static_cast(a) % + static_cast(b)) + : 0); + }))); + + rules_[spv::Op::OpSMod].push_back(FoldBinaryOp( + FoldBinaryIntegerOperation([](uint64_t a, uint64_t b) { + if (b == 0) return static_cast(0ull); + + int64_t signed_a = static_cast(a); + int64_t signed_b = static_cast(b); + int64_t result = signed_a % signed_b; + if ((signed_b < 0) != (result < 0)) result += signed_b; + return static_cast(result); + }))); + + // Add rules for GLSLstd450 + FeatureManager* feature_manager = context_->get_feature_mgr(); + uint32_t ext_inst_glslstd450_id = + feature_manager->GetExtInstImportId_GLSLstd450(); + if (ext_inst_glslstd450_id != 0) { + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450FMix}].push_back(FoldFMix()); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450SMin}].push_back( + FoldFPBinaryOp(FoldMin)); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450UMin}].push_back( + FoldFPBinaryOp(FoldMin)); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450FMin}].push_back( + FoldFPBinaryOp(FoldMin)); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450SMax}].push_back( + FoldFPBinaryOp(FoldMax)); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450UMax}].push_back( + FoldFPBinaryOp(FoldMax)); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450FMax}].push_back( + FoldFPBinaryOp(FoldMax)); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450UClamp}].push_back( + FoldClamp1); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450UClamp}].push_back( + FoldClamp2); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450UClamp}].push_back( + FoldClamp3); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450SClamp}].push_back( + FoldClamp1); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450SClamp}].push_back( + FoldClamp2); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450SClamp}].push_back( + FoldClamp3); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450FClamp}].push_back( + FoldClamp1); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450FClamp}].push_back( + FoldClamp2); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450FClamp}].push_back( + FoldClamp3); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Sin}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::sin))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Cos}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::cos))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Tan}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::tan))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Asin}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::asin))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Acos}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::acos))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Atan}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::atan))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Exp}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::exp))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Log}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::log))); + +#ifdef __ANDROID__ + // Android NDK r15c targeting ABI 15 doesn't have full support for C++11 + // (no std::exp2/log2). ::exp2 is available from C99 but ::log2 isn't + // available up until ABI 18 so we use a shim + auto log2_shim = [](double v) -> double { return log(v) / log(2.0); }; + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Exp2}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(::exp2))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Log2}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(log2_shim))); +#else + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Exp2}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::exp2))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Log2}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::log2))); +#endif + + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Sqrt}].push_back( + FoldFPUnaryOp(FoldFTranscendentalUnary(std::sqrt))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Atan2}].push_back( + FoldFPBinaryOp(FoldFTranscendentalBinary(std::atan2))); + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450Pow}].push_back( + FoldFPBinaryOp(FoldFTranscendentalBinary(std::pow))); + } +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/const_folding_rules.h b/thirdparty/glslang/External/spirv-tools/source/opt/const_folding_rules.h new file mode 100644 index 000000000000..fa345321fc9d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/const_folding_rules.h @@ -0,0 +1,136 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_CONST_FOLDING_RULES_H_ +#define SOURCE_OPT_CONST_FOLDING_RULES_H_ + +#include +#include + +#include "source/opt/constants.h" + +namespace spvtools { +namespace opt { + +// Constant Folding Rules: +// +// The folding mechanism is built around the concept of a |ConstantFoldingRule|. +// A constant folding rule is a function that implements a method of simplifying +// an instruction to a constant. +// +// The inputs to a folding rule are: +// |inst| - the instruction to be simplified. +// |constants| - if an in-operands is an id of a constant, then the +// corresponding value in |constants| contains that +// constant value. Otherwise, the corresponding entry in +// |constants| is |nullptr|. +// +// A constant folding rule returns a pointer to an Constant if |inst| can be +// simplified using this rule. Otherwise, it returns |nullptr|. +// +// See const_folding_rules.cpp for examples on how to write a constant folding +// rule. +// +// Be sure to add new constant folding rules to the table of constant folding +// rules in the constructor for ConstantFoldingRules. The new rule should be +// added to the list for every opcode that it applies to. Note that earlier +// rules in the list are given priority. That is, if an earlier rule is able to +// fold an instruction, the later rules will not be attempted. + +using ConstantFoldingRule = std::function& constants)>; + +class ConstantFoldingRules { + protected: + // The |Key| and |Value| structs are used to by-pass a "decorated name length + // exceeded, name was truncated" warning on VS2013 and VS2015. + struct Key { + uint32_t instruction_set; + uint32_t opcode; + }; + + friend bool operator<(const Key& a, const Key& b) { + if (a.instruction_set < b.instruction_set) { + return true; + } + if (a.instruction_set > b.instruction_set) { + return false; + } + return a.opcode < b.opcode; + } + + struct Value { + std::vector value; + void push_back(ConstantFoldingRule rule) { value.push_back(rule); } + }; + + public: + ConstantFoldingRules(IRContext* ctx) : context_(ctx) {} + virtual ~ConstantFoldingRules() = default; + + // Returns true if there is at least 1 folding rule for |opcode|. + bool HasFoldingRule(const Instruction* inst) const { + return !GetRulesForInstruction(inst).empty(); + } + + // Returns true if there is at least 1 folding rule for |inst|. + const std::vector& GetRulesForInstruction( + const Instruction* inst) const { + if (inst->opcode() != spv::Op::OpExtInst) { + auto it = rules_.find(inst->opcode()); + if (it != rules_.end()) { + return it->second.value; + } + } else { + uint32_t ext_inst_id = inst->GetSingleWordInOperand(0); + uint32_t ext_opcode = inst->GetSingleWordInOperand(1); + auto it = ext_rules_.find({ext_inst_id, ext_opcode}); + if (it != ext_rules_.end()) { + return it->second.value; + } + } + return empty_vector_; + } + + // Add the folding rules. + virtual void AddFoldingRules(); + + protected: + struct hasher { + size_t operator()(const spv::Op& op) const noexcept { + return std::hash()(uint32_t(op)); + } + }; + + // |rules[opcode]| is the set of rules that can be applied to instructions + // with |opcode| as the opcode. + std::unordered_map rules_; + + // The folding rules for extended instructions. + std::map ext_rules_; + + private: + // The context that the instruction to be folded will be a part of. + IRContext* context_; + + // The empty set of rules to be used as the default return value in + // |GetRulesForInstruction|. + std::vector empty_vector_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_CONST_FOLDING_RULES_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/constants.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/constants.cpp new file mode 100644 index 000000000000..a487a45b885c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/constants.cpp @@ -0,0 +1,551 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/constants.h" + +#include + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace analysis { + +float Constant::GetFloat() const { + assert(type()->AsFloat() != nullptr && type()->AsFloat()->width() == 32); + + if (const FloatConstant* fc = AsFloatConstant()) { + return fc->GetFloatValue(); + } else { + assert(AsNullConstant() && "Must be a floating point constant."); + return 0.0f; + } +} + +double Constant::GetDouble() const { + assert(type()->AsFloat() != nullptr && type()->AsFloat()->width() == 64); + + if (const FloatConstant* fc = AsFloatConstant()) { + return fc->GetDoubleValue(); + } else { + assert(AsNullConstant() && "Must be a floating point constant."); + return 0.0; + } +} + +double Constant::GetValueAsDouble() const { + assert(type()->AsFloat() != nullptr); + if (type()->AsFloat()->width() == 32) { + return GetFloat(); + } else { + assert(type()->AsFloat()->width() == 64); + return GetDouble(); + } +} + +uint32_t Constant::GetU32() const { + assert(type()->AsInteger() != nullptr); + assert(type()->AsInteger()->width() == 32); + + if (const IntConstant* ic = AsIntConstant()) { + return ic->GetU32BitValue(); + } else { + assert(AsNullConstant() && "Must be an integer constant."); + return 0u; + } +} + +uint64_t Constant::GetU64() const { + assert(type()->AsInteger() != nullptr); + assert(type()->AsInteger()->width() == 64); + + if (const IntConstant* ic = AsIntConstant()) { + return ic->GetU64BitValue(); + } else { + assert(AsNullConstant() && "Must be an integer constant."); + return 0u; + } +} + +int32_t Constant::GetS32() const { + assert(type()->AsInteger() != nullptr); + assert(type()->AsInteger()->width() == 32); + + if (const IntConstant* ic = AsIntConstant()) { + return ic->GetS32BitValue(); + } else { + assert(AsNullConstant() && "Must be an integer constant."); + return 0; + } +} + +int64_t Constant::GetS64() const { + assert(type()->AsInteger() != nullptr); + assert(type()->AsInteger()->width() == 64); + + if (const IntConstant* ic = AsIntConstant()) { + return ic->GetS64BitValue(); + } else { + assert(AsNullConstant() && "Must be an integer constant."); + return 0; + } +} + +uint64_t Constant::GetZeroExtendedValue() const { + const auto* int_type = type()->AsInteger(); + assert(int_type != nullptr); + const auto width = int_type->width(); + assert(width <= 64); + + uint64_t value = 0; + if (const IntConstant* ic = AsIntConstant()) { + if (width <= 32) { + value = ic->GetU32BitValue(); + } else { + value = ic->GetU64BitValue(); + } + } else { + assert(AsNullConstant() && "Must be an integer constant."); + } + return value; +} + +int64_t Constant::GetSignExtendedValue() const { + const auto* int_type = type()->AsInteger(); + assert(int_type != nullptr); + const auto width = int_type->width(); + assert(width <= 64); + + int64_t value = 0; + if (const IntConstant* ic = AsIntConstant()) { + if (width <= 32) { + // Let the C++ compiler do the sign extension. + value = int64_t(ic->GetS32BitValue()); + } else { + value = ic->GetS64BitValue(); + } + } else { + assert(AsNullConstant() && "Must be an integer constant."); + } + return value; +} + +ConstantManager::ConstantManager(IRContext* ctx) : ctx_(ctx) { + // Populate the constant table with values from constant declarations in the + // module. The values of each OpConstant declaration is the identity + // assignment (i.e., each constant is its own value). + for (const auto& inst : ctx_->module()->GetConstants()) { + MapInst(inst); + } +} + +Type* ConstantManager::GetType(const Instruction* inst) const { + return context()->get_type_mgr()->GetType(inst->type_id()); +} + +std::vector ConstantManager::GetOperandConstants( + const Instruction* inst) const { + std::vector constants; + constants.reserve(inst->NumInOperands()); + for (uint32_t i = 0; i < inst->NumInOperands(); i++) { + const Operand* operand = &inst->GetInOperand(i); + if (operand->type != SPV_OPERAND_TYPE_ID) { + constants.push_back(nullptr); + } else { + uint32_t id = operand->words[0]; + const analysis::Constant* constant = FindDeclaredConstant(id); + constants.push_back(constant); + } + } + return constants; +} + +uint32_t ConstantManager::FindDeclaredConstant(const Constant* c, + uint32_t type_id) const { + c = FindConstant(c); + if (c == nullptr) { + return 0; + } + + for (auto range = const_val_to_id_.equal_range(c); + range.first != range.second; ++range.first) { + Instruction* const_def = + context()->get_def_use_mgr()->GetDef(range.first->second); + if (type_id == 0 || const_def->type_id() == type_id) { + return range.first->second; + } + } + return 0; +} + +std::vector ConstantManager::GetConstantsFromIds( + const std::vector& ids) const { + std::vector constants; + for (uint32_t id : ids) { + if (const Constant* c = FindDeclaredConstant(id)) { + constants.push_back(c); + } else { + return {}; + } + } + return constants; +} + +Instruction* ConstantManager::BuildInstructionAndAddToModule( + const Constant* new_const, Module::inst_iterator* pos, uint32_t type_id) { + // TODO(1841): Handle id overflow. + uint32_t new_id = context()->TakeNextId(); + if (new_id == 0) { + return nullptr; + } + + auto new_inst = CreateInstruction(new_id, new_const, type_id); + if (!new_inst) { + return nullptr; + } + auto* new_inst_ptr = new_inst.get(); + *pos = pos->InsertBefore(std::move(new_inst)); + ++(*pos); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(new_inst_ptr); + MapConstantToInst(new_const, new_inst_ptr); + return new_inst_ptr; +} + +Instruction* ConstantManager::GetDefiningInstruction( + const Constant* c, uint32_t type_id, Module::inst_iterator* pos) { + uint32_t decl_id = FindDeclaredConstant(c, type_id); + if (decl_id == 0) { + auto iter = context()->types_values_end(); + if (pos == nullptr) pos = &iter; + return BuildInstructionAndAddToModule(c, pos, type_id); + } else { + auto def = context()->get_def_use_mgr()->GetDef(decl_id); + assert(def != nullptr); + assert((type_id == 0 || def->type_id() == type_id) && + "This constant already has an instruction with a different type."); + return def; + } +} + +std::unique_ptr ConstantManager::CreateConstant( + const Type* type, const std::vector& literal_words_or_ids) const { + if (literal_words_or_ids.size() == 0) { + // Constant declared with OpConstantNull + return MakeUnique(type); + } else if (auto* bt = type->AsBool()) { + assert(literal_words_or_ids.size() == 1 && + "Bool constant should be declared with one operand"); + return MakeUnique(bt, literal_words_or_ids.front()); + } else if (auto* it = type->AsInteger()) { + return MakeUnique(it, literal_words_or_ids); + } else if (auto* ft = type->AsFloat()) { + return MakeUnique(ft, literal_words_or_ids); + } else if (auto* vt = type->AsVector()) { + auto components = GetConstantsFromIds(literal_words_or_ids); + if (components.empty()) return nullptr; + // All components of VectorConstant must be of type Bool, Integer or Float. + if (!std::all_of(components.begin(), components.end(), + [](const Constant* c) { + if (c->type()->AsBool() || c->type()->AsInteger() || + c->type()->AsFloat()) { + return true; + } else { + return false; + } + })) + return nullptr; + // All components of VectorConstant must be in the same type. + const auto* component_type = components.front()->type(); + if (!std::all_of(components.begin(), components.end(), + [&component_type](const Constant* c) { + if (c->type() == component_type) return true; + return false; + })) + return nullptr; + return MakeUnique(vt, components); + } else if (auto* mt = type->AsMatrix()) { + auto components = GetConstantsFromIds(literal_words_or_ids); + if (components.empty()) return nullptr; + return MakeUnique(mt, components); + } else if (auto* st = type->AsStruct()) { + auto components = GetConstantsFromIds(literal_words_or_ids); + if (components.empty()) return nullptr; + return MakeUnique(st, components); + } else if (auto* at = type->AsArray()) { + auto components = GetConstantsFromIds(literal_words_or_ids); + if (components.empty()) return nullptr; + return MakeUnique(at, components); + } else { + return nullptr; + } +} + +const Constant* ConstantManager::GetConstantFromInst(const Instruction* inst) { + std::vector literal_words_or_ids; + + // Collect the constant defining literals or component ids. + for (uint32_t i = 0; i < inst->NumInOperands(); i++) { + literal_words_or_ids.insert(literal_words_or_ids.end(), + inst->GetInOperand(i).words.begin(), + inst->GetInOperand(i).words.end()); + } + + switch (inst->opcode()) { + // OpConstant{True|False} have the value embedded in the opcode. So they + // are not handled by the for-loop above. Here we add the value explicitly. + case spv::Op::OpConstantTrue: + literal_words_or_ids.push_back(true); + break; + case spv::Op::OpConstantFalse: + literal_words_or_ids.push_back(false); + break; + case spv::Op::OpConstantNull: + case spv::Op::OpConstant: + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: + break; + default: + return nullptr; + } + + return GetConstant(GetType(inst), literal_words_or_ids); +} + +std::unique_ptr ConstantManager::CreateInstruction( + uint32_t id, const Constant* c, uint32_t type_id) const { + uint32_t type = + (type_id == 0) ? context()->get_type_mgr()->GetId(c->type()) : type_id; + if (c->AsNullConstant()) { + return MakeUnique(context(), spv::Op::OpConstantNull, type, id, + std::initializer_list{}); + } else if (const BoolConstant* bc = c->AsBoolConstant()) { + return MakeUnique( + context(), + bc->value() ? spv::Op::OpConstantTrue : spv::Op::OpConstantFalse, type, + id, std::initializer_list{}); + } else if (const IntConstant* ic = c->AsIntConstant()) { + return MakeUnique( + context(), spv::Op::OpConstant, type, id, + std::initializer_list{ + Operand(spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, + ic->words())}); + } else if (const FloatConstant* fc = c->AsFloatConstant()) { + return MakeUnique( + context(), spv::Op::OpConstant, type, id, + std::initializer_list{ + Operand(spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, + fc->words())}); + } else if (const CompositeConstant* cc = c->AsCompositeConstant()) { + return CreateCompositeInstruction(id, cc, type_id); + } else { + return nullptr; + } +} + +std::unique_ptr ConstantManager::CreateCompositeInstruction( + uint32_t result_id, const CompositeConstant* cc, uint32_t type_id) const { + std::vector operands; + Instruction* type_inst = context()->get_def_use_mgr()->GetDef(type_id); + uint32_t component_index = 0; + for (const Constant* component_const : cc->GetComponents()) { + uint32_t component_type_id = 0; + if (type_inst && type_inst->opcode() == spv::Op::OpTypeStruct) { + component_type_id = type_inst->GetSingleWordInOperand(component_index); + } else if (type_inst && type_inst->opcode() == spv::Op::OpTypeArray) { + component_type_id = type_inst->GetSingleWordInOperand(0); + } + uint32_t id = FindDeclaredConstant(component_const, component_type_id); + + if (id == 0) { + // Cannot get the id of the component constant, while all components + // should have been added to the module prior to the composite constant. + // Cannot create OpConstantComposite instruction in this case. + return nullptr; + } + operands.emplace_back(spv_operand_type_t::SPV_OPERAND_TYPE_ID, + std::initializer_list{id}); + component_index++; + } + uint32_t type = + (type_id == 0) ? context()->get_type_mgr()->GetId(cc->type()) : type_id; + return MakeUnique(context(), spv::Op::OpConstantComposite, type, + result_id, std::move(operands)); +} + +const Constant* ConstantManager::GetConstant( + const Type* type, const std::vector& literal_words_or_ids) { + auto cst = CreateConstant(type, literal_words_or_ids); + return cst ? RegisterConstant(std::move(cst)) : nullptr; +} + +const Constant* ConstantManager::GetNullCompositeConstant(const Type* type) { + std::vector literal_words_or_id; + + if (type->AsVector()) { + const Type* element_type = type->AsVector()->element_type(); + const uint32_t null_id = GetNullConstId(element_type); + const uint32_t element_count = type->AsVector()->element_count(); + for (uint32_t i = 0; i < element_count; i++) { + literal_words_or_id.push_back(null_id); + } + } else if (type->AsMatrix()) { + const Type* element_type = type->AsMatrix()->element_type(); + const uint32_t null_id = GetNullConstId(element_type); + const uint32_t element_count = type->AsMatrix()->element_count(); + for (uint32_t i = 0; i < element_count; i++) { + literal_words_or_id.push_back(null_id); + } + } else if (type->AsStruct()) { + // TODO (sfricke-lunarg) add proper struct support + return nullptr; + } else if (type->AsArray()) { + const Type* element_type = type->AsArray()->element_type(); + const uint32_t null_id = GetNullConstId(element_type); + assert(type->AsArray()->length_info().words[0] == + analysis::Array::LengthInfo::kConstant && + "unexpected array length"); + const uint32_t element_count = type->AsArray()->length_info().words[0]; + for (uint32_t i = 0; i < element_count; i++) { + literal_words_or_id.push_back(null_id); + } + } else { + return nullptr; + } + + return GetConstant(type, literal_words_or_id); +} + +const Constant* ConstantManager::GetNumericVectorConstantWithWords( + const Vector* type, const std::vector& literal_words) { + const auto* element_type = type->element_type(); + uint32_t words_per_element = 0; + if (const auto* float_type = element_type->AsFloat()) + words_per_element = float_type->width() / 32; + else if (const auto* int_type = element_type->AsInteger()) + words_per_element = int_type->width() / 32; + else if (element_type->AsBool() != nullptr) + words_per_element = 1; + + if (words_per_element != 1 && words_per_element != 2) return nullptr; + + if (words_per_element * type->element_count() != + static_cast(literal_words.size())) { + return nullptr; + } + + std::vector element_ids; + for (uint32_t i = 0; i < type->element_count(); ++i) { + auto first_word = literal_words.begin() + (words_per_element * i); + std::vector const_data(first_word, + first_word + words_per_element); + const analysis::Constant* element_constant = + GetConstant(element_type, const_data); + auto element_id = GetDefiningInstruction(element_constant)->result_id(); + element_ids.push_back(element_id); + } + + return GetConstant(type, element_ids); +} + +uint32_t ConstantManager::GetFloatConstId(float val) { + const Constant* c = GetFloatConst(val); + return GetDefiningInstruction(c)->result_id(); +} + +const Constant* ConstantManager::GetFloatConst(float val) { + Type* float_type = context()->get_type_mgr()->GetFloatType(); + utils::FloatProxy v(val); + const Constant* c = GetConstant(float_type, v.GetWords()); + return c; +} + +uint32_t ConstantManager::GetDoubleConstId(double val) { + const Constant* c = GetDoubleConst(val); + return GetDefiningInstruction(c)->result_id(); +} + +const Constant* ConstantManager::GetDoubleConst(double val) { + Type* float_type = context()->get_type_mgr()->GetDoubleType(); + utils::FloatProxy v(val); + const Constant* c = GetConstant(float_type, v.GetWords()); + return c; +} + +uint32_t ConstantManager::GetSIntConstId(int32_t val) { + Type* sint_type = context()->get_type_mgr()->GetSIntType(); + const Constant* c = GetConstant(sint_type, {static_cast(val)}); + return GetDefiningInstruction(c)->result_id(); +} + +const Constant* ConstantManager::GetIntConst(uint64_t val, int32_t bitWidth, + bool isSigned) { + Type* int_type = context()->get_type_mgr()->GetIntType(bitWidth, isSigned); + + if (isSigned) { + // Sign extend the value. + int32_t num_of_bit_to_ignore = 64 - bitWidth; + val = static_cast(val << num_of_bit_to_ignore) >> + num_of_bit_to_ignore; + } else { + // Clear the upper bit that are not used. + uint64_t mask = ((1ull << bitWidth) - 1); + val &= mask; + } + + if (bitWidth <= 32) { + return GetConstant(int_type, {static_cast(val)}); + } + + // If the value is more than 32-bit, we need to split the operands into two + // 32-bit integers. + return GetConstant( + int_type, {static_cast(val >> 32), static_cast(val)}); +} + +uint32_t ConstantManager::GetUIntConstId(uint32_t val) { + Type* uint_type = context()->get_type_mgr()->GetUIntType(); + const Constant* c = GetConstant(uint_type, {val}); + return GetDefiningInstruction(c)->result_id(); +} + +uint32_t ConstantManager::GetNullConstId(const Type* type) { + const Constant* c = GetConstant(type, {}); + return GetDefiningInstruction(c)->result_id(); +} + +std::vector Constant::GetVectorComponents( + analysis::ConstantManager* const_mgr) const { + std::vector components; + const analysis::VectorConstant* a = this->AsVectorConstant(); + const analysis::Vector* vector_type = this->type()->AsVector(); + assert(vector_type != nullptr); + if (a != nullptr) { + for (uint32_t i = 0; i < vector_type->element_count(); ++i) { + components.push_back(a->GetComponents()[i]); + } + } else { + const analysis::Type* element_type = vector_type->element_type(); + const analysis::Constant* element_null_const = + const_mgr->GetConstant(element_type, {}); + for (uint32_t i = 0; i < vector_type->element_count(); ++i) { + components.push_back(element_null_const); + } + } + return components; +} + +} // namespace analysis +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/constants.h b/thirdparty/glslang/External/spirv-tools/source/opt/constants.h new file mode 100644 index 000000000000..ae8dc6259d9f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/constants.h @@ -0,0 +1,744 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_CONSTANTS_H_ +#define SOURCE_OPT_CONSTANTS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/module.h" +#include "source/opt/type_manager.h" +#include "source/opt/types.h" +#include "source/util/hex_float.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { + +class IRContext; + +namespace analysis { + +// Class hierarchy to represent the normal constants defined through +// OpConstantTrue, OpConstantFalse, OpConstant, OpConstantNull and +// OpConstantComposite instructions. +// TODO(qining): Add class for constants defined with OpConstantSampler. +class Constant; +class ScalarConstant; +class IntConstant; +class FloatConstant; +class BoolConstant; +class CompositeConstant; +class StructConstant; +class VectorConstant; +class MatrixConstant; +class ArrayConstant; +class NullConstant; +class ConstantManager; + +// Abstract class for a SPIR-V constant. It has a bunch of As methods, +// which is used as a way to probe the actual +class Constant { + public: + Constant() = delete; + virtual ~Constant() = default; + + // Make a deep copy of this constant. + virtual std::unique_ptr Copy() const = 0; + + // reflections + virtual ScalarConstant* AsScalarConstant() { return nullptr; } + virtual IntConstant* AsIntConstant() { return nullptr; } + virtual FloatConstant* AsFloatConstant() { return nullptr; } + virtual BoolConstant* AsBoolConstant() { return nullptr; } + virtual CompositeConstant* AsCompositeConstant() { return nullptr; } + virtual StructConstant* AsStructConstant() { return nullptr; } + virtual VectorConstant* AsVectorConstant() { return nullptr; } + virtual MatrixConstant* AsMatrixConstant() { return nullptr; } + virtual ArrayConstant* AsArrayConstant() { return nullptr; } + virtual NullConstant* AsNullConstant() { return nullptr; } + + virtual const ScalarConstant* AsScalarConstant() const { return nullptr; } + virtual const IntConstant* AsIntConstant() const { return nullptr; } + virtual const FloatConstant* AsFloatConstant() const { return nullptr; } + virtual const BoolConstant* AsBoolConstant() const { return nullptr; } + virtual const CompositeConstant* AsCompositeConstant() const { + return nullptr; + } + virtual const StructConstant* AsStructConstant() const { return nullptr; } + virtual const VectorConstant* AsVectorConstant() const { return nullptr; } + virtual const MatrixConstant* AsMatrixConstant() const { return nullptr; } + virtual const ArrayConstant* AsArrayConstant() const { return nullptr; } + virtual const NullConstant* AsNullConstant() const { return nullptr; } + + // Returns the float representation of the constant. Must be a 32 bit + // Float type. + float GetFloat() const; + + // Returns the double representation of the constant. Must be a 64 bit + // Float type. + double GetDouble() const; + + // Returns the double representation of the constant. Must be a 32-bit or + // 64-bit Float type. + double GetValueAsDouble() const; + + // Returns uint32_t representation of the constant. Must be a 32 bit + // Integer type. + uint32_t GetU32() const; + + // Returns uint64_t representation of the constant. Must be a 64 bit + // Integer type. + uint64_t GetU64() const; + + // Returns int32_t representation of the constant. Must be a 32 bit + // Integer type. + int32_t GetS32() const; + + // Returns int64_t representation of the constant. Must be a 64 bit + // Integer type. + int64_t GetS64() const; + + // Returns the zero-extended representation of an integer constant. Must + // be an integral constant of at most 64 bits. + uint64_t GetZeroExtendedValue() const; + + // Returns the sign-extended representation of an integer constant. Must + // be an integral constant of at most 64 bits. + int64_t GetSignExtendedValue() const; + + // Returns true if the constant is a zero or a composite containing 0s. + virtual bool IsZero() const { return false; } + + const Type* type() const { return type_; } + + // Returns an std::vector containing the elements of |constant|. The type of + // |constant| must be |Vector|. + std::vector GetVectorComponents( + ConstantManager* const_mgr) const; + + protected: + Constant(const Type* ty) : type_(ty) {} + + // The type of this constant. + const Type* type_; +}; + +// Abstract class for scalar type constants. +class ScalarConstant : public Constant { + public: + ScalarConstant() = delete; + ScalarConstant* AsScalarConstant() override { return this; } + const ScalarConstant* AsScalarConstant() const override { return this; } + + // Returns a const reference of the value of this constant in 32-bit words. + virtual const std::vector& words() const { return words_; } + + // Returns true if the value is zero. + bool IsZero() const override { + bool is_zero = true; + for (uint32_t v : words()) { + if (v != 0) { + is_zero = false; + break; + } + } + return is_zero; + } + + uint32_t GetU32BitValue() const { + // Relies on unsigned values smaller than 32-bit being zero extended. See + // section 2.2.1 of the SPIR-V spec. + assert(words().size() == 1); + return words()[0]; + } + + uint64_t GetU64BitValue() const { + // Relies on unsigned values smaller than 64-bit being zero extended. See + // section 2.2.1 of the SPIR-V spec. + assert(words().size() == 2); + return static_cast(words()[1]) << 32 | + static_cast(words()[0]); + } + + protected: + ScalarConstant(const Type* ty, const std::vector& w) + : Constant(ty), words_(w) {} + ScalarConstant(const Type* ty, std::vector&& w) + : Constant(ty), words_(std::move(w)) {} + std::vector words_; +}; + +// Integer type constant. +class IntConstant : public ScalarConstant { + public: + IntConstant(const Integer* ty, const std::vector& w) + : ScalarConstant(ty, w) {} + IntConstant(const Integer* ty, std::vector&& w) + : ScalarConstant(ty, std::move(w)) {} + + IntConstant* AsIntConstant() override { return this; } + const IntConstant* AsIntConstant() const override { return this; } + + int32_t GetS32BitValue() const { + // Relies on signed values smaller than 32-bit being sign extended. See + // section 2.2.1 of the SPIR-V spec. + assert(words().size() == 1); + return words()[0]; + } + + int64_t GetS64BitValue() const { + // Relies on unsigned values smaller than 64-bit being sign extended. See + // section 2.2.1 of the SPIR-V spec. + assert(words().size() == 2); + return static_cast(words()[1]) << 32 | + static_cast(words()[0]); + } + + // Make a copy of this IntConstant instance. + std::unique_ptr CopyIntConstant() const { + return MakeUnique(type_->AsInteger(), words_); + } + std::unique_ptr Copy() const override { + return std::unique_ptr(CopyIntConstant().release()); + } +}; + +// Float type constant. +class FloatConstant : public ScalarConstant { + public: + FloatConstant(const Float* ty, const std::vector& w) + : ScalarConstant(ty, w) {} + FloatConstant(const Float* ty, std::vector&& w) + : ScalarConstant(ty, std::move(w)) {} + + FloatConstant* AsFloatConstant() override { return this; } + const FloatConstant* AsFloatConstant() const override { return this; } + + // Make a copy of this FloatConstant instance. + std::unique_ptr CopyFloatConstant() const { + return MakeUnique(type_->AsFloat(), words_); + } + std::unique_ptr Copy() const override { + return std::unique_ptr(CopyFloatConstant().release()); + } + + // Returns the float value of |this|. The type of |this| must be |Float| with + // width of 32. + float GetFloatValue() const { + assert(type()->AsFloat()->width() == 32 && + "Not a 32-bit floating point value."); + utils::FloatProxy a(words()[0]); + return a.getAsFloat(); + } + + // Returns the double value of |this|. The type of |this| must be |Float| + // with width of 64. + double GetDoubleValue() const { + assert(type()->AsFloat()->width() == 64 && + "Not a 32-bit floating point value."); + uint64_t combined_words = words()[1]; + combined_words = combined_words << 32; + combined_words |= words()[0]; + utils::FloatProxy a(combined_words); + return a.getAsFloat(); + } +}; + +// Bool type constant. +class BoolConstant : public ScalarConstant { + public: + BoolConstant(const Bool* ty, bool v) + : ScalarConstant(ty, {static_cast(v)}), value_(v) {} + + BoolConstant* AsBoolConstant() override { return this; } + const BoolConstant* AsBoolConstant() const override { return this; } + + // Make a copy of this BoolConstant instance. + std::unique_ptr CopyBoolConstant() const { + return MakeUnique(type_->AsBool(), value_); + } + std::unique_ptr Copy() const override { + return std::unique_ptr(CopyBoolConstant().release()); + } + + bool value() const { return value_; } + + private: + bool value_; +}; + +// Abstract class for composite constants. +class CompositeConstant : public Constant { + public: + CompositeConstant() = delete; + CompositeConstant* AsCompositeConstant() override { return this; } + const CompositeConstant* AsCompositeConstant() const override { return this; } + + // Returns a const reference of the components held in this composite + // constant. + virtual const std::vector& GetComponents() const { + return components_; + } + + bool IsZero() const override { + for (const Constant* c : GetComponents()) { + if (!c->IsZero()) { + return false; + } + } + return true; + } + + protected: + CompositeConstant(const Type* ty) : Constant(ty), components_() {} + CompositeConstant(const Type* ty, + const std::vector& components) + : Constant(ty), components_(components) {} + CompositeConstant(const Type* ty, std::vector&& components) + : Constant(ty), components_(std::move(components)) {} + std::vector components_; +}; + +// Struct type constant. +class StructConstant : public CompositeConstant { + public: + StructConstant(const Struct* ty) : CompositeConstant(ty) {} + StructConstant(const Struct* ty, + const std::vector& components) + : CompositeConstant(ty, components) {} + StructConstant(const Struct* ty, std::vector&& components) + : CompositeConstant(ty, std::move(components)) {} + + StructConstant* AsStructConstant() override { return this; } + const StructConstant* AsStructConstant() const override { return this; } + + // Make a copy of this StructConstant instance. + std::unique_ptr CopyStructConstant() const { + return MakeUnique(type_->AsStruct(), components_); + } + std::unique_ptr Copy() const override { + return std::unique_ptr(CopyStructConstant().release()); + } +}; + +// Vector type constant. +class VectorConstant : public CompositeConstant { + public: + VectorConstant(const Vector* ty) + : CompositeConstant(ty), component_type_(ty->element_type()) {} + VectorConstant(const Vector* ty, + const std::vector& components) + : CompositeConstant(ty, components), + component_type_(ty->element_type()) {} + VectorConstant(const Vector* ty, std::vector&& components) + : CompositeConstant(ty, std::move(components)), + component_type_(ty->element_type()) {} + + VectorConstant* AsVectorConstant() override { return this; } + const VectorConstant* AsVectorConstant() const override { return this; } + + // Make a copy of this VectorConstant instance. + std::unique_ptr CopyVectorConstant() const { + auto another = MakeUnique(type_->AsVector()); + another->components_.insert(another->components_.end(), components_.begin(), + components_.end()); + return another; + } + std::unique_ptr Copy() const override { + return std::unique_ptr(CopyVectorConstant().release()); + } + + const Type* component_type() const { return component_type_; } + + private: + const Type* component_type_; +}; + +// Matrix type constant. +class MatrixConstant : public CompositeConstant { + public: + MatrixConstant(const Matrix* ty) + : CompositeConstant(ty), component_type_(ty->element_type()) {} + MatrixConstant(const Matrix* ty, + const std::vector& components) + : CompositeConstant(ty, components), + component_type_(ty->element_type()) {} + MatrixConstant(const Vector* ty, std::vector&& components) + : CompositeConstant(ty, std::move(components)), + component_type_(ty->element_type()) {} + + MatrixConstant* AsMatrixConstant() override { return this; } + const MatrixConstant* AsMatrixConstant() const override { return this; } + + // Make a copy of this MatrixConstant instance. + std::unique_ptr CopyMatrixConstant() const { + auto another = MakeUnique(type_->AsMatrix()); + another->components_.insert(another->components_.end(), components_.begin(), + components_.end()); + return another; + } + std::unique_ptr Copy() const override { + return std::unique_ptr(CopyMatrixConstant().release()); + } + + const Type* component_type() { return component_type_; } + + private: + const Type* component_type_; +}; + +// Array type constant. +class ArrayConstant : public CompositeConstant { + public: + ArrayConstant(const Array* ty) : CompositeConstant(ty) {} + ArrayConstant(const Array* ty, const std::vector& components) + : CompositeConstant(ty, components) {} + ArrayConstant(const Array* ty, std::vector&& components) + : CompositeConstant(ty, std::move(components)) {} + + ArrayConstant* AsArrayConstant() override { return this; } + const ArrayConstant* AsArrayConstant() const override { return this; } + + // Make a copy of this ArrayConstant instance. + std::unique_ptr CopyArrayConstant() const { + return MakeUnique(type_->AsArray(), components_); + } + std::unique_ptr Copy() const override { + return std::unique_ptr(CopyArrayConstant().release()); + } +}; + +// Null type constant. +class NullConstant : public Constant { + public: + NullConstant(const Type* ty) : Constant(ty) {} + NullConstant* AsNullConstant() override { return this; } + const NullConstant* AsNullConstant() const override { return this; } + + // Make a copy of this NullConstant instance. + std::unique_ptr CopyNullConstant() const { + return MakeUnique(type_); + } + std::unique_ptr Copy() const override { + return std::unique_ptr(CopyNullConstant().release()); + } + bool IsZero() const override { return true; } +}; + +// Hash function for Constant instances. Use the structure of the constant as +// the key. +struct ConstantHash { + void add_pointer(std::u32string* h, const void* p) const { + uint64_t ptr_val = reinterpret_cast(p); + h->push_back(static_cast(ptr_val >> 32)); + h->push_back(static_cast(ptr_val)); + } + + size_t operator()(const Constant* const_val) const { + std::u32string h; + add_pointer(&h, const_val->type()); + if (const auto scalar = const_val->AsScalarConstant()) { + for (const auto& w : scalar->words()) { + h.push_back(w); + } + } else if (const auto composite = const_val->AsCompositeConstant()) { + for (const auto& c : composite->GetComponents()) { + add_pointer(&h, c); + } + } else if (const_val->AsNullConstant()) { + h.push_back(0); + } else { + assert( + false && + "Tried to compute the hash value of an invalid Constant instance."); + } + + return std::hash()(h); + } +}; + +// Equality comparison structure for two constants. +struct ConstantEqual { + bool operator()(const Constant* c1, const Constant* c2) const { + if (c1->type() != c2->type()) { + return false; + } + + if (const auto& s1 = c1->AsScalarConstant()) { + const auto& s2 = c2->AsScalarConstant(); + return s2 && s1->words() == s2->words(); + } else if (const auto& composite1 = c1->AsCompositeConstant()) { + const auto& composite2 = c2->AsCompositeConstant(); + return composite2 && + composite1->GetComponents() == composite2->GetComponents(); + } else if (c1->AsNullConstant()) { + return c2->AsNullConstant() != nullptr; + } else { + assert(false && "Tried to compare two invalid Constant instances."); + } + return false; + } +}; + +// This class represents a pool of constants. +class ConstantManager { + public: + ConstantManager(IRContext* ctx); + + IRContext* context() const { return ctx_; } + + // Gets or creates a unique Constant instance of type |type| and a vector of + // constant defining words or ids for elements of Vector type + // |literal_words_or_ids|. If a Constant instance existed already in the + // constant pool, it returns a pointer to it. Otherwise, it creates one using + // CreateConstant. If a new Constant instance cannot be created, it returns + // nullptr. + const Constant* GetConstant( + const Type* type, const std::vector& literal_words_or_ids); + + template + const Constant* GetConstant(const Type* type, const C& literal_words_or_ids) { + return GetConstant(type, std::vector(literal_words_or_ids.begin(), + literal_words_or_ids.end())); + } + + // Takes a type and creates a OpConstantComposite + // This allows a + // OpConstantNull %composite_type + // to become a + // OpConstantComposite %composite_type %null %null ... etc + // Assumes type is a Composite already, otherwise returns null + const Constant* GetNullCompositeConstant(const Type* type); + + // Gets or creates a unique Constant instance of Vector type |type| with + // numeric elements and a vector of constant defining words |literal_words|. + // If a Constant instance existed already in the constant pool, it returns a + // pointer to it. Otherwise, it creates one using CreateConstant. If a new + // Constant instance cannot be created, it returns nullptr. + const Constant* GetNumericVectorConstantWithWords( + const Vector* type, const std::vector& literal_words); + + // Gets or creates a Constant instance to hold the constant value of the given + // instruction. It returns a pointer to a Constant instance or nullptr if it + // could not create the constant. + const Constant* GetConstantFromInst(const Instruction* inst); + + // Gets or creates a constant defining instruction for the given Constant |c|. + // If |c| had already been defined, it returns a pointer to the existing + // declaration. Otherwise, it calls BuildInstructionAndAddToModule. If the + // optional |pos| is given, it will insert any newly created instructions at + // the given instruction iterator position. Otherwise, it inserts the new + // instruction at the end of the current module's types section. + // + // |type_id| is an optional argument for disambiguating equivalent types. If + // |type_id| is specified, the constant returned will have that type id. + Instruction* GetDefiningInstruction(const Constant* c, uint32_t type_id = 0, + Module::inst_iterator* pos = nullptr); + + // Creates a constant defining instruction for the given Constant instance + // and inserts the instruction at the position specified by the given + // instruction iterator. Returns a pointer to the created instruction if + // succeeded, otherwise returns a null pointer. The instruction iterator + // points to the same instruction before and after the insertion. This is the + // only method that actually manages id creation/assignment and instruction + // creation/insertion for a new Constant instance. + // + // |type_id| is an optional argument for disambiguating equivalent types. If + // |type_id| is specified, it is used as the type of the constant. Otherwise + // the type of the constant is derived by getting an id from the type manager + // for |c|. + Instruction* BuildInstructionAndAddToModule(const Constant* c, + Module::inst_iterator* pos, + uint32_t type_id = 0); + + // A helper function to get the result type of the given instruction. Returns + // nullptr if the instruction does not have a type id (type id is 0). + Type* GetType(const Instruction* inst) const; + + // A helper function to get the collected normal constant with the given id. + // Returns the pointer to the Constant instance in case it is found. + // Otherwise, it returns a null pointer. + const Constant* FindDeclaredConstant(uint32_t id) const { + auto iter = id_to_const_val_.find(id); + return (iter != id_to_const_val_.end()) ? iter->second : nullptr; + } + + // A helper function to get the id of a collected constant with the pointer + // to the Constant instance. Returns 0 in case the constant is not found. + uint32_t FindDeclaredConstant(const Constant* c, uint32_t type_id) const; + + // Returns the canonical constant that has the same structure and value as the + // given Constant |cst|. If none is found, it returns nullptr. + // + // TODO: Should be able to give a type id to disambiguate types with the same + // structure. + const Constant* FindConstant(const Constant* c) const { + auto it = const_pool_.find(c); + return (it != const_pool_.end()) ? *it : nullptr; + } + + // Registers a new constant |cst| in the constant pool. If the constant + // existed already, it returns a pointer to the previously existing Constant + // in the pool. Otherwise, it returns |cst|. + const Constant* RegisterConstant(std::unique_ptr cst) { + auto ret = const_pool_.insert(cst.get()); + if (ret.second) { + owned_constants_.emplace_back(std::move(cst)); + } + return *ret.first; + } + + // A helper function to get a vector of Constant instances with the specified + // ids. If it can not find the Constant instance for any one of the ids, + // it returns an empty vector. + std::vector GetConstantsFromIds( + const std::vector& ids) const; + + // Returns a vector of constants representing each in operand. If an operand + // is not constant its entry is nullptr. + std::vector GetOperandConstants( + const Instruction* inst) const; + + // Records a mapping between |inst| and the constant value generated by it. + // It returns true if a new Constant was successfully mapped, false if |inst| + // generates no constant values. + bool MapInst(Instruction* inst) { + if (auto cst = GetConstantFromInst(inst)) { + MapConstantToInst(cst, inst); + return true; + } + return false; + } + + void RemoveId(uint32_t id) { + auto it = id_to_const_val_.find(id); + if (it != id_to_const_val_.end()) { + const_val_to_id_.erase(it->second); + id_to_const_val_.erase(it); + } + } + + // Records a new mapping between |inst| and |const_value|. This updates the + // two mappings |id_to_const_val_| and |const_val_to_id_|. + void MapConstantToInst(const Constant* const_value, Instruction* inst) { + if (id_to_const_val_.insert({inst->result_id(), const_value}).second) { + const_val_to_id_.insert({const_value, inst->result_id()}); + } + } + + // Returns the id of a 32-bit floating point constant with value |val|. + uint32_t GetFloatConstId(float val); + + // Returns a 32-bit float constant with the given value. + const Constant* GetFloatConst(float val); + + // Returns the id of a 64-bit floating point constant with value |val|. + uint32_t GetDoubleConstId(double val); + + // Returns a 64-bit float constant with the given value. + const Constant* GetDoubleConst(double val); + + // Returns the id of a 32-bit signed integer constant with value |val|. + uint32_t GetSIntConstId(int32_t val); + + // Returns an integer constant with `bitWidth` and value |val|. If `isSigned` + // is true, the constant will be a signed integer. Otherwise it will be + // unsigned. Only the `bitWidth` lower order bits of |val| will be used. The + // rest will be ignored. + const Constant* GetIntConst(uint64_t val, int32_t bitWidth, bool isSigned); + + // Returns the id of a 32-bit unsigned integer constant with value |val|. + uint32_t GetUIntConstId(uint32_t val); + + // Returns the id of a OpConstantNull with type of |type|. + uint32_t GetNullConstId(const Type* type); + + private: + // Creates a Constant instance with the given type and a vector of constant + // defining words. Returns a unique pointer to the created Constant instance + // if the Constant instance can be created successfully. To create scalar + // type constants, the vector should contain the constant value in 32 bit + // words and the given type must be of type Bool, Integer or Float. To create + // composite type constants, the vector should contain the component ids, and + // those component ids should have been recorded before as Normal Constants. + // And the given type must be of type Struct, Vector or Array. When creating + // VectorType Constant instance, the components must be scalars of the same + // type, either Bool, Integer or Float. If any of the rules above failed, the + // creation will fail and nullptr will be returned. If the vector is empty, + // a NullConstant instance will be created with the given type. + std::unique_ptr CreateConstant( + const Type* type, + const std::vector& literal_words_or_ids) const; + + // Creates an instruction with the given result id to declare a constant + // represented by the given Constant instance. Returns an unique pointer to + // the created instruction if the instruction can be created successfully. + // Otherwise, returns a null pointer. + // + // |type_id| is an optional argument for disambiguating equivalent types. If + // |type_id| is specified, it is used as the type of the constant. Otherwise + // the type of the constant is derived by getting an id from the type manager + // for |c|. + std::unique_ptr CreateInstruction(uint32_t result_id, + const Constant* c, + uint32_t type_id = 0) const; + + // Creates an OpConstantComposite instruction with the given result id and + // the CompositeConst instance which represents a composite constant. Returns + // an unique pointer to the created instruction if succeeded. Otherwise + // returns a null pointer. + // + // |type_id| is an optional argument for disambiguating equivalent types. If + // |type_id| is specified, it is used as the type of the constant. Otherwise + // the type of the constant is derived by getting an id from the type manager + // for |c|. + std::unique_ptr CreateCompositeInstruction( + uint32_t result_id, const CompositeConstant* cc, + uint32_t type_id = 0) const; + + // IR context that owns this constant manager. + IRContext* ctx_; + + // A mapping from the result ids of Normal Constants to their + // Constant instances. All Normal Constants in the module, either + // existing ones before optimization or the newly generated ones, should have + // their Constant instance stored and their result id registered in this map. + std::unordered_map id_to_const_val_; + + // A mapping from the Constant instance of Normal Constants to their + // result id in the module. This is a mirror map of |id_to_const_val_|. All + // Normal Constants that defining instructions in the module should have + // their Constant and their result id registered here. + std::multimap const_val_to_id_; + + // The constant pool. All created constants are registered here. + std::unordered_set const_pool_; + + // The constant that are owned by the constant manager. Every constant in + // |const_pool_| should be in |owned_constants_| as well. + std::vector> owned_constants_; +}; + +} // namespace analysis +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_CONSTANTS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/control_dependence.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/control_dependence.cpp new file mode 100644 index 000000000000..3d48139636a8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/control_dependence.cpp @@ -0,0 +1,153 @@ +// Copyright (c) 2021 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/control_dependence.h" + +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/cfg.h" +#include "source/opt/dominator_analysis.h" +#include "source/opt/function.h" +#include "source/opt/instruction.h" + +// Computes the control dependence graph (CDG) using the algorithm in Cytron +// 1991, "Efficiently Computing Static Single Assignment Form and the Control +// Dependence Graph." It relies on the fact that the control dependence sources +// (blocks on which a block is control dependent) are exactly the post-dominance +// frontier for that block. The explanation and proofs are given in Section 6 of +// that paper. +// Link: https://www.cs.utexas.edu/~pingali/CS380C/2010/papers/ssaCytron.pdf +// +// The algorithm in Section 4.2 of the same paper is used to construct the +// dominance frontier. It uses the post-dominance tree, which is available in +// the IR context. + +namespace spvtools { +namespace opt { +constexpr uint32_t ControlDependenceAnalysis::kPseudoEntryBlock; + +uint32_t ControlDependence::GetConditionID(const CFG& cfg) const { + if (source_bb_id() == 0) { + // Entry dependence; return 0. + return 0; + } + const BasicBlock* source_bb = cfg.block(source_bb_id()); + const Instruction* branch = source_bb->terminator(); + assert((branch->opcode() == spv::Op::OpBranchConditional || + branch->opcode() == spv::Op::OpSwitch) && + "invalid control dependence; last instruction must be conditional " + "branch or switch"); + return branch->GetSingleWordInOperand(0); +} + +bool ControlDependence::operator<(const ControlDependence& other) const { + return std::tie(source_bb_id_, target_bb_id_, branch_target_bb_id_) < + std::tie(other.source_bb_id_, other.target_bb_id_, + other.branch_target_bb_id_); +} + +bool ControlDependence::operator==(const ControlDependence& other) const { + return std::tie(source_bb_id_, target_bb_id_, branch_target_bb_id_) == + std::tie(other.source_bb_id_, other.target_bb_id_, + other.branch_target_bb_id_); +} + +std::ostream& operator<<(std::ostream& os, const ControlDependence& dep) { + os << dep.source_bb_id() << "->" << dep.target_bb_id(); + if (dep.branch_target_bb_id() != dep.target_bb_id()) { + os << " through " << dep.branch_target_bb_id(); + } + return os; +} + +void ControlDependenceAnalysis::ComputePostDominanceFrontiers( + const CFG& cfg, const PostDominatorAnalysis& pdom) { + // Compute post-dominance frontiers (reverse graph). + // The dominance frontier for a block X is equal to (Equation 4) + // DF_local(X) U { B in DF_up(Z) | X = ipdom(Z) } + // (ipdom(Z) is the immediate post-dominator of Z.) + // where + // DF_local(X) = { Y | X -> Y in CFG, X does not strictly post-dominate Y } + // represents the contribution of X's predecessors to the DF, and + // DF_up(Z) = { Y | Y in DF(Z), ipdom(Z) does not strictly post-dominate Y } + // (note: ipdom(Z) = X.) + // represents the contribution of a block to its immediate post- + // dominator's DF. + // This is computed in one pass through a post-order traversal of the + // post-dominator tree. + + // Assert that there is a block other than the pseudo exit in the pdom tree, + // as we need one to get the function entry point (as the pseudo exit is not + // actually part of the function.) + assert(!cfg.IsPseudoExitBlock(pdom.GetDomTree().post_begin()->bb_)); + Function* function = pdom.GetDomTree().post_begin()->bb_->GetParent(); + uint32_t function_entry = function->entry()->id(); + // Explicitly initialize pseudo-entry block, as it doesn't depend on anything, + // so it won't be initialized in the following loop. + reverse_nodes_[kPseudoEntryBlock] = {}; + for (auto it = pdom.GetDomTree().post_cbegin(); + it != pdom.GetDomTree().post_cend(); ++it) { + ComputePostDominanceFrontierForNode(cfg, pdom, function_entry, *it); + } +} + +void ControlDependenceAnalysis::ComputePostDominanceFrontierForNode( + const CFG& cfg, const PostDominatorAnalysis& pdom, uint32_t function_entry, + const DominatorTreeNode& pdom_node) { + const uint32_t label = pdom_node.id(); + ControlDependenceList& edges = reverse_nodes_[label]; + for (uint32_t pred : cfg.preds(label)) { + if (!pdom.StrictlyDominates(label, pred)) { + edges.push_back(ControlDependence(pred, label)); + } + } + if (label == function_entry) { + // Add edge from pseudo-entry to entry. + // In CDG construction, an edge is added from entry to exit, so only the + // exit node can post-dominate entry. + edges.push_back(ControlDependence(kPseudoEntryBlock, label)); + } + for (DominatorTreeNode* child : pdom_node) { + // Note: iterate dependences by value, as we need a copy. + for (const ControlDependence& dep : reverse_nodes_[child->id()]) { + // Special-case pseudo-entry, as above. + if (dep.source_bb_id() == kPseudoEntryBlock || + !pdom.StrictlyDominates(label, dep.source_bb_id())) { + edges.push_back(ControlDependence(dep.source_bb_id(), label, + dep.branch_target_bb_id())); + } + } + } +} + +void ControlDependenceAnalysis::ComputeControlDependenceGraph( + const CFG& cfg, const PostDominatorAnalysis& pdom) { + ComputePostDominanceFrontiers(cfg, pdom); + ComputeForwardGraphFromReverse(); +} + +void ControlDependenceAnalysis::ComputeForwardGraphFromReverse() { + for (const auto& entry : reverse_nodes_) { + // Ensure an entry is created for each node. + forward_nodes_[entry.first]; + for (const ControlDependence& dep : entry.second) { + forward_nodes_[dep.source_bb_id()].push_back(dep); + } + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/control_dependence.h b/thirdparty/glslang/External/spirv-tools/source/opt/control_dependence.h new file mode 100644 index 000000000000..993f3793645d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/control_dependence.h @@ -0,0 +1,197 @@ +// Copyright (c) 2021 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_CONTROL_DEPENDENCE_H_ +#define SOURCE_OPT_CONTROL_DEPENDENCE_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/cfg.h" +#include "source/opt/dominator_analysis.h" + +namespace spvtools { +namespace opt { + +class ControlDependence { + public: + // The label of the source of this dependence, i.e. the block on which the + // target is dependent on. + // A |source_bb_id| of 0 represents an "entry" dependence, meaning that the + // execution of |target_bb_id| is only dependent on entry to the function. + uint32_t source_bb_id() const { return source_bb_id_; } + // The label of the target of this dependence, i.e. the block which is + // dependent on the source. + uint32_t target_bb_id() const { return target_bb_id_; } + // The label of the target of the *branch* for this dependence. + // Equal to the ID of the entry block for entry dependences. + // + // For example, for the partial CFG pictured below: + // 1 ---> 2 ---> 4 ---> 6 + // \ \ ^ + // \-> 3 \-> 5 -----/ + // Block 6 is control dependent on block 1, but this dependence comes from the + // branch 1 -> 2, so in this case the branch target ID would be 2. + uint32_t branch_target_bb_id() const { return branch_target_bb_id_; } + + // Create a direct control dependence from BB ID |source| to |target|. + ControlDependence(uint32_t source, uint32_t target) + : source_bb_id_(source), + target_bb_id_(target), + branch_target_bb_id_(target) {} + // Create a control dependence from BB ID |source| to |target| through the + // branch from |source| to |branch_target|. + ControlDependence(uint32_t source, uint32_t target, uint32_t branch_target) + : source_bb_id_(source), + target_bb_id_(target), + branch_target_bb_id_(branch_target) {} + + // Gets the ID of the conditional value for the branch corresponding to this + // control dependence. This is the first input operand for both + // OpConditionalBranch and OpSwitch. + // Returns 0 for entry dependences. + uint32_t GetConditionID(const CFG& cfg) const; + + bool operator==(const ControlDependence& other) const; + bool operator!=(const ControlDependence& other) const { + return !(*this == other); + } + + // Comparison operators, ordered lexicographically. Total ordering. + bool operator<(const ControlDependence& other) const; + bool operator>(const ControlDependence& other) const { return other < *this; } + bool operator<=(const ControlDependence& other) const { + return !(*this > other); + } + bool operator>=(const ControlDependence& other) const { + return !(*this < other); + } + + private: + uint32_t source_bb_id_; + uint32_t target_bb_id_; + uint32_t branch_target_bb_id_; +}; + +// Prints |dep| to |os| in a human-readable way. For example, +// 1->2 (target_bb_id = branch_target_bb_id = 2) +// 3->4 through 5 (target_bb_id = 4, branch_target_bb_id = 5) +std::ostream& operator<<(std::ostream& os, const ControlDependence& dep); + +// Represents the control dependence graph. A basic block is control dependent +// on another if the result of that block (e.g. the condition of a conditional +// branch) influences whether it is executed or not. More formally, a block A is +// control dependent on B iff: +// 1. there exists a path from A to the exit node that does *not* go through B +// (i.e., A does not postdominate B), and +// 2. there exists a path B -> b_1 -> ... -> b_n -> A such that A post-dominates +// all nodes b_i. +class ControlDependenceAnalysis { + public: + // Map basic block labels to control dependencies/dependents. + // Not guaranteed to be in any particular order. + using ControlDependenceList = std::vector; + using ControlDependenceListMap = + std::unordered_map; + + // 0, the label number for the pseudo entry block. + // All control dependences on the pseudo entry block are of type kEntry, and + // vice versa. + static constexpr uint32_t kPseudoEntryBlock = 0; + + // Build the control dependence graph for the given control flow graph |cfg| + // and corresponding post-dominator analysis |pdom|. + void ComputeControlDependenceGraph(const CFG& cfg, + const PostDominatorAnalysis& pdom); + + // Get the list of the nodes that depend on a block. + // Return value is not guaranteed to be in any particular order. + const ControlDependenceList& GetDependenceTargets(uint32_t block) const { + return forward_nodes_.at(block); + } + + // Get the list of the nodes on which a block depends on. + // Return value is not guaranteed to be in any particular order. + const ControlDependenceList& GetDependenceSources(uint32_t block) const { + return reverse_nodes_.at(block); + } + + // Runs the function |f| on each block label in the CDG. If any iteration + // returns false, immediately stops iteration and returns false. Otherwise + // returns true. Nodes are iterated in some undefined order, including the + // pseudo-entry block. + bool WhileEachBlockLabel(std::function f) const { + for (const auto& entry : forward_nodes_) { + if (!f(entry.first)) { + return false; + } + } + return true; + } + + // Runs the function |f| on each block label in the CDG. Nodes are iterated in + // some undefined order, including the pseudo-entry block. + void ForEachBlockLabel(std::function f) const { + WhileEachBlockLabel([&f](uint32_t label) { + f(label); + return true; + }); + } + + // Returns true if the block |id| exists in the control dependence graph. + // This can be false even if the block exists in the function when it is part + // of an infinite loop, since it is not part of the post-dominator tree. + bool HasBlock(uint32_t id) const { return forward_nodes_.count(id) > 0; } + + // Returns true if block |a| is dependent on block |b|. + bool IsDependent(uint32_t a, uint32_t b) const { + if (!HasBlock(a)) return false; + // BBs tend to have more dependents (targets) than they are dependent on + // (sources), so search sources. + const ControlDependenceList& a_sources = GetDependenceSources(a); + return std::find_if(a_sources.begin(), a_sources.end(), + [b](const ControlDependence& dep) { + return dep.source_bb_id() == b; + }) != a_sources.end(); + } + + private: + // Computes the post-dominance frontiers (i.e. the reverse CDG) for each node + // in the post-dominator tree. Only modifies reverse_nodes_; forward_nodes_ is + // not modified. + void ComputePostDominanceFrontiers(const CFG& cfg, + const PostDominatorAnalysis& pdom); + // Computes the post-dominance frontier for a specific node |pdom_node| in the + // post-dominator tree. Result is placed in reverse_nodes_[pdom_node.id()]. + void ComputePostDominanceFrontierForNode(const CFG& cfg, + const PostDominatorAnalysis& pdom, + uint32_t function_entry, + const DominatorTreeNode& pdom_node); + + // Computes the forward graph (forward_nodes_) from the reverse graph + // (reverse_nodes_). + void ComputeForwardGraphFromReverse(); + + ControlDependenceListMap forward_nodes_; + ControlDependenceListMap reverse_nodes_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_CONTROL_DEPENDENCE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_half_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_half_pass.cpp new file mode 100644 index 000000000000..e243bedf0c62 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_half_pass.cpp @@ -0,0 +1,517 @@ +// Copyright (c) 2019 The Khronos Group Inc. +// Copyright (c) 2019 Valve Corporation +// Copyright (c) 2019 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "convert_to_half_pass.h" + +#include "source/opt/ir_builder.h" + +namespace spvtools { +namespace opt { +namespace { +// Indices of operands in SPIR-V instructions +constexpr int kImageSampleDrefIdInIdx = 2; +} // namespace + +bool ConvertToHalfPass::IsArithmetic(Instruction* inst) { + return target_ops_core_.count(inst->opcode()) != 0 || + (inst->opcode() == spv::Op::OpExtInst && + inst->GetSingleWordInOperand(0) == + context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && + target_ops_450_.count(inst->GetSingleWordInOperand(1)) != 0); +} + +bool ConvertToHalfPass::IsFloat(Instruction* inst, uint32_t width) { + uint32_t ty_id = inst->type_id(); + if (ty_id == 0) return false; + return Pass::IsFloat(ty_id, width); +} + +bool ConvertToHalfPass::IsStruct(Instruction* inst) { + uint32_t ty_id = inst->type_id(); + if (ty_id == 0) return false; + Instruction* ty_inst = Pass::GetBaseType(ty_id); + return (ty_inst->opcode() == spv::Op::OpTypeStruct); +} + +bool ConvertToHalfPass::IsDecoratedRelaxed(Instruction* inst) { + uint32_t r_id = inst->result_id(); + for (auto r_inst : get_decoration_mgr()->GetDecorationsFor(r_id, false)) + if (r_inst->opcode() == spv::Op::OpDecorate && + spv::Decoration(r_inst->GetSingleWordInOperand(1)) == + spv::Decoration::RelaxedPrecision) { + return true; + } + return false; +} + +bool ConvertToHalfPass::IsRelaxed(uint32_t id) { + return relaxed_ids_set_.count(id) > 0; +} + +void ConvertToHalfPass::AddRelaxed(uint32_t id) { relaxed_ids_set_.insert(id); } + +bool ConvertToHalfPass::CanRelaxOpOperands(Instruction* inst) { + return image_ops_.count(inst->opcode()) == 0; +} + +analysis::Type* ConvertToHalfPass::FloatScalarType(uint32_t width) { + analysis::Float float_ty(width); + return context()->get_type_mgr()->GetRegisteredType(&float_ty); +} + +analysis::Type* ConvertToHalfPass::FloatVectorType(uint32_t v_len, + uint32_t width) { + analysis::Type* reg_float_ty = FloatScalarType(width); + analysis::Vector vec_ty(reg_float_ty, v_len); + return context()->get_type_mgr()->GetRegisteredType(&vec_ty); +} + +analysis::Type* ConvertToHalfPass::FloatMatrixType(uint32_t v_cnt, + uint32_t vty_id, + uint32_t width) { + Instruction* vty_inst = get_def_use_mgr()->GetDef(vty_id); + uint32_t v_len = vty_inst->GetSingleWordInOperand(1); + analysis::Type* reg_vec_ty = FloatVectorType(v_len, width); + analysis::Matrix mat_ty(reg_vec_ty, v_cnt); + return context()->get_type_mgr()->GetRegisteredType(&mat_ty); +} + +uint32_t ConvertToHalfPass::EquivFloatTypeId(uint32_t ty_id, uint32_t width) { + analysis::Type* reg_equiv_ty; + Instruction* ty_inst = get_def_use_mgr()->GetDef(ty_id); + if (ty_inst->opcode() == spv::Op::OpTypeMatrix) + reg_equiv_ty = FloatMatrixType(ty_inst->GetSingleWordInOperand(1), + ty_inst->GetSingleWordInOperand(0), width); + else if (ty_inst->opcode() == spv::Op::OpTypeVector) + reg_equiv_ty = FloatVectorType(ty_inst->GetSingleWordInOperand(1), width); + else // spv::Op::OpTypeFloat + reg_equiv_ty = FloatScalarType(width); + return context()->get_type_mgr()->GetTypeInstruction(reg_equiv_ty); +} + +void ConvertToHalfPass::GenConvert(uint32_t* val_idp, uint32_t width, + Instruction* inst) { + Instruction* val_inst = get_def_use_mgr()->GetDef(*val_idp); + uint32_t ty_id = val_inst->type_id(); + uint32_t nty_id = EquivFloatTypeId(ty_id, width); + if (nty_id == ty_id) return; + Instruction* cvt_inst; + InstructionBuilder builder( + context(), inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + if (val_inst->opcode() == spv::Op::OpUndef) + cvt_inst = builder.AddNullaryOp(nty_id, spv::Op::OpUndef); + else + cvt_inst = builder.AddUnaryOp(nty_id, spv::Op::OpFConvert, *val_idp); + *val_idp = cvt_inst->result_id(); +} + +bool ConvertToHalfPass::MatConvertCleanup(Instruction* inst) { + if (inst->opcode() != spv::Op::OpFConvert) return false; + uint32_t mty_id = inst->type_id(); + Instruction* mty_inst = get_def_use_mgr()->GetDef(mty_id); + if (mty_inst->opcode() != spv::Op::OpTypeMatrix) return false; + uint32_t vty_id = mty_inst->GetSingleWordInOperand(0); + uint32_t v_cnt = mty_inst->GetSingleWordInOperand(1); + Instruction* vty_inst = get_def_use_mgr()->GetDef(vty_id); + uint32_t cty_id = vty_inst->GetSingleWordInOperand(0); + Instruction* cty_inst = get_def_use_mgr()->GetDef(cty_id); + InstructionBuilder builder( + context(), inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // Convert each component vector, combine them with OpCompositeConstruct + // and replace original instruction. + uint32_t orig_width = (cty_inst->GetSingleWordInOperand(0) == 16) ? 32 : 16; + uint32_t orig_mat_id = inst->GetSingleWordInOperand(0); + uint32_t orig_vty_id = EquivFloatTypeId(vty_id, orig_width); + std::vector opnds = {}; + for (uint32_t vidx = 0; vidx < v_cnt; ++vidx) { + Instruction* ext_inst = builder.AddIdLiteralOp( + orig_vty_id, spv::Op::OpCompositeExtract, orig_mat_id, vidx); + Instruction* cvt_inst = + builder.AddUnaryOp(vty_id, spv::Op::OpFConvert, ext_inst->result_id()); + opnds.push_back({SPV_OPERAND_TYPE_ID, {cvt_inst->result_id()}}); + } + uint32_t mat_id = TakeNextId(); + std::unique_ptr mat_inst(new Instruction( + context(), spv::Op::OpCompositeConstruct, mty_id, mat_id, opnds)); + (void)builder.AddInstruction(std::move(mat_inst)); + context()->ReplaceAllUsesWith(inst->result_id(), mat_id); + // Turn original instruction into copy so it is valid. + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetResultType(EquivFloatTypeId(mty_id, orig_width)); + get_def_use_mgr()->AnalyzeInstUse(inst); + return true; +} + +bool ConvertToHalfPass::RemoveRelaxedDecoration(uint32_t id) { + return context()->get_decoration_mgr()->RemoveDecorationsFrom( + id, [](const Instruction& dec) { + if (dec.opcode() == spv::Op::OpDecorate && + spv::Decoration(dec.GetSingleWordInOperand(1u)) == + spv::Decoration::RelaxedPrecision) { + return true; + } else + return false; + }); +} + +bool ConvertToHalfPass::GenHalfArith(Instruction* inst) { + bool modified = false; + // If this is a OpCompositeExtract instruction and has a struct operand, we + // should not relax this instruction. Doing so could cause a mismatch between + // the result type and the struct member type. + bool hasStructOperand = false; + if (inst->opcode() == spv::Op::OpCompositeExtract) { + inst->ForEachInId([&hasStructOperand, this](uint32_t* idp) { + Instruction* op_inst = get_def_use_mgr()->GetDef(*idp); + if (IsStruct(op_inst)) hasStructOperand = true; + }); + if (hasStructOperand) { + return false; + } + } + // Convert all float32 based operands to float16 equivalent and change + // instruction type to float16 equivalent. + inst->ForEachInId([&inst, &modified, this](uint32_t* idp) { + Instruction* op_inst = get_def_use_mgr()->GetDef(*idp); + if (!IsFloat(op_inst, 32)) return; + GenConvert(idp, 16, inst); + modified = true; + }); + if (IsFloat(inst, 32)) { + inst->SetResultType(EquivFloatTypeId(inst->type_id(), 16)); + converted_ids_.insert(inst->result_id()); + modified = true; + } + if (modified) get_def_use_mgr()->AnalyzeInstUse(inst); + return modified; +} + +bool ConvertToHalfPass::ProcessPhi(Instruction* inst, uint32_t from_width, + uint32_t to_width) { + // Add converts of any float operands to to_width if they are of from_width. + // If converting to 16, change type of phi to float16 equivalent and remember + // result id. Converts need to be added to preceding blocks. + uint32_t ocnt = 0; + uint32_t* prev_idp; + bool modified = false; + inst->ForEachInId([&ocnt, &prev_idp, &from_width, &to_width, &modified, + this](uint32_t* idp) { + if (ocnt % 2 == 0) { + prev_idp = idp; + } else { + Instruction* val_inst = get_def_use_mgr()->GetDef(*prev_idp); + if (IsFloat(val_inst, from_width)) { + BasicBlock* bp = context()->get_instr_block(*idp); + auto insert_before = bp->tail(); + if (insert_before != bp->begin()) { + --insert_before; + if (insert_before->opcode() != spv::Op::OpSelectionMerge && + insert_before->opcode() != spv::Op::OpLoopMerge) + ++insert_before; + } + GenConvert(prev_idp, to_width, &*insert_before); + modified = true; + } + } + ++ocnt; + }); + if (to_width == 16u) { + inst->SetResultType(EquivFloatTypeId(inst->type_id(), 16u)); + converted_ids_.insert(inst->result_id()); + modified = true; + } + if (modified) get_def_use_mgr()->AnalyzeInstUse(inst); + return modified; +} + +bool ConvertToHalfPass::ProcessConvert(Instruction* inst) { + // If float32 and relaxed, change to float16 convert + if (IsFloat(inst, 32) && IsRelaxed(inst->result_id())) { + inst->SetResultType(EquivFloatTypeId(inst->type_id(), 16)); + get_def_use_mgr()->AnalyzeInstUse(inst); + converted_ids_.insert(inst->result_id()); + } + // If operand and result types are the same, change FConvert to CopyObject to + // keep validator happy; simplification and DCE will clean it up + // One way this can happen is if an FConvert generated during this pass + // (likely by ProcessPhi) is later encountered here and its operand has been + // changed to half. + uint32_t val_id = inst->GetSingleWordInOperand(0); + Instruction* val_inst = get_def_use_mgr()->GetDef(val_id); + if (inst->type_id() == val_inst->type_id()) + inst->SetOpcode(spv::Op::OpCopyObject); + return true; // modified +} + +bool ConvertToHalfPass::ProcessImageRef(Instruction* inst) { + bool modified = false; + // If image reference, only need to convert dref args back to float32 + if (dref_image_ops_.count(inst->opcode()) != 0) { + uint32_t dref_id = inst->GetSingleWordInOperand(kImageSampleDrefIdInIdx); + if (converted_ids_.count(dref_id) > 0) { + GenConvert(&dref_id, 32, inst); + inst->SetInOperand(kImageSampleDrefIdInIdx, {dref_id}); + get_def_use_mgr()->AnalyzeInstUse(inst); + modified = true; + } + } + return modified; +} + +bool ConvertToHalfPass::ProcessDefault(Instruction* inst) { + // If non-relaxed instruction has changed operands, need to convert + // them back to float32 + if (inst->opcode() == spv::Op::OpPhi) return ProcessPhi(inst, 16u, 32u); + bool modified = false; + inst->ForEachInId([&inst, &modified, this](uint32_t* idp) { + if (converted_ids_.count(*idp) == 0) return; + uint32_t old_id = *idp; + GenConvert(idp, 32, inst); + if (*idp != old_id) modified = true; + }); + if (modified) get_def_use_mgr()->AnalyzeInstUse(inst); + return modified; +} + +bool ConvertToHalfPass::GenHalfInst(Instruction* inst) { + bool modified = false; + // Remember id for later deletion of RelaxedPrecision decoration + bool inst_relaxed = IsRelaxed(inst->result_id()); + if (IsArithmetic(inst) && inst_relaxed) + modified = GenHalfArith(inst); + else if (inst->opcode() == spv::Op::OpPhi && inst_relaxed) + modified = ProcessPhi(inst, 32u, 16u); + else if (inst->opcode() == spv::Op::OpFConvert) + modified = ProcessConvert(inst); + else if (image_ops_.count(inst->opcode()) != 0) + modified = ProcessImageRef(inst); + else + modified = ProcessDefault(inst); + return modified; +} + +bool ConvertToHalfPass::CloseRelaxInst(Instruction* inst) { + if (inst->result_id() == 0) return false; + if (IsRelaxed(inst->result_id())) return false; + if (!IsFloat(inst, 32)) return false; + if (IsDecoratedRelaxed(inst)) { + AddRelaxed(inst->result_id()); + return true; + } + if (closure_ops_.count(inst->opcode()) == 0) return false; + // Can relax if all float operands are relaxed + bool relax = true; + bool hasStructOperand = false; + inst->ForEachInId([&relax, &hasStructOperand, this](uint32_t* idp) { + Instruction* op_inst = get_def_use_mgr()->GetDef(*idp); + if (IsStruct(op_inst)) hasStructOperand = true; + if (!IsFloat(op_inst, 32)) return; + if (!IsRelaxed(*idp)) relax = false; + }); + // If the instruction has a struct operand, we should not relax it, even if + // all its uses are relaxed. Doing so could cause a mismatch between the + // result type and the struct member type. + if (hasStructOperand) { + return false; + } + if (relax) { + AddRelaxed(inst->result_id()); + return true; + } + // Can relax if all uses are relaxed + relax = true; + get_def_use_mgr()->ForEachUser(inst, [&relax, this](Instruction* uinst) { + if (uinst->result_id() == 0 || !IsFloat(uinst, 32) || + (!IsDecoratedRelaxed(uinst) && !IsRelaxed(uinst->result_id())) || + !CanRelaxOpOperands(uinst)) { + relax = false; + return; + } + }); + if (relax) { + AddRelaxed(inst->result_id()); + return true; + } + return false; +} + +bool ConvertToHalfPass::ProcessFunction(Function* func) { + // Do a closure of Relaxed on composite and phi instructions + bool changed = true; + while (changed) { + changed = false; + cfg()->ForEachBlockInReversePostOrder( + func->entry().get(), [&changed, this](BasicBlock* bb) { + for (auto ii = bb->begin(); ii != bb->end(); ++ii) + changed |= CloseRelaxInst(&*ii); + }); + } + // Do convert of relaxed instructions to half precision + bool modified = false; + cfg()->ForEachBlockInReversePostOrder( + func->entry().get(), [&modified, this](BasicBlock* bb) { + for (auto ii = bb->begin(); ii != bb->end(); ++ii) + modified |= GenHalfInst(&*ii); + }); + // Replace invalid converts of matrix into equivalent vector extracts, + // converts and finally a composite construct + cfg()->ForEachBlockInReversePostOrder( + func->entry().get(), [&modified, this](BasicBlock* bb) { + for (auto ii = bb->begin(); ii != bb->end(); ++ii) + modified |= MatConvertCleanup(&*ii); + }); + return modified; +} + +Pass::Status ConvertToHalfPass::ProcessImpl() { + Pass::ProcessFunction pfn = [this](Function* fp) { + return ProcessFunction(fp); + }; + bool modified = context()->ProcessReachableCallTree(pfn); + // If modified, make sure module has Float16 capability + if (modified) context()->AddCapability(spv::Capability::Float16); + // Remove all RelaxedPrecision decorations from instructions and globals + for (auto c_id : relaxed_ids_set_) { + modified |= RemoveRelaxedDecoration(c_id); + } + for (auto& val : get_module()->types_values()) { + uint32_t v_id = val.result_id(); + if (v_id != 0) { + modified |= RemoveRelaxedDecoration(v_id); + } + } + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +Pass::Status ConvertToHalfPass::Process() { + Initialize(); + return ProcessImpl(); +} + +void ConvertToHalfPass::Initialize() { + target_ops_core_ = { + spv::Op::OpVectorExtractDynamic, + spv::Op::OpVectorInsertDynamic, + spv::Op::OpVectorShuffle, + spv::Op::OpCompositeConstruct, + spv::Op::OpCompositeInsert, + spv::Op::OpCompositeExtract, + spv::Op::OpCopyObject, + spv::Op::OpTranspose, + spv::Op::OpConvertSToF, + spv::Op::OpConvertUToF, + // spv::Op::OpFConvert, + // spv::Op::OpQuantizeToF16, + spv::Op::OpFNegate, + spv::Op::OpFAdd, + spv::Op::OpFSub, + spv::Op::OpFMul, + spv::Op::OpFDiv, + spv::Op::OpFMod, + spv::Op::OpVectorTimesScalar, + spv::Op::OpMatrixTimesScalar, + spv::Op::OpVectorTimesMatrix, + spv::Op::OpMatrixTimesVector, + spv::Op::OpMatrixTimesMatrix, + spv::Op::OpOuterProduct, + spv::Op::OpDot, + spv::Op::OpSelect, + spv::Op::OpFOrdEqual, + spv::Op::OpFUnordEqual, + spv::Op::OpFOrdNotEqual, + spv::Op::OpFUnordNotEqual, + spv::Op::OpFOrdLessThan, + spv::Op::OpFUnordLessThan, + spv::Op::OpFOrdGreaterThan, + spv::Op::OpFUnordGreaterThan, + spv::Op::OpFOrdLessThanEqual, + spv::Op::OpFUnordLessThanEqual, + spv::Op::OpFOrdGreaterThanEqual, + spv::Op::OpFUnordGreaterThanEqual, + }; + target_ops_450_ = { + GLSLstd450Round, GLSLstd450RoundEven, GLSLstd450Trunc, GLSLstd450FAbs, + GLSLstd450FSign, GLSLstd450Floor, GLSLstd450Ceil, GLSLstd450Fract, + GLSLstd450Radians, GLSLstd450Degrees, GLSLstd450Sin, GLSLstd450Cos, + GLSLstd450Tan, GLSLstd450Asin, GLSLstd450Acos, GLSLstd450Atan, + GLSLstd450Sinh, GLSLstd450Cosh, GLSLstd450Tanh, GLSLstd450Asinh, + GLSLstd450Acosh, GLSLstd450Atanh, GLSLstd450Atan2, GLSLstd450Pow, + GLSLstd450Exp, GLSLstd450Log, GLSLstd450Exp2, GLSLstd450Log2, + GLSLstd450Sqrt, GLSLstd450InverseSqrt, GLSLstd450Determinant, + GLSLstd450MatrixInverse, + // TODO(greg-lunarg): GLSLstd450ModfStruct, + GLSLstd450FMin, GLSLstd450FMax, GLSLstd450FClamp, GLSLstd450FMix, + GLSLstd450Step, GLSLstd450SmoothStep, GLSLstd450Fma, + // TODO(greg-lunarg): GLSLstd450FrexpStruct, + GLSLstd450Ldexp, GLSLstd450Length, GLSLstd450Distance, GLSLstd450Cross, + GLSLstd450Normalize, GLSLstd450FaceForward, GLSLstd450Reflect, + GLSLstd450Refract, GLSLstd450NMin, GLSLstd450NMax, GLSLstd450NClamp}; + image_ops_ = {spv::Op::OpImageSampleImplicitLod, + spv::Op::OpImageSampleExplicitLod, + spv::Op::OpImageSampleDrefImplicitLod, + spv::Op::OpImageSampleDrefExplicitLod, + spv::Op::OpImageSampleProjImplicitLod, + spv::Op::OpImageSampleProjExplicitLod, + spv::Op::OpImageSampleProjDrefImplicitLod, + spv::Op::OpImageSampleProjDrefExplicitLod, + spv::Op::OpImageFetch, + spv::Op::OpImageGather, + spv::Op::OpImageDrefGather, + spv::Op::OpImageRead, + spv::Op::OpImageSparseSampleImplicitLod, + spv::Op::OpImageSparseSampleExplicitLod, + spv::Op::OpImageSparseSampleDrefImplicitLod, + spv::Op::OpImageSparseSampleDrefExplicitLod, + spv::Op::OpImageSparseSampleProjImplicitLod, + spv::Op::OpImageSparseSampleProjExplicitLod, + spv::Op::OpImageSparseSampleProjDrefImplicitLod, + spv::Op::OpImageSparseSampleProjDrefExplicitLod, + spv::Op::OpImageSparseFetch, + spv::Op::OpImageSparseGather, + spv::Op::OpImageSparseDrefGather, + spv::Op::OpImageSparseTexelsResident, + spv::Op::OpImageSparseRead}; + dref_image_ops_ = { + spv::Op::OpImageSampleDrefImplicitLod, + spv::Op::OpImageSampleDrefExplicitLod, + spv::Op::OpImageSampleProjDrefImplicitLod, + spv::Op::OpImageSampleProjDrefExplicitLod, + spv::Op::OpImageDrefGather, + spv::Op::OpImageSparseSampleDrefImplicitLod, + spv::Op::OpImageSparseSampleDrefExplicitLod, + spv::Op::OpImageSparseSampleProjDrefImplicitLod, + spv::Op::OpImageSparseSampleProjDrefExplicitLod, + spv::Op::OpImageSparseDrefGather, + }; + closure_ops_ = { + spv::Op::OpVectorExtractDynamic, + spv::Op::OpVectorInsertDynamic, + spv::Op::OpVectorShuffle, + spv::Op::OpCompositeConstruct, + spv::Op::OpCompositeInsert, + spv::Op::OpCompositeExtract, + spv::Op::OpCopyObject, + spv::Op::OpTranspose, + spv::Op::OpPhi, + }; + relaxed_ids_set_.clear(); + converted_ids_.clear(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_half_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_half_pass.h new file mode 100644 index 000000000000..8e10c4fb95be --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_half_pass.h @@ -0,0 +1,158 @@ +// Copyright (c) 2019 Valve Corporation +// Copyright (c) 2019 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBSPIRV_OPT_CONVERT_TO_HALF_PASS_H_ +#define LIBSPIRV_OPT_CONVERT_TO_HALF_PASS_H_ + +#include "source/opt/ir_builder.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +class ConvertToHalfPass : public Pass { + public: + ConvertToHalfPass() : Pass() {} + + ~ConvertToHalfPass() override = default; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping; + } + + // See optimizer.hpp for pass user documentation. + Status Process() override; + + const char* name() const override { return "convert-to-half-pass"; } + + private: + // Return true if |inst| is an arithmetic, composite or phi op that can be + // of type float16 + bool IsArithmetic(Instruction* inst); + + // Return true if |inst| returns scalar, vector or matrix type with base + // float and |width| + bool IsFloat(Instruction* inst, uint32_t width); + bool IsStruct(Instruction* inst); + + // Return true if |inst| is decorated with RelaxedPrecision + bool IsDecoratedRelaxed(Instruction* inst); + + // Return true if |id| has been added to the relaxed id set + bool IsRelaxed(uint32_t id); + + // Add |id| to the relaxed id set + void AddRelaxed(uint32_t id); + + // Return true if the instruction's operands can be relaxed + bool CanRelaxOpOperands(Instruction* inst); + + // Return type id for float with |width| + analysis::Type* FloatScalarType(uint32_t width); + + // Return type id for vector of length |vlen| of float of |width| + analysis::Type* FloatVectorType(uint32_t v_len, uint32_t width); + + // Return type id for matrix of |v_cnt| vectors of length identical to + // |vty_id| of float of |width| + analysis::Type* FloatMatrixType(uint32_t v_cnt, uint32_t vty_id, + uint32_t width); + + // Return equivalent to float type |ty_id| with |width| + uint32_t EquivFloatTypeId(uint32_t ty_id, uint32_t width); + + // Append instructions to builder to convert value |*val_idp| to type + // |ty_id| but with |width|. Set |*val_idp| to the new id. + void GenConvert(uint32_t* val_idp, uint32_t width, Instruction* inst); + + // Remove RelaxedPrecision decoration of |id|. + bool RemoveRelaxedDecoration(uint32_t id); + + // Add |inst| to relaxed instruction set if warranted. Specifically, if + // it is float32 and either decorated relaxed or a composite or phi + // instruction where all operands are relaxed or all uses are relaxed. + bool CloseRelaxInst(Instruction* inst); + + // If |inst| is an arithmetic, phi, extract or convert instruction of float32 + // base type and decorated with RelaxedPrecision, change it to the equivalent + // float16 based type instruction. Specifically, insert instructions to + // convert all operands to float16 (if needed) and change its type to the + // equivalent float16 type. Otherwise, insert instructions to convert its + // operands back to their original types, if needed. + bool GenHalfInst(Instruction* inst); + + // Gen code for relaxed arithmetic |inst| + bool GenHalfArith(Instruction* inst); + + // Gen code for relaxed phi |inst| + bool ProcessPhi(Instruction* inst, uint32_t from_width, uint32_t to_width); + + // Gen code for relaxed convert |inst| + bool ProcessConvert(Instruction* inst); + + // Gen code for image reference |inst| + bool ProcessImageRef(Instruction* inst); + + // Process default non-relaxed |inst| + bool ProcessDefault(Instruction* inst); + + // If |inst| is an FConvert of a matrix type, decompose it to a series + // of vector extracts, converts and inserts into an Undef. These are + // generated by GenHalfInst because they are easier to manipulate, but are + // invalid so we need to clean them up. + bool MatConvertCleanup(Instruction* inst); + + // Call GenHalfInst on every instruction in |func|. + // If code is generated for an instruction, replace the instruction + // with the new instructions that are generated. + bool ProcessFunction(Function* func); + + Pass::Status ProcessImpl(); + + // Initialize state for converting to half + void Initialize(); + + struct hasher { + size_t operator()(const spv::Op& op) const noexcept { + return std::hash()(uint32_t(op)); + } + }; + + // Set of core operations to be processed + std::unordered_set target_ops_core_; + + // Set of 450 extension operations to be processed + std::unordered_set target_ops_450_; + + // Set of all sample operations, including dref and non-dref operations + std::unordered_set image_ops_; + + // Set of only dref sample operations + std::unordered_set dref_image_ops_; + + // Set of operations that can be marked as relaxed + std::unordered_set closure_ops_; + + // Set of ids of all relaxed instructions + std::unordered_set relaxed_ids_set_; + + // Ids of all converted instructions + std::unordered_set converted_ids_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // LIBSPIRV_OPT_CONVERT_TO_HALF_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp new file mode 100644 index 000000000000..c82db41cec89 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp @@ -0,0 +1,437 @@ +// Copyright (c) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/convert_to_sampled_image_pass.h" + +#include +#include + +#include "source/opt/ir_builder.h" +#include "source/util/make_unique.h" +#include "source/util/parse_number.h" + +namespace spvtools { +namespace opt { + +using VectorOfDescriptorSetAndBindingPairs = + std::vector; +using DescriptorSetBindingToInstruction = + ConvertToSampledImagePass::DescriptorSetBindingToInstruction; + +namespace { + +using utils::ParseNumber; + +// Returns true if the given char is ':', '\0' or considered as blank space +// (i.e.: '\n', '\r', '\v', '\t', '\f' and ' '). +bool IsSeparator(char ch) { + return std::strchr(":\0", ch) || std::isspace(ch) != 0; +} + +// Reads characters starting from |str| until it meets a separator. Parses a +// number from the characters and stores it into |number|. Returns the pointer +// to the separator if it succeeds. Otherwise, returns nullptr. +const char* ParseNumberUntilSeparator(const char* str, uint32_t* number) { + const char* number_begin = str; + while (!IsSeparator(*str)) str++; + const char* number_end = str; + std::string number_in_str(number_begin, number_end - number_begin); + if (!utils::ParseNumber(number_in_str.c_str(), number)) { + // The descriptor set is not a valid uint32 number. + return nullptr; + } + return str; +} + +// Returns id of the image type used for the sampled image type of +// |sampled_image|. +uint32_t GetImageTypeOfSampledImage(analysis::TypeManager* type_mgr, + Instruction* sampled_image) { + auto* sampled_image_type = + type_mgr->GetType(sampled_image->type_id())->AsSampledImage(); + return type_mgr->GetTypeInstruction(sampled_image_type->image_type()); +} + +// Finds the instruction whose id is |inst_id|. Follows the operand of +// OpCopyObject recursively if the opcode of the instruction is OpCopyObject +// and returns the first instruction that does not have OpCopyObject as opcode. +Instruction* GetNonCopyObjectDef(analysis::DefUseManager* def_use_mgr, + uint32_t inst_id) { + Instruction* inst = def_use_mgr->GetDef(inst_id); + while (inst->opcode() == spv::Op::OpCopyObject) { + inst_id = inst->GetSingleWordInOperand(0u); + inst = def_use_mgr->GetDef(inst_id); + } + return inst; +} + +} // namespace + +bool ConvertToSampledImagePass::GetDescriptorSetBinding( + const Instruction& inst, + DescriptorSetAndBinding* descriptor_set_binding) const { + auto* decoration_manager = context()->get_decoration_mgr(); + bool found_descriptor_set_to_convert = false; + bool found_binding_to_convert = false; + for (auto decorate : + decoration_manager->GetDecorationsFor(inst.result_id(), false)) { + spv::Decoration decoration = + spv::Decoration(decorate->GetSingleWordInOperand(1u)); + if (decoration == spv::Decoration::DescriptorSet) { + if (found_descriptor_set_to_convert) { + assert(false && "A resource has two OpDecorate for the descriptor set"); + return false; + } + descriptor_set_binding->descriptor_set = + decorate->GetSingleWordInOperand(2u); + found_descriptor_set_to_convert = true; + } else if (decoration == spv::Decoration::Binding) { + if (found_binding_to_convert) { + assert(false && "A resource has two OpDecorate for the binding"); + return false; + } + descriptor_set_binding->binding = decorate->GetSingleWordInOperand(2u); + found_binding_to_convert = true; + } + } + return found_descriptor_set_to_convert && found_binding_to_convert; +} + +bool ConvertToSampledImagePass::ShouldResourceBeConverted( + const DescriptorSetAndBinding& descriptor_set_binding) const { + return descriptor_set_binding_pairs_.find(descriptor_set_binding) != + descriptor_set_binding_pairs_.end(); +} + +const analysis::Type* ConvertToSampledImagePass::GetVariableType( + const Instruction& variable) const { + if (variable.opcode() != spv::Op::OpVariable) return nullptr; + auto* type = context()->get_type_mgr()->GetType(variable.type_id()); + auto* pointer_type = type->AsPointer(); + if (!pointer_type) return nullptr; + + return pointer_type->pointee_type(); +} + +spv::StorageClass ConvertToSampledImagePass::GetStorageClass( + const Instruction& variable) const { + assert(variable.opcode() == spv::Op::OpVariable); + auto* type = context()->get_type_mgr()->GetType(variable.type_id()); + auto* pointer_type = type->AsPointer(); + if (!pointer_type) return spv::StorageClass::Max; + + return pointer_type->storage_class(); +} + +bool ConvertToSampledImagePass::CollectResourcesToConvert( + DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_sampler, + DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_image) + const { + for (auto& inst : context()->types_values()) { + const auto* variable_type = GetVariableType(inst); + if (variable_type == nullptr) continue; + + DescriptorSetAndBinding descriptor_set_binding; + if (!GetDescriptorSetBinding(inst, &descriptor_set_binding)) continue; + + if (!ShouldResourceBeConverted(descriptor_set_binding)) { + continue; + } + + if (variable_type->AsImage()) { + if (!descriptor_set_binding_pair_to_image + ->insert({descriptor_set_binding, &inst}) + .second) { + return false; + } + } else if (variable_type->AsSampler()) { + if (!descriptor_set_binding_pair_to_sampler + ->insert({descriptor_set_binding, &inst}) + .second) { + return false; + } + } + } + return true; +} + +Pass::Status ConvertToSampledImagePass::Process() { + Status status = Status::SuccessWithoutChange; + + DescriptorSetBindingToInstruction descriptor_set_binding_pair_to_sampler, + descriptor_set_binding_pair_to_image; + if (!CollectResourcesToConvert(&descriptor_set_binding_pair_to_sampler, + &descriptor_set_binding_pair_to_image)) { + return Status::Failure; + } + + for (auto& image : descriptor_set_binding_pair_to_image) { + status = CombineStatus( + status, UpdateImageVariableToSampledImage(image.second, image.first)); + if (status == Status::Failure) { + return status; + } + } + + for (const auto& sampler : descriptor_set_binding_pair_to_sampler) { + // Converting only a Sampler to Sampled Image is not allowed. It must have a + // corresponding image to combine the sampler with. + auto image_itr = descriptor_set_binding_pair_to_image.find(sampler.first); + if (image_itr == descriptor_set_binding_pair_to_image.end() || + image_itr->second == nullptr) { + return Status::Failure; + } + + status = CombineStatus( + status, CheckUsesOfSamplerVariable(sampler.second, image_itr->second)); + if (status == Status::Failure) { + return status; + } + } + + return status; +} + +void ConvertToSampledImagePass::FindUses(const Instruction* inst, + std::vector* uses, + spv::Op user_opcode) const { + auto* def_use_mgr = context()->get_def_use_mgr(); + def_use_mgr->ForEachUser(inst, [uses, user_opcode, this](Instruction* user) { + if (user->opcode() == user_opcode) { + uses->push_back(user); + } else if (user->opcode() == spv::Op::OpCopyObject) { + FindUses(user, uses, user_opcode); + } + }); +} + +void ConvertToSampledImagePass::FindUsesOfImage( + const Instruction* image, std::vector* uses) const { + auto* def_use_mgr = context()->get_def_use_mgr(); + def_use_mgr->ForEachUser(image, [uses, this](Instruction* user) { + switch (user->opcode()) { + case spv::Op::OpImageFetch: + case spv::Op::OpImageRead: + case spv::Op::OpImageWrite: + case spv::Op::OpImageQueryFormat: + case spv::Op::OpImageQueryOrder: + case spv::Op::OpImageQuerySizeLod: + case spv::Op::OpImageQuerySize: + case spv::Op::OpImageQueryLevels: + case spv::Op::OpImageQuerySamples: + case spv::Op::OpImageSparseFetch: + uses->push_back(user); + default: + break; + } + if (user->opcode() == spv::Op::OpCopyObject) { + FindUsesOfImage(user, uses); + } + }); +} + +Instruction* ConvertToSampledImagePass::CreateImageExtraction( + Instruction* sampled_image) { + InstructionBuilder builder( + context(), sampled_image->NextNode(), + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + return builder.AddUnaryOp( + GetImageTypeOfSampledImage(context()->get_type_mgr(), sampled_image), + spv::Op::OpImage, sampled_image->result_id()); +} + +uint32_t ConvertToSampledImagePass::GetSampledImageTypeForImage( + Instruction* image_variable) { + const auto* variable_type = GetVariableType(*image_variable); + if (variable_type == nullptr) return 0; + const auto* image_type = variable_type->AsImage(); + if (image_type == nullptr) return 0; + + analysis::Image image_type_for_sampled_image(*image_type); + analysis::SampledImage sampled_image_type(&image_type_for_sampled_image); + return context()->get_type_mgr()->GetTypeInstruction(&sampled_image_type); +} + +Instruction* ConvertToSampledImagePass::UpdateImageUses( + Instruction* sampled_image_load) { + std::vector uses_of_load; + FindUsesOfImage(sampled_image_load, &uses_of_load); + if (uses_of_load.empty()) return nullptr; + + auto* extracted_image = CreateImageExtraction(sampled_image_load); + for (auto* user : uses_of_load) { + user->SetInOperand(0, {extracted_image->result_id()}); + context()->get_def_use_mgr()->AnalyzeInstUse(user); + } + return extracted_image; +} + +bool ConvertToSampledImagePass:: + IsSamplerOfSampledImageDecoratedByDescriptorSetBinding( + Instruction* sampled_image_inst, + const DescriptorSetAndBinding& descriptor_set_binding) { + auto* def_use_mgr = context()->get_def_use_mgr(); + uint32_t sampler_id = sampled_image_inst->GetSingleWordInOperand(1u); + auto* sampler_load = def_use_mgr->GetDef(sampler_id); + if (sampler_load->opcode() != spv::Op::OpLoad) return false; + auto* sampler = def_use_mgr->GetDef(sampler_load->GetSingleWordInOperand(0u)); + DescriptorSetAndBinding sampler_descriptor_set_binding; + return GetDescriptorSetBinding(*sampler, &sampler_descriptor_set_binding) && + sampler_descriptor_set_binding == descriptor_set_binding; +} + +void ConvertToSampledImagePass::UpdateSampledImageUses( + Instruction* image_load, Instruction* image_extraction, + const DescriptorSetAndBinding& image_descriptor_set_binding) { + std::vector sampled_image_users; + FindUses(image_load, &sampled_image_users, spv::Op::OpSampledImage); + + auto* def_use_mgr = context()->get_def_use_mgr(); + for (auto* sampled_image_inst : sampled_image_users) { + if (IsSamplerOfSampledImageDecoratedByDescriptorSetBinding( + sampled_image_inst, image_descriptor_set_binding)) { + context()->ReplaceAllUsesWith(sampled_image_inst->result_id(), + image_load->result_id()); + def_use_mgr->AnalyzeInstUse(image_load); + context()->KillInst(sampled_image_inst); + } else { + if (!image_extraction) + image_extraction = CreateImageExtraction(image_load); + sampled_image_inst->SetInOperand(0, {image_extraction->result_id()}); + def_use_mgr->AnalyzeInstUse(sampled_image_inst); + } + } +} + +void ConvertToSampledImagePass::MoveInstructionNextToType(Instruction* inst, + uint32_t type_id) { + auto* type_inst = context()->get_def_use_mgr()->GetDef(type_id); + inst->SetResultType(type_id); + inst->RemoveFromList(); + inst->InsertAfter(type_inst); +} + +bool ConvertToSampledImagePass::ConvertImageVariableToSampledImage( + Instruction* image_variable, uint32_t sampled_image_type_id) { + auto* sampled_image_type = + context()->get_type_mgr()->GetType(sampled_image_type_id); + if (sampled_image_type == nullptr) return false; + auto storage_class = GetStorageClass(*image_variable); + if (storage_class == spv::StorageClass::Max) return false; + analysis::Pointer sampled_image_pointer(sampled_image_type, storage_class); + + // Make sure |image_variable| is behind its type i.e., avoid the forward + // reference. + uint32_t type_id = + context()->get_type_mgr()->GetTypeInstruction(&sampled_image_pointer); + MoveInstructionNextToType(image_variable, type_id); + return true; +} + +Pass::Status ConvertToSampledImagePass::UpdateImageVariableToSampledImage( + Instruction* image_variable, + const DescriptorSetAndBinding& descriptor_set_binding) { + std::vector image_variable_loads; + FindUses(image_variable, &image_variable_loads, spv::Op::OpLoad); + if (image_variable_loads.empty()) return Status::SuccessWithoutChange; + + const uint32_t sampled_image_type_id = + GetSampledImageTypeForImage(image_variable); + if (!sampled_image_type_id) return Status::Failure; + + for (auto* load : image_variable_loads) { + load->SetResultType(sampled_image_type_id); + auto* image_extraction = UpdateImageUses(load); + UpdateSampledImageUses(load, image_extraction, descriptor_set_binding); + } + + return ConvertImageVariableToSampledImage(image_variable, + sampled_image_type_id) + ? Status::SuccessWithChange + : Status::Failure; +} + +bool ConvertToSampledImagePass::DoesSampledImageReferenceImage( + Instruction* sampled_image_inst, Instruction* image_variable) { + if (sampled_image_inst->opcode() != spv::Op::OpSampledImage) return false; + auto* def_use_mgr = context()->get_def_use_mgr(); + auto* image_load = GetNonCopyObjectDef( + def_use_mgr, sampled_image_inst->GetSingleWordInOperand(0u)); + if (image_load->opcode() != spv::Op::OpLoad) return false; + auto* image = + GetNonCopyObjectDef(def_use_mgr, image_load->GetSingleWordInOperand(0u)); + return image->opcode() == spv::Op::OpVariable && + image->result_id() == image_variable->result_id(); +} + +Pass::Status ConvertToSampledImagePass::CheckUsesOfSamplerVariable( + const Instruction* sampler_variable, + Instruction* image_to_be_combined_with) { + if (image_to_be_combined_with == nullptr) return Status::Failure; + + std::vector sampler_variable_loads; + FindUses(sampler_variable, &sampler_variable_loads, spv::Op::OpLoad); + for (auto* load : sampler_variable_loads) { + std::vector sampled_image_users; + FindUses(load, &sampled_image_users, spv::Op::OpSampledImage); + for (auto* sampled_image_inst : sampled_image_users) { + if (!DoesSampledImageReferenceImage(sampled_image_inst, + image_to_be_combined_with)) { + return Status::Failure; + } + } + } + return Status::SuccessWithoutChange; +} + +std::unique_ptr +ConvertToSampledImagePass::ParseDescriptorSetBindingPairsString( + const char* str) { + if (!str) return nullptr; + + auto descriptor_set_binding_pairs = + MakeUnique(); + + while (std::isspace(*str)) str++; // skip leading spaces. + + // The parsing loop, break when points to the end. + while (*str) { + // Parse the descriptor set. + uint32_t descriptor_set = 0; + str = ParseNumberUntilSeparator(str, &descriptor_set); + if (str == nullptr) return nullptr; + + // Find the ':', spaces between the descriptor set and the ':' are not + // allowed. + if (*str++ != ':') { + // ':' not found + return nullptr; + } + + // Parse the binding. + uint32_t binding = 0; + str = ParseNumberUntilSeparator(str, &binding); + if (str == nullptr) return nullptr; + + descriptor_set_binding_pairs->push_back({descriptor_set, binding}); + + // Skip trailing spaces. + while (std::isspace(*str)) str++; + } + + return descriptor_set_binding_pairs; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_sampled_image_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_sampled_image_pass.h new file mode 100644 index 000000000000..a8b1501e6fe8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/convert_to_sampled_image_pass.h @@ -0,0 +1,207 @@ +// Copyright (c) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_ +#define SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_ + +#include +#include +#include + +#include "source/opt/pass.h" +#include "source/opt/types.h" + +namespace spvtools { +namespace opt { + +// A struct for a pair of descriptor set and binding. +struct DescriptorSetAndBinding { + uint32_t descriptor_set; + uint32_t binding; + + bool operator==(const DescriptorSetAndBinding& descriptor_set_binding) const { + return descriptor_set_binding.descriptor_set == descriptor_set && + descriptor_set_binding.binding == binding; + } +}; + +// See optimizer.hpp for documentation. +class ConvertToSampledImagePass : public Pass { + public: + // Hashing functor for the pair of descriptor set and binding. + struct DescriptorSetAndBindingHash { + size_t operator()( + const DescriptorSetAndBinding& descriptor_set_binding) const { + return std::hash()(descriptor_set_binding.descriptor_set) ^ + std::hash()(descriptor_set_binding.binding); + } + }; + + using SetOfDescriptorSetAndBindingPairs = + std::unordered_set; + using DescriptorSetBindingToInstruction = + std::unordered_map; + + explicit ConvertToSampledImagePass( + const std::vector& descriptor_set_binding_pairs) + : descriptor_set_binding_pairs_(descriptor_set_binding_pairs.begin(), + descriptor_set_binding_pairs.end()) {} + + const char* name() const override { return "convert-to-sampled-image"; } + Status Process() override; + + // Parses the given null-terminated C string to get a vector of descriptor set + // and binding pairs. Returns a unique pointer to the vector of descriptor set + // and binding pairs built from the given |str| on success. Returns a nullptr + // if the given string is not valid for building the vector of pairs. + // A valid string for building the vector of pairs should follow the rule + // below: + // + // ": : ..." + // Example: + // "3:5 2:1 0:4" + // + // Entries are separated with blank spaces (i.e.:' ', '\n', '\r', '\t', + // '\f', '\v'). Each entry corresponds to a descriptor set and binding pair. + // Multiple spaces between, before or after entries are allowed. However, + // spaces are not allowed within a descriptor set or binding. + // + // In each entry, the descriptor set and binding are separated by ':'. + // Missing ':' in any entry is invalid. And it is invalid to have blank + // spaces in between the descriptor set and ':' or ':' and the binding. + // + // : the descriptor set. + // The text must represent a valid uint32_t number. + // + // : the binding. + // The text must represent a valid uint32_t number. + static std::unique_ptr> + ParseDescriptorSetBindingPairsString(const char* str); + + private: + // Collects resources to convert to sampled image and saves them in + // |descriptor_set_binding_pair_to_sampler| if the resource is a sampler and + // saves them in |descriptor_set_binding_pair_to_image| if the resource is an + // image. Returns false if two samplers or two images have the same descriptor + // set and binding. Otherwise, returns true. + bool CollectResourcesToConvert( + DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_sampler, + DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_image) + const; + + // Finds an OpDecorate with DescriptorSet decorating |inst| and another + // OpDecorate with Binding decorating |inst|. Stores the descriptor set and + // binding in |descriptor_set_binding|. Returns whether it successfully finds + // the descriptor set and binding or not. + bool GetDescriptorSetBinding( + const Instruction& inst, + DescriptorSetAndBinding* descriptor_set_binding) const; + + // Returns whether |descriptor_set_binding| is a pair of a descriptor set + // and a binding that we have to convert resources with it to a sampled image + // or not. + bool ShouldResourceBeConverted( + const DescriptorSetAndBinding& descriptor_set_binding) const; + + // Returns the pointee type of the type of variable |variable|. If |variable| + // is not an OpVariable instruction, just returns nullptr. + const analysis::Type* GetVariableType(const Instruction& variable) const; + + // Returns the storage class of |variable|. + spv::StorageClass GetStorageClass(const Instruction& variable) const; + + // Finds |inst|'s users whose opcode is |user_opcode| or users of OpCopyObject + // instructions of |inst| whose opcode is |user_opcode| and puts them in + // |uses|. + void FindUses(const Instruction* inst, std::vector* uses, + spv::Op user_opcode) const; + + // Finds OpImage* instructions using |image| or OpCopyObject instructions that + // copy |image| and puts them in |uses|. + void FindUsesOfImage(const Instruction* image, + std::vector* uses) const; + + // Creates an OpImage instruction that extracts the image from the sampled + // image |sampled_image|. + Instruction* CreateImageExtraction(Instruction* sampled_image); + + // Converts |image_variable| whose type is an image pointer to sampled image + // type. Updates users of |image_variable| accordingly. If some instructions + // e.g., OpImageRead use |image_variable| as an Image operand, creates an + // image extracted from the sampled image using OpImage and replace the Image + // operands of the users with the extracted image. If some OpSampledImage + // instructions use |image_variable| and sampler whose descriptor set and + // binding are the same with |image_variable|, just combines |image_variable| + // and the sampler to a sampled image. + Pass::Status UpdateImageVariableToSampledImage( + Instruction* image_variable, + const DescriptorSetAndBinding& descriptor_set_binding); + + // Returns the id of type sampled image type whose image type is the one of + // |image_variable|. + uint32_t GetSampledImageTypeForImage(Instruction* image_variable); + + // Moves |inst| next to the OpType* instruction with |type_id|. + void MoveInstructionNextToType(Instruction* inst, uint32_t type_id); + + // Converts |image_variable| whose type is an image pointer to sampled image + // with the type id |sampled_image_type_id|. Returns whether it successfully + // converts the type of |image_variable| or not. + bool ConvertImageVariableToSampledImage(Instruction* image_variable, + uint32_t sampled_image_type_id); + + // Replaces |sampled_image_load| instruction used by OpImage* with the image + // extracted from |sampled_image_load|. Returns the extracted image or nullptr + // if it does not have uses. + Instruction* UpdateImageUses(Instruction* sampled_image_load); + + // Returns true if the sampler of |sampled_image_inst| is decorated by a + // descriptor set and a binding |descriptor_set_binding|. + bool IsSamplerOfSampledImageDecoratedByDescriptorSetBinding( + Instruction* sampled_image_inst, + const DescriptorSetAndBinding& descriptor_set_binding); + + // Replaces OpSampledImage instructions using |image_load| with |image_load| + // if the sampler of the OpSampledImage instruction has descriptor set and + // binding |image_descriptor_set_binding|. Otherwise, replaces |image_load| + // with |image_extraction|. + void UpdateSampledImageUses( + Instruction* image_load, Instruction* image_extraction, + const DescriptorSetAndBinding& image_descriptor_set_binding); + + // Checks the uses of |sampler_variable|. When a sampler is used by + // OpSampledImage instruction, the corresponding image must be + // |image_to_be_combined_with| that should be already converted to a sampled + // image by UpdateImageVariableToSampledImage() method. + Pass::Status CheckUsesOfSamplerVariable( + const Instruction* sampler_variable, + Instruction* image_to_be_combined_with); + + // Returns true if Image operand of |sampled_image_inst| is the image of + // |image_variable|. + bool DoesSampledImageReferenceImage(Instruction* sampled_image_inst, + Instruction* image_variable); + + // A set of pairs of descriptor set and binding. If an image and/or a sampler + // have a pair of descriptor set and binding that is an element of + // |descriptor_set_binding_pairs_|, they/it will be converted to a sampled + // image by this pass. + const SetOfDescriptorSetAndBindingPairs descriptor_set_binding_pairs_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/copy_prop_arrays.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/copy_prop_arrays.cpp new file mode 100644 index 000000000000..c2bea8ad0412 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/copy_prop_arrays.cpp @@ -0,0 +1,884 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/copy_prop_arrays.h" + +#include + +#include "source/opt/ir_builder.h" + +namespace spvtools { +namespace opt { +namespace { + +constexpr uint32_t kLoadPointerInOperand = 0; +constexpr uint32_t kStorePointerInOperand = 0; +constexpr uint32_t kStoreObjectInOperand = 1; +constexpr uint32_t kCompositeExtractObjectInOperand = 0; +constexpr uint32_t kTypePointerStorageClassInIdx = 0; +constexpr uint32_t kTypePointerPointeeInIdx = 1; + +bool IsDebugDeclareOrValue(Instruction* di) { + auto dbg_opcode = di->GetCommonDebugOpcode(); + return dbg_opcode == CommonDebugInfoDebugDeclare || + dbg_opcode == CommonDebugInfoDebugValue; +} + +// Returns the number of members in |type|. If |type| is not a composite type +// or the number of components is not known at compile time, the return value +// will be 0. +uint32_t GetNumberOfMembers(const analysis::Type* type, IRContext* context) { + if (const analysis::Struct* struct_type = type->AsStruct()) { + return static_cast(struct_type->element_types().size()); + } else if (const analysis::Array* array_type = type->AsArray()) { + const analysis::Constant* length_const = + context->get_constant_mgr()->FindDeclaredConstant( + array_type->LengthId()); + + if (length_const == nullptr) { + // This can happen if the length is an OpSpecConstant. + return 0; + } + assert(length_const->type()->AsInteger()); + return length_const->GetU32(); + } else if (const analysis::Vector* vector_type = type->AsVector()) { + return vector_type->element_count(); + } else if (const analysis::Matrix* matrix_type = type->AsMatrix()) { + return matrix_type->element_count(); + } else { + return 0; + } +} + +} // namespace + +Pass::Status CopyPropagateArrays::Process() { + bool modified = false; + for (Function& function : *get_module()) { + if (function.IsDeclaration()) { + continue; + } + + BasicBlock* entry_bb = &*function.begin(); + + for (auto var_inst = entry_bb->begin(); + var_inst->opcode() == spv::Op::OpVariable; ++var_inst) { + if (!IsPointerToArrayType(var_inst->type_id())) { + continue; + } + + // Find the only store to the entire memory location, if it exists. + Instruction* store_inst = FindStoreInstruction(&*var_inst); + + if (!store_inst) { + continue; + } + + std::unique_ptr source_object = + FindSourceObjectIfPossible(&*var_inst, store_inst); + + if (source_object != nullptr) { + if (CanUpdateUses(&*var_inst, source_object->GetPointerTypeId(this))) { + modified = true; + PropagateObject(&*var_inst, source_object.get(), store_inst); + } + } + } + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +std::unique_ptr +CopyPropagateArrays::FindSourceObjectIfPossible(Instruction* var_inst, + Instruction* store_inst) { + assert(var_inst->opcode() == spv::Op::OpVariable && "Expecting a variable."); + + // Check that the variable is a composite object where |store_inst| + // dominates all of its loads. + if (!store_inst) { + return nullptr; + } + + // Look at the loads to ensure they are dominated by the store. + if (!HasValidReferencesOnly(var_inst, store_inst)) { + return nullptr; + } + + // If so, look at the store to see if it is the copy of an object. + std::unique_ptr source = GetSourceObjectIfAny( + store_inst->GetSingleWordInOperand(kStoreObjectInOperand)); + + if (!source) { + return nullptr; + } + + // Ensure that |source| does not change between the point at which it is + // loaded, and the position in which |var_inst| is loaded. + // + // For now we will go with the easy to implement approach, and check that the + // entire variable (not just the specific component) is never written to. + + if (!HasNoStores(source->GetVariable())) { + return nullptr; + } + return source; +} + +Instruction* CopyPropagateArrays::FindStoreInstruction( + const Instruction* var_inst) const { + Instruction* store_inst = nullptr; + get_def_use_mgr()->WhileEachUser( + var_inst, [&store_inst, var_inst](Instruction* use) { + if (use->opcode() == spv::Op::OpStore && + use->GetSingleWordInOperand(kStorePointerInOperand) == + var_inst->result_id()) { + if (store_inst == nullptr) { + store_inst = use; + } else { + store_inst = nullptr; + return false; + } + } + return true; + }); + return store_inst; +} + +void CopyPropagateArrays::PropagateObject(Instruction* var_inst, + MemoryObject* source, + Instruction* insertion_point) { + assert(var_inst->opcode() == spv::Op::OpVariable && + "This function propagates variables."); + + Instruction* new_access_chain = BuildNewAccessChain(insertion_point, source); + context()->KillNamesAndDecorates(var_inst); + UpdateUses(var_inst, new_access_chain); +} + +Instruction* CopyPropagateArrays::BuildNewAccessChain( + Instruction* insertion_point, + CopyPropagateArrays::MemoryObject* source) const { + InstructionBuilder builder( + context(), insertion_point, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + if (source->AccessChain().size() == 0) { + return source->GetVariable(); + } + + source->BuildConstants(); + std::vector access_ids(source->AccessChain().size()); + std::transform( + source->AccessChain().cbegin(), source->AccessChain().cend(), + access_ids.begin(), [](const AccessChainEntry& entry) { + assert(entry.is_result_id && "Constants needs to be built first."); + return entry.result_id; + }); + + return builder.AddAccessChain(source->GetPointerTypeId(this), + source->GetVariable()->result_id(), access_ids); +} + +bool CopyPropagateArrays::HasNoStores(Instruction* ptr_inst) { + return get_def_use_mgr()->WhileEachUser(ptr_inst, [this](Instruction* use) { + if (use->opcode() == spv::Op::OpLoad) { + return true; + } else if (use->opcode() == spv::Op::OpAccessChain) { + return HasNoStores(use); + } else if (use->IsDecoration() || use->opcode() == spv::Op::OpName) { + return true; + } else if (use->opcode() == spv::Op::OpStore) { + return false; + } else if (use->opcode() == spv::Op::OpImageTexelPointer) { + return true; + } else if (use->opcode() == spv::Op::OpEntryPoint) { + return true; + } + // Some other instruction. Be conservative. + return false; + }); +} + +bool CopyPropagateArrays::HasValidReferencesOnly(Instruction* ptr_inst, + Instruction* store_inst) { + BasicBlock* store_block = context()->get_instr_block(store_inst); + DominatorAnalysis* dominator_analysis = + context()->GetDominatorAnalysis(store_block->GetParent()); + + return get_def_use_mgr()->WhileEachUser( + ptr_inst, + [this, store_inst, dominator_analysis, ptr_inst](Instruction* use) { + if (use->opcode() == spv::Op::OpLoad || + use->opcode() == spv::Op::OpImageTexelPointer) { + // TODO: If there are many load in the same BB as |store_inst| the + // time to do the multiple traverses can add up. Consider collecting + // those loads and doing a single traversal. + return dominator_analysis->Dominates(store_inst, use); + } else if (use->opcode() == spv::Op::OpAccessChain) { + return HasValidReferencesOnly(use, store_inst); + } else if (use->IsDecoration() || use->opcode() == spv::Op::OpName) { + return true; + } else if (use->opcode() == spv::Op::OpStore) { + // If we are storing to part of the object it is not an candidate. + return ptr_inst->opcode() == spv::Op::OpVariable && + store_inst->GetSingleWordInOperand(kStorePointerInOperand) == + ptr_inst->result_id(); + } else if (IsDebugDeclareOrValue(use)) { + return true; + } + // Some other instruction. Be conservative. + return false; + }); +} + +std::unique_ptr +CopyPropagateArrays::GetSourceObjectIfAny(uint32_t result) { + Instruction* result_inst = context()->get_def_use_mgr()->GetDef(result); + + switch (result_inst->opcode()) { + case spv::Op::OpLoad: + return BuildMemoryObjectFromLoad(result_inst); + case spv::Op::OpCompositeExtract: + return BuildMemoryObjectFromExtract(result_inst); + case spv::Op::OpCompositeConstruct: + return BuildMemoryObjectFromCompositeConstruct(result_inst); + case spv::Op::OpCopyObject: + return GetSourceObjectIfAny(result_inst->GetSingleWordInOperand(0)); + case spv::Op::OpCompositeInsert: + return BuildMemoryObjectFromInsert(result_inst); + default: + return nullptr; + } +} + +std::unique_ptr +CopyPropagateArrays::BuildMemoryObjectFromLoad(Instruction* load_inst) { + std::vector components_in_reverse; + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + + Instruction* current_inst = def_use_mgr->GetDef( + load_inst->GetSingleWordInOperand(kLoadPointerInOperand)); + + // Build the access chain for the memory object by collecting the indices used + // in the OpAccessChain instructions. If we find a variable index, then + // return |nullptr| because we cannot know for sure which memory location is + // used. + // + // It is built in reverse order because the different |OpAccessChain| + // instructions are visited in reverse order from which they are applied. + while (current_inst->opcode() == spv::Op::OpAccessChain) { + for (uint32_t i = current_inst->NumInOperands() - 1; i >= 1; --i) { + uint32_t element_index_id = current_inst->GetSingleWordInOperand(i); + components_in_reverse.push_back(element_index_id); + } + current_inst = def_use_mgr->GetDef(current_inst->GetSingleWordInOperand(0)); + } + + // If the address in the load is not constructed from an |OpVariable| + // instruction followed by a series of |OpAccessChain| instructions, then + // return |nullptr| because we cannot identify the owner or access chain + // exactly. + if (current_inst->opcode() != spv::Op::OpVariable) { + return nullptr; + } + + // Build the memory object. Use |rbegin| and |rend| to put the access chain + // back in the correct order. + return std::unique_ptr( + new MemoryObject(current_inst, components_in_reverse.rbegin(), + components_in_reverse.rend())); +} + +std::unique_ptr +CopyPropagateArrays::BuildMemoryObjectFromExtract(Instruction* extract_inst) { + assert(extract_inst->opcode() == spv::Op::OpCompositeExtract && + "Expecting an OpCompositeExtract instruction."); + std::unique_ptr result = GetSourceObjectIfAny( + extract_inst->GetSingleWordInOperand(kCompositeExtractObjectInOperand)); + + if (!result) { + return nullptr; + } + + // Copy the indices of the extract instruction to |OpAccessChain| indices. + std::vector components; + for (uint32_t i = 1; i < extract_inst->NumInOperands(); ++i) { + components.push_back({false, {extract_inst->GetSingleWordInOperand(i)}}); + } + result->PushIndirection(components); + return result; +} + +std::unique_ptr +CopyPropagateArrays::BuildMemoryObjectFromCompositeConstruct( + Instruction* conststruct_inst) { + assert(conststruct_inst->opcode() == spv::Op::OpCompositeConstruct && + "Expecting an OpCompositeConstruct instruction."); + + // If every operand in the instruction are part of the same memory object, and + // are being combined in the same order, then the result is the same as the + // parent. + + std::unique_ptr memory_object = + GetSourceObjectIfAny(conststruct_inst->GetSingleWordInOperand(0)); + + if (!memory_object) { + return nullptr; + } + + if (!memory_object->IsMember()) { + return nullptr; + } + + AccessChainEntry last_access = memory_object->AccessChain().back(); + if (!IsAccessChainIndexValidAndEqualTo(last_access, 0)) { + return nullptr; + } + + memory_object->PopIndirection(); + if (memory_object->GetNumberOfMembers() != + conststruct_inst->NumInOperands()) { + return nullptr; + } + + for (uint32_t i = 1; i < conststruct_inst->NumInOperands(); ++i) { + std::unique_ptr member_object = + GetSourceObjectIfAny(conststruct_inst->GetSingleWordInOperand(i)); + + if (!member_object) { + return nullptr; + } + + if (!member_object->IsMember()) { + return nullptr; + } + + if (!memory_object->Contains(member_object.get())) { + return nullptr; + } + + last_access = member_object->AccessChain().back(); + if (!IsAccessChainIndexValidAndEqualTo(last_access, i)) { + return nullptr; + } + } + return memory_object; +} + +std::unique_ptr +CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) { + assert(insert_inst->opcode() == spv::Op::OpCompositeInsert && + "Expecting an OpCompositeInsert instruction."); + + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + const analysis::Type* result_type = type_mgr->GetType(insert_inst->type_id()); + + uint32_t number_of_elements = GetNumberOfMembers(result_type, context()); + + if (number_of_elements == 0) { + return nullptr; + } + + if (insert_inst->NumInOperands() != 3) { + return nullptr; + } + + if (insert_inst->GetSingleWordInOperand(2) != number_of_elements - 1) { + return nullptr; + } + + std::unique_ptr memory_object = + GetSourceObjectIfAny(insert_inst->GetSingleWordInOperand(0)); + + if (!memory_object) { + return nullptr; + } + + if (!memory_object->IsMember()) { + return nullptr; + } + + AccessChainEntry last_access = memory_object->AccessChain().back(); + if (!IsAccessChainIndexValidAndEqualTo(last_access, number_of_elements - 1)) { + return nullptr; + } + + memory_object->PopIndirection(); + + Instruction* current_insert = + def_use_mgr->GetDef(insert_inst->GetSingleWordInOperand(1)); + for (uint32_t i = number_of_elements - 1; i > 0; --i) { + if (current_insert->opcode() != spv::Op::OpCompositeInsert) { + return nullptr; + } + + if (current_insert->NumInOperands() != 3) { + return nullptr; + } + + if (current_insert->GetSingleWordInOperand(2) != i - 1) { + return nullptr; + } + + std::unique_ptr current_memory_object = + GetSourceObjectIfAny(current_insert->GetSingleWordInOperand(0)); + + if (!current_memory_object) { + return nullptr; + } + + if (!current_memory_object->IsMember()) { + return nullptr; + } + + if (memory_object->AccessChain().size() + 1 != + current_memory_object->AccessChain().size()) { + return nullptr; + } + + if (!memory_object->Contains(current_memory_object.get())) { + return nullptr; + } + + AccessChainEntry current_last_access = + current_memory_object->AccessChain().back(); + if (!IsAccessChainIndexValidAndEqualTo(current_last_access, i - 1)) { + return nullptr; + } + current_insert = + def_use_mgr->GetDef(current_insert->GetSingleWordInOperand(1)); + } + + return memory_object; +} + +bool CopyPropagateArrays::IsAccessChainIndexValidAndEqualTo( + const AccessChainEntry& entry, uint32_t value) const { + if (!entry.is_result_id) { + return entry.immediate == value; + } + + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + const analysis::Constant* constant = + const_mgr->FindDeclaredConstant(entry.result_id); + if (!constant || !constant->type()->AsInteger()) { + return false; + } + return constant->GetU32() == value; +} + +bool CopyPropagateArrays::IsPointerToArrayType(uint32_t type_id) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Pointer* pointer_type = type_mgr->GetType(type_id)->AsPointer(); + if (pointer_type) { + return pointer_type->pointee_type()->kind() == analysis::Type::kArray || + pointer_type->pointee_type()->kind() == analysis::Type::kImage; + } + return false; +} + +bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, + uint32_t type_id) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + + analysis::Type* type = type_mgr->GetType(type_id); + if (type->AsRuntimeArray()) { + return false; + } + + if (!type->AsStruct() && !type->AsArray() && !type->AsPointer()) { + // If the type is not an aggregate, then the desired type must be the + // same as the current type. No work to do, and we can do that. + return true; + } + + return def_use_mgr->WhileEachUse(original_ptr_inst, [this, type_mgr, + const_mgr, + type](Instruction* use, + uint32_t) { + if (IsDebugDeclareOrValue(use)) return true; + + switch (use->opcode()) { + case spv::Op::OpLoad: { + analysis::Pointer* pointer_type = type->AsPointer(); + uint32_t new_type_id = type_mgr->GetId(pointer_type->pointee_type()); + + if (new_type_id != use->type_id()) { + return CanUpdateUses(use, new_type_id); + } + return true; + } + case spv::Op::OpAccessChain: { + analysis::Pointer* pointer_type = type->AsPointer(); + const analysis::Type* pointee_type = pointer_type->pointee_type(); + + std::vector access_chain; + for (uint32_t i = 1; i < use->NumInOperands(); ++i) { + const analysis::Constant* index_const = + const_mgr->FindDeclaredConstant(use->GetSingleWordInOperand(i)); + if (index_const) { + access_chain.push_back(index_const->GetU32()); + } else { + // Variable index means the type is a type where every element + // is the same type. Use element 0 to get the type. + access_chain.push_back(0); + + // We are trying to access a struct with variable indices. + // This cannot happen. + if (pointee_type->kind() == analysis::Type::kStruct) { + return false; + } + } + } + + const analysis::Type* new_pointee_type = + type_mgr->GetMemberType(pointee_type, access_chain); + analysis::Pointer pointerTy(new_pointee_type, + pointer_type->storage_class()); + uint32_t new_pointer_type_id = + context()->get_type_mgr()->GetTypeInstruction(&pointerTy); + if (new_pointer_type_id == 0) { + return false; + } + + if (new_pointer_type_id != use->type_id()) { + return CanUpdateUses(use, new_pointer_type_id); + } + return true; + } + case spv::Op::OpCompositeExtract: { + std::vector access_chain; + for (uint32_t i = 1; i < use->NumInOperands(); ++i) { + access_chain.push_back(use->GetSingleWordInOperand(i)); + } + + const analysis::Type* new_type = + type_mgr->GetMemberType(type, access_chain); + uint32_t new_type_id = type_mgr->GetTypeInstruction(new_type); + if (new_type_id == 0) { + return false; + } + + if (new_type_id != use->type_id()) { + return CanUpdateUses(use, new_type_id); + } + return true; + } + case spv::Op::OpStore: + // If needed, we can create an element-by-element copy to change the + // type of the value being stored. This way we can always handled + // stores. + return true; + case spv::Op::OpImageTexelPointer: + case spv::Op::OpName: + return true; + default: + return use->IsDecoration(); + } + }); +} + +void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, + Instruction* new_ptr_inst) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + + std::vector > uses; + def_use_mgr->ForEachUse(original_ptr_inst, + [&uses](Instruction* use, uint32_t index) { + uses.push_back({use, index}); + }); + + for (auto pair : uses) { + Instruction* use = pair.first; + uint32_t index = pair.second; + + if (use->IsCommonDebugInstr()) { + switch (use->GetCommonDebugOpcode()) { + case CommonDebugInfoDebugDeclare: { + if (new_ptr_inst->opcode() == spv::Op::OpVariable || + new_ptr_inst->opcode() == spv::Op::OpFunctionParameter) { + context()->ForgetUses(use); + use->SetOperand(index, {new_ptr_inst->result_id()}); + context()->AnalyzeUses(use); + } else { + // Based on the spec, we cannot use a pointer other than OpVariable + // or OpFunctionParameter for DebugDeclare. We have to use + // DebugValue with Deref. + + context()->ForgetUses(use); + + // Change DebugDeclare to DebugValue. + use->SetOperand(index - 2, + {static_cast(CommonDebugInfoDebugValue)}); + use->SetOperand(index, {new_ptr_inst->result_id()}); + + // Add Deref operation. + Instruction* dbg_expr = + def_use_mgr->GetDef(use->GetSingleWordOperand(index + 1)); + auto* deref_expr_instr = + context()->get_debug_info_mgr()->DerefDebugExpression(dbg_expr); + use->SetOperand(index + 1, {deref_expr_instr->result_id()}); + + context()->AnalyzeUses(deref_expr_instr); + context()->AnalyzeUses(use); + } + break; + } + case CommonDebugInfoDebugValue: + context()->ForgetUses(use); + use->SetOperand(index, {new_ptr_inst->result_id()}); + context()->AnalyzeUses(use); + break; + default: + assert(false && "Don't know how to rewrite instruction"); + break; + } + continue; + } + + switch (use->opcode()) { + case spv::Op::OpLoad: { + // Replace the actual use. + context()->ForgetUses(use); + use->SetOperand(index, {new_ptr_inst->result_id()}); + + // Update the type. + Instruction* pointer_type_inst = + def_use_mgr->GetDef(new_ptr_inst->type_id()); + uint32_t new_type_id = + pointer_type_inst->GetSingleWordInOperand(kTypePointerPointeeInIdx); + if (new_type_id != use->type_id()) { + use->SetResultType(new_type_id); + context()->AnalyzeUses(use); + UpdateUses(use, use); + } else { + context()->AnalyzeUses(use); + } + } break; + case spv::Op::OpAccessChain: { + // Update the actual use. + context()->ForgetUses(use); + use->SetOperand(index, {new_ptr_inst->result_id()}); + + // Convert the ids on the OpAccessChain to indices that can be used to + // get the specific member. + std::vector access_chain; + for (uint32_t i = 1; i < use->NumInOperands(); ++i) { + const analysis::Constant* index_const = + const_mgr->FindDeclaredConstant(use->GetSingleWordInOperand(i)); + if (index_const) { + access_chain.push_back(index_const->GetU32()); + } else { + // Variable index means the type is an type where every element + // is the same type. Use element 0 to get the type. + access_chain.push_back(0); + } + } + + Instruction* pointer_type_inst = + get_def_use_mgr()->GetDef(new_ptr_inst->type_id()); + + uint32_t new_pointee_type_id = GetMemberTypeId( + pointer_type_inst->GetSingleWordInOperand(kTypePointerPointeeInIdx), + access_chain); + + spv::StorageClass storage_class = static_cast( + pointer_type_inst->GetSingleWordInOperand( + kTypePointerStorageClassInIdx)); + + uint32_t new_pointer_type_id = + type_mgr->FindPointerToType(new_pointee_type_id, storage_class); + + if (new_pointer_type_id != use->type_id()) { + use->SetResultType(new_pointer_type_id); + context()->AnalyzeUses(use); + UpdateUses(use, use); + } else { + context()->AnalyzeUses(use); + } + } break; + case spv::Op::OpCompositeExtract: { + // Update the actual use. + context()->ForgetUses(use); + use->SetOperand(index, {new_ptr_inst->result_id()}); + + uint32_t new_type_id = new_ptr_inst->type_id(); + std::vector access_chain; + for (uint32_t i = 1; i < use->NumInOperands(); ++i) { + access_chain.push_back(use->GetSingleWordInOperand(i)); + } + + new_type_id = GetMemberTypeId(new_type_id, access_chain); + + if (new_type_id != use->type_id()) { + use->SetResultType(new_type_id); + context()->AnalyzeUses(use); + UpdateUses(use, use); + } else { + context()->AnalyzeUses(use); + } + } break; + case spv::Op::OpStore: + // If the use is the pointer, then it is the single store to that + // variable. We do not want to replace it. Instead, it will become + // dead after all of the loads are removed, and ADCE will get rid of it. + // + // If the use is the object being stored, we will create a copy of the + // object turning it into the correct type. The copy is done by + // decomposing the object into the base type, which must be the same, + // and then rebuilding them. + if (index == 1) { + Instruction* target_pointer = def_use_mgr->GetDef( + use->GetSingleWordInOperand(kStorePointerInOperand)); + Instruction* pointer_type = + def_use_mgr->GetDef(target_pointer->type_id()); + uint32_t pointee_type_id = + pointer_type->GetSingleWordInOperand(kTypePointerPointeeInIdx); + uint32_t copy = GenerateCopy(original_ptr_inst, pointee_type_id, use); + + context()->ForgetUses(use); + use->SetInOperand(index, {copy}); + context()->AnalyzeUses(use); + } + break; + case spv::Op::OpDecorate: + // We treat an OpImageTexelPointer as a load. The result type should + // always have the Image storage class, and should not need to be + // updated. + case spv::Op::OpImageTexelPointer: + // Replace the actual use. + context()->ForgetUses(use); + use->SetOperand(index, {new_ptr_inst->result_id()}); + context()->AnalyzeUses(use); + break; + default: + assert(false && "Don't know how to rewrite instruction"); + break; + } + } +} + +uint32_t CopyPropagateArrays::GetMemberTypeId( + uint32_t id, const std::vector& access_chain) const { + for (uint32_t element_index : access_chain) { + Instruction* type_inst = get_def_use_mgr()->GetDef(id); + switch (type_inst->opcode()) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: + id = type_inst->GetSingleWordInOperand(0); + break; + case spv::Op::OpTypeStruct: + id = type_inst->GetSingleWordInOperand(element_index); + break; + default: + break; + } + assert(id != 0 && + "Tried to extract from an object where it cannot be done."); + } + return id; +} + +void CopyPropagateArrays::MemoryObject::PushIndirection( + const std::vector& access_chain) { + access_chain_.insert(access_chain_.end(), access_chain.begin(), + access_chain.end()); +} + +uint32_t CopyPropagateArrays::MemoryObject::GetNumberOfMembers() { + IRContext* context = variable_inst_->context(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + + const analysis::Type* type = type_mgr->GetType(variable_inst_->type_id()); + type = type->AsPointer()->pointee_type(); + + std::vector access_indices = GetAccessIds(); + type = type_mgr->GetMemberType(type, access_indices); + + return opt::GetNumberOfMembers(type, context); +} +template +CopyPropagateArrays::MemoryObject::MemoryObject(Instruction* var_inst, + iterator begin, iterator end) + : variable_inst_(var_inst) { + std::transform(begin, end, std::back_inserter(access_chain_), + [](uint32_t id) { + return AccessChainEntry{true, {id}}; + }); +} + +std::vector CopyPropagateArrays::MemoryObject::GetAccessIds() const { + analysis::ConstantManager* const_mgr = + variable_inst_->context()->get_constant_mgr(); + + std::vector indices(AccessChain().size()); + std::transform(AccessChain().cbegin(), AccessChain().cend(), indices.begin(), + [&const_mgr](const AccessChainEntry& entry) { + if (entry.is_result_id) { + const analysis::Constant* constant = + const_mgr->FindDeclaredConstant(entry.result_id); + return constant == nullptr ? 0 : constant->GetU32(); + } + + return entry.immediate; + }); + return indices; +} + +bool CopyPropagateArrays::MemoryObject::Contains( + CopyPropagateArrays::MemoryObject* other) { + if (this->GetVariable() != other->GetVariable()) { + return false; + } + + if (AccessChain().size() > other->AccessChain().size()) { + return false; + } + + for (uint32_t i = 0; i < AccessChain().size(); i++) { + if (AccessChain()[i] != other->AccessChain()[i]) { + return false; + } + } + return true; +} + +void CopyPropagateArrays::MemoryObject::BuildConstants() { + for (auto& entry : access_chain_) { + if (entry.is_result_id) { + continue; + } + + auto context = variable_inst_->context(); + analysis::Integer int_type(32, false); + const analysis::Type* uint32_type = + context->get_type_mgr()->GetRegisteredType(&int_type); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Constant* index_const = + const_mgr->GetConstant(uint32_type, {entry.immediate}); + entry.result_id = + const_mgr->GetDefiningInstruction(index_const)->result_id(); + entry.is_result_id = true; + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/copy_prop_arrays.h b/thirdparty/glslang/External/spirv-tools/source/opt/copy_prop_arrays.h new file mode 100644 index 000000000000..c6ca7d251bc9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/copy_prop_arrays.h @@ -0,0 +1,262 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_COPY_PROP_ARRAYS_H_ +#define SOURCE_OPT_COPY_PROP_ARRAYS_H_ + +#include +#include + +#include "source/opt/mem_pass.h" + +namespace spvtools { +namespace opt { + +// This pass implements a simple array copy propagation. It does not do a full +// array data flow. It looks for simple cases that meet the following +// conditions: +// +// 1) The source must never be stored to. +// 2) The target must be stored to exactly once. +// 3) The store to the target must be a store to the entire array, and be a +// copy of the entire source. +// 4) All loads of the target must be dominated by the store. +// +// The hard part is keeping all of the types correct. We do not want to +// have to do too large a search to update everything, which may not be +// possible, so we give up if we see any instruction that might be hard to +// update. + +class CopyPropagateArrays : public MemPass { + public: + const char* name() const override { return "copy-propagate-arrays"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisCFG | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisDecorations | + IRContext::kAnalysisDominatorAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Represents one index in the OpAccessChain instruction. It can be either + // an instruction's result_id (OpConstant by ex), or a immediate value. + // Immediate values are used to prepare the final access chain without + // creating OpConstant instructions until done. + struct AccessChainEntry { + bool is_result_id; + union { + uint32_t result_id; + uint32_t immediate; + }; + + bool operator!=(const AccessChainEntry& other) const { + return other.is_result_id != is_result_id || other.result_id != result_id; + } + }; + + // The class used to identify a particular memory object. This memory object + // will be owned by a particular variable, meaning that the memory is part of + // that variable. It could be the entire variable or a member of the + // variable. + class MemoryObject { + public: + // Construction a memory object that is owned by |var_inst|. The iterator + // |begin| and |end| traverse a container of integers that identify which + // member of |var_inst| this memory object will represent. These integers + // are interpreted the same way they would be in an |OpAccessChain| + // instruction. + template + MemoryObject(Instruction* var_inst, iterator begin, iterator end); + + // Change |this| to now point to the member identified by |access_chain| + // (starting from the current member). The elements in |access_chain| are + // interpreted the same as the indices in the |OpAccessChain| + // instruction. + void PushIndirection(const std::vector& access_chain); + + // Change |this| to now represent the first enclosing object to which it + // belongs. (Remove the last element off the access_chain). It is invalid + // to call this function if |this| does not represent a member of its owner. + void PopIndirection() { + assert(IsMember()); + access_chain_.pop_back(); + } + + // Returns true if |this| represents a member of its owner, and not the + // entire variable. + bool IsMember() const { return !access_chain_.empty(); } + + // Returns the number of members in the object represented by |this|. If + // |this| does not represent a composite type or the number of components is + // not known at compile time, the return value will be 0. + uint32_t GetNumberOfMembers(); + + // Returns the owning variable that the memory object is contained in. + Instruction* GetVariable() const { return variable_inst_; } + + // Returns a vector of integers that can be used to access the specific + // member that |this| represents starting from the owning variable. These + // values are to be interpreted the same way the indices are in an + // |OpAccessChain| instruction. + const std::vector& AccessChain() const { + return access_chain_; + } + + // Converts all immediate values in the AccessChain their OpConstant + // equivalent. + void BuildConstants(); + + // Returns the type id of the pointer type that can be used to point to this + // memory object. + uint32_t GetPointerTypeId(const CopyPropagateArrays* pass) const { + analysis::DefUseManager* def_use_mgr = + GetVariable()->context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = + GetVariable()->context()->get_type_mgr(); + + Instruction* var_pointer_inst = + def_use_mgr->GetDef(GetVariable()->type_id()); + + uint32_t member_type_id = pass->GetMemberTypeId( + var_pointer_inst->GetSingleWordInOperand(1), GetAccessIds()); + + uint32_t member_pointer_type_id = type_mgr->FindPointerToType( + member_type_id, static_cast( + var_pointer_inst->GetSingleWordInOperand(0))); + return member_pointer_type_id; + } + + // Returns the storage class of the memory object. + spv::StorageClass GetStorageClass() const { + analysis::TypeManager* type_mgr = + GetVariable()->context()->get_type_mgr(); + const analysis::Pointer* pointer_type = + type_mgr->GetType(GetVariable()->type_id())->AsPointer(); + return pointer_type->storage_class(); + } + + // Returns true if |other| represents memory that is contains inside of the + // memory represented by |this|. + bool Contains(MemoryObject* other); + + private: + // The variable that owns this memory object. + Instruction* variable_inst_; + + // The access chain to reach the particular member the memory object + // represents. It should be interpreted the same way the indices in an + // |OpAccessChain| are interpreted. + std::vector access_chain_; + std::vector GetAccessIds() const; + }; + + // Returns the memory object being stored to |var_inst| in the store + // instruction |store_inst|, if one exists, that can be used in place of + // |var_inst| in all of the loads of |var_inst|. This code is conservative + // and only identifies very simple cases. If no such memory object can be + // found, the return value is |nullptr|. + std::unique_ptr FindSourceObjectIfPossible( + Instruction* var_inst, Instruction* store_inst); + + // Replaces all loads of |var_inst| with a load from |source| instead. + // |insertion_pos| is a position where it is possible to construct the + // address of |source| and also dominates all of the loads of |var_inst|. + void PropagateObject(Instruction* var_inst, MemoryObject* source, + Instruction* insertion_pos); + + // Returns true if all of the references to |ptr_inst| can be rewritten and + // are dominated by |store_inst|. + bool HasValidReferencesOnly(Instruction* ptr_inst, Instruction* store_inst); + + // Returns a memory object that at one time was equivalent to the value in + // |result|. If no such memory object exists, the return value is |nullptr|. + std::unique_ptr GetSourceObjectIfAny(uint32_t result); + + // Returns the memory object that is loaded by |load_inst|. If a memory + // object cannot be identified, the return value is |nullptr|. The opcode of + // |load_inst| must be |OpLoad|. + std::unique_ptr BuildMemoryObjectFromLoad( + Instruction* load_inst); + + // Returns the memory object that at some point was equivalent to the result + // of |extract_inst|. If a memory object cannot be identified, the return + // value is |nullptr|. The opcode of |extract_inst| must be + // |OpCompositeExtract|. + std::unique_ptr BuildMemoryObjectFromExtract( + Instruction* extract_inst); + + // Returns the memory object that at some point was equivalent to the result + // of |construct_inst|. If a memory object cannot be identified, the return + // value is |nullptr|. The opcode of |constuct_inst| must be + // |OpCompositeConstruct|. + std::unique_ptr BuildMemoryObjectFromCompositeConstruct( + Instruction* conststruct_inst); + + // Returns the memory object that at some point was equivalent to the result + // of |insert_inst|. If a memory object cannot be identified, the return + // value is |nullptr|. The opcode of |insert_inst| must be + // |OpCompositeInsert|. This function looks for a series of + // |OpCompositeInsert| instructions that insert the elements one at a time in + // order from beginning to end. + std::unique_ptr BuildMemoryObjectFromInsert( + Instruction* insert_inst); + + // Return true if the given entry can represent the given value. + bool IsAccessChainIndexValidAndEqualTo(const AccessChainEntry& entry, + uint32_t value) const; + + // Return true if |type_id| is a pointer type whose pointee type is an array. + bool IsPointerToArrayType(uint32_t type_id); + + // Returns true if there are not stores using |ptr_inst| or something derived + // from it. + bool HasNoStores(Instruction* ptr_inst); + + // Creates an |OpAccessChain| instruction whose result is a pointer the memory + // represented by |source|. The new instruction will be placed before + // |insertion_point|. |insertion_point| must be part of a function. Returns + // the new instruction. + Instruction* BuildNewAccessChain(Instruction* insertion_point, + MemoryObject* source) const; + + // Rewrites all uses of |original_ptr| to use |new_pointer_inst| updating + // types of other instructions as needed. This function should not be called + // if |CanUpdateUses(original_ptr_inst, new_pointer_inst->type_id())| returns + // false. + void UpdateUses(Instruction* original_ptr_inst, + Instruction* new_pointer_inst); + + // Return true if |UpdateUses| is able to change all of the uses of + // |original_ptr_inst| to |type_id| and still have valid code. + bool CanUpdateUses(Instruction* original_ptr_inst, uint32_t type_id); + + // Returns a store to |var_inst| that writes to the entire variable, and is + // the only store that does so. Note it does not look through OpAccessChain + // instruction, so partial stores are not considered. + Instruction* FindStoreInstruction(const Instruction* var_inst) const; + + // Return the type id of the member of the type |id| access using + // |access_chain|. The elements of |access_chain| are to be interpreted the + // same way the indexes are used in an |OpCompositeExtract| instruction. + uint32_t GetMemberTypeId(uint32_t id, + const std::vector& access_chain) const; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_COPY_PROP_ARRAYS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dataflow.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/dataflow.cpp new file mode 100644 index 000000000000..63737f1984fa --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dataflow.cpp @@ -0,0 +1,90 @@ +// Copyright (c) 2021 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/dataflow.h" + +#include + +namespace spvtools { +namespace opt { + +bool DataFlowAnalysis::Enqueue(Instruction* inst) { + bool& is_enqueued = on_worklist_[inst]; + if (is_enqueued) return false; + is_enqueued = true; + worklist_.push(inst); + return true; +} + +DataFlowAnalysis::VisitResult DataFlowAnalysis::RunOnce( + Function* function, bool is_first_iteration) { + InitializeWorklist(function, is_first_iteration); + VisitResult ret = VisitResult::kResultFixed; + while (!worklist_.empty()) { + Instruction* top = worklist_.front(); + worklist_.pop(); + on_worklist_[top] = false; + VisitResult result = Visit(top); + if (result == VisitResult::kResultChanged) { + EnqueueSuccessors(top); + ret = VisitResult::kResultChanged; + } + } + return ret; +} + +void DataFlowAnalysis::Run(Function* function) { + VisitResult result = RunOnce(function, true); + while (result == VisitResult::kResultChanged) { + result = RunOnce(function, false); + } +} + +void ForwardDataFlowAnalysis::InitializeWorklist(Function* function, + bool /*is_first_iteration*/) { + context().cfg()->ForEachBlockInReversePostOrder( + function->entry().get(), [this](BasicBlock* bb) { + if (label_position_ == LabelPosition::kLabelsOnly) { + Enqueue(bb->GetLabelInst()); + return; + } + if (label_position_ == LabelPosition::kLabelsAtBeginning) { + Enqueue(bb->GetLabelInst()); + } + for (Instruction& inst : *bb) { + Enqueue(&inst); + } + if (label_position_ == LabelPosition::kLabelsAtEnd) { + Enqueue(bb->GetLabelInst()); + } + }); +} + +void ForwardDataFlowAnalysis::EnqueueUsers(Instruction* inst) { + context().get_def_use_mgr()->ForEachUser( + inst, [this](Instruction* user) { Enqueue(user); }); +} + +void ForwardDataFlowAnalysis::EnqueueBlockSuccessors(Instruction* inst) { + if (inst->opcode() != spv::Op::OpLabel) return; + context() + .cfg() + ->block(inst->result_id()) + ->ForEachSuccessorLabel([this](uint32_t* label) { + Enqueue(context().cfg()->block(*label)->GetLabelInst()); + }); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dataflow.h b/thirdparty/glslang/External/spirv-tools/source/opt/dataflow.h new file mode 100644 index 000000000000..be07415db538 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dataflow.h @@ -0,0 +1,148 @@ +// Copyright (c) 2021 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DATAFLOW_H_ +#define SOURCE_OPT_DATAFLOW_H_ + +#include +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +// Generic data-flow analysis. +// Maintains a worklist of instructions to process and processes them in a +// specified order. See also ForwardDataFlowAnalysis, which is specialized for +// forward data-flow analysis. +class DataFlowAnalysis { + public: + // The result of a |Visit| operation on an instruction. + // This is used to determine when analysis has reached a fixpoint. + enum class VisitResult { + // The analysis result for this instruction has changed. + // This means that any instructions that depend on it (its successors) must + // be recomputed. + kResultChanged, + // The analysis result for this instruction has not changed. + // When all visit operations return |kResultFixed|, the analysis has reached + // a fixpoint (converged). + kResultFixed, + }; + + virtual ~DataFlowAnalysis() {} + + // Run this analysis on a given function. + // For analyses which work interprocedurally, |function| may be ignored. + void Run(Function* function); + + protected: + DataFlowAnalysis(IRContext& context) : context_(context) {} + + // Initialize the worklist for a given function. + // |is_first_iteration| is true on the first call to |Run| and false + // afterwards. All subsequent runs are only necessary to check if the analysis + // has converged; if |EnqueueSuccessors| is complete, |InitializeWorklist| + // should do nothing after the first iteration. + virtual void InitializeWorklist(Function* function, + bool is_first_iteration) = 0; + + // Enqueues the successors (instructions which use the analysis result) of + // |inst|. This is not required to be complete, but convergence is faster when + // it is. This is called whenever |Visit| returns |kResultChanged|. + virtual void EnqueueSuccessors(Instruction* inst) = 0; + + // Visits the given instruction, recomputing the analysis result. This is + // called once per instruction queued in |InitializeWorklist| and afterward + // when a predecessor is changed, through |EnqueueSuccessors|. + virtual VisitResult Visit(Instruction* inst) = 0; + + // Enqueues the given instruction to be visited. Ignored if already in the + // worklist. + bool Enqueue(Instruction* inst); + + IRContext& context() { return context_; } + + private: + // Runs one pass, calling |InitializeWorklist| and then iterating through the + // worklist until all fixed. + VisitResult RunOnce(Function* function, bool is_first_iteration); + + IRContext& context_; + std::unordered_map on_worklist_; + // The worklist, which contains the list of instructions to be visited. + // + // The choice of data structure was influenced by the data in "Iterative + // Data-flow Analysis, Revisited" (Cooper et al, 2002). + // https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.125.1549&rep=rep1&type=pdf + // The paper shows that the overall performance benefit of a priority queue + // over a regular queue or stack is relatively small (or negative). + // + // A queue has the advantage that nodes are visited in the same order they are + // enqueued, which relieves the analysis from inserting nodes "backwards", for + // example in worklist initialization. Also, as the paper claims that sorting + // successors does not improve runtime, we can use a single queue which is + // modified during iteration. + std::queue worklist_; +}; + +// A generic data flow analysis, specialized for forward analysis. +class ForwardDataFlowAnalysis : public DataFlowAnalysis { + public: + // Indicates where labels should be in the worklist RPO ordering. + enum class LabelPosition { + // Labels should be placed at the beginning of their blocks. + kLabelsAtBeginning, + // Labels should be placed at the end of their blocks. + kLabelsAtEnd, + // Labels should not be in the worklist. + kNoLabels, + // Only labels should be placed in the worklist. + kLabelsOnly, + }; + + ForwardDataFlowAnalysis(IRContext& context, LabelPosition label_position) + : DataFlowAnalysis(context), label_position_(label_position) {} + + protected: + // Initializes the worklist in reverse postorder, regardless of + // |is_first_iteration|. Labels are placed according to the label position + // specified in the constructor. + void InitializeWorklist(Function* function, bool is_first_iteration) override; + + // Enqueues the users and block successors of the given instruction. + // See |EnqueueUsers| and |EnqueueBlockSuccessors|. + void EnqueueSuccessors(Instruction* inst) override { + EnqueueUsers(inst); + EnqueueBlockSuccessors(inst); + } + + // Enqueues the users of the given instruction. + void EnqueueUsers(Instruction* inst); + + // Enqueues the labels of the successors of the block corresponding to the + // given label instruction. Does nothing for other instructions. + void EnqueueBlockSuccessors(Instruction* inst); + + private: + LabelPosition label_position_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DATAFLOW_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dead_branch_elim_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/dead_branch_elim_pass.cpp new file mode 100644 index 000000000000..1526b9e05e33 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dead_branch_elim_pass.cpp @@ -0,0 +1,651 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/dead_branch_elim_pass.h" + +#include +#include +#include + +#include "source/cfa.h" +#include "source/opt/ir_context.h" +#include "source/opt/struct_cfg_analysis.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kBranchCondTrueLabIdInIdx = 1; +constexpr uint32_t kBranchCondFalseLabIdInIdx = 2; +} // namespace + +bool DeadBranchElimPass::GetConstCondition(uint32_t condId, bool* condVal) { + bool condIsConst; + Instruction* cInst = get_def_use_mgr()->GetDef(condId); + switch (cInst->opcode()) { + case spv::Op::OpConstantNull: + case spv::Op::OpConstantFalse: { + *condVal = false; + condIsConst = true; + } break; + case spv::Op::OpConstantTrue: { + *condVal = true; + condIsConst = true; + } break; + case spv::Op::OpLogicalNot: { + bool negVal; + condIsConst = + GetConstCondition(cInst->GetSingleWordInOperand(0), &negVal); + if (condIsConst) *condVal = !negVal; + } break; + default: { condIsConst = false; } break; + } + return condIsConst; +} + +bool DeadBranchElimPass::GetConstInteger(uint32_t selId, uint32_t* selVal) { + Instruction* sInst = get_def_use_mgr()->GetDef(selId); + uint32_t typeId = sInst->type_id(); + Instruction* typeInst = get_def_use_mgr()->GetDef(typeId); + if (!typeInst || (typeInst->opcode() != spv::Op::OpTypeInt)) return false; + // TODO(greg-lunarg): Support non-32 bit ints + if (typeInst->GetSingleWordInOperand(0) != 32) return false; + if (sInst->opcode() == spv::Op::OpConstant) { + *selVal = sInst->GetSingleWordInOperand(0); + return true; + } else if (sInst->opcode() == spv::Op::OpConstantNull) { + *selVal = 0; + return true; + } + return false; +} + +void DeadBranchElimPass::AddBranch(uint32_t labelId, BasicBlock* bp) { + assert(get_def_use_mgr()->GetDef(labelId) != nullptr); + std::unique_ptr newBranch( + new Instruction(context(), spv::Op::OpBranch, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); + context()->AnalyzeDefUse(&*newBranch); + context()->set_instr_block(&*newBranch, bp); + bp->AddInstruction(std::move(newBranch)); +} + +BasicBlock* DeadBranchElimPass::GetParentBlock(uint32_t id) { + return context()->get_instr_block(get_def_use_mgr()->GetDef(id)); +} + +bool DeadBranchElimPass::MarkLiveBlocks( + Function* func, std::unordered_set* live_blocks) { + std::vector> conditions_to_simplify; + std::unordered_set blocks_with_backedge; + std::vector stack; + stack.push_back(&*func->begin()); + bool modified = false; + while (!stack.empty()) { + BasicBlock* block = stack.back(); + stack.pop_back(); + + // Live blocks doubles as visited set. + if (!live_blocks->insert(block).second) continue; + + uint32_t cont_id = block->ContinueBlockIdIfAny(); + if (cont_id != 0) { + AddBlocksWithBackEdge(cont_id, block->id(), block->MergeBlockIdIfAny(), + &blocks_with_backedge); + } + + Instruction* terminator = block->terminator(); + uint32_t live_lab_id = 0; + // Check if the terminator has a single valid successor. + if (terminator->opcode() == spv::Op::OpBranchConditional) { + bool condVal; + if (GetConstCondition(terminator->GetSingleWordInOperand(0u), &condVal)) { + live_lab_id = terminator->GetSingleWordInOperand( + condVal ? kBranchCondTrueLabIdInIdx : kBranchCondFalseLabIdInIdx); + } + } else if (terminator->opcode() == spv::Op::OpSwitch) { + uint32_t sel_val; + if (GetConstInteger(terminator->GetSingleWordInOperand(0u), &sel_val)) { + // Search switch operands for selector value, set live_lab_id to + // corresponding label, use default if not found. + uint32_t icnt = 0; + uint32_t case_val; + terminator->WhileEachInOperand( + [&icnt, &case_val, &sel_val, &live_lab_id](const uint32_t* idp) { + if (icnt == 1) { + // Start with default label. + live_lab_id = *idp; + } else if (icnt > 1) { + if (icnt % 2 == 0) { + case_val = *idp; + } else { + if (case_val == sel_val) { + live_lab_id = *idp; + return false; + } + } + } + ++icnt; + return true; + }); + } + } + + // Don't simplify back edges unless it becomes a branch to the header. Every + // loop must have exactly one back edge to the loop header, so we cannot + // remove it. + bool simplify = false; + if (live_lab_id != 0) { + if (!blocks_with_backedge.count(block)) { + // This is not a back edge. + simplify = true; + } else { + const auto& struct_cfg_analysis = context()->GetStructuredCFGAnalysis(); + uint32_t header_id = struct_cfg_analysis->ContainingLoop(block->id()); + if (live_lab_id == header_id) { + // The new branch will be a branch to the header. + simplify = true; + } + } + } + + if (simplify) { + conditions_to_simplify.push_back({block, live_lab_id}); + stack.push_back(GetParentBlock(live_lab_id)); + } else { + // All successors are live. + const auto* const_block = block; + const_block->ForEachSuccessorLabel([&stack, this](const uint32_t label) { + stack.push_back(GetParentBlock(label)); + }); + } + } + + // Traverse |conditions_to_simplify| in reverse order. This is done so that + // we simplify nested constructs before simplifying the constructs that + // contain them. + for (auto b = conditions_to_simplify.rbegin(); + b != conditions_to_simplify.rend(); ++b) { + modified |= SimplifyBranch(b->first, b->second); + } + + return modified; +} + +bool DeadBranchElimPass::SimplifyBranch(BasicBlock* block, + uint32_t live_lab_id) { + Instruction* merge_inst = block->GetMergeInst(); + Instruction* terminator = block->terminator(); + if (merge_inst && merge_inst->opcode() == spv::Op::OpSelectionMerge) { + if (merge_inst->NextNode()->opcode() == spv::Op::OpSwitch && + SwitchHasNestedBreak(block->id())) { + if (terminator->NumInOperands() == 2) { + // We cannot remove the branch, and it already has a single case, so no + // work to do. + return false; + } + // We have to keep the switch because it has a nest break, so we + // remove all cases except for the live one. + Instruction::OperandList new_operands; + new_operands.push_back(terminator->GetInOperand(0)); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {live_lab_id}}); + terminator->SetInOperands(std::move(new_operands)); + context()->UpdateDefUse(terminator); + } else { + // Check if the merge instruction is still needed because of a + // non-nested break from the construct. Move the merge instruction if + // it is still needed. + StructuredCFGAnalysis* cfg_analysis = + context()->GetStructuredCFGAnalysis(); + Instruction* first_break = FindFirstExitFromSelectionMerge( + live_lab_id, merge_inst->GetSingleWordInOperand(0), + cfg_analysis->LoopMergeBlock(live_lab_id), + cfg_analysis->LoopContinueBlock(live_lab_id), + cfg_analysis->SwitchMergeBlock(live_lab_id)); + + AddBranch(live_lab_id, block); + context()->KillInst(terminator); + if (first_break == nullptr) { + context()->KillInst(merge_inst); + } else { + merge_inst->RemoveFromList(); + first_break->InsertBefore(std::unique_ptr(merge_inst)); + context()->set_instr_block(merge_inst, + context()->get_instr_block(first_break)); + } + } + } else { + AddBranch(live_lab_id, block); + context()->KillInst(terminator); + } + return true; +} + +void DeadBranchElimPass::MarkUnreachableStructuredTargets( + const std::unordered_set& live_blocks, + std::unordered_set* unreachable_merges, + std::unordered_map* unreachable_continues) { + for (auto block : live_blocks) { + if (auto merge_id = block->MergeBlockIdIfAny()) { + BasicBlock* merge_block = GetParentBlock(merge_id); + if (!live_blocks.count(merge_block)) { + unreachable_merges->insert(merge_block); + } + if (auto cont_id = block->ContinueBlockIdIfAny()) { + BasicBlock* cont_block = GetParentBlock(cont_id); + if (!live_blocks.count(cont_block)) { + (*unreachable_continues)[cont_block] = block; + } + } + } + } +} + +bool DeadBranchElimPass::FixPhiNodesInLiveBlocks( + Function* func, const std::unordered_set& live_blocks, + const std::unordered_map& unreachable_continues) { + bool modified = false; + for (auto& block : *func) { + if (live_blocks.count(&block)) { + for (auto iter = block.begin(); iter != block.end();) { + if (iter->opcode() != spv::Op::OpPhi) { + break; + } + + bool changed = false; + bool backedge_added = false; + Instruction* inst = &*iter; + std::vector operands; + // Build a complete set of operands (not just input operands). Start + // with type and result id operands. + operands.push_back(inst->GetOperand(0u)); + operands.push_back(inst->GetOperand(1u)); + // Iterate through the incoming labels and determine which to keep + // and/or modify. If there in an unreachable continue block, there will + // be an edge from that block to the header. We need to keep it to + // maintain the structured control flow. If the header has more that 2 + // incoming edges, then the OpPhi must have an entry for that edge. + // However, if there is only one other incoming edge, the OpPhi can be + // eliminated. + for (uint32_t i = 1; i < inst->NumInOperands(); i += 2) { + BasicBlock* inc = GetParentBlock(inst->GetSingleWordInOperand(i)); + auto cont_iter = unreachable_continues.find(inc); + if (cont_iter != unreachable_continues.end() && + cont_iter->second == &block && inst->NumInOperands() > 4) { + if (get_def_use_mgr() + ->GetDef(inst->GetSingleWordInOperand(i - 1)) + ->opcode() == spv::Op::OpUndef) { + // Already undef incoming value, no change necessary. + operands.push_back(inst->GetInOperand(i - 1)); + operands.push_back(inst->GetInOperand(i)); + backedge_added = true; + } else { + // Replace incoming value with undef if this phi exists in the + // loop header. Otherwise, this edge is not live since the + // unreachable continue block will be replaced with an + // unconditional branch to the header only. + operands.emplace_back( + SPV_OPERAND_TYPE_ID, + std::initializer_list{Type2Undef(inst->type_id())}); + operands.push_back(inst->GetInOperand(i)); + changed = true; + backedge_added = true; + } + } else if (live_blocks.count(inc) && inc->IsSuccessor(&block)) { + // Keep live incoming edge. + operands.push_back(inst->GetInOperand(i - 1)); + operands.push_back(inst->GetInOperand(i)); + } else { + // Remove incoming edge. + changed = true; + } + } + + if (changed) { + modified = true; + uint32_t continue_id = block.ContinueBlockIdIfAny(); + if (!backedge_added && continue_id != 0 && + unreachable_continues.count(GetParentBlock(continue_id)) && + operands.size() > 4) { + // Changed the backedge to branch from the continue block instead + // of a successor of the continue block. Add an entry to the phi to + // provide an undef for the continue block. Since the successor of + // the continue must also be unreachable (dominated by the continue + // block), any entry for the original backedge has been removed + // from the phi operands. + operands.emplace_back( + SPV_OPERAND_TYPE_ID, + std::initializer_list{Type2Undef(inst->type_id())}); + operands.emplace_back(SPV_OPERAND_TYPE_ID, + std::initializer_list{continue_id}); + } + + // Either replace the phi with a single value or rebuild the phi out + // of |operands|. + // + // We always have type and result id operands. So this phi has a + // single source if there are two more operands beyond those. + if (operands.size() == 4) { + // First input data operands is at index 2. + uint32_t replId = operands[2u].words[0]; + context()->KillNamesAndDecorates(inst->result_id()); + context()->ReplaceAllUsesWith(inst->result_id(), replId); + iter = context()->KillInst(&*inst); + } else { + // We've rewritten the operands, so first instruct the def/use + // manager to forget uses in the phi before we replace them. After + // replacing operands update the def/use manager by re-analyzing + // the used ids in this phi. + get_def_use_mgr()->EraseUseRecordsOfOperandIds(inst); + inst->ReplaceOperands(operands); + get_def_use_mgr()->AnalyzeInstUse(inst); + ++iter; + } + } else { + ++iter; + } + } + } + } + + return modified; +} + +bool DeadBranchElimPass::EraseDeadBlocks( + Function* func, const std::unordered_set& live_blocks, + const std::unordered_set& unreachable_merges, + const std::unordered_map& unreachable_continues) { + bool modified = false; + for (auto ebi = func->begin(); ebi != func->end();) { + if (unreachable_continues.count(&*ebi)) { + uint32_t cont_id = unreachable_continues.find(&*ebi)->second->id(); + if (ebi->begin() != ebi->tail() || + ebi->terminator()->opcode() != spv::Op::OpBranch || + ebi->terminator()->GetSingleWordInOperand(0u) != cont_id) { + // Make unreachable, but leave the label. + KillAllInsts(&*ebi, false); + // Add unconditional branch to header. + assert(unreachable_continues.count(&*ebi)); + ebi->AddInstruction(MakeUnique( + context(), spv::Op::OpBranch, 0, 0, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {cont_id}}})); + get_def_use_mgr()->AnalyzeInstUse(&*ebi->tail()); + context()->set_instr_block(&*ebi->tail(), &*ebi); + modified = true; + } + ++ebi; + } else if (unreachable_merges.count(&*ebi)) { + if (ebi->begin() != ebi->tail() || + ebi->terminator()->opcode() != spv::Op::OpUnreachable) { + // Make unreachable, but leave the label. + KillAllInsts(&*ebi, false); + // Add unreachable terminator. + ebi->AddInstruction( + MakeUnique(context(), spv::Op::OpUnreachable, 0, 0, + std::initializer_list{})); + context()->AnalyzeUses(ebi->terminator()); + context()->set_instr_block(ebi->terminator(), &*ebi); + modified = true; + } + ++ebi; + } else if (!live_blocks.count(&*ebi)) { + // Kill this block. + KillAllInsts(&*ebi); + ebi = ebi.Erase(); + modified = true; + } else { + ++ebi; + } + } + + return modified; +} + +bool DeadBranchElimPass::EliminateDeadBranches(Function* func) { + if (func->IsDeclaration()) { + return false; + } + + bool modified = false; + std::unordered_set live_blocks; + modified |= MarkLiveBlocks(func, &live_blocks); + + std::unordered_set unreachable_merges; + std::unordered_map unreachable_continues; + MarkUnreachableStructuredTargets(live_blocks, &unreachable_merges, + &unreachable_continues); + modified |= FixPhiNodesInLiveBlocks(func, live_blocks, unreachable_continues); + modified |= EraseDeadBlocks(func, live_blocks, unreachable_merges, + unreachable_continues); + + return modified; +} + +void DeadBranchElimPass::FixBlockOrder() { + context()->BuildInvalidAnalyses(IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis); + // Reorders blocks according to DFS of dominator tree. + ProcessFunction reorder_dominators = [this](Function* function) { + DominatorAnalysis* dominators = context()->GetDominatorAnalysis(function); + std::vector blocks; + for (auto iter = dominators->GetDomTree().begin(); + iter != dominators->GetDomTree().end(); ++iter) { + if (iter->id() != 0) { + blocks.push_back(iter->bb_); + } + } + for (uint32_t i = 1; i < blocks.size(); ++i) { + function->MoveBasicBlockToAfter(blocks[i]->id(), blocks[i - 1]); + } + return true; + }; + + // Reorders blocks according to structured order. + ProcessFunction reorder_structured = [](Function* function) { + function->ReorderBasicBlocksInStructuredOrder(); + return true; + }; + + // Structured order is more intuitive so use it where possible. + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { + context()->ProcessReachableCallTree(reorder_structured); + } else { + context()->ProcessReachableCallTree(reorder_dominators); + } +} + +Pass::Status DeadBranchElimPass::Process() { + // Do not process if module contains OpGroupDecorate. Additional + // support required in KillNamesAndDecorates(). + // TODO(greg-lunarg): Add support for OpGroupDecorate + for (auto& ai : get_module()->annotations()) + if (ai.opcode() == spv::Op::OpGroupDecorate) + return Status::SuccessWithoutChange; + // Process all entry point functions + ProcessFunction pfn = [this](Function* fp) { + return EliminateDeadBranches(fp); + }; + bool modified = context()->ProcessReachableCallTree(pfn); + if (modified) FixBlockOrder(); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +Instruction* DeadBranchElimPass::FindFirstExitFromSelectionMerge( + uint32_t start_block_id, uint32_t merge_block_id, uint32_t loop_merge_id, + uint32_t loop_continue_id, uint32_t switch_merge_id) { + // To find the "first" exit, we follow branches looking for a conditional + // branch that is not in a nested construct and is not the header of a new + // construct. We follow the control flow from |start_block_id| to find the + // first one. + + while (start_block_id != merge_block_id && start_block_id != loop_merge_id && + start_block_id != loop_continue_id) { + BasicBlock* start_block = context()->get_instr_block(start_block_id); + Instruction* branch = start_block->terminator(); + uint32_t next_block_id = 0; + switch (branch->opcode()) { + case spv::Op::OpBranchConditional: + next_block_id = start_block->MergeBlockIdIfAny(); + if (next_block_id == 0) { + // If a possible target is the |loop_merge_id| or |loop_continue_id|, + // which are not the current merge node, then we continue the search + // with the other target. + for (uint32_t i = 1; i < 3; i++) { + if (branch->GetSingleWordInOperand(i) == loop_merge_id && + loop_merge_id != merge_block_id) { + next_block_id = branch->GetSingleWordInOperand(3 - i); + break; + } + if (branch->GetSingleWordInOperand(i) == loop_continue_id && + loop_continue_id != merge_block_id) { + next_block_id = branch->GetSingleWordInOperand(3 - i); + break; + } + if (branch->GetSingleWordInOperand(i) == switch_merge_id && + switch_merge_id != merge_block_id) { + next_block_id = branch->GetSingleWordInOperand(3 - i); + break; + } + } + + if (next_block_id == 0) { + return branch; + } + } + break; + case spv::Op::OpSwitch: + next_block_id = start_block->MergeBlockIdIfAny(); + if (next_block_id == 0) { + // A switch with no merge instructions can have at most 5 targets: + // a. |merge_block_id| + // b. |loop_merge_id| + // c. |loop_continue_id| + // d. |switch_merge_id| + // e. 1 block inside the current region. + // + // Note that because this is a switch, |merge_block_id| must equal + // |switch_merge_id|. + // + // This leads to a number of cases of what to do. + // + // 1. Does not jump to a block inside of the current construct. In + // this case, there is not conditional break, so we should return + // |nullptr|. + // + // 2. Jumps to |merge_block_id| and a block inside the current + // construct. In this case, this branch conditionally break to the + // end of the current construct, so return the current branch. + // + // 3. Otherwise, this branch may break, but not to the current merge + // block. So we continue with the block that is inside the loop. + bool found_break = false; + for (uint32_t i = 1; i < branch->NumInOperands(); i += 2) { + uint32_t target = branch->GetSingleWordInOperand(i); + if (target == merge_block_id) { + found_break = true; + } else if (target != loop_merge_id && target != loop_continue_id) { + next_block_id = branch->GetSingleWordInOperand(i); + } + } + + if (next_block_id == 0) { + // Case 1. + return nullptr; + } + + if (found_break) { + // Case 2. + return branch; + } + + // The fall through is case 3. + } + break; + case spv::Op::OpBranch: + // Need to check if this is the header of a loop nested in the + // selection construct. + next_block_id = start_block->MergeBlockIdIfAny(); + if (next_block_id == 0) { + next_block_id = branch->GetSingleWordInOperand(0); + } + break; + default: + return nullptr; + } + start_block_id = next_block_id; + } + return nullptr; +} + +void DeadBranchElimPass::AddBlocksWithBackEdge( + uint32_t cont_id, uint32_t header_id, uint32_t merge_id, + std::unordered_set* blocks_with_back_edges) { + std::unordered_set visited; + visited.insert(cont_id); + visited.insert(header_id); + visited.insert(merge_id); + + std::vector work_list; + work_list.push_back(cont_id); + + while (!work_list.empty()) { + uint32_t bb_id = work_list.back(); + work_list.pop_back(); + + BasicBlock* bb = context()->get_instr_block(bb_id); + + bool has_back_edge = false; + bb->ForEachSuccessorLabel([header_id, &visited, &work_list, + &has_back_edge](uint32_t* succ_label_id) { + if (visited.insert(*succ_label_id).second) { + work_list.push_back(*succ_label_id); + } + if (*succ_label_id == header_id) { + has_back_edge = true; + } + }); + + if (has_back_edge) { + blocks_with_back_edges->insert(bb); + } + } +} + +bool DeadBranchElimPass::SwitchHasNestedBreak(uint32_t switch_header_id) { + std::vector block_in_construct; + BasicBlock* start_block = context()->get_instr_block(switch_header_id); + uint32_t merge_block_id = start_block->MergeBlockIdIfAny(); + + StructuredCFGAnalysis* cfg_analysis = context()->GetStructuredCFGAnalysis(); + return !get_def_use_mgr()->WhileEachUser( + merge_block_id, + [this, cfg_analysis, switch_header_id](Instruction* inst) { + if (!inst->IsBranch()) { + return true; + } + + BasicBlock* bb = context()->get_instr_block(inst); + if (bb->id() == switch_header_id) { + return true; + } + return (cfg_analysis->ContainingConstruct(inst) == switch_header_id && + bb->GetMergeInst() == nullptr); + }); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dead_branch_elim_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/dead_branch_elim_pass.h new file mode 100644 index 000000000000..198bad2dcb05 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dead_branch_elim_pass.h @@ -0,0 +1,176 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DEAD_BRANCH_ELIM_PASS_H_ +#define SOURCE_OPT_DEAD_BRANCH_ELIM_PASS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class DeadBranchElimPass : public MemPass { + using cbb_ptr = const BasicBlock*; + + public: + DeadBranchElimPass() = default; + + const char* name() const override { return "eliminate-dead-branches"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // If |condId| is boolean constant, return conditional value in |condVal| and + // return true, otherwise return false. + bool GetConstCondition(uint32_t condId, bool* condVal); + + // If |valId| is a 32-bit integer constant, return value via |value| and + // return true, otherwise return false. + bool GetConstInteger(uint32_t valId, uint32_t* value); + + // Add branch to |labelId| to end of block |bp|. + void AddBranch(uint32_t labelId, BasicBlock* bp); + + // For function |func|, look for BranchConditionals with constant condition + // and convert to a Branch to the indicated label. Delete resulting dead + // blocks. Note some such branches and blocks may be left to avoid creating + // invalid control flow. + // TODO(greg-lunarg): Remove remaining constant conditional branches and dead + // blocks. + bool EliminateDeadBranches(Function* func); + + // Returns the basic block containing |id|. + // Note: this pass only requires correct instruction block mappings for the + // input. This pass does not preserve the block mapping, so it is not kept + // up-to-date during processing. + BasicBlock* GetParentBlock(uint32_t id); + + // Marks live blocks reachable from the entry of |func|. Simplifies constant + // branches and switches as it proceeds, to limit the number of live blocks. + // It is careful not to eliminate backedges even if they are dead, but the + // header is live. Likewise, unreachable merge blocks named in live merge + // instruction must be retained (though they may be clobbered). + bool MarkLiveBlocks(Function* func, + std::unordered_set* live_blocks); + + // Checks for unreachable merge and continue blocks with live headers; those + // blocks must be retained. Continues are tracked separately so that a live + // phi can be updated to take an undef value from any of its predecessors + // that are unreachable continues. + // + // |unreachable_continues| maps the id of an unreachable continue target to + // the header block that declares it. + void MarkUnreachableStructuredTargets( + const std::unordered_set& live_blocks, + std::unordered_set* unreachable_merges, + std::unordered_map* unreachable_continues); + + // Fix phis in reachable blocks so that only live (or unremovable) incoming + // edges are present. If the block now only has a single live incoming edge, + // remove the phi and replace its uses with its data input. If the single + // remaining incoming edge is from the phi itself, the phi is in an + // unreachable single block loop. Either the block is dead and will be + // removed, or it's reachable from an unreachable continue target. In the + // latter case that continue target block will be collapsed into a block that + // only branches back to its header and we'll eliminate the block with the + // phi. + // + // |unreachable_continues| maps continue targets that cannot be reached to + // merge instruction that declares them. + bool FixPhiNodesInLiveBlocks( + Function* func, const std::unordered_set& live_blocks, + const std::unordered_map& + unreachable_continues); + + // Erases dead blocks. Any block captured in |unreachable_merges| or + // |unreachable_continues| is a dead block that is required to remain due to + // a live merge instruction in the corresponding header. These blocks will + // have their instructions clobbered and will become a label and terminator. + // Unreachable merge blocks are terminated by OpUnreachable, while + // unreachable continue blocks are terminated by an unconditional branch to + // the header. Otherwise, blocks are dead if not explicitly captured in + // |live_blocks| and are totally removed. + // + // |unreachable_continues| maps continue targets that cannot be reached to + // corresponding header block that declares them. + bool EraseDeadBlocks( + Function* func, const std::unordered_set& live_blocks, + const std::unordered_set& unreachable_merges, + const std::unordered_map& + unreachable_continues); + + // Reorders blocks in reachable functions so that they satisfy dominator + // block ordering rules. + void FixBlockOrder(); + + // Return the first branch instruction that is a conditional branch to + // |merge_block_id|. Returns |nullptr| if no such branch exists. If there are + // multiple such branches, the first one is the one that would be executed + // first when running the code. That is, the one that dominates all of the + // others. + // + // |start_block_id| must be a block whose innermost containing merge construct + // has |merge_block_id| as the merge block. + // + // |loop_merge_id| and |loop_continue_id| are the merge and continue block ids + // of the innermost loop containing |start_block_id|. + Instruction* FindFirstExitFromSelectionMerge(uint32_t start_block_id, + uint32_t merge_block_id, + uint32_t loop_merge_id, + uint32_t loop_continue_id, + uint32_t switch_merge_id); + + // Adds to |blocks_with_back_edges| all of the blocks on the path from the + // basic block |cont_id| to |header_id| and |merge_id|. The intention is that + // |cond_id| is a the continue target of a loop, |header_id| is the header of + // the loop, and |merge_id| is the merge block of the loop. + void AddBlocksWithBackEdge( + uint32_t cont_id, uint32_t header_id, uint32_t merge_id, + std::unordered_set* blocks_with_back_edges); + + // Returns true if there is a branch to the merge node of the selection + // construct |switch_header_id| that is inside a nested selection construct or + // in the header of the nested selection construct. + bool SwitchHasNestedBreak(uint32_t switch_header_id); + + // Return true of the terminator of |block| is successfully replaced with a + // branch to |live_lab_id|. The merge instruction is deleted or moved as + // needed to maintain structured control flow. Assumes that the + // StructuredCFGAnalysis is valid for the constructs containing |block|. + bool SimplifyBranch(BasicBlock* block, uint32_t live_lab_id); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DEAD_BRANCH_ELIM_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dead_insert_elim_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/dead_insert_elim_pass.cpp new file mode 100644 index 000000000000..f985e4c268bd --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dead_insert_elim_pass.cpp @@ -0,0 +1,262 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/dead_insert_elim_pass.h" + +#include "source/opt/composite.h" +#include "source/opt/ir_context.h" +#include "source/opt/iterator.h" +#include "spirv/1.2/GLSL.std.450.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kTypeVectorCountInIdx = 1; +constexpr uint32_t kTypeMatrixCountInIdx = 1; +constexpr uint32_t kTypeArrayLengthIdInIdx = 1; +constexpr uint32_t kTypeIntWidthInIdx = 0; +constexpr uint32_t kConstantValueInIdx = 0; +constexpr uint32_t kInsertObjectIdInIdx = 0; +constexpr uint32_t kInsertCompositeIdInIdx = 1; +} // namespace + +uint32_t DeadInsertElimPass::NumComponents(Instruction* typeInst) { + switch (typeInst->opcode()) { + case spv::Op::OpTypeVector: { + return typeInst->GetSingleWordInOperand(kTypeVectorCountInIdx); + } break; + case spv::Op::OpTypeMatrix: { + return typeInst->GetSingleWordInOperand(kTypeMatrixCountInIdx); + } break; + case spv::Op::OpTypeArray: { + uint32_t lenId = + typeInst->GetSingleWordInOperand(kTypeArrayLengthIdInIdx); + Instruction* lenInst = get_def_use_mgr()->GetDef(lenId); + if (lenInst->opcode() != spv::Op::OpConstant) return 0; + uint32_t lenTypeId = lenInst->type_id(); + Instruction* lenTypeInst = get_def_use_mgr()->GetDef(lenTypeId); + // TODO(greg-lunarg): Support non-32-bit array length + if (lenTypeInst->GetSingleWordInOperand(kTypeIntWidthInIdx) != 32) + return 0; + return lenInst->GetSingleWordInOperand(kConstantValueInIdx); + } break; + case spv::Op::OpTypeStruct: { + return typeInst->NumInOperands(); + } break; + default: { return 0; } break; + } +} + +void DeadInsertElimPass::MarkInsertChain( + Instruction* insertChain, std::vector* pExtIndices, + uint32_t extOffset, std::unordered_set* visited_phis) { + // Not currently optimizing array inserts. + Instruction* typeInst = get_def_use_mgr()->GetDef(insertChain->type_id()); + if (typeInst->opcode() == spv::Op::OpTypeArray) return; + // Insert chains are only composed of inserts and phis + if (insertChain->opcode() != spv::Op::OpCompositeInsert && + insertChain->opcode() != spv::Op::OpPhi) + return; + // If extract indices are empty, mark all subcomponents if type + // is constant length. + if (pExtIndices == nullptr) { + uint32_t cnum = NumComponents(typeInst); + if (cnum > 0) { + std::vector extIndices; + for (uint32_t i = 0; i < cnum; i++) { + extIndices.clear(); + extIndices.push_back(i); + std::unordered_set sub_visited_phis; + MarkInsertChain(insertChain, &extIndices, 0, &sub_visited_phis); + } + return; + } + } + Instruction* insInst = insertChain; + while (insInst->opcode() == spv::Op::OpCompositeInsert) { + // If no extract indices, mark insert and inserted object (which might + // also be an insert chain) and continue up the chain though the input + // composite. + // + // Note: We mark inserted objects in this function (rather than in + // EliminateDeadInsertsOnePass) because in some cases, we can do it + // more accurately here. + if (pExtIndices == nullptr) { + liveInserts_.insert(insInst->result_id()); + uint32_t objId = insInst->GetSingleWordInOperand(kInsertObjectIdInIdx); + std::unordered_set obj_visited_phis; + MarkInsertChain(get_def_use_mgr()->GetDef(objId), nullptr, 0, + &obj_visited_phis); + // If extract indices match insert, we are done. Mark insert and + // inserted object. + } else if (ExtInsMatch(*pExtIndices, insInst, extOffset)) { + liveInserts_.insert(insInst->result_id()); + uint32_t objId = insInst->GetSingleWordInOperand(kInsertObjectIdInIdx); + std::unordered_set obj_visited_phis; + MarkInsertChain(get_def_use_mgr()->GetDef(objId), nullptr, 0, + &obj_visited_phis); + break; + // If non-matching intersection, mark insert + } else if (ExtInsConflict(*pExtIndices, insInst, extOffset)) { + liveInserts_.insert(insInst->result_id()); + // If more extract indices than insert, we are done. Use remaining + // extract indices to mark inserted object. + uint32_t numInsertIndices = insInst->NumInOperands() - 2; + if (pExtIndices->size() - extOffset > numInsertIndices) { + uint32_t objId = insInst->GetSingleWordInOperand(kInsertObjectIdInIdx); + std::unordered_set obj_visited_phis; + MarkInsertChain(get_def_use_mgr()->GetDef(objId), pExtIndices, + extOffset + numInsertIndices, &obj_visited_phis); + break; + // If fewer extract indices than insert, also mark inserted object and + // continue up chain. + } else { + uint32_t objId = insInst->GetSingleWordInOperand(kInsertObjectIdInIdx); + std::unordered_set obj_visited_phis; + MarkInsertChain(get_def_use_mgr()->GetDef(objId), nullptr, 0, + &obj_visited_phis); + } + } + // Get next insert in chain + const uint32_t compId = + insInst->GetSingleWordInOperand(kInsertCompositeIdInIdx); + insInst = get_def_use_mgr()->GetDef(compId); + } + // If insert chain ended with phi, do recursive call on each operand + if (insInst->opcode() != spv::Op::OpPhi) return; + // Mark phi visited to prevent potential infinite loop. If phi is already + // visited, return to avoid infinite loop. + if (visited_phis->count(insInst->result_id()) != 0) return; + visited_phis->insert(insInst->result_id()); + + // Phis may have duplicate inputs values for different edges, prune incoming + // ids lists before recursing. + std::vector ids; + for (uint32_t i = 0; i < insInst->NumInOperands(); i += 2) { + ids.push_back(insInst->GetSingleWordInOperand(i)); + } + std::sort(ids.begin(), ids.end()); + auto new_end = std::unique(ids.begin(), ids.end()); + for (auto id_iter = ids.begin(); id_iter != new_end; ++id_iter) { + Instruction* pi = get_def_use_mgr()->GetDef(*id_iter); + MarkInsertChain(pi, pExtIndices, extOffset, visited_phis); + } +} + +bool DeadInsertElimPass::EliminateDeadInserts(Function* func) { + bool modified = false; + bool lastmodified = true; + // Each pass can delete dead instructions, thus potentially revealing + // new dead insertions ie insertions with no uses. + while (lastmodified) { + lastmodified = EliminateDeadInsertsOnePass(func); + modified |= lastmodified; + } + return modified; +} + +bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) { + bool modified = false; + liveInserts_.clear(); + visitedPhis_.clear(); + // Mark all live inserts + for (auto bi = func->begin(); bi != func->end(); ++bi) { + for (auto ii = bi->begin(); ii != bi->end(); ++ii) { + // Only process Inserts and composite Phis + spv::Op op = ii->opcode(); + Instruction* typeInst = get_def_use_mgr()->GetDef(ii->type_id()); + if (op != spv::Op::OpCompositeInsert && + (op != spv::Op::OpPhi || !spvOpcodeIsComposite(typeInst->opcode()))) + continue; + // The marking algorithm can be expensive for large arrays and the + // efficacy of eliminating dead inserts into arrays is questionable. + // Skip optimizing array inserts for now. Just mark them live. + // TODO(greg-lunarg): Eliminate dead array inserts + if (op == spv::Op::OpCompositeInsert) { + if (typeInst->opcode() == spv::Op::OpTypeArray) { + liveInserts_.insert(ii->result_id()); + continue; + } + } + const uint32_t id = ii->result_id(); + get_def_use_mgr()->ForEachUser(id, [&ii, this](Instruction* user) { + if (user->IsCommonDebugInstr()) return; + switch (user->opcode()) { + case spv::Op::OpCompositeInsert: + case spv::Op::OpPhi: + // Use by insert or phi does not initiate marking + break; + case spv::Op::OpCompositeExtract: { + // Capture extract indices + std::vector extIndices; + uint32_t icnt = 0; + user->ForEachInOperand([&icnt, &extIndices](const uint32_t* idp) { + if (icnt > 0) extIndices.push_back(*idp); + ++icnt; + }); + // Mark all inserts in chain that intersect with extract + std::unordered_set visited_phis; + MarkInsertChain(&*ii, &extIndices, 0, &visited_phis); + } break; + default: { + // Mark inserts in chain for all components + std::unordered_set visited_phis; + MarkInsertChain(&*ii, nullptr, 0, &visited_phis); + } break; + } + }); + } + } + // Find and disconnect dead inserts + std::vector dead_instructions; + for (auto bi = func->begin(); bi != func->end(); ++bi) { + for (auto ii = bi->begin(); ii != bi->end(); ++ii) { + if (ii->opcode() != spv::Op::OpCompositeInsert) continue; + const uint32_t id = ii->result_id(); + if (liveInserts_.find(id) != liveInserts_.end()) continue; + const uint32_t replId = + ii->GetSingleWordInOperand(kInsertCompositeIdInIdx); + (void)context()->ReplaceAllUsesWith(id, replId); + dead_instructions.push_back(&*ii); + modified = true; + } + } + // DCE dead inserts + while (!dead_instructions.empty()) { + Instruction* inst = dead_instructions.back(); + dead_instructions.pop_back(); + DCEInst(inst, [&dead_instructions](Instruction* other_inst) { + auto i = std::find(dead_instructions.begin(), dead_instructions.end(), + other_inst); + if (i != dead_instructions.end()) { + dead_instructions.erase(i); + } + }); + } + return modified; +} + +Pass::Status DeadInsertElimPass::Process() { + // Process all entry point functions. + ProcessFunction pfn = [this](Function* fp) { + return EliminateDeadInserts(fp); + }; + bool modified = context()->ProcessReachableCallTree(pfn); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dead_insert_elim_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/dead_insert_elim_pass.h new file mode 100644 index 000000000000..01f12bb04819 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dead_insert_elim_pass.h @@ -0,0 +1,90 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DEAD_INSERT_ELIM_PASS_H_ +#define SOURCE_OPT_DEAD_INSERT_ELIM_PASS_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class DeadInsertElimPass : public MemPass { + public: + DeadInsertElimPass() = default; + + const char* name() const override { return "eliminate-dead-inserts"; } + Status Process() override; + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + // Return the number of subcomponents in the composite type |typeId|. + // Return 0 if not a composite type or number of components is not a + // 32-bit constant. + uint32_t NumComponents(Instruction* typeInst); + + // Mark all inserts in instruction chain ending at |insertChain| with + // indices that intersect with extract indices |extIndices| starting with + // index at |extOffset|. Chains are composed solely of Inserts and Phis. + // Mark all inserts in chain if |extIndices| is nullptr. + void MarkInsertChain(Instruction* insertChain, + std::vector* extIndices, uint32_t extOffset, + std::unordered_set* visited_phis); + + // Perform EliminateDeadInsertsOnePass(|func|) until no modification is + // made. Return true if modified. + bool EliminateDeadInserts(Function* func); + + // DCE all dead struct, matrix and vector inserts in |func|. An insert is + // dead if the value it inserts is never used. Replace any reference to the + // insert with its original composite. Return true if modified. Dead inserts + // in dependence cycles are not currently eliminated. Dead inserts into + // arrays are not currently eliminated. + bool EliminateDeadInsertsOnePass(Function* func); + + // Return true if all extensions in this module are allowed by this pass. + bool AllExtensionsSupported() const; + + // Live inserts + std::unordered_set liveInserts_; + + // Visited phis as insert chain is traversed; used to avoid infinite loop + std::unordered_map visitedPhis_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DEAD_INSERT_ELIM_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dead_variable_elimination.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/dead_variable_elimination.cpp new file mode 100644 index 000000000000..e39132c22d6e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dead_variable_elimination.cpp @@ -0,0 +1,112 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/dead_variable_elimination.h" + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/reflect.h" + +namespace spvtools { +namespace opt { + +// This optimization removes global variables that are not needed because they +// are definitely not accessed. +Pass::Status DeadVariableElimination::Process() { + // The algorithm will compute the reference count for every global variable. + // Anything with a reference count of 0 will then be deleted. For variables + // that might have references that are not explicit in this context, we use + // the value kMustKeep as the reference count. + std::vector ids_to_remove; + + // Get the reference count for all of the global OpVariable instructions. + for (auto& inst : context()->types_values()) { + if (inst.opcode() != spv::Op::OpVariable) { + continue; + } + + size_t count = 0; + uint32_t result_id = inst.result_id(); + + // Check the linkage. If it is exported, it could be reference somewhere + // else, so we must keep the variable around. + get_decoration_mgr()->ForEachDecoration( + result_id, uint32_t(spv::Decoration::LinkageAttributes), + [&count](const Instruction& linkage_instruction) { + uint32_t last_operand = linkage_instruction.NumOperands() - 1; + if (spv::LinkageType(linkage_instruction.GetSingleWordOperand( + last_operand)) == spv::LinkageType::Export) { + count = kMustKeep; + } + }); + + if (count != kMustKeep) { + // If we don't have to keep the instruction for other reasons, then look + // at the uses and count the number of real references. + count = 0; + get_def_use_mgr()->ForEachUser(result_id, [&count](Instruction* user) { + if (!IsAnnotationInst(user->opcode()) && + user->opcode() != spv::Op::OpName) { + ++count; + } + }); + } + reference_count_[result_id] = count; + if (count == 0) { + ids_to_remove.push_back(result_id); + } + } + + // Remove all of the variables that have a reference count of 0. + bool modified = false; + if (!ids_to_remove.empty()) { + modified = true; + for (auto result_id : ids_to_remove) { + DeleteVariable(result_id); + } + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +void DeadVariableElimination::DeleteVariable(uint32_t result_id) { + Instruction* inst = get_def_use_mgr()->GetDef(result_id); + assert(inst->opcode() == spv::Op::OpVariable && + "Should not be trying to delete anything other than an OpVariable."); + + // Look for an initializer that references another variable. We need to know + // if that variable can be deleted after the reference is removed. + if (inst->NumOperands() == 4) { + Instruction* initializer = + get_def_use_mgr()->GetDef(inst->GetSingleWordOperand(3)); + + // TODO: Handle OpSpecConstantOP which might be defined in terms of other + // variables. Will probably require a unified dead code pass that does all + // instruction types. (Issue 906) + if (initializer->opcode() == spv::Op::OpVariable) { + uint32_t initializer_id = initializer->result_id(); + size_t& count = reference_count_[initializer_id]; + if (count != kMustKeep) { + --count; + } + + if (count == 0) { + DeleteVariable(initializer_id); + } + } + } + context()->KillDef(result_id); +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dead_variable_elimination.h b/thirdparty/glslang/External/spirv-tools/source/opt/dead_variable_elimination.h new file mode 100644 index 000000000000..5dde71ba798c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dead_variable_elimination.h @@ -0,0 +1,56 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DEAD_VARIABLE_ELIMINATION_H_ +#define SOURCE_OPT_DEAD_VARIABLE_ELIMINATION_H_ + +#include +#include + +#include "source/opt/decoration_manager.h" +#include "source/opt/mem_pass.h" + +namespace spvtools { +namespace opt { + +class DeadVariableElimination : public MemPass { + public: + const char* name() const override { return "eliminate-dead-variables"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + // Deletes the OpVariable instruction who result id is |result_id|. + void DeleteVariable(uint32_t result_id); + + // Keeps track of the number of references of an id. Once that value is 0, it + // is safe to remove the corresponding instruction. + // + // Note that the special value kMustKeep is used to indicate that the + // instruction cannot be deleted for reasons other that is being explicitly + // referenced. + std::unordered_map reference_count_; + + // Special value used to indicate that an id cannot be safely deleted. + enum { kMustKeep = INT_MAX }; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DEAD_VARIABLE_ELIMINATION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/debug_info_manager.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/debug_info_manager.cpp new file mode 100644 index 000000000000..1e614c6ff30b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/debug_info_manager.cpp @@ -0,0 +1,931 @@ +// Copyright (c) 2020-2022 Google LLC +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/debug_info_manager.h" + +#include + +#include "source/opt/ir_context.h" + +// Constants for OpenCL.DebugInfo.100 & NonSemantic.Shader.DebugInfo.100 +// extension instructions. + +namespace spvtools { +namespace opt { +namespace analysis { +namespace { +constexpr uint32_t kOpLineOperandLineIndex = 1; +constexpr uint32_t kLineOperandIndexDebugFunction = 7; +constexpr uint32_t kLineOperandIndexDebugLexicalBlock = 5; +constexpr uint32_t kLineOperandIndexDebugLine = 5; +constexpr uint32_t kDebugFunctionOperandFunctionIndex = 13; +constexpr uint32_t kDebugFunctionDefinitionOperandDebugFunctionIndex = 4; +constexpr uint32_t kDebugFunctionDefinitionOperandOpFunctionIndex = 5; +constexpr uint32_t kDebugFunctionOperandParentIndex = 9; +constexpr uint32_t kDebugTypeCompositeOperandParentIndex = 9; +constexpr uint32_t kDebugLexicalBlockOperandParentIndex = 7; +constexpr uint32_t kDebugInlinedAtOperandInlinedIndex = 6; +constexpr uint32_t kDebugExpressOperandOperationIndex = 4; +constexpr uint32_t kDebugDeclareOperandLocalVariableIndex = 4; +constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; +constexpr uint32_t kDebugValueOperandExpressionIndex = 6; +constexpr uint32_t kDebugOperationOperandOperationIndex = 4; +constexpr uint32_t kOpVariableOperandStorageClassIndex = 2; +constexpr uint32_t kDebugLocalVariableOperandParentIndex = 9; +constexpr uint32_t kExtInstInstructionInIdx = 1; +constexpr uint32_t kDebugGlobalVariableOperandFlagsIndex = 12; +constexpr uint32_t kDebugLocalVariableOperandFlagsIndex = 10; + +void SetInlinedOperand(Instruction* dbg_inlined_at, uint32_t inlined_operand) { + assert(dbg_inlined_at); + assert(dbg_inlined_at->GetCommonDebugOpcode() == + CommonDebugInfoDebugInlinedAt); + if (dbg_inlined_at->NumOperands() <= kDebugInlinedAtOperandInlinedIndex) { + dbg_inlined_at->AddOperand( + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inlined_operand}}); + } else { + dbg_inlined_at->SetOperand(kDebugInlinedAtOperandInlinedIndex, + {inlined_operand}); + } +} + +uint32_t GetInlinedOperand(Instruction* dbg_inlined_at) { + assert(dbg_inlined_at); + assert(dbg_inlined_at->GetCommonDebugOpcode() == + CommonDebugInfoDebugInlinedAt); + if (dbg_inlined_at->NumOperands() <= kDebugInlinedAtOperandInlinedIndex) + return kNoInlinedAt; + return dbg_inlined_at->GetSingleWordOperand( + kDebugInlinedAtOperandInlinedIndex); +} + +bool IsEmptyDebugExpression(Instruction* instr) { + return (instr->GetCommonDebugOpcode() == CommonDebugInfoDebugExpression) && + instr->NumOperands() == kDebugExpressOperandOperationIndex; +} + +} // namespace + +DebugInfoManager::DebugInfoManager(IRContext* c) : context_(c) { + AnalyzeDebugInsts(*c->module()); +} + +uint32_t DebugInfoManager::GetDbgSetImportId() { + uint32_t setId = + context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo(); + if (setId == 0) { + setId = + context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo(); + } + return setId; +} + +Instruction* DebugInfoManager::GetDbgInst(uint32_t id) { + auto dbg_inst_it = id_to_dbg_inst_.find(id); + return dbg_inst_it == id_to_dbg_inst_.end() ? nullptr : dbg_inst_it->second; +} + +void DebugInfoManager::RegisterDbgInst(Instruction* inst) { + assert(inst->NumInOperands() != 0 && + (GetDbgSetImportId() == inst->GetInOperand(0).words[0]) && + "Given instruction is not a debug instruction"); + id_to_dbg_inst_[inst->result_id()] = inst; +} + +void DebugInfoManager::RegisterDbgFunction(Instruction* inst) { + if (inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugFunction) { + auto fn_id = inst->GetSingleWordOperand(kDebugFunctionOperandFunctionIndex); + // Do not register function that has been optimized away. + auto fn_inst = GetDbgInst(fn_id); + if (fn_inst != nullptr) { + assert(GetDbgInst(fn_id)->GetOpenCL100DebugOpcode() == + OpenCLDebugInfo100DebugInfoNone); + return; + } + assert( + fn_id_to_dbg_fn_.find(fn_id) == fn_id_to_dbg_fn_.end() && + "Register DebugFunction for a function that already has DebugFunction"); + fn_id_to_dbg_fn_[fn_id] = inst; + } else if (inst->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugFunctionDefinition) { + auto fn_id = inst->GetSingleWordOperand( + kDebugFunctionDefinitionOperandOpFunctionIndex); + auto fn_inst = GetDbgInst(inst->GetSingleWordOperand( + kDebugFunctionDefinitionOperandDebugFunctionIndex)); + assert(fn_inst && fn_inst->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugFunction); + assert(fn_id_to_dbg_fn_.find(fn_id) == fn_id_to_dbg_fn_.end() && + "Register DebugFunctionDefinition for a function that already has " + "DebugFunctionDefinition"); + fn_id_to_dbg_fn_[fn_id] = fn_inst; + } else { + assert(false && "inst is not a DebugFunction"); + } +} + +void DebugInfoManager::RegisterDbgDeclare(uint32_t var_id, + Instruction* dbg_declare) { + assert(dbg_declare->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare || + dbg_declare->GetCommonDebugOpcode() == CommonDebugInfoDebugValue); + auto dbg_decl_itr = var_id_to_dbg_decl_.find(var_id); + if (dbg_decl_itr == var_id_to_dbg_decl_.end()) { + var_id_to_dbg_decl_[var_id] = {dbg_declare}; + } else { + dbg_decl_itr->second.insert(dbg_declare); + } +} + +// Create new constant directly into global value area, bypassing the +// Constant manager. This is used when the DefUse or Constant managers +// are invalid and cannot be regenerated due to the module being in an +// inconsistent state e.g. in the middle of significant modification +// such as inlining. Invalidate Constant and DefUse managers if used. +uint32_t AddNewConstInGlobals(IRContext* context, uint32_t const_value) { + uint32_t id = context->TakeNextId(); + std::unique_ptr new_const(new Instruction( + context, spv::Op::OpConstant, context->get_type_mgr()->GetUIntTypeId(), + id, + { + {spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, + {const_value}}, + })); + context->module()->AddGlobalValue(std::move(new_const)); + context->InvalidateAnalyses(IRContext::kAnalysisConstants); + context->InvalidateAnalyses(IRContext::kAnalysisDefUse); + return id; +} + +uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line, + const DebugScope& scope) { + uint32_t setId = GetDbgSetImportId(); + + if (setId == 0) return kNoInlinedAt; + + spv_operand_type_t line_number_type = + spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER; + + // In NonSemantic.Shader.DebugInfo.100, all constants are IDs of OpConstant, + // not literals. + if (setId == + context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo()) + line_number_type = spv_operand_type_t::SPV_OPERAND_TYPE_ID; + + uint32_t line_number = 0; + if (line == nullptr) { + auto* lexical_scope_inst = GetDbgInst(scope.GetLexicalScope()); + if (lexical_scope_inst == nullptr) return kNoInlinedAt; + CommonDebugInfoInstructions debug_opcode = + lexical_scope_inst->GetCommonDebugOpcode(); + switch (debug_opcode) { + case CommonDebugInfoDebugFunction: + line_number = lexical_scope_inst->GetSingleWordOperand( + kLineOperandIndexDebugFunction); + break; + case CommonDebugInfoDebugLexicalBlock: + line_number = lexical_scope_inst->GetSingleWordOperand( + kLineOperandIndexDebugLexicalBlock); + break; + case CommonDebugInfoDebugTypeComposite: + case CommonDebugInfoDebugCompilationUnit: + assert(false && + "DebugTypeComposite and DebugCompilationUnit are lexical " + "scopes, but we inline functions into a function or a block " + "of a function, not into a struct/class or a global scope."); + break; + default: + assert(false && + "Unreachable. a debug extension instruction for a " + "lexical scope must be DebugFunction, DebugTypeComposite, " + "DebugLexicalBlock, or DebugCompilationUnit."); + break; + } + } else { + if (line->opcode() == spv::Op::OpLine) { + line_number = line->GetSingleWordOperand(kOpLineOperandLineIndex); + } else if (line->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugLine) { + line_number = line->GetSingleWordOperand(kLineOperandIndexDebugLine); + } else { + assert(false && + "Unreachable. A line instruction must be OpLine or DebugLine"); + } + + // If we need the line number as an ID, generate that constant now. + // If Constant or DefUse managers are invalid, generate constant + // directly into the global value section of the module; do not + // use Constant manager which may attempt to invoke building of the + // DefUse manager which cannot be done during inlining. The extra + // constants that may be generated here is likely not significant + // and will likely be cleaned up in later passes. + if (line_number_type == spv_operand_type_t::SPV_OPERAND_TYPE_ID && + line->opcode() == spv::Op::OpLine) { + if (!context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse) || + !context()->AreAnalysesValid(IRContext::Analysis::kAnalysisConstants)) + line_number = AddNewConstInGlobals(context(), line_number); + else + line_number = + context()->get_constant_mgr()->GetUIntConstId(line_number); + } + } + + uint32_t result_id = context()->TakeNextId(); + std::unique_ptr inlined_at(new Instruction( + context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + result_id, + { + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {setId}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast(CommonDebugInfoDebugInlinedAt)}}, + {line_number_type, {line_number}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {scope.GetLexicalScope()}}, + })); + // |scope| already has DebugInlinedAt. We put the existing DebugInlinedAt + // into the Inlined operand of this new DebugInlinedAt. + if (scope.GetInlinedAt() != kNoInlinedAt) { + inlined_at->AddOperand( + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {scope.GetInlinedAt()}}); + } + RegisterDbgInst(inlined_at.get()); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(inlined_at.get()); + context()->module()->AddExtInstDebugInfo(std::move(inlined_at)); + return result_id; +} + +DebugScope DebugInfoManager::BuildDebugScope( + const DebugScope& callee_instr_scope, + DebugInlinedAtContext* inlined_at_ctx) { + return DebugScope(callee_instr_scope.GetLexicalScope(), + BuildDebugInlinedAtChain(callee_instr_scope.GetInlinedAt(), + inlined_at_ctx)); +} + +uint32_t DebugInfoManager::BuildDebugInlinedAtChain( + uint32_t callee_inlined_at, DebugInlinedAtContext* inlined_at_ctx) { + if (inlined_at_ctx->GetScopeOfCallInstruction().GetLexicalScope() == + kNoDebugScope) + return kNoInlinedAt; + + // Reuse the already generated DebugInlinedAt chain if exists. + uint32_t already_generated_chain_head_id = + inlined_at_ctx->GetDebugInlinedAtChain(callee_inlined_at); + if (already_generated_chain_head_id != kNoInlinedAt) { + return already_generated_chain_head_id; + } + + const uint32_t new_dbg_inlined_at_id = + CreateDebugInlinedAt(inlined_at_ctx->GetLineOfCallInstruction(), + inlined_at_ctx->GetScopeOfCallInstruction()); + if (new_dbg_inlined_at_id == kNoInlinedAt) return kNoInlinedAt; + + if (callee_inlined_at == kNoInlinedAt) { + inlined_at_ctx->SetDebugInlinedAtChain(kNoInlinedAt, new_dbg_inlined_at_id); + return new_dbg_inlined_at_id; + } + + uint32_t chain_head_id = kNoInlinedAt; + uint32_t chain_iter_id = callee_inlined_at; + Instruction* last_inlined_at_in_chain = nullptr; + do { + Instruction* new_inlined_at_in_chain = CloneDebugInlinedAt( + chain_iter_id, /* insert_before */ last_inlined_at_in_chain); + assert(new_inlined_at_in_chain != nullptr); + + // Set DebugInlinedAt of the new scope as the head of the chain. + if (chain_head_id == kNoInlinedAt) + chain_head_id = new_inlined_at_in_chain->result_id(); + + // Previous DebugInlinedAt of the chain must point to the new + // DebugInlinedAt as its Inlined operand to build a recursive + // chain. + if (last_inlined_at_in_chain != nullptr) { + SetInlinedOperand(last_inlined_at_in_chain, + new_inlined_at_in_chain->result_id()); + } + last_inlined_at_in_chain = new_inlined_at_in_chain; + + chain_iter_id = GetInlinedOperand(new_inlined_at_in_chain); + } while (chain_iter_id != kNoInlinedAt); + + // Put |new_dbg_inlined_at_id| into the end of the chain. + SetInlinedOperand(last_inlined_at_in_chain, new_dbg_inlined_at_id); + + // Keep the new chain information that will be reused it. + inlined_at_ctx->SetDebugInlinedAtChain(callee_inlined_at, chain_head_id); + return chain_head_id; +} + +Instruction* DebugInfoManager::GetDebugOperationWithDeref() { + if (deref_operation_ != nullptr) return deref_operation_; + + uint32_t result_id = context()->TakeNextId(); + std::unique_ptr deref_operation; + + if (context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()) { + deref_operation = std::unique_ptr(new Instruction( + context(), spv::Op::OpExtInst, + context()->get_type_mgr()->GetVoidTypeId(), result_id, + { + {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, + {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast(OpenCLDebugInfo100DebugOperation)}}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, + {static_cast(OpenCLDebugInfo100Deref)}}, + })); + } else { + uint32_t deref_id = context()->get_constant_mgr()->GetUIntConstId( + NonSemanticShaderDebugInfo100Deref); + + deref_operation = std::unique_ptr( + new Instruction(context(), spv::Op::OpExtInst, + context()->get_type_mgr()->GetVoidTypeId(), result_id, + { + {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, + {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast( + NonSemanticShaderDebugInfo100DebugOperation)}}, + {SPV_OPERAND_TYPE_ID, {deref_id}}, + })); + } + + // Add to the front of |ext_inst_debuginfo_|. + deref_operation_ = + context()->module()->ext_inst_debuginfo_begin()->InsertBefore( + std::move(deref_operation)); + + RegisterDbgInst(deref_operation_); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(deref_operation_); + return deref_operation_; +} + +Instruction* DebugInfoManager::DerefDebugExpression(Instruction* dbg_expr) { + assert(dbg_expr->GetCommonDebugOpcode() == CommonDebugInfoDebugExpression); + std::unique_ptr deref_expr(dbg_expr->Clone(context())); + deref_expr->SetResultId(context()->TakeNextId()); + deref_expr->InsertOperand( + kDebugExpressOperandOperationIndex, + {SPV_OPERAND_TYPE_ID, {GetDebugOperationWithDeref()->result_id()}}); + auto* deref_expr_instr = + context()->ext_inst_debuginfo_end()->InsertBefore(std::move(deref_expr)); + AnalyzeDebugInst(deref_expr_instr); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(deref_expr_instr); + return deref_expr_instr; +} + +Instruction* DebugInfoManager::GetDebugInfoNone() { + if (debug_info_none_inst_ != nullptr) return debug_info_none_inst_; + + uint32_t result_id = context()->TakeNextId(); + std::unique_ptr dbg_info_none_inst(new Instruction( + context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + result_id, + { + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast(CommonDebugInfoDebugInfoNone)}}, + })); + + // Add to the front of |ext_inst_debuginfo_|. + debug_info_none_inst_ = + context()->module()->ext_inst_debuginfo_begin()->InsertBefore( + std::move(dbg_info_none_inst)); + + RegisterDbgInst(debug_info_none_inst_); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(debug_info_none_inst_); + return debug_info_none_inst_; +} + +Instruction* DebugInfoManager::GetEmptyDebugExpression() { + if (empty_debug_expr_inst_ != nullptr) return empty_debug_expr_inst_; + + uint32_t result_id = context()->TakeNextId(); + std::unique_ptr empty_debug_expr(new Instruction( + context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + result_id, + { + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast(CommonDebugInfoDebugExpression)}}, + })); + + // Add to the front of |ext_inst_debuginfo_|. + empty_debug_expr_inst_ = + context()->module()->ext_inst_debuginfo_begin()->InsertBefore( + std::move(empty_debug_expr)); + + RegisterDbgInst(empty_debug_expr_inst_); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(empty_debug_expr_inst_); + return empty_debug_expr_inst_; +} + +Instruction* DebugInfoManager::GetDebugInlinedAt(uint32_t dbg_inlined_at_id) { + auto* inlined_at = GetDbgInst(dbg_inlined_at_id); + if (inlined_at == nullptr) return nullptr; + if (inlined_at->GetCommonDebugOpcode() != CommonDebugInfoDebugInlinedAt) { + return nullptr; + } + return inlined_at; +} + +Instruction* DebugInfoManager::CloneDebugInlinedAt(uint32_t clone_inlined_at_id, + Instruction* insert_before) { + auto* inlined_at = GetDebugInlinedAt(clone_inlined_at_id); + if (inlined_at == nullptr) return nullptr; + std::unique_ptr new_inlined_at(inlined_at->Clone(context())); + new_inlined_at->SetResultId(context()->TakeNextId()); + RegisterDbgInst(new_inlined_at.get()); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(new_inlined_at.get()); + if (insert_before != nullptr) + return insert_before->InsertBefore(std::move(new_inlined_at)); + return context()->module()->ext_inst_debuginfo_end()->InsertBefore( + std::move(new_inlined_at)); +} + +bool DebugInfoManager::IsVariableDebugDeclared(uint32_t variable_id) { + auto dbg_decl_itr = var_id_to_dbg_decl_.find(variable_id); + return dbg_decl_itr != var_id_to_dbg_decl_.end(); +} + +bool DebugInfoManager::KillDebugDeclares(uint32_t variable_id) { + bool modified = false; + auto dbg_decl_itr = var_id_to_dbg_decl_.find(variable_id); + if (dbg_decl_itr != var_id_to_dbg_decl_.end()) { + // We intentionally copy the list of DebugDeclare instructions because + // context()->KillInst(dbg_decl) will update |var_id_to_dbg_decl_|. If we + // directly use |dbg_decl_itr->second|, it accesses a dangling pointer. + auto copy_dbg_decls = dbg_decl_itr->second; + + for (auto* dbg_decl : copy_dbg_decls) { + context()->KillInst(dbg_decl); + modified = true; + } + var_id_to_dbg_decl_.erase(dbg_decl_itr); + } + return modified; +} + +uint32_t DebugInfoManager::GetParentScope(uint32_t child_scope) { + auto dbg_scope_itr = id_to_dbg_inst_.find(child_scope); + assert(dbg_scope_itr != id_to_dbg_inst_.end()); + CommonDebugInfoInstructions debug_opcode = + dbg_scope_itr->second->GetCommonDebugOpcode(); + uint32_t parent_scope = kNoDebugScope; + switch (debug_opcode) { + case CommonDebugInfoDebugFunction: + parent_scope = dbg_scope_itr->second->GetSingleWordOperand( + kDebugFunctionOperandParentIndex); + break; + case CommonDebugInfoDebugLexicalBlock: + parent_scope = dbg_scope_itr->second->GetSingleWordOperand( + kDebugLexicalBlockOperandParentIndex); + break; + case CommonDebugInfoDebugTypeComposite: + parent_scope = dbg_scope_itr->second->GetSingleWordOperand( + kDebugTypeCompositeOperandParentIndex); + break; + case CommonDebugInfoDebugCompilationUnit: + // DebugCompilationUnit does not have a parent scope. + break; + default: + assert(false && + "Unreachable. A debug scope instruction must be " + "DebugFunction, DebugTypeComposite, DebugLexicalBlock, " + "or DebugCompilationUnit."); + break; + } + return parent_scope; +} + +bool DebugInfoManager::IsAncestorOfScope(uint32_t scope, uint32_t ancestor) { + uint32_t ancestor_scope_itr = scope; + while (ancestor_scope_itr != kNoDebugScope) { + if (ancestor == ancestor_scope_itr) return true; + ancestor_scope_itr = GetParentScope(ancestor_scope_itr); + } + return false; +} + +bool DebugInfoManager::IsDeclareVisibleToInstr(Instruction* dbg_declare, + Instruction* scope) { + assert(dbg_declare != nullptr); + assert(scope != nullptr); + + std::vector scope_ids; + if (scope->opcode() == spv::Op::OpPhi) { + scope_ids.push_back(scope->GetDebugScope().GetLexicalScope()); + for (uint32_t i = 0; i < scope->NumInOperands(); i += 2) { + auto* value = context()->get_def_use_mgr()->GetDef( + scope->GetSingleWordInOperand(i)); + if (value != nullptr) + scope_ids.push_back(value->GetDebugScope().GetLexicalScope()); + } + } else { + scope_ids.push_back(scope->GetDebugScope().GetLexicalScope()); + } + + uint32_t dbg_local_var_id = + dbg_declare->GetSingleWordOperand(kDebugDeclareOperandLocalVariableIndex); + auto dbg_local_var_itr = id_to_dbg_inst_.find(dbg_local_var_id); + assert(dbg_local_var_itr != id_to_dbg_inst_.end()); + uint32_t decl_scope_id = dbg_local_var_itr->second->GetSingleWordOperand( + kDebugLocalVariableOperandParentIndex); + + // If the scope of DebugDeclare is an ancestor scope of the instruction's + // scope, the local variable is visible to the instruction. + for (uint32_t scope_id : scope_ids) { + if (scope_id != kNoDebugScope && + IsAncestorOfScope(scope_id, decl_scope_id)) { + return true; + } + } + return false; +} + +bool DebugInfoManager::AddDebugValueForVariable(Instruction* scope_and_line, + uint32_t variable_id, + uint32_t value_id, + Instruction* insert_pos) { + assert(scope_and_line != nullptr); + + auto dbg_decl_itr = var_id_to_dbg_decl_.find(variable_id); + if (dbg_decl_itr == var_id_to_dbg_decl_.end()) return false; + + bool modified = false; + for (auto* dbg_decl_or_val : dbg_decl_itr->second) { + // Avoid inserting the new DebugValue between OpPhi or OpVariable + // instructions. + Instruction* insert_before = insert_pos->NextNode(); + while (insert_before->opcode() == spv::Op::OpPhi || + insert_before->opcode() == spv::Op::OpVariable) { + insert_before = insert_before->NextNode(); + } + modified |= AddDebugValueForDecl(dbg_decl_or_val, value_id, insert_before, + scope_and_line) != nullptr; + } + return modified; +} + +Instruction* DebugInfoManager::AddDebugValueForDecl( + Instruction* dbg_decl, uint32_t value_id, Instruction* insert_before, + Instruction* scope_and_line) { + if (dbg_decl == nullptr || !IsDebugDeclare(dbg_decl)) return nullptr; + + std::unique_ptr dbg_val(dbg_decl->Clone(context())); + dbg_val->SetResultId(context()->TakeNextId()); + dbg_val->SetInOperand(kExtInstInstructionInIdx, {CommonDebugInfoDebugValue}); + dbg_val->SetOperand(kDebugDeclareOperandVariableIndex, {value_id}); + dbg_val->SetOperand(kDebugValueOperandExpressionIndex, + {GetEmptyDebugExpression()->result_id()}); + dbg_val->UpdateDebugInfoFrom(scope_and_line); + + auto* added_dbg_val = insert_before->InsertBefore(std::move(dbg_val)); + AnalyzeDebugInst(added_dbg_val); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(added_dbg_val); + if (context()->AreAnalysesValid( + IRContext::Analysis::kAnalysisInstrToBlockMapping)) { + auto insert_blk = context()->get_instr_block(insert_before); + context()->set_instr_block(added_dbg_val, insert_blk); + } + return added_dbg_val; +} + +uint32_t DebugInfoManager::GetVulkanDebugOperation(Instruction* inst) { + assert(inst->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugOperation && + "inst must be Vulkan DebugOperation"); + return context() + ->get_constant_mgr() + ->GetConstantFromInst(context()->get_def_use_mgr()->GetDef( + inst->GetSingleWordOperand(kDebugOperationOperandOperationIndex))) + ->GetU32(); +} + +uint32_t DebugInfoManager::GetVariableIdOfDebugValueUsedForDeclare( + Instruction* inst) { + if (inst->GetCommonDebugOpcode() != CommonDebugInfoDebugValue) return 0; + + auto* expr = + GetDbgInst(inst->GetSingleWordOperand(kDebugValueOperandExpressionIndex)); + if (expr == nullptr) return 0; + if (expr->NumOperands() != kDebugExpressOperandOperationIndex + 1) return 0; + + auto* operation = GetDbgInst( + expr->GetSingleWordOperand(kDebugExpressOperandOperationIndex)); + if (operation == nullptr) return 0; + + // OpenCL.DebugInfo.100 contains a literal for the operation, Vulkan uses an + // OpConstant. + if (inst->IsOpenCL100DebugInstr()) { + if (operation->GetSingleWordOperand(kDebugOperationOperandOperationIndex) != + OpenCLDebugInfo100Deref) { + return 0; + } + } else { + uint32_t operation_const = GetVulkanDebugOperation(operation); + if (operation_const != NonSemanticShaderDebugInfo100Deref) { + return 0; + } + } + + uint32_t var_id = + inst->GetSingleWordOperand(kDebugDeclareOperandVariableIndex); + if (!context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) { + assert(false && + "Checking a DebugValue can be used for declare needs DefUseManager"); + return 0; + } + + auto* var = context()->get_def_use_mgr()->GetDef(var_id); + if (var->opcode() == spv::Op::OpVariable && + spv::StorageClass( + var->GetSingleWordOperand(kOpVariableOperandStorageClassIndex)) == + spv::StorageClass::Function) { + return var_id; + } + return 0; +} + +bool DebugInfoManager::IsDebugDeclare(Instruction* instr) { + if (!instr->IsCommonDebugInstr()) return false; + return instr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare || + GetVariableIdOfDebugValueUsedForDeclare(instr) != 0; +} + +void DebugInfoManager::ReplaceAllUsesInDebugScopeWithPredicate( + uint32_t before, uint32_t after, + const std::function& predicate) { + auto scope_id_to_users_itr = scope_id_to_users_.find(before); + if (scope_id_to_users_itr != scope_id_to_users_.end()) { + for (Instruction* inst : scope_id_to_users_itr->second) { + if (predicate(inst)) inst->UpdateLexicalScope(after); + } + scope_id_to_users_[after] = scope_id_to_users_itr->second; + scope_id_to_users_.erase(scope_id_to_users_itr); + } + auto inlinedat_id_to_users_itr = inlinedat_id_to_users_.find(before); + if (inlinedat_id_to_users_itr != inlinedat_id_to_users_.end()) { + for (Instruction* inst : inlinedat_id_to_users_itr->second) { + if (predicate(inst)) inst->UpdateDebugInlinedAt(after); + } + inlinedat_id_to_users_[after] = inlinedat_id_to_users_itr->second; + inlinedat_id_to_users_.erase(inlinedat_id_to_users_itr); + } +} + +void DebugInfoManager::ClearDebugScopeAndInlinedAtUses(Instruction* inst) { + auto scope_id_to_users_itr = scope_id_to_users_.find(inst->result_id()); + if (scope_id_to_users_itr != scope_id_to_users_.end()) { + scope_id_to_users_.erase(scope_id_to_users_itr); + } + auto inlinedat_id_to_users_itr = + inlinedat_id_to_users_.find(inst->result_id()); + if (inlinedat_id_to_users_itr != inlinedat_id_to_users_.end()) { + inlinedat_id_to_users_.erase(inlinedat_id_to_users_itr); + } +} + +void DebugInfoManager::AnalyzeDebugInst(Instruction* inst) { + if (inst->GetDebugScope().GetLexicalScope() != kNoDebugScope) { + auto& users = scope_id_to_users_[inst->GetDebugScope().GetLexicalScope()]; + users.insert(inst); + } + if (inst->GetDebugInlinedAt() != kNoInlinedAt) { + auto& users = inlinedat_id_to_users_[inst->GetDebugInlinedAt()]; + users.insert(inst); + } + + if (!inst->IsCommonDebugInstr()) return; + + RegisterDbgInst(inst); + + if (inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugFunction || + inst->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugFunctionDefinition) { + RegisterDbgFunction(inst); + } + + if (deref_operation_ == nullptr && + inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugOperation && + inst->GetSingleWordOperand(kDebugOperationOperandOperationIndex) == + OpenCLDebugInfo100Deref) { + deref_operation_ = inst; + } + + if (deref_operation_ == nullptr && + inst->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugOperation) { + uint32_t operation_const = GetVulkanDebugOperation(inst); + if (operation_const == NonSemanticShaderDebugInfo100Deref) { + deref_operation_ = inst; + } + } + + if (debug_info_none_inst_ == nullptr && + inst->GetCommonDebugOpcode() == CommonDebugInfoDebugInfoNone) { + debug_info_none_inst_ = inst; + } + + if (empty_debug_expr_inst_ == nullptr && IsEmptyDebugExpression(inst)) { + empty_debug_expr_inst_ = inst; + } + + if (inst->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { + uint32_t var_id = + inst->GetSingleWordOperand(kDebugDeclareOperandVariableIndex); + RegisterDbgDeclare(var_id, inst); + } + + if (uint32_t var_id = GetVariableIdOfDebugValueUsedForDeclare(inst)) { + RegisterDbgDeclare(var_id, inst); + } +} + +void DebugInfoManager::ConvertDebugGlobalToLocalVariable( + Instruction* dbg_global_var, Instruction* local_var) { + if (dbg_global_var->GetCommonDebugOpcode() != + CommonDebugInfoDebugGlobalVariable) { + return; + } + assert(local_var->opcode() == spv::Op::OpVariable || + local_var->opcode() == spv::Op::OpFunctionParameter); + + // Convert |dbg_global_var| to DebugLocalVariable + dbg_global_var->SetInOperand(kExtInstInstructionInIdx, + {CommonDebugInfoDebugLocalVariable}); + auto flags = dbg_global_var->GetSingleWordOperand( + kDebugGlobalVariableOperandFlagsIndex); + for (uint32_t i = dbg_global_var->NumInOperands() - 1; + i >= kDebugLocalVariableOperandFlagsIndex; --i) { + dbg_global_var->RemoveOperand(i); + } + dbg_global_var->SetOperand(kDebugLocalVariableOperandFlagsIndex, {flags}); + context()->ForgetUses(dbg_global_var); + context()->AnalyzeUses(dbg_global_var); + + // Create a DebugDeclare + std::unique_ptr new_dbg_decl(new Instruction( + context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context()->TakeNextId(), + { + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast(CommonDebugInfoDebugDeclare)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {dbg_global_var->result_id()}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {local_var->result_id()}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {GetEmptyDebugExpression()->result_id()}}, + })); + // Must insert after all OpVariables in block + Instruction* insert_before = local_var; + while (insert_before->opcode() == spv::Op::OpVariable) + insert_before = insert_before->NextNode(); + auto* added_dbg_decl = insert_before->InsertBefore(std::move(new_dbg_decl)); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(added_dbg_decl); + if (context()->AreAnalysesValid( + IRContext::Analysis::kAnalysisInstrToBlockMapping)) { + auto insert_blk = context()->get_instr_block(local_var); + context()->set_instr_block(added_dbg_decl, insert_blk); + } +} + +void DebugInfoManager::AnalyzeDebugInsts(Module& module) { + deref_operation_ = nullptr; + debug_info_none_inst_ = nullptr; + empty_debug_expr_inst_ = nullptr; + module.ForEachInst([this](Instruction* cpi) { AnalyzeDebugInst(cpi); }); + + // Move |empty_debug_expr_inst_| to the beginning of the debug instruction + // list. + if (empty_debug_expr_inst_ != nullptr && + empty_debug_expr_inst_->PreviousNode() != nullptr && + empty_debug_expr_inst_->PreviousNode()->IsCommonDebugInstr()) { + empty_debug_expr_inst_->InsertBefore( + &*context()->module()->ext_inst_debuginfo_begin()); + } + + // Move |debug_info_none_inst_| to the beginning of the debug instruction + // list. + if (debug_info_none_inst_ != nullptr && + debug_info_none_inst_->PreviousNode() != nullptr && + debug_info_none_inst_->PreviousNode()->IsCommonDebugInstr()) { + debug_info_none_inst_->InsertBefore( + &*context()->module()->ext_inst_debuginfo_begin()); + } +} + +void DebugInfoManager::ClearDebugInfo(Instruction* instr) { + auto scope_id_to_users_itr = + scope_id_to_users_.find(instr->GetDebugScope().GetLexicalScope()); + if (scope_id_to_users_itr != scope_id_to_users_.end()) { + scope_id_to_users_itr->second.erase(instr); + } + auto inlinedat_id_to_users_itr = + inlinedat_id_to_users_.find(instr->GetDebugInlinedAt()); + if (inlinedat_id_to_users_itr != inlinedat_id_to_users_.end()) { + inlinedat_id_to_users_itr->second.erase(instr); + } + + if (instr == nullptr || !instr->IsCommonDebugInstr()) { + return; + } + + id_to_dbg_inst_.erase(instr->result_id()); + + if (instr->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugFunction) { + auto fn_id = + instr->GetSingleWordOperand(kDebugFunctionOperandFunctionIndex); + fn_id_to_dbg_fn_.erase(fn_id); + } + if (instr->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugFunctionDefinition) { + auto fn_id = instr->GetSingleWordOperand( + kDebugFunctionDefinitionOperandOpFunctionIndex); + fn_id_to_dbg_fn_.erase(fn_id); + } + + if (instr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare || + instr->GetCommonDebugOpcode() == CommonDebugInfoDebugValue) { + auto var_or_value_id = + instr->GetSingleWordOperand(kDebugDeclareOperandVariableIndex); + auto dbg_decl_itr = var_id_to_dbg_decl_.find(var_or_value_id); + if (dbg_decl_itr != var_id_to_dbg_decl_.end()) { + dbg_decl_itr->second.erase(instr); + } + } + + if (deref_operation_ == instr) { + deref_operation_ = nullptr; + for (auto dbg_instr_itr = context()->module()->ext_inst_debuginfo_begin(); + dbg_instr_itr != context()->module()->ext_inst_debuginfo_end(); + ++dbg_instr_itr) { + // OpenCL.DebugInfo.100 contains the operation as a literal operand, in + // Vulkan it's referenced as an OpConstant. + if (instr != &*dbg_instr_itr && + dbg_instr_itr->GetOpenCL100DebugOpcode() == + OpenCLDebugInfo100DebugOperation && + dbg_instr_itr->GetSingleWordOperand( + kDebugOperationOperandOperationIndex) == + OpenCLDebugInfo100Deref) { + deref_operation_ = &*dbg_instr_itr; + break; + } else if (instr != &*dbg_instr_itr && + dbg_instr_itr->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugOperation) { + uint32_t operation_const = GetVulkanDebugOperation(&*dbg_instr_itr); + if (operation_const == NonSemanticShaderDebugInfo100Deref) { + deref_operation_ = &*dbg_instr_itr; + break; + } + } + } + } + + if (debug_info_none_inst_ == instr) { + debug_info_none_inst_ = nullptr; + for (auto dbg_instr_itr = context()->module()->ext_inst_debuginfo_begin(); + dbg_instr_itr != context()->module()->ext_inst_debuginfo_end(); + ++dbg_instr_itr) { + if (instr != &*dbg_instr_itr && dbg_instr_itr->GetCommonDebugOpcode() == + CommonDebugInfoDebugInfoNone) { + debug_info_none_inst_ = &*dbg_instr_itr; + break; + } + } + } + + if (empty_debug_expr_inst_ == instr) { + empty_debug_expr_inst_ = nullptr; + for (auto dbg_instr_itr = context()->module()->ext_inst_debuginfo_begin(); + dbg_instr_itr != context()->module()->ext_inst_debuginfo_end(); + ++dbg_instr_itr) { + if (instr != &*dbg_instr_itr && IsEmptyDebugExpression(&*dbg_instr_itr)) { + empty_debug_expr_inst_ = &*dbg_instr_itr; + break; + } + } + } +} + +} // namespace analysis +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/debug_info_manager.h b/thirdparty/glslang/External/spirv-tools/source/opt/debug_info_manager.h new file mode 100644 index 000000000000..abb7b9a08b7b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/debug_info_manager.h @@ -0,0 +1,285 @@ +// Copyright (c) 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DEBUG_INFO_MANAGER_H_ +#define SOURCE_OPT_DEBUG_INFO_MANAGER_H_ + +#include +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { +namespace analysis { + +// When an instruction of a callee function is inlined to its caller function, +// we need the line and the scope information of the function call instruction +// to generate DebugInlinedAt. This class keeps the data. For multiple inlining +// of a single instruction, we have to create multiple DebugInlinedAt +// instructions as a chain. This class keeps the information of the generated +// DebugInlinedAt chains to reduce the number of chains. +class DebugInlinedAtContext { + public: + explicit DebugInlinedAtContext(Instruction* call_inst) + : call_inst_line_(call_inst->dbg_line_inst()), + call_inst_scope_(call_inst->GetDebugScope()) {} + + const Instruction* GetLineOfCallInstruction() { return call_inst_line_; } + const DebugScope& GetScopeOfCallInstruction() { return call_inst_scope_; } + // Puts the DebugInlinedAt chain that is generated for the callee instruction + // whose DebugInlinedAt of DebugScope is |callee_instr_inlined_at| into + // |callee_inlined_at2chain_|. + void SetDebugInlinedAtChain(uint32_t callee_instr_inlined_at, + uint32_t chain_head_id) { + callee_inlined_at2chain_[callee_instr_inlined_at] = chain_head_id; + } + // Gets the DebugInlinedAt chain from |callee_inlined_at2chain_|. + uint32_t GetDebugInlinedAtChain(uint32_t callee_instr_inlined_at) { + auto chain_itr = callee_inlined_at2chain_.find(callee_instr_inlined_at); + if (chain_itr != callee_inlined_at2chain_.end()) return chain_itr->second; + return kNoInlinedAt; + } + + private: + // The line information of the function call instruction that will be + // replaced by the callee function. + const Instruction* call_inst_line_; + + // The scope information of the function call instruction that will be + // replaced by the callee function. + const DebugScope call_inst_scope_; + + // Map from DebugInlinedAt ids of callee to head ids of new generated + // DebugInlinedAt chain. + std::unordered_map callee_inlined_at2chain_; +}; + +// A class for analyzing, managing, and creating OpenCL.DebugInfo.100 and +// NonSemantic.Shader.DebugInfo.100 extension instructions. +class DebugInfoManager { + public: + // Constructs a debug information manager from the given |context|. + DebugInfoManager(IRContext* context); + + DebugInfoManager(const DebugInfoManager&) = delete; + DebugInfoManager(DebugInfoManager&&) = delete; + DebugInfoManager& operator=(const DebugInfoManager&) = delete; + DebugInfoManager& operator=(DebugInfoManager&&) = delete; + + friend bool operator==(const DebugInfoManager&, const DebugInfoManager&); + friend bool operator!=(const DebugInfoManager& lhs, + const DebugInfoManager& rhs) { + return !(lhs == rhs); + } + + // Analyzes DebugInfo instruction |dbg_inst|. + void AnalyzeDebugInst(Instruction* dbg_inst); + + // Creates new DebugInlinedAt and returns its id. Its line operand is the + // line number of |line| if |line| is not nullptr. Otherwise, its line operand + // is the line number of lexical scope of |scope|. Its Scope and Inlined + // operands are Scope and Inlined of |scope|. + uint32_t CreateDebugInlinedAt(const Instruction* line, + const DebugScope& scope); + + // Clones DebugExpress instruction |dbg_expr| and add Deref Operation + // in the front of the Operation list of |dbg_expr|. + Instruction* DerefDebugExpression(Instruction* dbg_expr); + + // Returns a DebugInfoNone instruction. + Instruction* GetDebugInfoNone(); + + // Returns DebugInlinedAt whose id is |dbg_inlined_at_id|. If it does not + // exist or it is not a DebugInlinedAt instruction, return nullptr. + Instruction* GetDebugInlinedAt(uint32_t dbg_inlined_at_id); + + // Returns DebugFunction whose Function operand is |fn_id|. If it does not + // exist, return nullptr. + Instruction* GetDebugFunction(uint32_t fn_id) { + auto dbg_fn_it = fn_id_to_dbg_fn_.find(fn_id); + return dbg_fn_it == fn_id_to_dbg_fn_.end() ? nullptr : dbg_fn_it->second; + } + + // Clones DebugInlinedAt whose id is |clone_inlined_at_id|. If + // |clone_inlined_at_id| is not an id of DebugInlinedAt, returns nullptr. + // If |insert_before| is given, inserts the new DebugInlinedAt before it. + // Otherwise, inserts the new DebugInlinedAt into the debug instruction + // section of the module. + Instruction* CloneDebugInlinedAt(uint32_t clone_inlined_at_id, + Instruction* insert_before = nullptr); + + // Returns the debug scope corresponding to an inlining instruction in the + // scope |callee_instr_scope| into |inlined_at_ctx|. Generates all new + // debug instructions needed to represent the scope. + DebugScope BuildDebugScope(const DebugScope& callee_instr_scope, + DebugInlinedAtContext* inlined_at_ctx); + + // Returns DebugInlinedAt corresponding to inlining an instruction, which + // was inlined at |callee_inlined_at|, into |inlined_at_ctx|. Generates all + // new debug instructions needed to represent the DebugInlinedAt. + uint32_t BuildDebugInlinedAtChain(uint32_t callee_inlined_at, + DebugInlinedAtContext* inlined_at_ctx); + + // Returns true if there is a debug declaration instruction whose + // 'Local Variable' operand is |variable_id|. + bool IsVariableDebugDeclared(uint32_t variable_id); + + // Kills all debug declaration instructions with Deref whose 'Local Variable' + // operand is |variable_id|. Returns whether it kills an instruction or not. + bool KillDebugDeclares(uint32_t variable_id); + + // Generates a DebugValue instruction with value |value_id| for every local + // variable that is in the scope of |scope_and_line| and whose memory is + // |variable_id| and inserts it after the instruction |insert_pos|. + // Returns whether a DebugValue is added or not. + bool AddDebugValueForVariable(Instruction* scope_and_line, + uint32_t variable_id, uint32_t value_id, + Instruction* insert_pos); + + // Creates a DebugValue for DebugDeclare |dbg_decl| and inserts it before + // |insert_before|. The new DebugValue has the same line and scope as + // |scope_and_line|, or no scope and line information if |scope_and_line| + // is nullptr. The new DebugValue has the same operands as DebugDeclare + // but it uses |value_id| for the value. Returns the created DebugValue, + // or nullptr if fails to create one. + Instruction* AddDebugValueForDecl(Instruction* dbg_decl, uint32_t value_id, + Instruction* insert_before, + Instruction* scope_and_line); + + // Erases |instr| from data structures of this class. + void ClearDebugInfo(Instruction* instr); + + // Return the opcode for the Vulkan DebugOperation inst + uint32_t GetVulkanDebugOperation(Instruction* inst); + + // Returns the id of Value operand if |inst| is DebugValue who has Deref + // operation and its Value operand is a result id of OpVariable with + // Function storage class. Otherwise, returns 0. + uint32_t GetVariableIdOfDebugValueUsedForDeclare(Instruction* inst); + + // Converts DebugGlobalVariable |dbg_global_var| to a DebugLocalVariable and + // creates a DebugDeclare mapping the new DebugLocalVariable to |local_var|. + void ConvertDebugGlobalToLocalVariable(Instruction* dbg_global_var, + Instruction* local_var); + + // Returns true if |instr| is a debug declaration instruction. + bool IsDebugDeclare(Instruction* instr); + + // Replace all uses of |before| id that is an operand of a DebugScope with + // |after| id if those uses (instruction) return true for |predicate|. + void ReplaceAllUsesInDebugScopeWithPredicate( + uint32_t before, uint32_t after, + const std::function& predicate); + + // Removes uses of DebugScope |inst| from |scope_id_to_users_| or uses of + // DebugInlinedAt |inst| from |inlinedat_id_to_users_|. + void ClearDebugScopeAndInlinedAtUses(Instruction* inst); + + private: + IRContext* context() { return context_; } + + // Analyzes DebugInfo instructions in the given |module| and + // populates data structures in this class. + void AnalyzeDebugInsts(Module& module); + + // Get the DebugInfo ExtInstImport Id, or 0 if no DebugInfo is available. + uint32_t GetDbgSetImportId(); + + // Returns the debug instruction whose id is |id|. Returns |nullptr| if one + // does not exists. + Instruction* GetDbgInst(uint32_t id); + + // Returns a DebugOperation instruction with OpCode Deref. + Instruction* GetDebugOperationWithDeref(); + + // Registers the debug instruction |inst| into |id_to_dbg_inst_| using id of + // |inst| as a key. + void RegisterDbgInst(Instruction* inst); + + // Register the DebugFunction instruction |inst|. The function referenced + // in |inst| must not already be registered. + void RegisterDbgFunction(Instruction* inst); + + // Register the DebugDeclare or DebugValue with Deref operation + // |dbg_declare| into |var_id_to_dbg_decl_| using OpVariable id + // |var_id| as a key. + void RegisterDbgDeclare(uint32_t var_id, Instruction* dbg_declare); + + // Returns a DebugExpression instruction without Operation operands. + Instruction* GetEmptyDebugExpression(); + + // Returns true if a scope |ancestor| is |scope| or an ancestor scope + // of |scope|. + bool IsAncestorOfScope(uint32_t scope, uint32_t ancestor); + + // Returns true if the declaration of a local variable |dbg_declare| + // is visible in the scope of an instruction |instr_scope_id|. + bool IsDeclareVisibleToInstr(Instruction* dbg_declare, Instruction* scope); + + // Returns the parent scope of the scope |child_scope|. + uint32_t GetParentScope(uint32_t child_scope); + + IRContext* context_; + + // Mapping from ids of DebugInfo extension instructions. + // to their Instruction instances. + std::unordered_map id_to_dbg_inst_; + + // Mapping from function's ids to DebugFunction instructions whose + // operand is the function. + std::unordered_map fn_id_to_dbg_fn_; + + // Orders Instruction* for use in associative containers (i.e. less than + // ordering). Unique Id is used. + typedef Instruction* InstPtr; + struct InstPtrLess { + bool operator()(const InstPtr& lhs, const InstPtr& rhs) const { + return lhs->unique_id() < rhs->unique_id(); + } + }; + + // Mapping from variable or value ids to DebugDeclare or DebugValue + // instructions whose operand is the variable or value. + std::unordered_map> + var_id_to_dbg_decl_; + + // Mapping from DebugScope ids to users. + std::unordered_map> + scope_id_to_users_; + + // Mapping from DebugInlinedAt ids to users. + std::unordered_map> + inlinedat_id_to_users_; + + // DebugOperation whose OpCode is OpenCLDebugInfo100Deref. + Instruction* deref_operation_; + + // DebugInfoNone instruction. We need only a single DebugInfoNone. + // To reuse the existing one, we keep it using this member variable. + Instruction* debug_info_none_inst_; + + // DebugExpression instruction without Operation operands. We need only + // a single DebugExpression without Operation operands. To reuse the + // existing one, we keep it using this member variable. + Instruction* empty_debug_expr_inst_; +}; + +} // namespace analysis +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DEBUG_INFO_MANAGER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/decoration_manager.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/decoration_manager.cpp new file mode 100644 index 000000000000..3e95dbc3529c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/decoration_manager.cpp @@ -0,0 +1,644 @@ +// Copyright (c) 2017 Pierre Moreau +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/decoration_manager.h" + +#include +#include +#include +#include +#include + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace analysis { +namespace { +using InstructionVector = std::vector; +using DecorationSet = std::set; + +// Returns true if |a| is a subet of |b|. +bool IsSubset(const DecorationSet& a, const DecorationSet& b) { + auto it1 = a.begin(); + auto it2 = b.begin(); + + while (it1 != a.end()) { + if (it2 == b.end() || *it1 < *it2) { + // |*it1| is in |a|, but not in |b|. + return false; + } + if (*it1 == *it2) { + // Found the element move to the next one. + it1++; + it2++; + } else /* *it1 > *it2 */ { + // Did not find |*it1| yet, check the next element in |b|. + it2++; + } + } + return true; +} +} // namespace + +bool DecorationManager::RemoveDecorationsFrom( + uint32_t id, std::function pred) { + bool was_modified = false; + const auto ids_iter = id_to_decoration_insts_.find(id); + if (ids_iter == id_to_decoration_insts_.end()) { + return was_modified; + } + + TargetData& decorations_info = ids_iter->second; + auto context = module_->context(); + std::vector insts_to_kill; + const bool is_group = !decorations_info.decorate_insts.empty(); + + // Schedule all direct decorations for removal if instructed as such by + // |pred|. + for (Instruction* inst : decorations_info.direct_decorations) + if (pred(*inst)) insts_to_kill.push_back(inst); + + // For all groups being directly applied to |id|, remove |id| (and the + // literal if |inst| is an OpGroupMemberDecorate) from the instruction + // applying the group. + std::unordered_set indirect_decorations_to_remove; + for (Instruction* inst : decorations_info.indirect_decorations) { + assert(inst->opcode() == spv::Op::OpGroupDecorate || + inst->opcode() == spv::Op::OpGroupMemberDecorate); + + std::vector group_decorations_to_keep; + const uint32_t group_id = inst->GetSingleWordInOperand(0u); + const auto group_iter = id_to_decoration_insts_.find(group_id); + assert(group_iter != id_to_decoration_insts_.end() && + "Unknown decoration group"); + const auto& group_decorations = group_iter->second.direct_decorations; + for (Instruction* decoration : group_decorations) { + if (!pred(*decoration)) group_decorations_to_keep.push_back(decoration); + } + + // If all decorations should be kept, then we can keep |id| part of the + // group. However, if the group itself has no decorations, we should remove + // the id from the group. This is needed to make |KillNameAndDecorate| work + // correctly when a decoration group has no decorations. + if (group_decorations_to_keep.size() == group_decorations.size() && + group_decorations.size() != 0) { + continue; + } + + // Otherwise, remove |id| from the targets of |group_id| + const uint32_t stride = + inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; + for (uint32_t i = 1u; i < inst->NumInOperands();) { + if (inst->GetSingleWordInOperand(i) != id) { + i += stride; + continue; + } + + const uint32_t last_operand_index = inst->NumInOperands() - stride; + if (i < last_operand_index) + inst->GetInOperand(i) = inst->GetInOperand(last_operand_index); + // Remove the associated literal, if it exists. + if (stride == 2u) { + if (i < last_operand_index) + inst->GetInOperand(i + 1u) = + inst->GetInOperand(last_operand_index + 1u); + inst->RemoveInOperand(last_operand_index + 1u); + } + inst->RemoveInOperand(last_operand_index); + was_modified = true; + } + + // If the instruction has no targets left, remove the instruction + // altogether. + if (inst->NumInOperands() == 1u) { + indirect_decorations_to_remove.emplace(inst); + insts_to_kill.push_back(inst); + } else if (was_modified) { + context->ForgetUses(inst); + indirect_decorations_to_remove.emplace(inst); + context->AnalyzeUses(inst); + } + + // If only some of the decorations should be kept, clone them and apply + // them directly to |id|. + if (!group_decorations_to_keep.empty()) { + for (Instruction* decoration : group_decorations_to_keep) { + // simply clone decoration and change |group_id| to |id| + std::unique_ptr new_inst( + decoration->Clone(module_->context())); + new_inst->SetInOperand(0, {id}); + module_->AddAnnotationInst(std::move(new_inst)); + auto decoration_iter = --module_->annotation_end(); + context->AnalyzeUses(&*decoration_iter); + } + } + } + + auto& indirect_decorations = decorations_info.indirect_decorations; + indirect_decorations.erase( + std::remove_if( + indirect_decorations.begin(), indirect_decorations.end(), + [&indirect_decorations_to_remove](const Instruction* inst) { + return indirect_decorations_to_remove.count(inst); + }), + indirect_decorations.end()); + + was_modified |= !insts_to_kill.empty(); + for (Instruction* inst : insts_to_kill) context->KillInst(inst); + insts_to_kill.clear(); + + // Schedule all instructions applying the group for removal if this group no + // longer applies decorations, either directly or indirectly. + if (is_group && decorations_info.direct_decorations.empty() && + decorations_info.indirect_decorations.empty()) { + for (Instruction* inst : decorations_info.decorate_insts) + insts_to_kill.push_back(inst); + } + was_modified |= !insts_to_kill.empty(); + for (Instruction* inst : insts_to_kill) context->KillInst(inst); + + if (decorations_info.direct_decorations.empty() && + decorations_info.indirect_decorations.empty() && + decorations_info.decorate_insts.empty()) { + id_to_decoration_insts_.erase(ids_iter); + } + return was_modified; +} + +std::vector DecorationManager::GetDecorationsFor( + uint32_t id, bool include_linkage) { + return InternalGetDecorationsFor(id, include_linkage); +} + +std::vector DecorationManager::GetDecorationsFor( + uint32_t id, bool include_linkage) const { + return const_cast(this) + ->InternalGetDecorationsFor(id, include_linkage); +} + +bool DecorationManager::HaveTheSameDecorations(uint32_t id1, + uint32_t id2) const { + const InstructionVector decorations_for1 = GetDecorationsFor(id1, false); + const InstructionVector decorations_for2 = GetDecorationsFor(id2, false); + + // This function splits the decoration instructions into different sets, + // based on their opcode; only OpDecorate, OpDecorateId, + // OpDecorateStringGOOGLE, and OpMemberDecorate are considered, the other + // opcodes are ignored. + const auto fillDecorationSets = + [](const InstructionVector& decoration_list, DecorationSet* decorate_set, + DecorationSet* decorate_id_set, DecorationSet* decorate_string_set, + DecorationSet* member_decorate_set) { + for (const Instruction* inst : decoration_list) { + std::u32string decoration_payload; + // Ignore the opcode and the target as we do not want them to be + // compared. + for (uint32_t i = 1u; i < inst->NumInOperands(); ++i) { + for (uint32_t word : inst->GetInOperand(i).words) { + decoration_payload.push_back(word); + } + } + + switch (inst->opcode()) { + case spv::Op::OpDecorate: + decorate_set->emplace(std::move(decoration_payload)); + break; + case spv::Op::OpMemberDecorate: + member_decorate_set->emplace(std::move(decoration_payload)); + break; + case spv::Op::OpDecorateId: + decorate_id_set->emplace(std::move(decoration_payload)); + break; + case spv::Op::OpDecorateStringGOOGLE: + decorate_string_set->emplace(std::move(decoration_payload)); + break; + default: + break; + } + } + }; + + DecorationSet decorate_set_for1; + DecorationSet decorate_id_set_for1; + DecorationSet decorate_string_set_for1; + DecorationSet member_decorate_set_for1; + fillDecorationSets(decorations_for1, &decorate_set_for1, + &decorate_id_set_for1, &decorate_string_set_for1, + &member_decorate_set_for1); + + DecorationSet decorate_set_for2; + DecorationSet decorate_id_set_for2; + DecorationSet decorate_string_set_for2; + DecorationSet member_decorate_set_for2; + fillDecorationSets(decorations_for2, &decorate_set_for2, + &decorate_id_set_for2, &decorate_string_set_for2, + &member_decorate_set_for2); + + const bool result = decorate_set_for1 == decorate_set_for2 && + decorate_id_set_for1 == decorate_id_set_for2 && + member_decorate_set_for1 == member_decorate_set_for2 && + // Compare string sets last in case the strings are long. + decorate_string_set_for1 == decorate_string_set_for2; + return result; +} + +bool DecorationManager::HaveSubsetOfDecorations(uint32_t id1, + uint32_t id2) const { + const InstructionVector decorations_for1 = GetDecorationsFor(id1, false); + const InstructionVector decorations_for2 = GetDecorationsFor(id2, false); + + // This function splits the decoration instructions into different sets, + // based on their opcode; only OpDecorate, OpDecorateId, + // OpDecorateStringGOOGLE, and OpMemberDecorate are considered, the other + // opcodes are ignored. + const auto fillDecorationSets = + [](const InstructionVector& decoration_list, DecorationSet* decorate_set, + DecorationSet* decorate_id_set, DecorationSet* decorate_string_set, + DecorationSet* member_decorate_set) { + for (const Instruction* inst : decoration_list) { + std::u32string decoration_payload; + // Ignore the opcode and the target as we do not want them to be + // compared. + for (uint32_t i = 1u; i < inst->NumInOperands(); ++i) { + for (uint32_t word : inst->GetInOperand(i).words) { + decoration_payload.push_back(word); + } + } + + switch (inst->opcode()) { + case spv::Op::OpDecorate: + decorate_set->emplace(std::move(decoration_payload)); + break; + case spv::Op::OpMemberDecorate: + member_decorate_set->emplace(std::move(decoration_payload)); + break; + case spv::Op::OpDecorateId: + decorate_id_set->emplace(std::move(decoration_payload)); + break; + case spv::Op::OpDecorateStringGOOGLE: + decorate_string_set->emplace(std::move(decoration_payload)); + break; + default: + break; + } + } + }; + + DecorationSet decorate_set_for1; + DecorationSet decorate_id_set_for1; + DecorationSet decorate_string_set_for1; + DecorationSet member_decorate_set_for1; + fillDecorationSets(decorations_for1, &decorate_set_for1, + &decorate_id_set_for1, &decorate_string_set_for1, + &member_decorate_set_for1); + + DecorationSet decorate_set_for2; + DecorationSet decorate_id_set_for2; + DecorationSet decorate_string_set_for2; + DecorationSet member_decorate_set_for2; + fillDecorationSets(decorations_for2, &decorate_set_for2, + &decorate_id_set_for2, &decorate_string_set_for2, + &member_decorate_set_for2); + + const bool result = + IsSubset(decorate_set_for1, decorate_set_for2) && + IsSubset(decorate_id_set_for1, decorate_id_set_for2) && + IsSubset(member_decorate_set_for1, member_decorate_set_for2) && + // Compare string sets last in case the strings are long. + IsSubset(decorate_string_set_for1, decorate_string_set_for2); + return result; +} + +// TODO(pierremoreau): If OpDecorateId is referencing an OpConstant, one could +// check that the constants are the same rather than just +// looking at the constant ID. +bool DecorationManager::AreDecorationsTheSame(const Instruction* inst1, + const Instruction* inst2, + bool ignore_target) const { + switch (inst1->opcode()) { + case spv::Op::OpDecorate: + case spv::Op::OpMemberDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + break; + default: + return false; + } + + if (inst1->opcode() != inst2->opcode() || + inst1->NumInOperands() != inst2->NumInOperands()) + return false; + + for (uint32_t i = ignore_target ? 1u : 0u; i < inst1->NumInOperands(); ++i) + if (inst1->GetInOperand(i) != inst2->GetInOperand(i)) return false; + + return true; +} + +void DecorationManager::AnalyzeDecorations() { + if (!module_) return; + + // For each group and instruction, collect all their decoration instructions. + for (Instruction& inst : module_->annotations()) { + AddDecoration(&inst); + } +} + +void DecorationManager::AddDecoration(Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorate: { + const auto target_id = inst->GetSingleWordInOperand(0u); + id_to_decoration_insts_[target_id].direct_decorations.push_back(inst); + break; + } + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: { + const uint32_t start = + inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; + const uint32_t stride = start; + for (uint32_t i = start; i < inst->NumInOperands(); i += stride) { + const auto target_id = inst->GetSingleWordInOperand(i); + TargetData& target_data = id_to_decoration_insts_[target_id]; + target_data.indirect_decorations.push_back(inst); + } + const auto target_id = inst->GetSingleWordInOperand(0u); + id_to_decoration_insts_[target_id].decorate_insts.push_back(inst); + break; + } + default: + break; + } +} + +void DecorationManager::AddDecoration(spv::Op opcode, + std::vector opnds) { + IRContext* ctx = module_->context(); + std::unique_ptr newDecoOp( + new Instruction(ctx, opcode, 0, 0, opnds)); + ctx->AddAnnotationInst(std::move(newDecoOp)); +} + +void DecorationManager::AddDecoration(uint32_t inst_id, uint32_t decoration) { + AddDecoration( + spv::Op::OpDecorate, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}}); +} + +void DecorationManager::AddDecorationVal(uint32_t inst_id, uint32_t decoration, + uint32_t decoration_value) { + AddDecoration( + spv::Op::OpDecorate, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {decoration_value}}}); +} + +void DecorationManager::AddMemberDecoration(uint32_t inst_id, uint32_t member, + uint32_t decoration, + uint32_t decoration_value) { + AddDecoration( + spv::Op::OpMemberDecorate, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {member}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {decoration_value}}}); +} + +template +std::vector DecorationManager::InternalGetDecorationsFor( + uint32_t id, bool include_linkage) { + std::vector decorations; + + const auto ids_iter = id_to_decoration_insts_.find(id); + // |id| has no decorations + if (ids_iter == id_to_decoration_insts_.end()) return decorations; + + const TargetData& target_data = ids_iter->second; + + const auto process_direct_decorations = + [include_linkage, + &decorations](const std::vector& direct_decorations) { + for (Instruction* inst : direct_decorations) { + const bool is_linkage = + inst->opcode() == spv::Op::OpDecorate && + spv::Decoration(inst->GetSingleWordInOperand(1u)) == + spv::Decoration::LinkageAttributes; + if (include_linkage || !is_linkage) decorations.push_back(inst); + } + }; + + // Process |id|'s decorations. + process_direct_decorations(ids_iter->second.direct_decorations); + + // Process the decorations of all groups applied to |id|. + for (const Instruction* inst : target_data.indirect_decorations) { + const uint32_t group_id = inst->GetSingleWordInOperand(0u); + const auto group_iter = id_to_decoration_insts_.find(group_id); + assert(group_iter != id_to_decoration_insts_.end() && "Unknown group ID"); + process_direct_decorations(group_iter->second.direct_decorations); + } + + return decorations; +} + +bool DecorationManager::WhileEachDecoration( + uint32_t id, uint32_t decoration, + std::function f) const { + for (const Instruction* inst : GetDecorationsFor(id, true)) { + switch (inst->opcode()) { + case spv::Op::OpMemberDecorate: + if (inst->GetSingleWordInOperand(2) == decoration) { + if (!f(*inst)) return false; + } + break; + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + if (inst->GetSingleWordInOperand(1) == decoration) { + if (!f(*inst)) return false; + } + break; + default: + assert(false && "Unexpected decoration instruction"); + } + } + return true; +} + +void DecorationManager::ForEachDecoration( + uint32_t id, uint32_t decoration, + std::function f) const { + WhileEachDecoration(id, decoration, [&f](const Instruction& inst) { + f(inst); + return true; + }); +} + +bool DecorationManager::HasDecoration(uint32_t id, + spv::Decoration decoration) const { + return HasDecoration(id, static_cast(decoration)); +} + +bool DecorationManager::HasDecoration(uint32_t id, uint32_t decoration) const { + bool has_decoration = false; + ForEachDecoration(id, decoration, [&has_decoration](const Instruction&) { + has_decoration = true; + }); + return has_decoration; +} + +bool DecorationManager::FindDecoration( + uint32_t id, uint32_t decoration, + std::function f) { + return !WhileEachDecoration( + id, decoration, [&f](const Instruction& inst) { return !f(inst); }); +} + +void DecorationManager::CloneDecorations(uint32_t from, uint32_t to) { + const auto decoration_list = id_to_decoration_insts_.find(from); + if (decoration_list == id_to_decoration_insts_.end()) return; + auto context = module_->context(); + for (Instruction* inst : decoration_list->second.direct_decorations) { + // simply clone decoration and change |target-id| to |to| + std::unique_ptr new_inst(inst->Clone(module_->context())); + new_inst->SetInOperand(0, {to}); + module_->AddAnnotationInst(std::move(new_inst)); + auto decoration_iter = --module_->annotation_end(); + context->AnalyzeUses(&*decoration_iter); + } + // We need to copy the list of instructions as ForgetUses and AnalyzeUses are + // going to modify it. + std::vector indirect_decorations = + decoration_list->second.indirect_decorations; + for (Instruction* inst : indirect_decorations) { + switch (inst->opcode()) { + case spv::Op::OpGroupDecorate: + context->ForgetUses(inst); + // add |to| to list of decorated id's + inst->AddOperand( + Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {to})); + context->AnalyzeUses(inst); + break; + case spv::Op::OpGroupMemberDecorate: { + context->ForgetUses(inst); + // for each (id == from), add (to, literal) as operands + const uint32_t num_operands = inst->NumOperands(); + for (uint32_t i = 1; i < num_operands; i += 2) { + Operand op = inst->GetOperand(i); + if (op.words[0] == from) { // add new pair of operands: (to, literal) + inst->AddOperand( + Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {to})); + op = inst->GetOperand(i + 1); + inst->AddOperand(std::move(op)); + } + } + context->AnalyzeUses(inst); + break; + } + default: + assert(false && "Unexpected decoration instruction"); + } + } +} + +void DecorationManager::CloneDecorations( + uint32_t from, uint32_t to, + const std::vector& decorations_to_copy) { + const auto decoration_list = id_to_decoration_insts_.find(from); + if (decoration_list == id_to_decoration_insts_.end()) return; + auto context = module_->context(); + for (Instruction* inst : decoration_list->second.direct_decorations) { + if (std::find(decorations_to_copy.begin(), decorations_to_copy.end(), + spv::Decoration(inst->GetSingleWordInOperand(1))) == + decorations_to_copy.end()) { + continue; + } + + // Clone decoration and change |target-id| to |to|. + std::unique_ptr new_inst(inst->Clone(module_->context())); + new_inst->SetInOperand(0, {to}); + module_->AddAnnotationInst(std::move(new_inst)); + auto decoration_iter = --module_->annotation_end(); + context->AnalyzeUses(&*decoration_iter); + } + + // We need to copy the list of instructions as ForgetUses and AnalyzeUses are + // going to modify it. + std::vector indirect_decorations = + decoration_list->second.indirect_decorations; + for (Instruction* inst : indirect_decorations) { + switch (inst->opcode()) { + case spv::Op::OpGroupDecorate: + CloneDecorations(inst->GetSingleWordInOperand(0), to, + decorations_to_copy); + break; + case spv::Op::OpGroupMemberDecorate: { + assert(false && "The source id is not suppose to be a type."); + break; + } + default: + assert(false && "Unexpected decoration instruction"); + } + } +} + +void DecorationManager::RemoveDecoration(Instruction* inst) { + const auto remove_from_container = [inst](std::vector& v) { + v.erase(std::remove(v.begin(), v.end(), inst), v.end()); + }; + + switch (inst->opcode()) { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorate: { + const auto target_id = inst->GetSingleWordInOperand(0u); + auto const iter = id_to_decoration_insts_.find(target_id); + if (iter == id_to_decoration_insts_.end()) return; + remove_from_container(iter->second.direct_decorations); + } break; + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: { + const uint32_t stride = + inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; + for (uint32_t i = 1u; i < inst->NumInOperands(); i += stride) { + const auto target_id = inst->GetSingleWordInOperand(i); + auto const iter = id_to_decoration_insts_.find(target_id); + if (iter == id_to_decoration_insts_.end()) continue; + remove_from_container(iter->second.indirect_decorations); + } + const auto group_id = inst->GetSingleWordInOperand(0u); + auto const iter = id_to_decoration_insts_.find(group_id); + if (iter == id_to_decoration_insts_.end()) return; + remove_from_container(iter->second.decorate_insts); + } break; + default: + break; + } +} + +bool operator==(const DecorationManager& lhs, const DecorationManager& rhs) { + return lhs.id_to_decoration_insts_ == rhs.id_to_decoration_insts_; +} + +} // namespace analysis +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/decoration_manager.h b/thirdparty/glslang/External/spirv-tools/source/opt/decoration_manager.h new file mode 100644 index 000000000000..2be016a71a89 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/decoration_manager.h @@ -0,0 +1,212 @@ +// Copyright (c) 2017 Pierre Moreau +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DECORATION_MANAGER_H_ +#define SOURCE_OPT_DECORATION_MANAGER_H_ + +#include +#include +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { +namespace analysis { + +// A class for analyzing and managing decorations in an Module. +class DecorationManager { + public: + // Constructs a decoration manager from the given |module| + explicit DecorationManager(Module* module) : module_(module) { + AnalyzeDecorations(); + } + DecorationManager() = delete; + + // Removes all decorations (direct and through groups) where |pred| is + // true and that apply to |id| so that they no longer apply to |id|. Returns + // true if something changed. + // + // If |id| is part of a group, it will be removed from the group if it + // does not use all of the group's decorations, or, if there are no + // decorations that apply to the group. + // + // If decoration groups become empty, the |OpGroupDecorate| and + // |OpGroupMemberDecorate| instructions will be killed. + // + // Decoration instructions that apply directly to |id| will be killed. + // + // If |id| is a decoration group and all of the group's decorations are + // removed, then the |OpGroupDecorate| and + // |OpGroupMemberDecorate| for the group will be killed, but not the defining + // |OpDecorationGroup| instruction. + bool RemoveDecorationsFrom( + uint32_t id, std::function pred = + [](const Instruction&) { return true; }); + + // Removes all decorations from the result id of |inst|. + // + // NOTE: This is only meant to be called from ir_context, as only metadata + // will be removed, and no actual instruction. + void RemoveDecoration(Instruction* inst); + + // Returns a vector of all decorations affecting |id|. If a group is applied + // to |id|, the decorations of that group are returned rather than the group + // decoration instruction. If |include_linkage| is not set, linkage + // decorations won't be returned. + std::vector GetDecorationsFor(uint32_t id, + bool include_linkage); + std::vector GetDecorationsFor(uint32_t id, + bool include_linkage) const; + // Returns whether two IDs have the same decorations. Two + // spv::Op::OpGroupDecorate instructions that apply the same decorations but + // to different IDs, still count as being the same. + bool HaveTheSameDecorations(uint32_t id1, uint32_t id2) const; + + // Returns whether two IDs have the same decorations. Two + // spv::Op::OpGroupDecorate instructions that apply the same decorations but + // to different IDs, still count as being the same. + bool HaveSubsetOfDecorations(uint32_t id1, uint32_t id2) const; + + // Returns whether the two decorations instructions are the same and are + // applying the same decorations; unless |ignore_target| is false, the targets + // to which they are applied to does not matter, except for the member part. + // + // This is only valid for OpDecorate, OpMemberDecorate and OpDecorateId; it + // will return false for other opcodes. + bool AreDecorationsTheSame(const Instruction* inst1, const Instruction* inst2, + bool ignore_target) const; + + // Returns whether a decoration instruction for |id| with decoration + // |decoration| exists or not. + bool HasDecoration(uint32_t id, uint32_t decoration) const; + bool HasDecoration(uint32_t id, spv::Decoration decoration) const; + + // |f| is run on each decoration instruction for |id| with decoration + // |decoration|. Processed are all decorations which target |id| either + // directly or indirectly by Decoration Groups. + void ForEachDecoration(uint32_t id, uint32_t decoration, + std::function f) const; + + // |f| is run on each decoration instruction for |id| with decoration + // |decoration|. Processes all decoration which target |id| either directly or + // indirectly through decoration groups. If |f| returns false, iteration is + // terminated and this function returns false. + bool WhileEachDecoration(uint32_t id, uint32_t decoration, + std::function f) const; + + // |f| is run on each decoration instruction for |id| with decoration + // |decoration|. Processes all decoration which target |id| either directly or + // indirectly through decoration groups. If |f| returns true, iteration is + // terminated and this function returns true. Otherwise returns false. + bool FindDecoration(uint32_t id, uint32_t decoration, + std::function f); + + // Clone all decorations from one id |from|. + // The cloned decorations are assigned to the given id |to| and are + // added to the module. The purpose is to decorate cloned instructions. + // This function does not check if the id |to| is already decorated. + void CloneDecorations(uint32_t from, uint32_t to); + + // Same as above, but only clone the decoration if the decoration operand is + // in |decorations_to_copy|. This function has the extra restriction that + // |from| and |to| must not be an object, not a type. + void CloneDecorations( + uint32_t from, uint32_t to, + const std::vector& decorations_to_copy); + + // Informs the decoration manager of a new decoration that it needs to track. + void AddDecoration(Instruction* inst); + + // Add decoration with |opcode| and operands |opnds|. + void AddDecoration(spv::Op opcode, const std::vector opnds); + + // Add |decoration| of |inst_id| to module. + void AddDecoration(uint32_t inst_id, uint32_t decoration); + + // Add |decoration, decoration_value| of |inst_id| to module. + void AddDecorationVal(uint32_t inst_id, uint32_t decoration, + uint32_t decoration_value); + + // Add |decoration, decoration_value| of |inst_id, member| to module. + void AddMemberDecoration(uint32_t inst_id, uint32_t member, + uint32_t decoration, uint32_t decoration_value); + + friend bool operator==(const DecorationManager&, const DecorationManager&); + friend bool operator!=(const DecorationManager& lhs, + const DecorationManager& rhs) { + return !(lhs == rhs); + } + + private: + // Analyzes the defs and uses in the given |module| and populates data + // structures in this class. Does nothing if |module| is nullptr. + void AnalyzeDecorations(); + + template + std::vector InternalGetDecorationsFor(uint32_t id, bool include_linkage); + + // Tracks decoration information of an ID. + struct TargetData { + std::vector direct_decorations; // All decorate + // instructions applied + // to the tracked ID. + std::vector indirect_decorations; // All instructions + // applying a group to + // the tracked ID. + std::vector decorate_insts; // All decorate instructions + // applying the decorations + // of the tracked ID to + // targets. + // It is empty if the + // tracked ID is not a + // group. + }; + + friend bool operator==(const TargetData& lhs, const TargetData& rhs) { + if (!std::is_permutation(lhs.direct_decorations.begin(), + lhs.direct_decorations.end(), + rhs.direct_decorations.begin())) { + return false; + } + if (!std::is_permutation(lhs.indirect_decorations.begin(), + lhs.indirect_decorations.end(), + rhs.indirect_decorations.begin())) { + return false; + } + if (!std::is_permutation(lhs.decorate_insts.begin(), + lhs.decorate_insts.end(), + rhs.decorate_insts.begin())) { + return false; + } + return true; + } + + // Mapping from ids to the instructions applying a decoration to those ids. + // In other words, for each id you get all decoration instructions + // referencing that id, be it directly (spv::Op::OpDecorate, + // spv::Op::OpMemberDecorate and spv::Op::OpDecorateId), or indirectly + // (spv::Op::OpGroupDecorate, spv::Op::OpMemberGroupDecorate). + std::unordered_map id_to_decoration_insts_; + // The enclosing module. + Module* module_; +}; + +} // namespace analysis +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DECORATION_MANAGER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/def_use_manager.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/def_use_manager.cpp new file mode 100644 index 000000000000..d54fdb65dd18 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/def_use_manager.cpp @@ -0,0 +1,313 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/def_use_manager.h" + +namespace spvtools { +namespace opt { +namespace analysis { + +void DefUseManager::AnalyzeInstDef(Instruction* inst) { + const uint32_t def_id = inst->result_id(); + if (def_id != 0) { + auto iter = id_to_def_.find(def_id); + if (iter != id_to_def_.end()) { + // Clear the original instruction that defining the same result id of the + // new instruction. + ClearInst(iter->second); + } + id_to_def_[def_id] = inst; + } else { + ClearInst(inst); + } +} + +void DefUseManager::AnalyzeInstUse(Instruction* inst) { + // Create entry for the given instruction. Note that the instruction may + // not have any in-operands. In such cases, we still need a entry for those + // instructions so this manager knows it has seen the instruction later. + auto* used_ids = &inst_to_used_ids_[inst]; + if (used_ids->size()) { + EraseUseRecordsOfOperandIds(inst); + used_ids = &inst_to_used_ids_[inst]; + } + used_ids->clear(); // It might have existed before. + + for (uint32_t i = 0; i < inst->NumOperands(); ++i) { + switch (inst->GetOperand(i).type) { + // For any id type but result id type + case SPV_OPERAND_TYPE_ID: + case SPV_OPERAND_TYPE_TYPE_ID: + case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: + case SPV_OPERAND_TYPE_SCOPE_ID: { + uint32_t use_id = inst->GetSingleWordOperand(i); + Instruction* def = GetDef(use_id); + assert(def && "Definition is not registered."); + id_to_users_.insert(UserEntry{def, inst}); + used_ids->push_back(use_id); + } break; + default: + break; + } + } +} + +void DefUseManager::AnalyzeInstDefUse(Instruction* inst) { + AnalyzeInstDef(inst); + AnalyzeInstUse(inst); + // Analyze lines last otherwise they will be cleared when inst is + // cleared by preceding two calls + for (auto& l_inst : inst->dbg_line_insts()) AnalyzeInstDefUse(&l_inst); +} + +void DefUseManager::UpdateDefUse(Instruction* inst) { + const uint32_t def_id = inst->result_id(); + if (def_id != 0) { + auto iter = id_to_def_.find(def_id); + if (iter == id_to_def_.end()) { + AnalyzeInstDef(inst); + } + } + AnalyzeInstUse(inst); +} + +Instruction* DefUseManager::GetDef(uint32_t id) { + auto iter = id_to_def_.find(id); + if (iter == id_to_def_.end()) return nullptr; + return iter->second; +} + +const Instruction* DefUseManager::GetDef(uint32_t id) const { + const auto iter = id_to_def_.find(id); + if (iter == id_to_def_.end()) return nullptr; + return iter->second; +} + +DefUseManager::IdToUsersMap::const_iterator DefUseManager::UsersBegin( + const Instruction* def) const { + return id_to_users_.lower_bound( + UserEntry{const_cast(def), nullptr}); +} + +bool DefUseManager::UsersNotEnd(const IdToUsersMap::const_iterator& iter, + const IdToUsersMap::const_iterator& cached_end, + const Instruction* inst) const { + return (iter != cached_end && iter->def == inst); +} + +bool DefUseManager::UsersNotEnd(const IdToUsersMap::const_iterator& iter, + const Instruction* inst) const { + return UsersNotEnd(iter, id_to_users_.end(), inst); +} + +bool DefUseManager::WhileEachUser( + const Instruction* def, const std::function& f) const { + // Ensure that |def| has been registered. + assert(def && (!def->HasResultId() || def == GetDef(def->result_id())) && + "Definition is not registered."); + if (!def->HasResultId()) return true; + + auto end = id_to_users_.end(); + for (auto iter = UsersBegin(def); UsersNotEnd(iter, end, def); ++iter) { + if (!f(iter->user)) return false; + } + return true; +} + +bool DefUseManager::WhileEachUser( + uint32_t id, const std::function& f) const { + return WhileEachUser(GetDef(id), f); +} + +void DefUseManager::ForEachUser( + const Instruction* def, const std::function& f) const { + WhileEachUser(def, [&f](Instruction* user) { + f(user); + return true; + }); +} + +void DefUseManager::ForEachUser( + uint32_t id, const std::function& f) const { + ForEachUser(GetDef(id), f); +} + +bool DefUseManager::WhileEachUse( + const Instruction* def, + const std::function& f) const { + // Ensure that |def| has been registered. + assert(def && (!def->HasResultId() || def == GetDef(def->result_id())) && + "Definition is not registered."); + if (!def->HasResultId()) return true; + + auto end = id_to_users_.end(); + for (auto iter = UsersBegin(def); UsersNotEnd(iter, end, def); ++iter) { + Instruction* user = iter->user; + for (uint32_t idx = 0; idx != user->NumOperands(); ++idx) { + const Operand& op = user->GetOperand(idx); + if (op.type != SPV_OPERAND_TYPE_RESULT_ID && spvIsIdType(op.type)) { + if (def->result_id() == op.words[0]) { + if (!f(user, idx)) return false; + } + } + } + } + return true; +} + +bool DefUseManager::WhileEachUse( + uint32_t id, const std::function& f) const { + return WhileEachUse(GetDef(id), f); +} + +void DefUseManager::ForEachUse( + const Instruction* def, + const std::function& f) const { + WhileEachUse(def, [&f](Instruction* user, uint32_t index) { + f(user, index); + return true; + }); +} + +void DefUseManager::ForEachUse( + uint32_t id, const std::function& f) const { + ForEachUse(GetDef(id), f); +} + +uint32_t DefUseManager::NumUsers(const Instruction* def) const { + uint32_t count = 0; + ForEachUser(def, [&count](Instruction*) { ++count; }); + return count; +} + +uint32_t DefUseManager::NumUsers(uint32_t id) const { + return NumUsers(GetDef(id)); +} + +uint32_t DefUseManager::NumUses(const Instruction* def) const { + uint32_t count = 0; + ForEachUse(def, [&count](Instruction*, uint32_t) { ++count; }); + return count; +} + +uint32_t DefUseManager::NumUses(uint32_t id) const { + return NumUses(GetDef(id)); +} + +std::vector DefUseManager::GetAnnotations(uint32_t id) const { + std::vector annos; + const Instruction* def = GetDef(id); + if (!def) return annos; + + ForEachUser(def, [&annos](Instruction* user) { + if (IsAnnotationInst(user->opcode())) { + annos.push_back(user); + } + }); + return annos; +} + +void DefUseManager::AnalyzeDefUse(Module* module) { + if (!module) return; + // Analyze all the defs before any uses to catch forward references. + module->ForEachInst( + std::bind(&DefUseManager::AnalyzeInstDef, this, std::placeholders::_1), + true); + module->ForEachInst( + std::bind(&DefUseManager::AnalyzeInstUse, this, std::placeholders::_1), + true); +} + +void DefUseManager::ClearInst(Instruction* inst) { + auto iter = inst_to_used_ids_.find(inst); + if (iter != inst_to_used_ids_.end()) { + EraseUseRecordsOfOperandIds(inst); + if (inst->result_id() != 0) { + // Remove all uses of this inst. + auto users_begin = UsersBegin(inst); + auto end = id_to_users_.end(); + auto new_end = users_begin; + for (; UsersNotEnd(new_end, end, inst); ++new_end) { + } + id_to_users_.erase(users_begin, new_end); + id_to_def_.erase(inst->result_id()); + } + } +} + +void DefUseManager::EraseUseRecordsOfOperandIds(const Instruction* inst) { + // Go through all ids used by this instruction, remove this instruction's + // uses of them. + auto iter = inst_to_used_ids_.find(inst); + if (iter != inst_to_used_ids_.end()) { + for (auto use_id : iter->second) { + id_to_users_.erase( + UserEntry{GetDef(use_id), const_cast(inst)}); + } + inst_to_used_ids_.erase(iter); + } +} + +bool CompareAndPrintDifferences(const DefUseManager& lhs, + const DefUseManager& rhs) { + bool same = true; + + if (lhs.id_to_def_ != rhs.id_to_def_) { + for (auto p : lhs.id_to_def_) { + if (rhs.id_to_def_.find(p.first) == rhs.id_to_def_.end()) { + printf("Diff in id_to_def: missing value in rhs\n"); + } + } + for (auto p : rhs.id_to_def_) { + if (lhs.id_to_def_.find(p.first) == lhs.id_to_def_.end()) { + printf("Diff in id_to_def: missing value in lhs\n"); + } + } + same = false; + } + + if (lhs.id_to_users_ != rhs.id_to_users_) { + for (auto p : lhs.id_to_users_) { + if (rhs.id_to_users_.count(p) == 0) { + printf("Diff in id_to_users: missing value in rhs\n"); + } + } + for (auto p : rhs.id_to_users_) { + if (lhs.id_to_users_.count(p) == 0) { + printf("Diff in id_to_users: missing value in lhs\n"); + } + } + same = false; + } + + if (lhs.inst_to_used_ids_ != rhs.inst_to_used_ids_) { + for (auto p : lhs.inst_to_used_ids_) { + if (rhs.inst_to_used_ids_.count(p.first) == 0) { + printf("Diff in inst_to_used_ids: missing value in rhs\n"); + } + } + for (auto p : rhs.inst_to_used_ids_) { + if (lhs.inst_to_used_ids_.count(p.first) == 0) { + printf("Diff in inst_to_used_ids: missing value in lhs\n"); + } + } + same = false; + } + + return same; +} + +} // namespace analysis +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/def_use_manager.h b/thirdparty/glslang/External/spirv-tools/source/opt/def_use_manager.h new file mode 100644 index 000000000000..13cf9bd3eddc --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/def_use_manager.h @@ -0,0 +1,230 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DEF_USE_MANAGER_H_ +#define SOURCE_OPT_DEF_USE_MANAGER_H_ + +#include +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/module.h" +#include "spirv-tools/libspirv.hpp" + +namespace spvtools { +namespace opt { +namespace analysis { + +// Definition should never be null. User can be null, however, such an entry +// should be used only for searching (e.g. all users of a particular definition) +// and never stored in a container. +struct UserEntry { + Instruction* def; + Instruction* user; +}; + +inline bool operator==(const UserEntry& lhs, const UserEntry& rhs) { + return lhs.def == rhs.def && lhs.user == rhs.user; +} + +// Orders UserEntry for use in associative containers (i.e. less than ordering). +// +// The definition of an UserEntry is treated as the major key and the users as +// the minor key so that all the users of a particular definition are +// consecutive in a container. +// +// A null user always compares less than a real user. This is done to provide +// easy values to search for the beginning of the users of a particular +// definition (i.e. using {def, nullptr}). +struct UserEntryLess { + bool operator()(const UserEntry& lhs, const UserEntry& rhs) const { + // If lhs.def and rhs.def are both null, fall through to checking the + // second entries. + if (!lhs.def && rhs.def) return true; + if (lhs.def && !rhs.def) return false; + + // If neither definition is null, then compare unique ids. + if (lhs.def && rhs.def) { + if (lhs.def->unique_id() < rhs.def->unique_id()) return true; + if (rhs.def->unique_id() < lhs.def->unique_id()) return false; + } + + // Return false on equality. + if (!lhs.user && !rhs.user) return false; + if (!lhs.user) return true; + if (!rhs.user) return false; + + // If neither user is null then compare unique ids. + return lhs.user->unique_id() < rhs.user->unique_id(); + } +}; + +// A class for analyzing and managing defs and uses in an Module. +class DefUseManager { + public: + using IdToDefMap = std::unordered_map; + + // Constructs a def-use manager from the given |module|. All internal messages + // will be communicated to the outside via the given message |consumer|. This + // instance only keeps a reference to the |consumer|, so the |consumer| should + // outlive this instance. + DefUseManager(Module* module) { AnalyzeDefUse(module); } + + DefUseManager(const DefUseManager&) = delete; + DefUseManager(DefUseManager&&) = delete; + DefUseManager& operator=(const DefUseManager&) = delete; + DefUseManager& operator=(DefUseManager&&) = delete; + + // Analyzes the defs in the given |inst|. + void AnalyzeInstDef(Instruction* inst); + + // Analyzes the uses in the given |inst|. + // + // All operands of |inst| must be analyzed as defs. + void AnalyzeInstUse(Instruction* inst); + + // Analyzes the defs and uses in the given |inst|. + void AnalyzeInstDefUse(Instruction* inst); + + // Returns the def instruction for the given |id|. If there is no instruction + // defining |id|, returns nullptr. + Instruction* GetDef(uint32_t id); + const Instruction* GetDef(uint32_t id) const; + + // Runs the given function |f| on each unique user instruction of |def| (or + // |id|). + // + // If one instruction uses |def| in multiple operands, that instruction will + // only be visited once. + // + // |def| (or |id|) must be registered as a definition. + void ForEachUser(const Instruction* def, + const std::function& f) const; + void ForEachUser(uint32_t id, + const std::function& f) const; + + // Runs the given function |f| on each unique user instruction of |def| (or + // |id|). If |f| returns false, iteration is terminated and this function + // returns false. + // + // If one instruction uses |def| in multiple operands, that instruction will + // be only be visited once. + // + // |def| (or |id|) must be registered as a definition. + bool WhileEachUser(const Instruction* def, + const std::function& f) const; + bool WhileEachUser(uint32_t id, + const std::function& f) const; + + // Runs the given function |f| on each unique use of |def| (or + // |id|). + // + // If one instruction uses |def| in multiple operands, each operand will be + // visited separately. + // + // |def| (or |id|) must be registered as a definition. + void ForEachUse( + const Instruction* def, + const std::function& f) const; + void ForEachUse( + uint32_t id, + const std::function& f) const; + + // Runs the given function |f| on each unique use of |def| (or + // |id|). If |f| returns false, iteration is terminated and this function + // returns false. + // + // If one instruction uses |def| in multiple operands, each operand will be + // visited separately. + // + // |def| (or |id|) must be registered as a definition. + bool WhileEachUse( + const Instruction* def, + const std::function& f) const; + bool WhileEachUse( + uint32_t id, + const std::function& f) const; + + // Returns the number of users of |def| (or |id|). + uint32_t NumUsers(const Instruction* def) const; + uint32_t NumUsers(uint32_t id) const; + + // Returns the number of uses of |def| (or |id|). + uint32_t NumUses(const Instruction* def) const; + uint32_t NumUses(uint32_t id) const; + + // Returns the annotation instrunctions which are a direct use of the given + // |id|. This means when the decorations are applied through decoration + // group(s), this function will just return the OpGroupDecorate + // instruction(s) which refer to the given id as an operand. The OpDecorate + // instructions which decorate the decoration group will not be returned. + std::vector GetAnnotations(uint32_t id) const; + + // Returns the map from ids to their def instructions. + const IdToDefMap& id_to_defs() const { return id_to_def_; } + + // Clear the internal def-use record of the given instruction |inst|. This + // method will update the use information of the operand ids of |inst|. The + // record: |inst| uses an |id|, will be removed from the use records of |id|. + // If |inst| defines an result id, the use record of this result id will also + // be removed. Does nothing if |inst| was not analyzed before. + void ClearInst(Instruction* inst); + + // Erases the records that a given instruction uses its operand ids. + void EraseUseRecordsOfOperandIds(const Instruction* inst); + + friend bool CompareAndPrintDifferences(const DefUseManager&, + const DefUseManager&); + + // If |inst| has not already been analysed, then analyses its definition and + // uses. + void UpdateDefUse(Instruction* inst); + + private: + using IdToUsersMap = std::set; + using InstToUsedIdsMap = + std::unordered_map>; + + // Returns the first location that {|def|, nullptr} could be inserted into the + // users map without violating ordering. + IdToUsersMap::const_iterator UsersBegin(const Instruction* def) const; + + // Returns true if |iter| has not reached the end of |def|'s users. + // + // In the first version |iter| is compared against the end of the map for + // validity before other checks. In the second version, |iter| is compared + // against |cached_end| for validity before other checks. This allows caching + // the map's end which is a performance improvement on some platforms. + bool UsersNotEnd(const IdToUsersMap::const_iterator& iter, + const Instruction* def) const; + bool UsersNotEnd(const IdToUsersMap::const_iterator& iter, + const IdToUsersMap::const_iterator& cached_end, + const Instruction* def) const; + + // Analyzes the defs and uses in the given |module| and populates data + // structures in this class. Does nothing if |module| is nullptr. + void AnalyzeDefUse(Module* module); + + IdToDefMap id_to_def_; // Mapping from ids to their definitions + IdToUsersMap id_to_users_; // Mapping from ids to their users + // Mapping from instructions to the ids used in the instruction. + InstToUsedIdsMap inst_to_used_ids_; +}; + +} // namespace analysis +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DEF_USE_MANAGER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa.cpp new file mode 100644 index 000000000000..2c0f4829f2b3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa.cpp @@ -0,0 +1,462 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/desc_sroa.h" + +#include "source/opt/desc_sroa_util.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { +namespace { + +bool IsDecorationBinding(Instruction* inst) { + if (inst->opcode() != spv::Op::OpDecorate) return false; + return spv::Decoration(inst->GetSingleWordInOperand(1u)) == + spv::Decoration::Binding; +} + +} // namespace + +Pass::Status DescriptorScalarReplacement::Process() { + bool modified = false; + + std::vector vars_to_kill; + + for (Instruction& var : context()->types_values()) { + if (descsroautil::IsDescriptorArray(context(), &var)) { + modified = true; + if (!ReplaceCandidate(&var)) { + return Status::Failure; + } + vars_to_kill.push_back(&var); + } + } + + for (Instruction* var : vars_to_kill) { + context()->KillInst(var); + } + + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) { + std::vector access_chain_work_list; + std::vector load_work_list; + std::vector entry_point_work_list; + bool failed = !get_def_use_mgr()->WhileEachUser( + var->result_id(), [this, &access_chain_work_list, &load_work_list, + &entry_point_work_list](Instruction* use) { + if (use->opcode() == spv::Op::OpName) { + return true; + } + + if (use->IsDecoration()) { + return true; + } + + switch (use->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + access_chain_work_list.push_back(use); + return true; + case spv::Op::OpLoad: + load_work_list.push_back(use); + return true; + case spv::Op::OpEntryPoint: + entry_point_work_list.push_back(use); + return true; + default: + context()->EmitErrorMessage( + "Variable cannot be replaced: invalid instruction", use); + return false; + } + return true; + }); + + if (failed) { + return false; + } + + for (Instruction* use : access_chain_work_list) { + if (!ReplaceAccessChain(var, use)) { + return false; + } + } + for (Instruction* use : load_work_list) { + if (!ReplaceLoadedValue(var, use)) { + return false; + } + } + for (Instruction* use : entry_point_work_list) { + if (!ReplaceEntryPoint(var, use)) { + return false; + } + } + return true; +} + +bool DescriptorScalarReplacement::ReplaceAccessChain(Instruction* var, + Instruction* use) { + if (use->NumInOperands() <= 1) { + context()->EmitErrorMessage( + "Variable cannot be replaced: invalid instruction", use); + return false; + } + + const analysis::Constant* const_index = + descsroautil::GetAccessChainIndexAsConst(context(), use); + if (const_index == nullptr) { + context()->EmitErrorMessage("Variable cannot be replaced: invalid index", + use); + return false; + } + + uint32_t idx = const_index->GetU32(); + uint32_t replacement_var = GetReplacementVariable(var, idx); + + if (use->NumInOperands() == 2) { + // We are not indexing into the replacement variable. We can replaces the + // access chain with the replacement variable itself. + context()->ReplaceAllUsesWith(use->result_id(), replacement_var); + context()->KillInst(use); + return true; + } + + // We need to build a new access chain with the replacement variable as the + // base address. + Instruction::OperandList new_operands; + + // Same result id and result type. + new_operands.emplace_back(use->GetOperand(0)); + new_operands.emplace_back(use->GetOperand(1)); + + // Use the replacement variable as the base address. + new_operands.push_back({SPV_OPERAND_TYPE_ID, {replacement_var}}); + + // Drop the first index because it is consumed by the replacement, and copy + // the rest. + for (uint32_t i = 4; i < use->NumOperands(); i++) { + new_operands.emplace_back(use->GetOperand(i)); + } + + use->ReplaceOperands(new_operands); + context()->UpdateDefUse(use); + return true; +} + +bool DescriptorScalarReplacement::ReplaceEntryPoint(Instruction* var, + Instruction* use) { + // Build a new |OperandList| for |use| that removes |var| and adds its + // replacement variables. + Instruction::OperandList new_operands; + + // Copy all operands except |var|. + bool found = false; + for (uint32_t idx = 0; idx < use->NumOperands(); idx++) { + Operand& op = use->GetOperand(idx); + if (op.type == SPV_OPERAND_TYPE_ID && op.words[0] == var->result_id()) { + found = true; + } else { + new_operands.emplace_back(op); + } + } + + if (!found) { + context()->EmitErrorMessage( + "Variable cannot be replaced: invalid instruction", use); + return false; + } + + // Add all new replacement variables. + uint32_t num_replacement_vars = + descsroautil::GetNumberOfElementsForArrayOrStruct(context(), var); + for (uint32_t i = 0; i < num_replacement_vars; i++) { + new_operands.push_back( + {SPV_OPERAND_TYPE_ID, {GetReplacementVariable(var, i)}}); + } + + use->ReplaceOperands(new_operands); + context()->UpdateDefUse(use); + return true; +} + +uint32_t DescriptorScalarReplacement::GetReplacementVariable(Instruction* var, + uint32_t idx) { + auto replacement_vars = replacement_variables_.find(var); + if (replacement_vars == replacement_variables_.end()) { + uint32_t number_of_elements = + descsroautil::GetNumberOfElementsForArrayOrStruct(context(), var); + replacement_vars = + replacement_variables_ + .insert({var, std::vector(number_of_elements, 0)}) + .first; + } + + if (replacement_vars->second[idx] == 0) { + replacement_vars->second[idx] = CreateReplacementVariable(var, idx); + } + + return replacement_vars->second[idx]; +} + +void DescriptorScalarReplacement::CopyDecorationsForNewVariable( + Instruction* old_var, uint32_t index, uint32_t new_var_id, + uint32_t new_var_ptr_type_id, const bool is_old_var_array, + const bool is_old_var_struct, Instruction* old_var_type) { + // Handle OpDecorate and OpDecorateString instructions. + for (auto old_decoration : + get_decoration_mgr()->GetDecorationsFor(old_var->result_id(), true)) { + uint32_t new_binding = 0; + if (IsDecorationBinding(old_decoration)) { + new_binding = GetNewBindingForElement( + old_decoration->GetSingleWordInOperand(2), index, new_var_ptr_type_id, + is_old_var_array, is_old_var_struct, old_var_type); + } + CreateNewDecorationForNewVariable(old_decoration, new_var_id, new_binding); + } + + // Handle OpMemberDecorate instructions. + for (auto old_decoration : get_decoration_mgr()->GetDecorationsFor( + old_var_type->result_id(), true)) { + assert(old_decoration->opcode() == spv::Op::OpMemberDecorate); + if (old_decoration->GetSingleWordInOperand(1u) != index) continue; + CreateNewDecorationForMemberDecorate(old_decoration, new_var_id); + } +} + +uint32_t DescriptorScalarReplacement::GetNewBindingForElement( + uint32_t old_binding, uint32_t index, uint32_t new_var_ptr_type_id, + const bool is_old_var_array, const bool is_old_var_struct, + Instruction* old_var_type) { + if (is_old_var_array) { + return old_binding + index * GetNumBindingsUsedByType(new_var_ptr_type_id); + } + if (is_old_var_struct) { + // The binding offset that should be added is the sum of binding + // numbers used by previous members of the current struct. + uint32_t new_binding = old_binding; + for (uint32_t i = 0; i < index; ++i) { + new_binding += + GetNumBindingsUsedByType(old_var_type->GetSingleWordInOperand(i)); + } + return new_binding; + } + return old_binding; +} + +void DescriptorScalarReplacement::CreateNewDecorationForNewVariable( + Instruction* old_decoration, uint32_t new_var_id, uint32_t new_binding) { + assert(old_decoration->opcode() == spv::Op::OpDecorate || + old_decoration->opcode() == spv::Op::OpDecorateString); + std::unique_ptr new_decoration(old_decoration->Clone(context())); + new_decoration->SetInOperand(0, {new_var_id}); + + if (IsDecorationBinding(new_decoration.get())) { + new_decoration->SetInOperand(2, {new_binding}); + } + context()->AddAnnotationInst(std::move(new_decoration)); +} + +void DescriptorScalarReplacement::CreateNewDecorationForMemberDecorate( + Instruction* old_member_decoration, uint32_t new_var_id) { + std::vector operands( + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {new_var_id}}}); + auto new_decorate_operand_begin = old_member_decoration->begin() + 2u; + auto new_decorate_operand_end = old_member_decoration->end(); + operands.insert(operands.end(), new_decorate_operand_begin, + new_decorate_operand_end); + get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, std::move(operands)); +} + +uint32_t DescriptorScalarReplacement::CreateReplacementVariable( + Instruction* var, uint32_t idx) { + // The storage class for the new variable is the same as the original. + spv::StorageClass storage_class = + static_cast(var->GetSingleWordInOperand(0)); + + // The type for the new variable will be a pointer to type of the elements of + // the array. + uint32_t ptr_type_id = var->type_id(); + Instruction* ptr_type_inst = get_def_use_mgr()->GetDef(ptr_type_id); + assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && + "Variable should be a pointer to an array or structure."); + uint32_t pointee_type_id = ptr_type_inst->GetSingleWordInOperand(1); + Instruction* pointee_type_inst = get_def_use_mgr()->GetDef(pointee_type_id); + const bool is_array = pointee_type_inst->opcode() == spv::Op::OpTypeArray; + const bool is_struct = pointee_type_inst->opcode() == spv::Op::OpTypeStruct; + assert((is_array || is_struct) && + "Variable should be a pointer to an array or structure."); + + uint32_t element_type_id = + is_array ? pointee_type_inst->GetSingleWordInOperand(0) + : pointee_type_inst->GetSingleWordInOperand(idx); + + uint32_t ptr_element_type_id = context()->get_type_mgr()->FindPointerToType( + element_type_id, storage_class); + + // Create the variable. + uint32_t id = TakeNextId(); + std::unique_ptr variable( + new Instruction(context(), spv::Op::OpVariable, ptr_element_type_id, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, + {static_cast(storage_class)}}})); + context()->AddGlobalValue(std::move(variable)); + + CopyDecorationsForNewVariable(var, idx, id, ptr_element_type_id, is_array, + is_struct, pointee_type_inst); + + // Create a new OpName for the replacement variable. + std::vector> names_to_add; + for (auto p : context()->GetNames(var->result_id())) { + Instruction* name_inst = p.second; + std::string name_str = utils::MakeString(name_inst->GetOperand(1).words); + if (is_array) { + name_str += "[" + utils::ToString(idx) + "]"; + } + if (is_struct) { + Instruction* member_name_inst = + context()->GetMemberName(pointee_type_inst->result_id(), idx); + name_str += "."; + if (member_name_inst) + name_str += utils::MakeString(member_name_inst->GetOperand(2).words); + else + // In case the member does not have a name assigned to it, use the + // member index. + name_str += utils::ToString(idx); + } + + std::unique_ptr new_name(new Instruction( + context(), spv::Op::OpName, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {id}}, + {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}})); + Instruction* new_name_inst = new_name.get(); + get_def_use_mgr()->AnalyzeInstDefUse(new_name_inst); + names_to_add.push_back(std::move(new_name)); + } + + // We shouldn't add the new names when we are iterating over name ranges + // above. We can add all the new names now. + for (auto& new_name : names_to_add) + context()->AddDebug2Inst(std::move(new_name)); + + return id; +} + +uint32_t DescriptorScalarReplacement::GetNumBindingsUsedByType( + uint32_t type_id) { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + + // If it's a pointer, look at the underlying type. + if (type_inst->opcode() == spv::Op::OpTypePointer) { + type_id = type_inst->GetSingleWordInOperand(1); + type_inst = get_def_use_mgr()->GetDef(type_id); + } + + // Arrays consume N*M binding numbers where N is the array length, and M is + // the number of bindings used by each array element. + if (type_inst->opcode() == spv::Op::OpTypeArray) { + uint32_t element_type_id = type_inst->GetSingleWordInOperand(0); + uint32_t length_id = type_inst->GetSingleWordInOperand(1); + const analysis::Constant* length_const = + context()->get_constant_mgr()->FindDeclaredConstant(length_id); + // OpTypeArray's length must always be a constant + assert(length_const != nullptr); + uint32_t num_elems = length_const->GetU32(); + return num_elems * GetNumBindingsUsedByType(element_type_id); + } + + // The number of bindings consumed by a structure is the sum of the bindings + // used by its members. + if (type_inst->opcode() == spv::Op::OpTypeStruct && + !descsroautil::IsTypeOfStructuredBuffer(context(), type_inst)) { + uint32_t sum = 0; + for (uint32_t i = 0; i < type_inst->NumInOperands(); i++) + sum += GetNumBindingsUsedByType(type_inst->GetSingleWordInOperand(i)); + return sum; + } + + // All other types are considered to take up 1 binding number. + return 1; +} + +bool DescriptorScalarReplacement::ReplaceLoadedValue(Instruction* var, + Instruction* value) { + // |var| is the global variable that has to be eliminated (OpVariable). + // |value| is the OpLoad instruction that has loaded |var|. + // The function expects all users of |value| to be OpCompositeExtract + // instructions. Otherwise the function returns false with an error message. + assert(value->opcode() == spv::Op::OpLoad); + assert(value->GetSingleWordInOperand(0) == var->result_id()); + std::vector work_list; + bool failed = !get_def_use_mgr()->WhileEachUser( + value->result_id(), [this, &work_list](Instruction* use) { + if (use->opcode() != spv::Op::OpCompositeExtract) { + context()->EmitErrorMessage( + "Variable cannot be replaced: invalid instruction", use); + return false; + } + work_list.push_back(use); + return true; + }); + + if (failed) { + return false; + } + + for (Instruction* use : work_list) { + if (!ReplaceCompositeExtract(var, use)) { + return false; + } + } + + // All usages of the loaded value have been killed. We can kill the OpLoad. + context()->KillInst(value); + return true; +} + +bool DescriptorScalarReplacement::ReplaceCompositeExtract( + Instruction* var, Instruction* extract) { + assert(extract->opcode() == spv::Op::OpCompositeExtract); + // We're currently only supporting extractions of one index at a time. If we + // need to, we can handle cases with multiple indexes in the future. + if (extract->NumInOperands() != 2) { + context()->EmitErrorMessage( + "Variable cannot be replaced: invalid instruction", extract); + return false; + } + + uint32_t replacement_var = + GetReplacementVariable(var, extract->GetSingleWordInOperand(1)); + + // The result type of the OpLoad is the same as the result type of the + // OpCompositeExtract. + uint32_t load_id = TakeNextId(); + std::unique_ptr load( + new Instruction(context(), spv::Op::OpLoad, extract->type_id(), load_id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {replacement_var}}})); + Instruction* load_instr = load.get(); + get_def_use_mgr()->AnalyzeInstDefUse(load_instr); + context()->set_instr_block(load_instr, context()->get_instr_block(extract)); + extract->InsertBefore(std::move(load)); + context()->ReplaceAllUsesWith(extract->result_id(), load_id); + context()->KillInst(extract); + return true; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa.h b/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa.h new file mode 100644 index 000000000000..901be3e98bcc --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa.h @@ -0,0 +1,149 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DESC_SROA_H_ +#define SOURCE_OPT_DESC_SROA_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/function.h" +#include "source/opt/pass.h" +#include "source/opt/type_manager.h" + +namespace spvtools { +namespace opt { + +// Documented in optimizer.hpp +class DescriptorScalarReplacement : public Pass { + public: + DescriptorScalarReplacement() {} + + const char* name() const override { return "descriptor-scalar-replacement"; } + + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Replaces all references to |var| by new variables, one for each element of + // the array |var|. The binding for the new variables corresponding to + // element i will be the binding of |var| plus i. Returns true if successful. + bool ReplaceCandidate(Instruction* var); + + // Replaces the base address |var| in the OpAccessChain or + // OpInBoundsAccessChain instruction |use| by the variable that the access + // chain accesses. The first index in |use| must be an |OpConstant|. Returns + // |true| if successful. + bool ReplaceAccessChain(Instruction* var, Instruction* use); + + // Replaces the given compososite variable |var| loaded by OpLoad |value| with + // replacement variables, one for each component that's accessed in the + // shader. Assumes that |value| is only used by OpCompositeExtract + // instructions, one index at a time. Returns true on success, and false + // otherwise. + bool ReplaceLoadedValue(Instruction* var, Instruction* value); + + // Replaces the given composite variable |var| in the OpEntryPoint with the + // new replacement variables, one for each element of the array |var|. Returns + // |true| if successful, and |false| otherwise. + bool ReplaceEntryPoint(Instruction* var, Instruction* use); + + // Replaces the given OpCompositeExtract |extract| and all of its references + // with an OpLoad of a replacement variable. |var| is the variable with + // composite type whose value is being used by |extract|. Assumes that + // |extract| is extracting one index only. Returns true on success, and false + // otherwise. + bool ReplaceCompositeExtract(Instruction* var, Instruction* extract); + + // Returns the id of the variable that will be used to replace the |idx|th + // element of |var|. The variable is created if it has not already been + // created. + uint32_t GetReplacementVariable(Instruction* var, uint32_t idx); + + // Returns the id of a new variable that can be used to replace the |idx|th + // element of |var|. + uint32_t CreateReplacementVariable(Instruction* var, uint32_t idx); + + // Returns the number of bindings used by the given |type_id|. + // All types are considered to use 1 binding slot, except: + // 1- A pointer type consumes as many binding numbers as its pointee. + // 2- An array of size N consumes N*M binding numbers, where M is the number + // of bindings used by each array element. + // 3- The number of bindings consumed by a structure is the sum of the + // bindings used by its members. + uint32_t GetNumBindingsUsedByType(uint32_t type_id); + + // Copy all of the decorations of variable |old_var| and make them as + // decorations for the new variable whose id is |new_var_id|. The new variable + // is supposed to replace |index|th element of |old_var|. + // |new_var_ptr_type_id| is the id of the pointer to the type of the new + // variable. |is_old_var_array| is true if |old_var| has an array type. + // |is_old_var_struct| is true if |old_var| has a structure type. + // |old_var_type| is the pointee type of |old_var|. + void CopyDecorationsForNewVariable(Instruction* old_var, uint32_t index, + uint32_t new_var_id, + uint32_t new_var_ptr_type_id, + const bool is_old_var_array, + const bool is_old_var_struct, + Instruction* old_var_type); + + // Get the new binding number for a new variable that will be replaced with an + // |index|th element of an old variable. The old variable has |old_binding| + // as its binding number. |ptr_elem_type_id| the id of the pointer to the + // element type. |is_old_var_array| is true if the old variable has an array + // type. |is_old_var_struct| is true if the old variable has a structure type. + // |old_var_type| is the pointee type of the old variable. + uint32_t GetNewBindingForElement(uint32_t old_binding, uint32_t index, + uint32_t ptr_elem_type_id, + const bool is_old_var_array, + const bool is_old_var_struct, + Instruction* old_var_type); + + // Create a new OpDecorate(String) instruction by cloning |old_decoration|. + // The new OpDecorate(String) instruction will be used for a variable whose id + // is |new_var_ptr_type_id|. If |old_decoration| is a decoration for a + // binding, the new OpDecorate(String) instruction will have |new_binding| as + // its binding. + void CreateNewDecorationForNewVariable(Instruction* old_decoration, + uint32_t new_var_id, + uint32_t new_binding); + + // Create a new OpDecorate instruction whose operand is the same as an + // OpMemberDecorate instruction |old_member_decoration| except Target operand. + // The Target operand of the new OpDecorate instruction will be |new_var_id|. + void CreateNewDecorationForMemberDecorate(Instruction* old_decoration, + uint32_t new_var_id); + + // A map from an OpVariable instruction to the set of variables that will be + // used to replace it. The entry |replacement_variables_[var][i]| is the id of + // a variable that will be used in the place of the ith element of the + // array |var|. If the entry is |0|, then the variable has not been + // created yet. + std::map> replacement_variables_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DESC_SROA_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa_util.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa_util.cpp new file mode 100644 index 000000000000..dba3de9c0515 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa_util.cpp @@ -0,0 +1,116 @@ +// Copyright (c) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/desc_sroa_util.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kOpAccessChainInOperandIndexes = 1; + +// Returns the length of array type |type|. +uint32_t GetLengthOfArrayType(IRContext* context, Instruction* type) { + assert(type->opcode() == spv::Op::OpTypeArray && "type must be array"); + uint32_t length_id = type->GetSingleWordInOperand(1); + const analysis::Constant* length_const = + context->get_constant_mgr()->FindDeclaredConstant(length_id); + assert(length_const != nullptr); + return length_const->GetU32(); +} + +} // namespace + +namespace descsroautil { + +bool IsDescriptorArray(IRContext* context, Instruction* var) { + if (var->opcode() != spv::Op::OpVariable) { + return false; + } + + uint32_t ptr_type_id = var->type_id(); + Instruction* ptr_type_inst = context->get_def_use_mgr()->GetDef(ptr_type_id); + if (ptr_type_inst->opcode() != spv::Op::OpTypePointer) { + return false; + } + + uint32_t var_type_id = ptr_type_inst->GetSingleWordInOperand(1); + Instruction* var_type_inst = context->get_def_use_mgr()->GetDef(var_type_id); + if (var_type_inst->opcode() != spv::Op::OpTypeArray && + var_type_inst->opcode() != spv::Op::OpTypeStruct) { + return false; + } + + // All structures with descriptor assignments must be replaced by variables, + // one for each of their members - with the exceptions of buffers. + if (IsTypeOfStructuredBuffer(context, var_type_inst)) { + return false; + } + + if (!context->get_decoration_mgr()->HasDecoration( + var->result_id(), uint32_t(spv::Decoration::DescriptorSet))) { + return false; + } + + return context->get_decoration_mgr()->HasDecoration( + var->result_id(), uint32_t(spv::Decoration::Binding)); +} + +bool IsTypeOfStructuredBuffer(IRContext* context, const Instruction* type) { + if (type->opcode() != spv::Op::OpTypeStruct) { + return false; + } + + // All buffers have offset decorations for members of their structure types. + // This is how we distinguish it from a structure of descriptors. + return context->get_decoration_mgr()->HasDecoration( + type->result_id(), uint32_t(spv::Decoration::Offset)); +} + +const analysis::Constant* GetAccessChainIndexAsConst( + IRContext* context, Instruction* access_chain) { + if (access_chain->NumInOperands() <= 1) { + return nullptr; + } + uint32_t idx_id = GetFirstIndexOfAccessChain(access_chain); + const analysis::Constant* idx_const = + context->get_constant_mgr()->FindDeclaredConstant(idx_id); + return idx_const; +} + +uint32_t GetFirstIndexOfAccessChain(Instruction* access_chain) { + assert(access_chain->NumInOperands() > 1 && + "OpAccessChain does not have Indexes operand"); + return access_chain->GetSingleWordInOperand(kOpAccessChainInOperandIndexes); +} + +uint32_t GetNumberOfElementsForArrayOrStruct(IRContext* context, + Instruction* var) { + uint32_t ptr_type_id = var->type_id(); + Instruction* ptr_type_inst = context->get_def_use_mgr()->GetDef(ptr_type_id); + assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && + "Variable should be a pointer to an array or structure."); + uint32_t pointee_type_id = ptr_type_inst->GetSingleWordInOperand(1); + Instruction* pointee_type_inst = + context->get_def_use_mgr()->GetDef(pointee_type_id); + if (pointee_type_inst->opcode() == spv::Op::OpTypeArray) { + return GetLengthOfArrayType(context, pointee_type_inst); + } + assert(pointee_type_inst->opcode() == spv::Op::OpTypeStruct && + "Variable should be a pointer to an array or structure."); + return pointee_type_inst->NumInOperands(); +} + +} // namespace descsroautil +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa_util.h b/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa_util.h new file mode 100644 index 000000000000..2f45c0c2f4f9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/desc_sroa_util.h @@ -0,0 +1,54 @@ +// Copyright (c) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DESC_SROA_UTIL_H_ +#define SOURCE_OPT_DESC_SROA_UTIL_H_ + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +// Provides functions for the descriptor array SROA. +namespace descsroautil { + +// Returns true if |var| is an OpVariable instruction that represents a +// descriptor array. +bool IsDescriptorArray(IRContext* context, Instruction* var); + +// Returns true if |type| is a type that could be used for a structured buffer +// as opposed to a type that would be used for a structure of resource +// descriptors. +bool IsTypeOfStructuredBuffer(IRContext* context, const Instruction* type); + +// Returns the first index of the OpAccessChain instruction |access_chain| as +// a constant. Returns nullptr if it is not a constant. +const analysis::Constant* GetAccessChainIndexAsConst(IRContext* context, + Instruction* access_chain); + +// Returns the number of elements of an OpVariable instruction |var| whose type +// must be a pointer to an array or a struct. +uint32_t GetNumberOfElementsForArrayOrStruct(IRContext* context, + Instruction* var); + +// Returns the first Indexes operand id of the OpAccessChain or +// OpInBoundsAccessChain instruction |access_chain|. The access chain must have +// at least 1 index. +uint32_t GetFirstIndexOfAccessChain(Instruction* access_chain); + +} // namespace descsroautil +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DESC_SROA_UTIL_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dominator_analysis.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/dominator_analysis.cpp new file mode 100644 index 000000000000..eb6dfc9e000e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dominator_analysis.cpp @@ -0,0 +1,81 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/dominator_analysis.h" + +#include + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +BasicBlock* DominatorAnalysisBase::CommonDominator(BasicBlock* b1, + BasicBlock* b2) const { + if (!b1 || !b2) return nullptr; + + std::unordered_set seen; + BasicBlock* block = b1; + while (block && seen.insert(block).second) { + block = ImmediateDominator(block); + } + + block = b2; + while (block && !seen.count(block)) { + block = ImmediateDominator(block); + } + + return block; +} + +bool DominatorAnalysisBase::Dominates(Instruction* a, Instruction* b) const { + if (!a || !b) { + return false; + } + + if (a == b) { + return true; + } + + BasicBlock* bb_a = a->context()->get_instr_block(a); + BasicBlock* bb_b = b->context()->get_instr_block(b); + + if (bb_a != bb_b) { + return tree_.Dominates(bb_a, bb_b); + } + + const Instruction* current = a; + const Instruction* other = b; + + if (tree_.IsPostDominator()) { + std::swap(current, other); + } + + // We handle OpLabel instructions explicitly since they are not stored in the + // instruction list. + if (current->opcode() == spv::Op::OpLabel) { + return true; + } + + while ((current = current->NextNode())) { + if (current == other) { + return true; + } + } + + return false; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dominator_analysis.h b/thirdparty/glslang/External/spirv-tools/source/opt/dominator_analysis.h new file mode 100644 index 000000000000..a94120a55f93 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dominator_analysis.h @@ -0,0 +1,138 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DOMINATOR_ANALYSIS_H_ +#define SOURCE_OPT_DOMINATOR_ANALYSIS_H_ + +#include +#include + +#include "source/opt/dominator_tree.h" + +namespace spvtools { +namespace opt { + +// Interface to perform dominator or postdominator analysis on a given function. +class DominatorAnalysisBase { + public: + explicit DominatorAnalysisBase(bool is_post_dom) : tree_(is_post_dom) {} + + // Calculates the dominator (or postdominator) tree for given function |f|. + inline void InitializeTree(const CFG& cfg, const Function* f) { + tree_.InitializeTree(cfg, f); + } + + // Returns true if BasicBlock |a| dominates BasicBlock |b|. + inline bool Dominates(const BasicBlock* a, const BasicBlock* b) const { + if (!a || !b) return false; + return Dominates(a->id(), b->id()); + } + + // Returns true if BasicBlock |a| dominates BasicBlock |b|. Same as above only + // using the BasicBlock IDs. + inline bool Dominates(uint32_t a, uint32_t b) const { + return tree_.Dominates(a, b); + } + + // Returns true if instruction |a| dominates instruction |b|. + bool Dominates(Instruction* a, Instruction* b) const; + + // Returns true if BasicBlock |a| strictly dominates BasicBlock |b|. + inline bool StrictlyDominates(const BasicBlock* a, + const BasicBlock* b) const { + if (!a || !b) return false; + return StrictlyDominates(a->id(), b->id()); + } + + // Returns true if BasicBlock |a| strictly dominates BasicBlock |b|. Same as + // above only using the BasicBlock IDs. + inline bool StrictlyDominates(uint32_t a, uint32_t b) const { + return tree_.StrictlyDominates(a, b); + } + + // Returns the immediate dominator of |node| or returns nullptr if it is has + // no dominator. + inline BasicBlock* ImmediateDominator(const BasicBlock* node) const { + if (!node) return nullptr; + return tree_.ImmediateDominator(node); + } + + // Returns the immediate dominator of |node_id| or returns nullptr if it is + // has no dominator. Same as above but operates on IDs. + inline BasicBlock* ImmediateDominator(uint32_t node_id) const { + return tree_.ImmediateDominator(node_id); + } + + // Returns true if |node| is reachable from the entry. + inline bool IsReachable(const BasicBlock* node) const { + if (!node) return false; + return tree_.ReachableFromRoots(node->id()); + } + + // Returns true if |node_id| is reachable from the entry. + inline bool IsReachable(uint32_t node_id) const { + return tree_.ReachableFromRoots(node_id); + } + + // Dump the tree structure into the given |out| stream in the dot format. + inline void DumpAsDot(std::ostream& out) const { tree_.DumpTreeAsDot(out); } + + // Returns true if this is a postdomiator tree. + inline bool IsPostDominator() const { return tree_.IsPostDominator(); } + + // Returns the tree itself for manual operations, such as traversing the + // roots. + // For normal dominance relationships the methods above should be used. + inline DominatorTree& GetDomTree() { return tree_; } + inline const DominatorTree& GetDomTree() const { return tree_; } + + // Force the dominator tree to be removed + inline void ClearTree() { tree_.ClearTree(); } + + // Applies the std::function |func| to dominator tree nodes in dominator + // order. + void Visit(std::function func) { + tree_.Visit(func); + } + + // Applies the std::function |func| to dominator tree nodes in dominator + // order. + void Visit(std::function func) const { + tree_.Visit(func); + } + + // Returns the most immediate basic block that dominates both |b1| and |b2|. + // If there is no such basic block, nullptr is returned. + BasicBlock* CommonDominator(BasicBlock* b1, BasicBlock* b2) const; + + protected: + DominatorTree tree_; +}; + +// Derived class for normal dominator analysis. +class DominatorAnalysis : public DominatorAnalysisBase { + public: + DominatorAnalysis() : DominatorAnalysisBase(false) {} +}; + +// Derived class for postdominator analysis. +class PostDominatorAnalysis : public DominatorAnalysisBase { + public: + PostDominatorAnalysis() : DominatorAnalysisBase(true) {} +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DOMINATOR_ANALYSIS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dominator_tree.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/dominator_tree.cpp new file mode 100644 index 000000000000..3c161a9b2457 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dominator_tree.cpp @@ -0,0 +1,385 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include "source/cfa.h" +#include "source/opt/dominator_tree.h" +#include "source/opt/ir_context.h" + +// Calculates the dominator or postdominator tree for a given function. +// 1 - Compute the successors and predecessors for each BasicBlock. We add a +// placeholder node for the start node or for postdominators the exit. This node +// will point to all entry or all exit nodes. +// 2 - Using the CFA::DepthFirstTraversal get a depth first postordered list of +// all BasicBlocks. Using the successors (or for postdominator, predecessors) +// calculated in step 1 to traverse the tree. +// 3 - Pass the list calculated in step 2 to the CFA::CalculateDominators using +// the predecessors list (or for postdominator, successors). This will give us a +// vector of BB pairs. Each BB and its immediate dominator. +// 4 - Using the list from 3 use those edges to build a tree of +// DominatorTreeNodes. Each node containing a link to the parent dominator and +// children which are dominated. +// 5 - Using the tree from 4, perform a depth first traversal to calculate the +// preorder and postorder index of each node. We use these indexes to compare +// nodes against each other for domination checks. + +namespace spvtools { +namespace opt { +namespace { + +// Wrapper around CFA::DepthFirstTraversal to provide an interface to perform +// depth first search on generic BasicBlock types. Will call post and pre order +// user defined functions during traversal +// +// BBType - BasicBlock type. Will either be BasicBlock or DominatorTreeNode +// SuccessorLambda - Lamdba matching the signature of 'const +// std::vector*(const BBType *A)'. Will return a vector of the nodes +// succeeding BasicBlock A. +// PostLambda - Lamdba matching the signature of 'void (const BBType*)' will be +// called on each node traversed AFTER their children. +// PreLambda - Lamdba matching the signature of 'void (const BBType*)' will be +// called on each node traversed BEFORE their children. +template +void DepthFirstSearch(const BBType* bb, SuccessorLambda successors, + PreLambda pre, PostLambda post) { + auto no_terminal_blocks = [](const BBType*) { return false; }; + CFA::DepthFirstTraversal(bb, successors, pre, post, + no_terminal_blocks); +} + +// Wrapper around CFA::DepthFirstTraversal to provide an interface to perform +// depth first search on generic BasicBlock types. This overload is for only +// performing user defined post order. +// +// BBType - BasicBlock type. Will either be BasicBlock or DominatorTreeNode +// SuccessorLambda - Lamdba matching the signature of 'const +// std::vector*(const BBType *A)'. Will return a vector of the nodes +// succeeding BasicBlock A. +// PostLambda - Lamdba matching the signature of 'void (const BBType*)' will be +// called on each node traversed after their children. +template +void DepthFirstSearchPostOrder(const BBType* bb, SuccessorLambda successors, + PostLambda post) { + // Ignore preorder operation. + auto nop_preorder = [](const BBType*) {}; + DepthFirstSearch(bb, successors, nop_preorder, post); +} + +// Small type trait to get the function class type. +template +struct GetFunctionClass { + using FunctionType = Function; +}; + +// Helper class to compute predecessors and successors for each Basic Block in a +// function. Through GetPredFunctor and GetSuccessorFunctor it provides an +// interface to get the successor and predecessor lists for each basic +// block. This is required by the DepthFirstTraversal and ComputeDominator +// functions which take as parameter an std::function returning the successors +// and predecessors respectively. +// +// When computing the post-dominator tree, all edges are inverted. So successors +// returned by this class will be predecessors in the original CFG. +template +class BasicBlockSuccessorHelper { + // This should eventually become const BasicBlock. + using BasicBlock = BBType; + using Function = typename GetFunctionClass::FunctionType; + + using BasicBlockListTy = std::vector; + using BasicBlockMapTy = + std::unordered_map; + + public: + // For compliance with the dominance tree computation, entry nodes are + // connected to a single placeholder node. + BasicBlockSuccessorHelper(Function& func, + const BasicBlock* placeholder_start_node, + bool post); + + // CFA::CalculateDominators requires std::vector. + using GetBlocksFunction = + std::function*(const BasicBlock*)>; + + // Returns the list of predecessor functions. + GetBlocksFunction GetPredFunctor() { + return [this](const BasicBlock* bb) { + BasicBlockListTy* v = &this->predecessors_[bb]; + return v; + }; + } + + // Returns a vector of the list of successor nodes from a given node. + GetBlocksFunction GetSuccessorFunctor() { + return [this](const BasicBlock* bb) { + BasicBlockListTy* v = &this->successors_[bb]; + return v; + }; + } + + private: + bool invert_graph_; + BasicBlockMapTy successors_; + BasicBlockMapTy predecessors_; + + // Build the successors and predecessors map for each basic blocks |f|. + // If |invert_graph_| is true, all edges are reversed (successors becomes + // predecessors and vice versa). + // For convenience, the start of the graph is |placeholder_start_node|. + // The dominator tree construction requires a unique entry node, which cannot + // be guaranteed for the postdominator graph. The |placeholder_start_node| BB + // is here to gather all entry nodes. + void CreateSuccessorMap(Function& f, + const BasicBlock* placeholder_start_node); +}; + +template +BasicBlockSuccessorHelper::BasicBlockSuccessorHelper( + Function& func, const BasicBlock* placeholder_start_node, bool invert) + : invert_graph_(invert) { + CreateSuccessorMap(func, placeholder_start_node); +} + +template +void BasicBlockSuccessorHelper::CreateSuccessorMap( + Function& f, const BasicBlock* placeholder_start_node) { + IRContext* context = f.DefInst().context(); + + if (invert_graph_) { + // For the post dominator tree, we see the inverted graph. + // successors_ in the inverted graph are the predecessors in the CFG. + // The tree construction requires 1 entry point, so we add a placeholder + // node that is connected to all function exiting basic blocks. An exiting + // basic block is a block with an OpKill, OpUnreachable, OpReturn, + // OpReturnValue, or OpTerminateInvocation as terminator instruction. + for (BasicBlock& bb : f) { + if (bb.hasSuccessor()) { + BasicBlockListTy& pred_list = predecessors_[&bb]; + const auto& const_bb = bb; + const_bb.ForEachSuccessorLabel( + [this, &pred_list, &bb, context](const uint32_t successor_id) { + BasicBlock* succ = context->get_instr_block(successor_id); + // Inverted graph: our successors in the CFG + // are our predecessors in the inverted graph. + this->successors_[succ].push_back(&bb); + pred_list.push_back(succ); + }); + } else { + successors_[placeholder_start_node].push_back(&bb); + predecessors_[&bb].push_back( + const_cast(placeholder_start_node)); + } + } + } else { + successors_[placeholder_start_node].push_back(f.entry().get()); + predecessors_[f.entry().get()].push_back( + const_cast(placeholder_start_node)); + for (BasicBlock& bb : f) { + BasicBlockListTy& succ_list = successors_[&bb]; + + const auto& const_bb = bb; + const_bb.ForEachSuccessorLabel([&](const uint32_t successor_id) { + BasicBlock* succ = context->get_instr_block(successor_id); + succ_list.push_back(succ); + predecessors_[succ].push_back(&bb); + }); + } + } +} + +} // namespace + +bool DominatorTree::StrictlyDominates(uint32_t a, uint32_t b) const { + if (a == b) return false; + return Dominates(a, b); +} + +bool DominatorTree::StrictlyDominates(const BasicBlock* a, + const BasicBlock* b) const { + return DominatorTree::StrictlyDominates(a->id(), b->id()); +} + +bool DominatorTree::StrictlyDominates(const DominatorTreeNode* a, + const DominatorTreeNode* b) const { + if (a == b) return false; + return Dominates(a, b); +} + +bool DominatorTree::Dominates(uint32_t a, uint32_t b) const { + // Check that both of the inputs are actual nodes. + const DominatorTreeNode* a_node = GetTreeNode(a); + const DominatorTreeNode* b_node = GetTreeNode(b); + if (!a_node || !b_node) return false; + + return Dominates(a_node, b_node); +} + +bool DominatorTree::Dominates(const DominatorTreeNode* a, + const DominatorTreeNode* b) const { + if (!a || !b) return false; + // Node A dominates node B if they are the same. + if (a == b) return true; + + return a->dfs_num_pre_ < b->dfs_num_pre_ && + a->dfs_num_post_ > b->dfs_num_post_; +} + +bool DominatorTree::Dominates(const BasicBlock* A, const BasicBlock* B) const { + return Dominates(A->id(), B->id()); +} + +BasicBlock* DominatorTree::ImmediateDominator(const BasicBlock* A) const { + return ImmediateDominator(A->id()); +} + +BasicBlock* DominatorTree::ImmediateDominator(uint32_t a) const { + // Check that A is a valid node in the tree. + auto a_itr = nodes_.find(a); + if (a_itr == nodes_.end()) return nullptr; + + const DominatorTreeNode* node = &a_itr->second; + + if (node->parent_ == nullptr) { + return nullptr; + } + + return node->parent_->bb_; +} + +DominatorTreeNode* DominatorTree::GetOrInsertNode(BasicBlock* bb) { + DominatorTreeNode* dtn = nullptr; + + std::map::iterator node_iter = + nodes_.find(bb->id()); + if (node_iter == nodes_.end()) { + dtn = &nodes_.emplace(std::make_pair(bb->id(), DominatorTreeNode{bb})) + .first->second; + } else { + dtn = &node_iter->second; + } + + return dtn; +} + +void DominatorTree::GetDominatorEdges( + const Function* f, const BasicBlock* placeholder_start_node, + std::vector>* edges) { + // Each time the depth first traversal calls the postorder callback + // std::function we push that node into the postorder vector to create our + // postorder list. + std::vector postorder; + auto postorder_function = [&](const BasicBlock* b) { + postorder.push_back(b); + }; + + // CFA::CalculateDominators requires std::vector + // BB are derived from F, so we need to const cast it at some point + // no modification is made on F. + BasicBlockSuccessorHelper helper{ + *const_cast(f), placeholder_start_node, postdominator_}; + + // The successor function tells DepthFirstTraversal how to move to successive + // nodes by providing an interface to get a list of successor nodes from any + // given node. + auto successor_functor = helper.GetSuccessorFunctor(); + + // The predecessor functor does the same as the successor functor + // but for all nodes preceding a given node. + auto predecessor_functor = helper.GetPredFunctor(); + + // If we're building a post dominator tree we traverse the tree in reverse + // using the predecessor function in place of the successor function and vice + // versa. + DepthFirstSearchPostOrder(placeholder_start_node, successor_functor, + postorder_function); + *edges = CFA::CalculateDominators(postorder, predecessor_functor); +} + +void DominatorTree::InitializeTree(const CFG& cfg, const Function* f) { + ClearTree(); + + // Skip over empty functions. + if (f->cbegin() == f->cend()) { + return; + } + + const BasicBlock* placeholder_start_node = + postdominator_ ? cfg.pseudo_exit_block() : cfg.pseudo_entry_block(); + + // Get the immediate dominator for each node. + std::vector> edges; + GetDominatorEdges(f, placeholder_start_node, &edges); + + // Transform the vector into the tree structure which we can use to + // efficiently query dominance. + for (auto edge : edges) { + DominatorTreeNode* first = GetOrInsertNode(edge.first); + + if (edge.first == edge.second) { + if (std::find(roots_.begin(), roots_.end(), first) == roots_.end()) + roots_.push_back(first); + continue; + } + + DominatorTreeNode* second = GetOrInsertNode(edge.second); + + first->parent_ = second; + second->children_.push_back(first); + } + ResetDFNumbering(); +} + +void DominatorTree::ResetDFNumbering() { + int index = 0; + auto preFunc = [&index](const DominatorTreeNode* node) { + const_cast(node)->dfs_num_pre_ = ++index; + }; + + auto postFunc = [&index](const DominatorTreeNode* node) { + const_cast(node)->dfs_num_post_ = ++index; + }; + + auto getSucc = [](const DominatorTreeNode* node) { return &node->children_; }; + + for (auto root : roots_) DepthFirstSearch(root, getSucc, preFunc, postFunc); +} + +void DominatorTree::DumpTreeAsDot(std::ostream& out_stream) const { + out_stream << "digraph {\n"; + Visit([&out_stream](const DominatorTreeNode* node) { + // Print the node. + if (node->bb_) { + out_stream << node->bb_->id() << "[label=\"" << node->bb_->id() + << "\"];\n"; + } + + // Print the arrow from the parent to this node. Entry nodes will not have + // parents so draw them as children from the placeholder node. + if (node->parent_) { + out_stream << node->parent_->bb_->id() << " -> " << node->bb_->id() + << ";\n"; + } + + // Return true to continue the traversal. + return true; + }); + out_stream << "}\n"; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/dominator_tree.h b/thirdparty/glslang/External/spirv-tools/source/opt/dominator_tree.h new file mode 100644 index 000000000000..1674b228fd7a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/dominator_tree.h @@ -0,0 +1,305 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DOMINATOR_TREE_H_ +#define SOURCE_OPT_DOMINATOR_TREE_H_ + +#include +#include +#include +#include +#include + +#include "source/opt/cfg.h" +#include "source/opt/tree_iterator.h" + +namespace spvtools { +namespace opt { +// This helper struct forms the nodes in the tree, with each node containing its +// children. It also contains two values, for the pre and post indexes in the +// tree which are used to compare two nodes. +struct DominatorTreeNode { + explicit DominatorTreeNode(BasicBlock* bb) + : bb_(bb), + parent_(nullptr), + children_({}), + dfs_num_pre_(-1), + dfs_num_post_(-1) {} + + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + + // depth first preorder iterator. + using df_iterator = TreeDFIterator; + using const_df_iterator = TreeDFIterator; + // depth first postorder iterator. + using post_iterator = PostOrderTreeDFIterator; + using const_post_iterator = PostOrderTreeDFIterator; + + iterator begin() { return children_.begin(); } + iterator end() { return children_.end(); } + const_iterator begin() const { return cbegin(); } + const_iterator end() const { return cend(); } + const_iterator cbegin() const { return children_.begin(); } + const_iterator cend() const { return children_.end(); } + + // Depth first preorder iterator using this node as root. + df_iterator df_begin() { return df_iterator(this); } + df_iterator df_end() { return df_iterator(); } + const_df_iterator df_begin() const { return df_cbegin(); } + const_df_iterator df_end() const { return df_cend(); } + const_df_iterator df_cbegin() const { return const_df_iterator(this); } + const_df_iterator df_cend() const { return const_df_iterator(); } + + // Depth first postorder iterator using this node as root. + post_iterator post_begin() { return post_iterator::begin(this); } + post_iterator post_end() { return post_iterator::end(nullptr); } + const_post_iterator post_begin() const { return post_cbegin(); } + const_post_iterator post_end() const { return post_cend(); } + const_post_iterator post_cbegin() const { + return const_post_iterator::begin(this); + } + const_post_iterator post_cend() const { + return const_post_iterator::end(nullptr); + } + + inline uint32_t id() const { return bb_->id(); } + + BasicBlock* bb_; + DominatorTreeNode* parent_; + std::vector children_; + + // These indexes are used to compare two given nodes. A node is a child or + // grandchild of another node if its preorder index is greater than the + // first nodes preorder index AND if its postorder index is less than the + // first nodes postorder index. + int dfs_num_pre_; + int dfs_num_post_; +}; + +// A class representing a tree of BasicBlocks in a given function, where each +// node is dominated by its parent. +class DominatorTree { + public: + // Map OpLabel ids to dominator tree nodes + using DominatorTreeNodeMap = std::map; + using iterator = TreeDFIterator; + using const_iterator = TreeDFIterator; + using post_iterator = PostOrderTreeDFIterator; + using const_post_iterator = PostOrderTreeDFIterator; + + // List of DominatorTreeNode to define the list of roots + using DominatorTreeNodeList = std::vector; + using roots_iterator = DominatorTreeNodeList::iterator; + using roots_const_iterator = DominatorTreeNodeList::const_iterator; + + DominatorTree() : postdominator_(false) {} + explicit DominatorTree(bool post) : postdominator_(post) {} + + // Depth first iterators. + // Traverse the dominator tree in a depth first pre-order. + // The pseudo-block is ignored. + iterator begin() { return ++iterator(GetRoot()); } + iterator end() { return iterator(); } + const_iterator begin() const { return cbegin(); } + const_iterator end() const { return cend(); } + const_iterator cbegin() const { return ++const_iterator(GetRoot()); } + const_iterator cend() const { return const_iterator(); } + + // Traverse the dominator tree in a depth first post-order. + // The pseudo-block is ignored. + post_iterator post_begin() { return post_iterator::begin(GetRoot()); } + post_iterator post_end() { return post_iterator::end(GetRoot()); } + const_post_iterator post_begin() const { return post_cbegin(); } + const_post_iterator post_end() const { return post_cend(); } + const_post_iterator post_cbegin() const { + return const_post_iterator::begin(GetRoot()); + } + const_post_iterator post_cend() const { + return const_post_iterator::end(GetRoot()); + } + + roots_iterator roots_begin() { return roots_.begin(); } + roots_iterator roots_end() { return roots_.end(); } + roots_const_iterator roots_begin() const { return roots_cbegin(); } + roots_const_iterator roots_end() const { return roots_cend(); } + roots_const_iterator roots_cbegin() const { return roots_.begin(); } + roots_const_iterator roots_cend() const { return roots_.end(); } + + // Get the unique root of the tree. + // It is guaranteed to work on a dominator tree. + // post-dominator might have a list. + DominatorTreeNode* GetRoot() { + assert(roots_.size() == 1); + return *roots_.begin(); + } + + const DominatorTreeNode* GetRoot() const { + assert(roots_.size() == 1); + return *roots_.begin(); + } + + const DominatorTreeNodeList& Roots() const { return roots_; } + + // Dumps the tree in the graphvis dot format into the |out_stream|. + void DumpTreeAsDot(std::ostream& out_stream) const; + + // Build the (post-)dominator tree for the given control flow graph + // |cfg| and the function |f|. |f| must exist in the |cfg|. Any + // existing data in the dominator tree will be overwritten + void InitializeTree(const CFG& cfg, const Function* f); + + // Check if the basic block |a| dominates the basic block |b|. + bool Dominates(const BasicBlock* a, const BasicBlock* b) const; + + // Check if the basic block id |a| dominates the basic block id |b|. + bool Dominates(uint32_t a, uint32_t b) const; + + // Check if the dominator tree node |a| dominates the dominator tree node |b|. + bool Dominates(const DominatorTreeNode* a, const DominatorTreeNode* b) const; + + // Check if the basic block |a| strictly dominates the basic block |b|. + bool StrictlyDominates(const BasicBlock* a, const BasicBlock* b) const; + + // Check if the basic block id |a| strictly dominates the basic block id |b|. + bool StrictlyDominates(uint32_t a, uint32_t b) const; + + // Check if the dominator tree node |a| strictly dominates the dominator tree + // node |b|. + bool StrictlyDominates(const DominatorTreeNode* a, + const DominatorTreeNode* b) const; + + // Returns the immediate dominator of basic block |a|. + BasicBlock* ImmediateDominator(const BasicBlock* A) const; + + // Returns the immediate dominator of basic block id |a|. + BasicBlock* ImmediateDominator(uint32_t a) const; + + // Returns true if the basic block |a| is reachable by this tree. A node would + // be unreachable if it cannot be reached by traversal from the start node or + // for a postdominator tree, cannot be reached from the exit nodes. + inline bool ReachableFromRoots(const BasicBlock* a) const { + if (!a) return false; + return ReachableFromRoots(a->id()); + } + + // Returns true if the basic block id |a| is reachable by this tree. + bool ReachableFromRoots(uint32_t a) const { + return GetTreeNode(a) != nullptr; + } + + // Returns true if this tree is a post dominator tree. + bool IsPostDominator() const { return postdominator_; } + + // Clean up the tree. + void ClearTree() { + nodes_.clear(); + roots_.clear(); + } + + // Applies the std::function |func| to all nodes in the dominator tree. + // Tree nodes are visited in a depth first pre-order. + bool Visit(std::function func) { + for (auto n : *this) { + if (!func(&n)) return false; + } + return true; + } + + // Applies the std::function |func| to all nodes in the dominator tree. + // Tree nodes are visited in a depth first pre-order. + bool Visit(std::function func) const { + for (auto n : *this) { + if (!func(&n)) return false; + } + return true; + } + + // Applies the std::function |func| to all nodes in the dominator tree from + // |node| downwards. The boolean return from |func| is used to determine + // whether or not the children should also be traversed. Tree nodes are + // visited in a depth first pre-order. + void VisitChildrenIf(std::function func, + iterator node) { + if (func(&*node)) { + for (auto n : *node) { + VisitChildrenIf(func, n->df_begin()); + } + } + } + + // Returns the DominatorTreeNode associated with the basic block |bb|. + // If the |bb| is unknown to the dominator tree, it returns null. + inline DominatorTreeNode* GetTreeNode(BasicBlock* bb) { + return GetTreeNode(bb->id()); + } + // Returns the DominatorTreeNode associated with the basic block |bb|. + // If the |bb| is unknown to the dominator tree, it returns null. + inline const DominatorTreeNode* GetTreeNode(BasicBlock* bb) const { + return GetTreeNode(bb->id()); + } + + // Returns the DominatorTreeNode associated with the basic block id |id|. + // If the id |id| is unknown to the dominator tree, it returns null. + inline DominatorTreeNode* GetTreeNode(uint32_t id) { + DominatorTreeNodeMap::iterator node_iter = nodes_.find(id); + if (node_iter == nodes_.end()) { + return nullptr; + } + return &node_iter->second; + } + // Returns the DominatorTreeNode associated with the basic block id |id|. + // If the id |id| is unknown to the dominator tree, it returns null. + inline const DominatorTreeNode* GetTreeNode(uint32_t id) const { + DominatorTreeNodeMap::const_iterator node_iter = nodes_.find(id); + if (node_iter == nodes_.end()) { + return nullptr; + } + return &node_iter->second; + } + + // Adds the basic block |bb| to the tree structure if it doesn't already + // exist. + DominatorTreeNode* GetOrInsertNode(BasicBlock* bb); + + // Recomputes the DF numbering of the tree. + void ResetDFNumbering(); + + private: + // Wrapper function which gets the list of pairs of each BasicBlocks to its + // immediately dominating BasicBlock and stores the result in the edges + // parameter. + // + // The |edges| vector will contain the dominator tree as pairs of nodes. + // The first node in the pair is a node in the graph. The second node in the + // pair is its immediate dominator. + // The root of the tree has themself as immediate dominator. + void GetDominatorEdges( + const Function* f, const BasicBlock* dummy_start_node, + std::vector>* edges); + + // The roots of the tree. + std::vector roots_; + + // Pairs each basic block id to the tree node containing that basic block. + DominatorTreeNodeMap nodes_; + + // True if this is a post dominator tree. + bool postdominator_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DOMINATOR_TREE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_constant_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_constant_pass.cpp new file mode 100644 index 000000000000..500fd8af9af7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_constant_pass.cpp @@ -0,0 +1,103 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/eliminate_dead_constant_pass.h" + +#include +#include +#include +#include + +#include "source/opt/def_use_manager.h" +#include "source/opt/log.h" +#include "source/opt/reflect.h" + +namespace spvtools { +namespace opt { + +Pass::Status EliminateDeadConstantPass::Process() { + std::unordered_set working_list; + // Traverse all the instructions to get the initial set of dead constants as + // working list and count number of real uses for constants. Uses in + // annotation instructions do not count. + std::unordered_map use_counts; + std::vector constants = context()->GetConstants(); + for (auto* c : constants) { + uint32_t const_id = c->result_id(); + size_t count = 0; + context()->get_def_use_mgr()->ForEachUse( + const_id, [&count](Instruction* user, uint32_t index) { + (void)index; + spv::Op op = user->opcode(); + if (!(IsAnnotationInst(op) || IsDebug1Inst(op) || IsDebug2Inst(op) || + IsDebug3Inst(op))) { + ++count; + } + }); + use_counts[c] = count; + if (!count) { + working_list.insert(c); + } + } + + // Start from the constants with 0 uses, back trace through the def-use chain + // to find all dead constants. + std::unordered_set dead_consts; + while (!working_list.empty()) { + Instruction* inst = *working_list.begin(); + // Back propagate if the instruction contains IDs in its operands. + switch (inst->opcode()) { + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: + case spv::Op::OpSpecConstantOp: + for (uint32_t i = 0; i < inst->NumInOperands(); i++) { + // SpecConstantOp instruction contains 'opcode' as its operand. Need + // to exclude such operands when decreasing uses. + if (inst->GetInOperand(i).type != SPV_OPERAND_TYPE_ID) { + continue; + } + uint32_t operand_id = inst->GetSingleWordInOperand(i); + Instruction* def_inst = + context()->get_def_use_mgr()->GetDef(operand_id); + // If the use_count does not have any count for the def_inst, + // def_inst must not be a constant, and should be ignored here. + if (!use_counts.count(def_inst)) { + continue; + } + // The number of uses should never be less then 0, so it can not be + // less than 1 before it decreases. + SPIRV_ASSERT(consumer(), use_counts[def_inst] > 0); + --use_counts[def_inst]; + if (!use_counts[def_inst]) { + working_list.insert(def_inst); + } + } + break; + default: + break; + } + dead_consts.insert(inst); + working_list.erase(inst); + } + + // Turn all dead instructions and uses of them to nop + for (auto* dc : dead_consts) { + context()->KillDef(dc->result_id()); + } + return dead_consts.empty() ? Status::SuccessWithoutChange + : Status::SuccessWithChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_constant_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_constant_pass.h new file mode 100644 index 000000000000..01692dbf4652 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_constant_pass.h @@ -0,0 +1,35 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ELIMINATE_DEAD_CONSTANT_PASS_H_ +#define SOURCE_OPT_ELIMINATE_DEAD_CONSTANT_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class EliminateDeadConstantPass : public Pass { + public: + const char* name() const override { return "eliminate-dead-const"; } + Status Process() override; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ELIMINATE_DEAD_CONSTANT_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_pass.cpp new file mode 100644 index 000000000000..a4655219371a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_pass.cpp @@ -0,0 +1,52 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/eliminate_dead_functions_pass.h" +#include "source/opt/eliminate_dead_functions_util.h" + +#include + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +Pass::Status EliminateDeadFunctionsPass::Process() { + // Identify live functions first. Those that are not live + // are dead. + std::unordered_set live_function_set; + ProcessFunction mark_live = [&live_function_set](Function* fp) { + live_function_set.insert(fp); + return false; + }; + context()->ProcessReachableCallTree(mark_live); + + bool modified = false; + for (auto funcIter = get_module()->begin(); + funcIter != get_module()->end();) { + if (live_function_set.count(&*funcIter) == 0) { + modified = true; + funcIter = + eliminatedeadfunctionsutil::EliminateFunction(context(), &funcIter); + } else { + ++funcIter; + } + } + + return modified ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_pass.h new file mode 100644 index 000000000000..6ed5c42b0ebf --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_pass.h @@ -0,0 +1,44 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_PASS_H_ +#define SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_PASS_H_ + +#include "source/opt/def_use_manager.h" +#include "source/opt/function.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class EliminateDeadFunctionsPass : public MemPass { + public: + const char* name() const override { return "eliminate-dead-functions"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + void EliminateFunction(Function* func); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_util.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_util.cpp new file mode 100644 index 000000000000..e95b7f6a8636 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_util.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "eliminate_dead_functions_util.h" + +namespace spvtools { +namespace opt { + +namespace eliminatedeadfunctionsutil { + +Module::iterator EliminateFunction(IRContext* context, + Module::iterator* func_iter) { + bool first_func = *func_iter == context->module()->begin(); + bool seen_func_end = false; + std::unordered_set to_kill; + (*func_iter) + ->ForEachInst( + [context, first_func, func_iter, &seen_func_end, + &to_kill](Instruction* inst) { + if (inst->opcode() == spv::Op::OpFunctionEnd) { + seen_func_end = true; + } + // Move non-semantic instructions to the previous function or + // global values if this is the first function. + if (seen_func_end && inst->opcode() == spv::Op::OpExtInst) { + assert(inst->IsNonSemanticInstruction()); + if (to_kill.find(inst) != to_kill.end()) return; + std::unique_ptr clone(inst->Clone(context)); + // Clear uses of "inst" to in case this moves a dependent chain of + // instructions. + context->get_def_use_mgr()->ClearInst(inst); + context->AnalyzeDefUse(clone.get()); + if (first_func) { + context->AddGlobalValue(std::move(clone)); + } else { + auto prev_func_iter = *func_iter; + --prev_func_iter; + prev_func_iter->AddNonSemanticInstruction(std::move(clone)); + } + inst->ToNop(); + } else if (to_kill.find(inst) == to_kill.end()) { + context->CollectNonSemanticTree(inst, &to_kill); + context->KillInst(inst); + } + }, + true, true); + + for (auto* dead : to_kill) { + context->KillInst(dead); + } + + return func_iter->Erase(); +} + +} // namespace eliminatedeadfunctionsutil +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_util.h b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_util.h new file mode 100644 index 000000000000..9fcce956fc4d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_functions_util.h @@ -0,0 +1,36 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_UTIL_H_ +#define SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_UTIL_H_ + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +// Provides functionality for eliminating functions that are not needed, for use +// by various analyses and passes. +namespace eliminatedeadfunctionsutil { + +// Removes all of the function's instructions, removes the function from the +// module, and returns the next iterator. +Module::iterator EliminateFunction(IRContext* context, + Module::iterator* func_iter); + +} // namespace eliminatedeadfunctionsutil +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_UTIL_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_io_components_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_io_components_pass.cpp new file mode 100644 index 000000000000..5553a3362f8a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_io_components_pass.cpp @@ -0,0 +1,256 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/eliminate_dead_io_components_pass.h" + +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" +#include "source/util/bit_vector.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kAccessChainBaseInIdx = 0; +constexpr uint32_t kAccessChainIndex0InIdx = 1; +constexpr uint32_t kAccessChainIndex1InIdx = 2; +constexpr uint32_t kConstantValueInIdx = 0; +} // namespace + +Pass::Status EliminateDeadIOComponentsPass::Process() { + // Only process input and output variables + if (elim_sclass_ != spv::StorageClass::Input && + elim_sclass_ != spv::StorageClass::Output) { + if (consumer()) { + std::string message = + "EliminateDeadIOComponentsPass only valid for input and output " + "variables."; + consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); + } + return Status::Failure; + } + // If safe mode, only process Input variables in vertex shader + const auto stage = context()->GetStage(); + if (safe_mode_ && !(stage == spv::ExecutionModel::Vertex && + elim_sclass_ == spv::StorageClass::Input)) + return Status::SuccessWithoutChange; + // Current functionality assumes shader capability. + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return Status::SuccessWithoutChange; + // Current functionality assumes vert, frag, tesc, tese or geom shader. + // TODO(issue #4988): Add GLCompute. + if (stage != spv::ExecutionModel::Vertex && + stage != spv::ExecutionModel::Fragment && + stage != spv::ExecutionModel::TessellationControl && + stage != spv::ExecutionModel::TessellationEvaluation && + stage != spv::ExecutionModel::Geometry) + return Status::SuccessWithoutChange; + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + bool modified = false; + std::vector vars_to_move; + for (auto& var : context()->types_values()) { + if (var.opcode() != spv::Op::OpVariable) { + continue; + } + analysis::Type* var_type = type_mgr->GetType(var.type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + if (ptr_type == nullptr) { + continue; + } + const auto sclass = ptr_type->storage_class(); + if (sclass != elim_sclass_) { + continue; + } + // For tesc, or input variables in tese or geom shaders, + // there is a outer per-vertex-array that must be ignored + // for the purposes of this analysis/optimization. Do the + // analysis on the inner type in these cases. + bool skip_first_index = false; + auto core_type = ptr_type->pointee_type(); + if (stage == spv::ExecutionModel::TessellationControl || + (sclass == spv::StorageClass::Input && + (stage == spv::ExecutionModel::TessellationEvaluation || + stage == spv::ExecutionModel::Geometry))) { + auto arr_type = core_type->AsArray(); + if (!arr_type) continue; + core_type = arr_type->element_type(); + skip_first_index = true; + } + const analysis::Array* arr_type = core_type->AsArray(); + if (arr_type != nullptr) { + // Only process array if input of vertex shader, or output of + // fragment shader. Otherwise, if one shader has a runtime index and the + // other does not, interface incompatibility can occur. + if (!((sclass == spv::StorageClass::Input && + stage == spv::ExecutionModel::Vertex) || + (sclass == spv::StorageClass::Output && + stage == spv::ExecutionModel::Fragment))) + continue; + unsigned arr_len_id = arr_type->LengthId(); + Instruction* arr_len_inst = def_use_mgr->GetDef(arr_len_id); + if (arr_len_inst->opcode() != spv::Op::OpConstant) { + continue; + } + // SPIR-V requires array size is >= 1, so this works for signed or + // unsigned size. + unsigned original_max = + arr_len_inst->GetSingleWordInOperand(kConstantValueInIdx) - 1; + unsigned max_idx = FindMaxIndex(var, original_max); + if (max_idx != original_max) { + ChangeArrayLength(var, max_idx + 1); + vars_to_move.push_back(&var); + modified = true; + } + continue; + } + const analysis::Struct* struct_type = core_type->AsStruct(); + if (struct_type == nullptr) continue; + const auto elt_types = struct_type->element_types(); + unsigned original_max = static_cast(elt_types.size()) - 1; + unsigned max_idx = FindMaxIndex(var, original_max, skip_first_index); + if (max_idx != original_max) { + ChangeIOVarStructLength(var, max_idx + 1); + vars_to_move.push_back(&var); + modified = true; + } + } + + // Move changed vars after their new type instruction to preserve backward + // referencing. + for (auto var : vars_to_move) { + auto type_id = var->type_id(); + auto type_inst = def_use_mgr->GetDef(type_id); + var->RemoveFromList(); + var->InsertAfter(type_inst); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +unsigned EliminateDeadIOComponentsPass::FindMaxIndex( + const Instruction& var, const unsigned original_max, + const bool skip_first_index) { + unsigned max = 0; + bool seen_non_const_ac = false; + assert(var.opcode() == spv::Op::OpVariable && "must be variable"); + context()->get_def_use_mgr()->WhileEachUser( + var.result_id(), [&max, &seen_non_const_ac, var, skip_first_index, + this](Instruction* use) { + auto use_opcode = use->opcode(); + if (use_opcode == spv::Op::OpLoad || use_opcode == spv::Op::OpStore || + use_opcode == spv::Op::OpCopyMemory || + use_opcode == spv::Op::OpCopyMemorySized || + use_opcode == spv::Op::OpCopyObject) { + seen_non_const_ac = true; + return false; + } + if (use->opcode() != spv::Op::OpAccessChain && + use->opcode() != spv::Op::OpInBoundsAccessChain) { + return true; + } + // OpAccessChain with no indices currently not optimized + if (use->NumInOperands() == 1 || + (skip_first_index && use->NumInOperands() == 2)) { + seen_non_const_ac = true; + return false; + } + const unsigned base_id = + use->GetSingleWordInOperand(kAccessChainBaseInIdx); + USE_ASSERT(base_id == var.result_id() && "unexpected base"); + const unsigned in_idx = skip_first_index ? kAccessChainIndex1InIdx + : kAccessChainIndex0InIdx; + const unsigned idx_id = use->GetSingleWordInOperand(in_idx); + Instruction* idx_inst = context()->get_def_use_mgr()->GetDef(idx_id); + if (idx_inst->opcode() != spv::Op::OpConstant) { + seen_non_const_ac = true; + return false; + } + unsigned value = idx_inst->GetSingleWordInOperand(kConstantValueInIdx); + if (value > max) max = value; + return true; + }); + return seen_non_const_ac ? original_max : max; +} + +void EliminateDeadIOComponentsPass::ChangeArrayLength(Instruction& arr_var, + unsigned length) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::Pointer* ptr_type = + type_mgr->GetType(arr_var.type_id())->AsPointer(); + const analysis::Array* arr_ty = ptr_type->pointee_type()->AsArray(); + assert(arr_ty && "expecting array type"); + uint32_t length_id = const_mgr->GetUIntConstId(length); + analysis::Array new_arr_ty(arr_ty->element_type(), + arr_ty->GetConstantLengthInfo(length_id, length)); + analysis::Type* reg_new_arr_ty = type_mgr->GetRegisteredType(&new_arr_ty); + analysis::Pointer new_ptr_ty(reg_new_arr_ty, ptr_type->storage_class()); + analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); + uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); + arr_var.SetResultType(new_ptr_ty_id); + def_use_mgr->AnalyzeInstUse(&arr_var); +} + +void EliminateDeadIOComponentsPass::ChangeIOVarStructLength(Instruction& io_var, + unsigned length) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Pointer* ptr_type = + type_mgr->GetType(io_var.type_id())->AsPointer(); + auto core_type = ptr_type->pointee_type(); + // Check for per-vertex-array of struct from tesc, tese and geom and grab + // embedded struct type. + const auto arr_type = core_type->AsArray(); + if (arr_type) core_type = arr_type->element_type(); + const analysis::Struct* struct_ty = core_type->AsStruct(); + assert(struct_ty && "expecting struct type"); + const auto orig_elt_types = struct_ty->element_types(); + std::vector new_elt_types; + for (unsigned u = 0; u < length; ++u) + new_elt_types.push_back(orig_elt_types[u]); + analysis::Struct new_struct_ty(new_elt_types); + uint32_t old_struct_ty_id = type_mgr->GetTypeInstruction(struct_ty); + std::vector decorations = + context()->get_decoration_mgr()->GetDecorationsFor(old_struct_ty_id, + true); + for (auto dec : decorations) { + if (dec->opcode() == spv::Op::OpMemberDecorate) { + uint32_t midx = dec->GetSingleWordInOperand(1); + if (midx >= length) continue; + } + type_mgr->AttachDecoration(*dec, &new_struct_ty); + } + // Clone name instructions for new struct type + analysis::Type* reg_new_str_ty = type_mgr->GetRegisteredType(&new_struct_ty); + uint32_t new_struct_ty_id = type_mgr->GetTypeInstruction(reg_new_str_ty); + context()->CloneNames(old_struct_ty_id, new_struct_ty_id, length); + // Attach new type to var + analysis::Type* reg_new_var_ty = reg_new_str_ty; + if (arr_type) { + analysis::Array new_arr_ty(reg_new_var_ty, arr_type->length_info()); + reg_new_var_ty = type_mgr->GetRegisteredType(&new_arr_ty); + } + analysis::Pointer new_ptr_ty(reg_new_var_ty, elim_sclass_); + analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); + uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); + io_var.SetResultType(new_ptr_ty_id); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + def_use_mgr->AnalyzeInstUse(&io_var); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_io_components_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_io_components_pass.h new file mode 100644 index 000000000000..ef4dfb71723c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_io_components_pass.h @@ -0,0 +1,75 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ELIMINATE_DEAD_INPUT_COMPONENTS_H_ +#define SOURCE_OPT_ELIMINATE_DEAD_INPUT_COMPONENTS_H_ + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class EliminateDeadIOComponentsPass : public Pass { + public: + explicit EliminateDeadIOComponentsPass(spv::StorageClass elim_sclass, + bool safe_mode = true) + : elim_sclass_(elim_sclass), safe_mode_(safe_mode) {} + + const char* name() const override { + return "eliminate-dead-input-components"; + } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Find the max constant used to index the variable declared by |var| + // through OpAccessChain or OpInBoundsAccessChain. If any non-constant + // indices or non-Op*AccessChain use of |var|, return |original_max|. + unsigned FindMaxIndex(const Instruction& var, const unsigned original_max, + const bool skip_first_index = false); + + // Change the length of the array |inst| to |length| + void ChangeArrayLength(Instruction& inst, unsigned length); + + // Change the length of the struct in |io_var| to |length|. |io_var| + // is either the struct or a per-vertex-array of the struct. + void ChangeIOVarStructLength(Instruction& io_var, unsigned length); + + // Storage class to be optimized. Must be Input or Output. + spv::StorageClass elim_sclass_; + + // Only make changes that will not cause interface incompatibility if done + // standalone. Currently this is only Input variables in vertex shaders. + bool safe_mode_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ELIMINATE_DEAD_INPUT_COMPONENTS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_members_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_members_pass.cpp new file mode 100644 index 000000000000..1c98502e223d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_members_pass.cpp @@ -0,0 +1,691 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/eliminate_dead_members_pass.h" + +#include "ir_builder.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kRemovedMember = 0xFFFFFFFF; +constexpr uint32_t kSpecConstOpOpcodeIdx = 0; +constexpr uint32_t kArrayElementTypeIdx = 0; +} // namespace + +Pass::Status EliminateDeadMembersPass::Process() { + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return Status::SuccessWithoutChange; + + FindLiveMembers(); + if (RemoveDeadMembers()) { + return Status::SuccessWithChange; + } + return Status::SuccessWithoutChange; +} + +void EliminateDeadMembersPass::FindLiveMembers() { + // Until we have implemented the rewriting of OpSpecConsantOp instructions, + // we have to mark them as fully used just to be safe. + for (auto& inst : get_module()->types_values()) { + if (inst.opcode() == spv::Op::OpSpecConstantOp) { + switch (spv::Op(inst.GetSingleWordInOperand(kSpecConstOpOpcodeIdx))) { + case spv::Op::OpCompositeExtract: + MarkMembersAsLiveForExtract(&inst); + break; + case spv::Op::OpCompositeInsert: + // Nothing specific to do. + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + assert(false && "Not implemented yet."); + break; + default: + break; + } + } else if (inst.opcode() == spv::Op::OpVariable) { + switch (spv::StorageClass(inst.GetSingleWordInOperand(0))) { + case spv::StorageClass::Input: + case spv::StorageClass::Output: + MarkPointeeTypeAsFullUsed(inst.type_id()); + break; + default: + // Ignore structured buffers as layout(offset) qualifiers cannot be + // applied to structure fields + if (inst.IsVulkanStorageBufferVariable()) + MarkPointeeTypeAsFullUsed(inst.type_id()); + break; + } + } + } + + for (const Function& func : *get_module()) { + FindLiveMembers(func); + } +} + +void EliminateDeadMembersPass::FindLiveMembers(const Function& function) { + function.ForEachInst( + [this](const Instruction* inst) { FindLiveMembers(inst); }); +} + +void EliminateDeadMembersPass::FindLiveMembers(const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpStore: + MarkMembersAsLiveForStore(inst); + break; + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + MarkMembersAsLiveForCopyMemory(inst); + break; + case spv::Op::OpCompositeExtract: + MarkMembersAsLiveForExtract(inst); + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + MarkMembersAsLiveForAccessChain(inst); + break; + case spv::Op::OpReturnValue: + // This should be an issue only if we are returning from the entry point. + // However, for now I will keep it more conservative because functions are + // often inlined leaving only the entry points. + MarkOperandTypeAsFullyUsed(inst, 0); + break; + case spv::Op::OpArrayLength: + MarkMembersAsLiveForArrayLength(inst); + break; + case spv::Op::OpLoad: + case spv::Op::OpCompositeInsert: + case spv::Op::OpCompositeConstruct: + break; + default: + // This path is here for safety. All instructions that can reference + // structs in a function body should be handled above. However, this will + // keep the pass valid, but not optimal, as new instructions get added + // or if something was missed. + MarkStructOperandsAsFullyUsed(inst); + break; + } +} + +void EliminateDeadMembersPass::MarkMembersAsLiveForStore( + const Instruction* inst) { + // We should only have to mark the members as live if the store is to + // memory that is read outside of the shader. Other passes can remove all + // store to memory that is not visible outside of the shader, so we do not + // complicate the code for now. + assert(inst->opcode() == spv::Op::OpStore); + uint32_t object_id = inst->GetSingleWordInOperand(1); + Instruction* object_inst = context()->get_def_use_mgr()->GetDef(object_id); + uint32_t object_type_id = object_inst->type_id(); + MarkTypeAsFullyUsed(object_type_id); +} + +void EliminateDeadMembersPass::MarkTypeAsFullyUsed(uint32_t type_id) { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + assert(type_inst != nullptr); + + switch (type_inst->opcode()) { + case spv::Op::OpTypeStruct: + // Mark every member and its type as fully used. + for (uint32_t i = 0; i < type_inst->NumInOperands(); ++i) { + used_members_[type_id].insert(i); + MarkTypeAsFullyUsed(type_inst->GetSingleWordInOperand(i)); + } + break; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + MarkTypeAsFullyUsed( + type_inst->GetSingleWordInOperand(kArrayElementTypeIdx)); + break; + default: + break; + } +} + +void EliminateDeadMembersPass::MarkPointeeTypeAsFullUsed(uint32_t ptr_type_id) { + Instruction* ptr_type_inst = get_def_use_mgr()->GetDef(ptr_type_id); + assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer); + MarkTypeAsFullyUsed(ptr_type_inst->GetSingleWordInOperand(1)); +} + +void EliminateDeadMembersPass::MarkMembersAsLiveForCopyMemory( + const Instruction* inst) { + uint32_t target_id = inst->GetSingleWordInOperand(0); + Instruction* target_inst = get_def_use_mgr()->GetDef(target_id); + uint32_t pointer_type_id = target_inst->type_id(); + Instruction* pointer_type_inst = get_def_use_mgr()->GetDef(pointer_type_id); + uint32_t type_id = pointer_type_inst->GetSingleWordInOperand(1); + MarkTypeAsFullyUsed(type_id); +} + +void EliminateDeadMembersPass::MarkMembersAsLiveForExtract( + const Instruction* inst) { + assert(inst->opcode() == spv::Op::OpCompositeExtract || + (inst->opcode() == spv::Op::OpSpecConstantOp && + spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == + spv::Op::OpCompositeExtract)); + + uint32_t first_operand = + (inst->opcode() == spv::Op::OpSpecConstantOp ? 1 : 0); + uint32_t composite_id = inst->GetSingleWordInOperand(first_operand); + Instruction* composite_inst = get_def_use_mgr()->GetDef(composite_id); + uint32_t type_id = composite_inst->type_id(); + + for (uint32_t i = first_operand + 1; i < inst->NumInOperands(); ++i) { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + uint32_t member_idx = inst->GetSingleWordInOperand(i); + switch (type_inst->opcode()) { + case spv::Op::OpTypeStruct: + used_members_[type_id].insert(member_idx); + type_id = type_inst->GetSingleWordInOperand(member_idx); + break; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + type_id = type_inst->GetSingleWordInOperand(0); + break; + default: + assert(false); + } + } +} + +void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain( + const Instruction* inst) { + assert(inst->opcode() == spv::Op::OpAccessChain || + inst->opcode() == spv::Op::OpInBoundsAccessChain || + inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain); + + uint32_t pointer_id = inst->GetSingleWordInOperand(0); + Instruction* pointer_inst = get_def_use_mgr()->GetDef(pointer_id); + uint32_t pointer_type_id = pointer_inst->type_id(); + Instruction* pointer_type_inst = get_def_use_mgr()->GetDef(pointer_type_id); + uint32_t type_id = pointer_type_inst->GetSingleWordInOperand(1); + + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + + // For a pointer access chain, we need to skip the |element| index. It is not + // a reference to the member of a struct, and it does not change the type. + uint32_t i = (inst->opcode() == spv::Op::OpAccessChain || + inst->opcode() == spv::Op::OpInBoundsAccessChain + ? 1 + : 2); + for (; i < inst->NumInOperands(); ++i) { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + switch (type_inst->opcode()) { + case spv::Op::OpTypeStruct: { + const analysis::IntConstant* member_idx = + const_mgr->FindDeclaredConstant(inst->GetSingleWordInOperand(i)) + ->AsIntConstant(); + assert(member_idx); + uint32_t index = + static_cast(member_idx->GetZeroExtendedValue()); + used_members_[type_id].insert(index); + type_id = type_inst->GetSingleWordInOperand(index); + } break; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + type_id = type_inst->GetSingleWordInOperand(0); + break; + default: + assert(false); + } + } +} + +void EliminateDeadMembersPass::MarkOperandTypeAsFullyUsed( + const Instruction* inst, uint32_t in_idx) { + uint32_t op_id = inst->GetSingleWordInOperand(in_idx); + Instruction* op_inst = get_def_use_mgr()->GetDef(op_id); + MarkTypeAsFullyUsed(op_inst->type_id()); +} + +void EliminateDeadMembersPass::MarkMembersAsLiveForArrayLength( + const Instruction* inst) { + assert(inst->opcode() == spv::Op::OpArrayLength); + uint32_t object_id = inst->GetSingleWordInOperand(0); + Instruction* object_inst = get_def_use_mgr()->GetDef(object_id); + uint32_t pointer_type_id = object_inst->type_id(); + Instruction* pointer_type_inst = get_def_use_mgr()->GetDef(pointer_type_id); + uint32_t type_id = pointer_type_inst->GetSingleWordInOperand(1); + used_members_[type_id].insert(inst->GetSingleWordInOperand(1)); +} + +bool EliminateDeadMembersPass::RemoveDeadMembers() { + bool modified = false; + + // First update all of the OpTypeStruct instructions. + get_module()->ForEachInst([&modified, this](Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpTypeStruct: + modified |= UpdateOpTypeStruct(inst); + break; + default: + break; + } + }); + + // Now update all of the instructions that reference the OpTypeStructs. + get_module()->ForEachInst([&modified, this](Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpMemberName: + modified |= UpdateOpMemberNameOrDecorate(inst); + break; + case spv::Op::OpMemberDecorate: + modified |= UpdateOpMemberNameOrDecorate(inst); + break; + case spv::Op::OpGroupMemberDecorate: + modified |= UpdateOpGroupMemberDecorate(inst); + break; + case spv::Op::OpSpecConstantComposite: + case spv::Op::OpConstantComposite: + case spv::Op::OpCompositeConstruct: + modified |= UpdateConstantComposite(inst); + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + modified |= UpdateAccessChain(inst); + break; + case spv::Op::OpCompositeExtract: + modified |= UpdateCompsiteExtract(inst); + break; + case spv::Op::OpCompositeInsert: + modified |= UpdateCompositeInsert(inst); + break; + case spv::Op::OpArrayLength: + modified |= UpdateOpArrayLength(inst); + break; + case spv::Op::OpSpecConstantOp: + switch (spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx))) { + case spv::Op::OpCompositeExtract: + modified |= UpdateCompsiteExtract(inst); + break; + case spv::Op::OpCompositeInsert: + modified |= UpdateCompositeInsert(inst); + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + assert(false && "Not implemented yet."); + break; + default: + break; + } + break; + default: + break; + } + }); + return modified; +} + +bool EliminateDeadMembersPass::UpdateOpTypeStruct(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpTypeStruct); + + const auto& live_members = used_members_[inst->result_id()]; + if (live_members.size() == inst->NumInOperands()) { + return false; + } + + Instruction::OperandList new_operands; + for (uint32_t idx : live_members) { + new_operands.emplace_back(inst->GetInOperand(idx)); + } + + inst->SetInOperands(std::move(new_operands)); + context()->UpdateDefUse(inst); + return true; +} + +bool EliminateDeadMembersPass::UpdateOpMemberNameOrDecorate(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpMemberName || + inst->opcode() == spv::Op::OpMemberDecorate); + + uint32_t type_id = inst->GetSingleWordInOperand(0); + auto live_members = used_members_.find(type_id); + if (live_members == used_members_.end()) { + return false; + } + + uint32_t orig_member_idx = inst->GetSingleWordInOperand(1); + uint32_t new_member_idx = GetNewMemberIndex(type_id, orig_member_idx); + + if (new_member_idx == kRemovedMember) { + context()->KillInst(inst); + return true; + } + + if (new_member_idx == orig_member_idx) { + return false; + } + + inst->SetInOperand(1, {new_member_idx}); + return true; +} + +bool EliminateDeadMembersPass::UpdateOpGroupMemberDecorate(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpGroupMemberDecorate); + + bool modified = false; + + Instruction::OperandList new_operands; + new_operands.emplace_back(inst->GetInOperand(0)); + for (uint32_t i = 1; i < inst->NumInOperands(); i += 2) { + uint32_t type_id = inst->GetSingleWordInOperand(i); + uint32_t member_idx = inst->GetSingleWordInOperand(i + 1); + uint32_t new_member_idx = GetNewMemberIndex(type_id, member_idx); + + if (new_member_idx == kRemovedMember) { + modified = true; + continue; + } + + new_operands.emplace_back(inst->GetOperand(i)); + if (new_member_idx != member_idx) { + new_operands.emplace_back( + Operand({SPV_OPERAND_TYPE_LITERAL_INTEGER, {new_member_idx}})); + modified = true; + } else { + new_operands.emplace_back(inst->GetOperand(i + 1)); + } + } + + if (!modified) { + return false; + } + + if (new_operands.size() == 1) { + context()->KillInst(inst); + return true; + } + + inst->SetInOperands(std::move(new_operands)); + context()->UpdateDefUse(inst); + return true; +} + +bool EliminateDeadMembersPass::UpdateConstantComposite(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpSpecConstantComposite || + inst->opcode() == spv::Op::OpConstantComposite || + inst->opcode() == spv::Op::OpCompositeConstruct); + uint32_t type_id = inst->type_id(); + + bool modified = false; + Instruction::OperandList new_operands; + for (uint32_t i = 0; i < inst->NumInOperands(); ++i) { + uint32_t new_idx = GetNewMemberIndex(type_id, i); + if (new_idx == kRemovedMember) { + modified = true; + } else { + new_operands.emplace_back(inst->GetInOperand(i)); + } + } + inst->SetInOperands(std::move(new_operands)); + context()->UpdateDefUse(inst); + return modified; +} + +bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpAccessChain || + inst->opcode() == spv::Op::OpInBoundsAccessChain || + inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain); + + uint32_t pointer_id = inst->GetSingleWordInOperand(0); + Instruction* pointer_inst = get_def_use_mgr()->GetDef(pointer_id); + uint32_t pointer_type_id = pointer_inst->type_id(); + Instruction* pointer_type_inst = get_def_use_mgr()->GetDef(pointer_type_id); + uint32_t type_id = pointer_type_inst->GetSingleWordInOperand(1); + + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + Instruction::OperandList new_operands; + bool modified = false; + new_operands.emplace_back(inst->GetInOperand(0)); + + // For pointer access chains we want to copy the element operand. + if (inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { + new_operands.emplace_back(inst->GetInOperand(1)); + } + + for (uint32_t i = static_cast(new_operands.size()); + i < inst->NumInOperands(); ++i) { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + switch (type_inst->opcode()) { + case spv::Op::OpTypeStruct: { + const analysis::IntConstant* member_idx = + const_mgr->FindDeclaredConstant(inst->GetSingleWordInOperand(i)) + ->AsIntConstant(); + assert(member_idx); + uint32_t orig_member_idx = + static_cast(member_idx->GetZeroExtendedValue()); + uint32_t new_member_idx = GetNewMemberIndex(type_id, orig_member_idx); + assert(new_member_idx != kRemovedMember); + if (orig_member_idx != new_member_idx) { + InstructionBuilder ir_builder( + context(), inst, + IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping); + uint32_t const_id = + ir_builder.GetUintConstant(new_member_idx)->result_id(); + new_operands.emplace_back(Operand({SPV_OPERAND_TYPE_ID, {const_id}})); + modified = true; + } else { + new_operands.emplace_back(inst->GetInOperand(i)); + } + // The type will have already been rewritten, so use the new member + // index. + type_id = type_inst->GetSingleWordInOperand(new_member_idx); + } break; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + new_operands.emplace_back(inst->GetInOperand(i)); + type_id = type_inst->GetSingleWordInOperand(0); + break; + default: + assert(false); + break; + } + } + + if (!modified) { + return false; + } + inst->SetInOperands(std::move(new_operands)); + context()->UpdateDefUse(inst); + return true; +} + +uint32_t EliminateDeadMembersPass::GetNewMemberIndex(uint32_t type_id, + uint32_t member_idx) { + auto live_members = used_members_.find(type_id); + if (live_members == used_members_.end()) { + return member_idx; + } + + auto current_member = live_members->second.find(member_idx); + if (current_member == live_members->second.end()) { + return kRemovedMember; + } + + return static_cast( + std::distance(live_members->second.begin(), current_member)); +} + +bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpCompositeExtract || + (inst->opcode() == spv::Op::OpSpecConstantOp && + spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == + spv::Op::OpCompositeExtract)); + + uint32_t first_operand = 0; + if (inst->opcode() == spv::Op::OpSpecConstantOp) { + first_operand = 1; + } + uint32_t object_id = inst->GetSingleWordInOperand(first_operand); + Instruction* object_inst = get_def_use_mgr()->GetDef(object_id); + uint32_t type_id = object_inst->type_id(); + + Instruction::OperandList new_operands; + bool modified = false; + for (uint32_t i = 0; i < first_operand + 1; i++) { + new_operands.emplace_back(inst->GetInOperand(i)); + } + for (uint32_t i = first_operand + 1; i < inst->NumInOperands(); ++i) { + uint32_t member_idx = inst->GetSingleWordInOperand(i); + uint32_t new_member_idx = GetNewMemberIndex(type_id, member_idx); + assert(new_member_idx != kRemovedMember); + if (member_idx != new_member_idx) { + modified = true; + } + new_operands.emplace_back( + Operand({SPV_OPERAND_TYPE_LITERAL_INTEGER, {new_member_idx}})); + + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + switch (type_inst->opcode()) { + case spv::Op::OpTypeStruct: + // The type will have already been rewritten, so use the new member + // index. + type_id = type_inst->GetSingleWordInOperand(new_member_idx); + break; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + type_id = type_inst->GetSingleWordInOperand(0); + break; + default: + assert(false); + } + } + + if (!modified) { + return false; + } + inst->SetInOperands(std::move(new_operands)); + context()->UpdateDefUse(inst); + return true; +} + +bool EliminateDeadMembersPass::UpdateCompositeInsert(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpCompositeInsert || + (inst->opcode() == spv::Op::OpSpecConstantOp && + spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == + spv::Op::OpCompositeInsert)); + + uint32_t first_operand = 0; + if (inst->opcode() == spv::Op::OpSpecConstantOp) { + first_operand = 1; + } + + uint32_t composite_id = inst->GetSingleWordInOperand(first_operand + 1); + Instruction* composite_inst = get_def_use_mgr()->GetDef(composite_id); + uint32_t type_id = composite_inst->type_id(); + + Instruction::OperandList new_operands; + bool modified = false; + + for (uint32_t i = 0; i < first_operand + 2; ++i) { + new_operands.emplace_back(inst->GetInOperand(i)); + } + for (uint32_t i = first_operand + 2; i < inst->NumInOperands(); ++i) { + uint32_t member_idx = inst->GetSingleWordInOperand(i); + uint32_t new_member_idx = GetNewMemberIndex(type_id, member_idx); + if (new_member_idx == kRemovedMember) { + context()->KillInst(inst); + return true; + } + + if (member_idx != new_member_idx) { + modified = true; + } + new_operands.emplace_back( + Operand({SPV_OPERAND_TYPE_LITERAL_INTEGER, {new_member_idx}})); + + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + switch (type_inst->opcode()) { + case spv::Op::OpTypeStruct: + // The type will have already been rewritten, so use the new member + // index. + type_id = type_inst->GetSingleWordInOperand(new_member_idx); + break; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + type_id = type_inst->GetSingleWordInOperand(0); + break; + default: + assert(false); + } + } + + if (!modified) { + return false; + } + inst->SetInOperands(std::move(new_operands)); + context()->UpdateDefUse(inst); + return true; +} + +bool EliminateDeadMembersPass::UpdateOpArrayLength(Instruction* inst) { + uint32_t struct_id = inst->GetSingleWordInOperand(0); + Instruction* struct_inst = get_def_use_mgr()->GetDef(struct_id); + uint32_t pointer_type_id = struct_inst->type_id(); + Instruction* pointer_type_inst = get_def_use_mgr()->GetDef(pointer_type_id); + uint32_t type_id = pointer_type_inst->GetSingleWordInOperand(1); + + uint32_t member_idx = inst->GetSingleWordInOperand(1); + uint32_t new_member_idx = GetNewMemberIndex(type_id, member_idx); + assert(new_member_idx != kRemovedMember); + + if (member_idx == new_member_idx) { + return false; + } + + inst->SetInOperand(1, {new_member_idx}); + context()->UpdateDefUse(inst); + return true; +} + +void EliminateDeadMembersPass::MarkStructOperandsAsFullyUsed( + const Instruction* inst) { + if (inst->type_id() != 0) { + MarkTypeAsFullyUsed(inst->type_id()); + } + + inst->ForEachInId([this](const uint32_t* id) { + Instruction* instruction = get_def_use_mgr()->GetDef(*id); + if (instruction->type_id() != 0) { + MarkTypeAsFullyUsed(instruction->type_id()); + } + }); +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_members_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_members_pass.h new file mode 100644 index 000000000000..4feaa55f4ff2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_members_pass.h @@ -0,0 +1,146 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ELIMINATE_DEAD_MEMBERS_PASS_H_ +#define SOURCE_OPT_ELIMINATE_DEAD_MEMBERS_PASS_H_ + +#include "source/opt/def_use_manager.h" +#include "source/opt/function.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// Remove unused members from structures. The remaining members will remain at +// the same offset. +class EliminateDeadMembersPass : public MemPass { + public: + const char* name() const override { return "eliminate-dead-members"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | + IRContext::kAnalysisScalarEvolution | + IRContext::kAnalysisRegisterPressure | + IRContext::kAnalysisValueNumberTable | + IRContext::kAnalysisStructuredCFG | + IRContext::kAnalysisBuiltinVarId | + IRContext::kAnalysisIdToFuncMapping; + } + + private: + // Populate |used_members_| with the member of structures that are live in the + // current context. + void FindLiveMembers(); + + // Add to |used_members_| the member of structures that are live in + // |function|. + void FindLiveMembers(const Function& function); + // Add to |used_members_| the member of structures that are live in |inst|. + void FindLiveMembers(const Instruction* inst); + + // Add to |used_members_| the members that are live in the |OpStore| + // instruction |inst|. + void MarkMembersAsLiveForStore(const Instruction* inst); + + // Add to |used_members_| the members that are live in the |OpCopyMemory*| + // instruction |inst|. + void MarkMembersAsLiveForCopyMemory(const Instruction* inst); + + // Add to |used_members_| the members that are live in the + // |OpCompositeExtract| instruction |inst|. + void MarkMembersAsLiveForExtract(const Instruction* inst); + + // Add to |used_members_| the members that are live in the |Op*AccessChain| + // instruction |inst|. + void MarkMembersAsLiveForAccessChain(const Instruction* inst); + + // Add the member referenced by the OpArrayLength instruction |inst| to + // |uses_members_|. + void MarkMembersAsLiveForArrayLength(const Instruction* inst); + + // Remove dead members from structs and updates any instructions that need to + // be updated as a consequence. Return true if something changed. + bool RemoveDeadMembers(); + + // Update |inst|, which must be an |OpMemberName| or |OpMemberDecorate| + // instruction, so it references the correct member after the struct is + // updated. Return true if something changed. + bool UpdateOpMemberNameOrDecorate(Instruction* inst); + + // Update |inst|, which must be an |OpGroupMemberDecorate| instruction, so it + // references the correct member after the struct is updated. Return true if + // something changed. + bool UpdateOpGroupMemberDecorate(Instruction* inst); + + // Update the |OpTypeStruct| instruction |inst| my removing the members that + // are not live. Return true if something changed. + bool UpdateOpTypeStruct(Instruction* inst); + + // Update the |OpConstantComposite| instruction |inst| to match the change + // made to the type that was being generated. Return true if something + // changed. + bool UpdateConstantComposite(Instruction* inst); + + // Update the |Op*AccessChain| instruction |inst| to reference the correct + // members. All members referenced in the access chain must be live. This + // function must be called after the |OpTypeStruct| instruction for the type + // has been updated. Return true if something changed. + bool UpdateAccessChain(Instruction* inst); + + // Update the |OpCompositeExtract| instruction |inst| to reference the correct + // members. All members referenced in the instruction must be live. This + // function must be called after the |OpTypeStruct| instruction for the type + // has been updated. Return true if something changed. + bool UpdateCompsiteExtract(Instruction* inst); + + // Update the |OpCompositeInsert| instruction |inst| to reference the correct + // members. If the member being inserted is not live, then |inst| is killed. + // This function must be called after the |OpTypeStruct| instruction for the + // type has been updated. Return true if something changed. + bool UpdateCompositeInsert(Instruction* inst); + + // Update the |OpArrayLength| instruction |inst| to reference the correct + // member. The member referenced in the instruction must be live. Return true + // if something changed. + bool UpdateOpArrayLength(Instruction* inst); + + // Add all of the members of type |type_id| and members of any subtypes to + // |used_members_|. + void MarkTypeAsFullyUsed(uint32_t type_id); + + // Add all of the members of the type of the operand |in_idx| in |inst| and + // members of any subtypes to |uses_members_|. + void MarkOperandTypeAsFullyUsed(const Instruction* inst, uint32_t in_idx); + + // Return the index of the member that use to be the |member_idx|th member of + // |type_id|. If the member has been removed, |kRemovedMember| is returned. + uint32_t GetNewMemberIndex(uint32_t type_id, uint32_t member_idx); + + // A map from a type id to a set of indices representing the members of the + // type that are used, and must be kept. + std::unordered_map> used_members_; + void MarkStructOperandsAsFullyUsed(const Instruction* inst); + void MarkPointeeTypeAsFullUsed(uint32_t ptr_type_id); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ELIMINATE_DEAD_MEMBERS_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp new file mode 100644 index 000000000000..99711a16e819 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp @@ -0,0 +1,237 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/eliminate_dead_output_stores_pass.h" + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kDecorationLocationInIdx = 2; +constexpr uint32_t kOpDecorateMemberMemberInIdx = 1; +constexpr uint32_t kOpDecorateBuiltInLiteralInIdx = 2; +constexpr uint32_t kOpDecorateMemberBuiltInLiteralInIdx = 3; +constexpr uint32_t kOpAccessChainIdx0InIdx = 1; +constexpr uint32_t kOpConstantValueInIdx = 0; +} // namespace + +Pass::Status EliminateDeadOutputStoresPass::Process() { + // Current functionality assumes shader capability + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return Status::SuccessWithoutChange; + Pass::Status status = DoDeadOutputStoreElimination(); + return status; +} + +void EliminateDeadOutputStoresPass::InitializeElimination() { + kill_list_.clear(); +} + +bool EliminateDeadOutputStoresPass::IsLiveBuiltin(uint32_t bi) { + return live_builtins_->find(bi) != live_builtins_->end(); +} + +bool EliminateDeadOutputStoresPass::AnyLocsAreLive(uint32_t start, + uint32_t count) { + auto finish = start + count; + for (uint32_t u = start; u < finish; ++u) { + if (live_locs_->find(u) != live_locs_->end()) return true; + } + return false; +} + +void EliminateDeadOutputStoresPass::KillAllStoresOfRef(Instruction* ref) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + if (ref->opcode() == spv::Op::OpStore) { + kill_list_.push_back(ref); + return; + } + assert((ref->opcode() == spv::Op::OpAccessChain || + ref->opcode() == spv::Op::OpInBoundsAccessChain) && + "unexpected use of output variable"); + def_use_mgr->ForEachUser(ref, [this](Instruction* user) { + if (user->opcode() == spv::Op::OpStore) kill_list_.push_back(user); + }); +} + +void EliminateDeadOutputStoresPass::KillAllDeadStoresOfLocRef( + Instruction* ref, Instruction* var) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + analysis::LivenessManager* live_mgr = context()->get_liveness_mgr(); + // Find variable location if present. + uint32_t start_loc = 0; + auto var_id = var->result_id(); + bool no_loc = deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::Location), + [&start_loc](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); + start_loc = deco.GetSingleWordInOperand(kDecorationLocationInIdx); + return false; + }); + // Find patch decoration if present + bool is_patch = !deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::Patch), [](const Instruction& deco) { + if (deco.opcode() != spv::Op::OpDecorate) + assert(false && "unexpected decoration"); + return false; + }); + // Compute offset and final type of reference. If no location found + // or any stored locations are live, return without removing stores. + auto ptr_type = type_mgr->GetType(var->type_id())->AsPointer(); + assert(ptr_type && "unexpected var type"); + auto var_type = ptr_type->pointee_type(); + uint32_t ref_loc = start_loc; + auto curr_type = var_type; + if (ref->opcode() == spv::Op::OpAccessChain || + ref->opcode() == spv::Op::OpInBoundsAccessChain) { + live_mgr->AnalyzeAccessChainLoc(ref, &curr_type, &ref_loc, &no_loc, + is_patch, /* input */ false); + } + if (no_loc || AnyLocsAreLive(ref_loc, live_mgr->GetLocSize(curr_type))) + return; + // Kill all stores based on this reference + KillAllStoresOfRef(ref); +} + +void EliminateDeadOutputStoresPass::KillAllDeadStoresOfBuiltinRef( + Instruction* ref, Instruction* var) { + auto deco_mgr = context()->get_decoration_mgr(); + auto def_use_mgr = context()->get_def_use_mgr(); + auto type_mgr = context()->get_type_mgr(); + auto live_mgr = context()->get_liveness_mgr(); + // Search for builtin decoration of base variable + uint32_t builtin = uint32_t(spv::BuiltIn::Max); + auto var_id = var->result_id(); + (void)deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::BuiltIn), + [&builtin](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); + builtin = deco.GetSingleWordInOperand(kOpDecorateBuiltInLiteralInIdx); + return false; + }); + // If analyzed builtin and not live, kill stores. + if (builtin != uint32_t(spv::BuiltIn::Max)) { + if (live_mgr->IsAnalyzedBuiltin(builtin) && !IsLiveBuiltin(builtin)) + KillAllStoresOfRef(ref); + return; + } + // Search for builtin decoration on indexed member + auto ref_op = ref->opcode(); + if (ref_op != spv::Op::OpAccessChain && + ref_op != spv::Op::OpInBoundsAccessChain) { + return; + } + uint32_t in_idx = kOpAccessChainIdx0InIdx; + analysis::Type* var_type = type_mgr->GetType(var->type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + auto curr_type = ptr_type->pointee_type(); + auto arr_type = curr_type->AsArray(); + if (arr_type) { + curr_type = arr_type->element_type(); + ++in_idx; + } + auto str_type = curr_type->AsStruct(); + auto str_type_id = type_mgr->GetId(str_type); + auto member_idx_id = ref->GetSingleWordInOperand(in_idx); + auto member_idx_inst = def_use_mgr->GetDef(member_idx_id); + assert(member_idx_inst->opcode() == spv::Op::OpConstant && + "unexpected non-constant index"); + auto ac_idx = member_idx_inst->GetSingleWordInOperand(kOpConstantValueInIdx); + (void)deco_mgr->WhileEachDecoration( + str_type_id, uint32_t(spv::Decoration::BuiltIn), + [ac_idx, &builtin](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpMemberDecorate && + "unexpected decoration"); + auto deco_idx = + deco.GetSingleWordInOperand(kOpDecorateMemberMemberInIdx); + if (deco_idx == ac_idx) { + builtin = + deco.GetSingleWordInOperand(kOpDecorateMemberBuiltInLiteralInIdx); + return false; + } + return true; + }); + assert(builtin != uint32_t(spv::BuiltIn::Max) && "builtin not found"); + // If analyzed builtin and not live, kill stores. + if (live_mgr->IsAnalyzedBuiltin(builtin) && !IsLiveBuiltin(builtin)) + KillAllStoresOfRef(ref); +} + +Pass::Status EliminateDeadOutputStoresPass::DoDeadOutputStoreElimination() { + // Current implementation only supports vert, tesc, tese, geom shaders + auto stage = context()->GetStage(); + if (stage != spv::ExecutionModel::Vertex && + stage != spv::ExecutionModel::TessellationControl && + stage != spv::ExecutionModel::TessellationEvaluation && + stage != spv::ExecutionModel::Geometry) + return Status::Failure; + InitializeElimination(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + // Process all output variables + for (auto& var : context()->types_values()) { + if (var.opcode() != spv::Op::OpVariable) { + continue; + } + analysis::Type* var_type = type_mgr->GetType(var.type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + if (ptr_type->storage_class() != spv::StorageClass::Output) { + continue; + } + // If builtin decoration on variable, process as builtin. + auto var_id = var.result_id(); + bool is_builtin = false; + if (deco_mgr->HasDecoration(var_id, uint32_t(spv::Decoration::BuiltIn))) { + is_builtin = true; + } else { + // If interface block with builtin members, process as builtin. + // Strip off outer array type if present. + auto curr_type = ptr_type->pointee_type(); + auto arr_type = curr_type->AsArray(); + if (arr_type) curr_type = arr_type->element_type(); + auto str_type = curr_type->AsStruct(); + if (str_type) { + auto str_type_id = type_mgr->GetId(str_type); + if (deco_mgr->HasDecoration(str_type_id, + uint32_t(spv::Decoration::BuiltIn))) + is_builtin = true; + } + } + // For each store or access chain using var, if dead builtin or all its + // locations are dead, kill store or all access chain's stores + def_use_mgr->ForEachUser( + var_id, [this, &var, is_builtin](Instruction* user) { + auto op = user->opcode(); + if (op == spv::Op::OpEntryPoint || op == spv::Op::OpName || + op == spv::Op::OpDecorate || user->IsNonSemanticInstruction()) + return; + if (is_builtin) + KillAllDeadStoresOfBuiltinRef(user, &var); + else + KillAllDeadStoresOfLocRef(user, &var); + }); + } + for (auto& kinst : kill_list_) context()->KillInst(kinst); + + return kill_list_.empty() ? Status::SuccessWithoutChange + : Status::SuccessWithChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_output_stores_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_output_stores_pass.h new file mode 100644 index 000000000000..676d4f4f0008 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/eliminate_dead_output_stores_pass.h @@ -0,0 +1,81 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ +#define SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class EliminateDeadOutputStoresPass : public Pass { + public: + explicit EliminateDeadOutputStoresPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins) + : live_locs_(live_locs), live_builtins_(live_builtins) {} + + const char* name() const override { return "eliminate-dead-output-stores"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Initialize elimination + void InitializeElimination(); + + // Do dead output store analysis + Status DoDeadOutputStoreElimination(); + + // Kill all stores resulting from |ref|. + void KillAllStoresOfRef(Instruction* ref); + + // Kill all dead stores resulting from |user| of loc-based |var|. + void KillAllDeadStoresOfLocRef(Instruction* user, Instruction* var); + + // Kill all dead stores resulting from |user| of builtin |var|. + void KillAllDeadStoresOfBuiltinRef(Instruction* user, Instruction* var); + + // Return true if any of |count| locations starting at location |start| are + // live. + bool AnyLocsAreLive(uint32_t start, uint32_t count); + + // Return true if builtin |bi| is live. + bool IsLiveBuiltin(uint32_t bi); + + std::unordered_set* live_locs_; + std::unordered_set* live_builtins_; + + std::vector kill_list_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/empty_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/empty_pass.h new file mode 100644 index 000000000000..1fd2ae59b576 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/empty_pass.h @@ -0,0 +1,36 @@ +// Copyright (c) 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_EMPTY_PASS_H_ +#define SOURCE_OPT_EMPTY_PASS_H_ + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// Documented in optimizer.hpp +class EmptyPass : public Pass { + public: + EmptyPass() {} + + const char* name() const override { return "empty-pass"; } + + Status Process() override { return Status::SuccessWithoutChange; } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_EMPTY_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/feature_manager.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/feature_manager.cpp new file mode 100644 index 000000000000..51883706aa20 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/feature_manager.cpp @@ -0,0 +1,119 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/feature_manager.h" + +#include + +#include "source/enum_string_mapping.h" + +namespace spvtools { +namespace opt { + +void FeatureManager::Analyze(Module* module) { + AddExtensions(module); + AddCapabilities(module); + AddExtInstImportIds(module); +} + +void FeatureManager::AddExtensions(Module* module) { + for (auto ext : module->extensions()) { + AddExtension(&ext); + } +} + +void FeatureManager::AddExtension(Instruction* ext) { + assert(ext->opcode() == spv::Op::OpExtension && + "Expecting an extension instruction."); + + const std::string name = ext->GetInOperand(0u).AsString(); + Extension extension; + if (GetExtensionFromString(name.c_str(), &extension)) { + extensions_.insert(extension); + } +} + +void FeatureManager::RemoveExtension(Extension ext) { + if (!extensions_.contains(ext)) return; + extensions_.erase(ext); +} + +void FeatureManager::AddCapability(spv::Capability cap) { + if (capabilities_.contains(cap)) return; + + capabilities_.insert(cap); + + spv_operand_desc desc = {}; + if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, + uint32_t(cap), &desc)) { + for (auto capability : + CapabilitySet(desc->numCapabilities, desc->capabilities)) { + AddCapability(capability); + } + } +} + +void FeatureManager::RemoveCapability(spv::Capability cap) { + if (!capabilities_.contains(cap)) return; + capabilities_.erase(cap); +} + +void FeatureManager::AddCapabilities(Module* module) { + for (Instruction& inst : module->capabilities()) { + AddCapability(static_cast(inst.GetSingleWordInOperand(0))); + } +} + +void FeatureManager::AddExtInstImportIds(Module* module) { + extinst_importid_GLSLstd450_ = module->GetExtInstImportId("GLSL.std.450"); + extinst_importid_OpenCL100DebugInfo_ = + module->GetExtInstImportId("OpenCL.DebugInfo.100"); + extinst_importid_Shader100DebugInfo_ = + module->GetExtInstImportId("NonSemantic.Shader.DebugInfo.100"); +} + +bool operator==(const FeatureManager& a, const FeatureManager& b) { + // We check that the addresses of the grammars are the same because they + // are large objects, and this is faster. It can be changed if needed as a + // later time. + if (&a.grammar_ != &b.grammar_) { + return false; + } + + if (a.capabilities_ != b.capabilities_) { + return false; + } + + if (a.extensions_ != b.extensions_) { + return false; + } + + if (a.extinst_importid_GLSLstd450_ != b.extinst_importid_GLSLstd450_) { + return false; + } + + if (a.extinst_importid_OpenCL100DebugInfo_ != + b.extinst_importid_OpenCL100DebugInfo_) { + return false; + } + + if (a.extinst_importid_Shader100DebugInfo_ != + b.extinst_importid_Shader100DebugInfo_) { + return false; + } + + return true; +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/feature_manager.h b/thirdparty/glslang/External/spirv-tools/source/opt/feature_manager.h new file mode 100644 index 000000000000..d150a2fa2b21 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/feature_manager.h @@ -0,0 +1,113 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_FEATURE_MANAGER_H_ +#define SOURCE_OPT_FEATURE_MANAGER_H_ + +#include "source/assembly_grammar.h" +#include "source/extensions.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// Tracks features enabled by a module. The IRContext has a FeatureManager. +class FeatureManager { + public: + // Returns true if |ext| is an enabled extension in the module. + bool HasExtension(Extension ext) const { return extensions_.contains(ext); } + + // Returns true if |cap| is an enabled capability in the module. + bool HasCapability(spv::Capability cap) const { + return capabilities_.contains(cap); + } + + // Returns the capabilities the module declares. + inline const CapabilitySet& GetCapabilities() const { return capabilities_; } + + // Returns the extensions the module imports. + inline const ExtensionSet& GetExtensions() const { return extensions_; } + + uint32_t GetExtInstImportId_GLSLstd450() const { + return extinst_importid_GLSLstd450_; + } + + uint32_t GetExtInstImportId_OpenCL100DebugInfo() const { + return extinst_importid_OpenCL100DebugInfo_; + } + + uint32_t GetExtInstImportId_Shader100DebugInfo() const { + return extinst_importid_Shader100DebugInfo_; + } + + friend bool operator==(const FeatureManager& a, const FeatureManager& b); + friend bool operator!=(const FeatureManager& a, const FeatureManager& b) { + return !(a == b); + } + + private: + explicit FeatureManager(const AssemblyGrammar& grammar) : grammar_(grammar) {} + + // Analyzes |module| and records enabled extensions and capabilities. + void Analyze(Module* module); + + // Add the extension |ext| to the feature manager. + void AddExtension(Instruction* ext); + + // Analyzes |module| and records enabled extensions. + void AddExtensions(Module* module); + + // Removes the given |extension| from the current FeatureManager. + void RemoveExtension(Extension extension); + + // Adds the given |capability| and all implied capabilities into the current + // FeatureManager. + void AddCapability(spv::Capability capability); + + // Analyzes |module| and records enabled capabilities. + void AddCapabilities(Module* module); + + // Removes the given |capability| from the current FeatureManager. + void RemoveCapability(spv::Capability capability); + + // Analyzes |module| and records imported external instruction sets. + void AddExtInstImportIds(Module* module); + + // Auxiliary object for querying SPIR-V grammar facts. + const AssemblyGrammar& grammar_; + + // The enabled extensions. + ExtensionSet extensions_; + + // The enabled capabilities. + CapabilitySet capabilities_; + + // Common external instruction import ids, cached for performance. + uint32_t extinst_importid_GLSLstd450_ = 0; + + // Common OpenCL100DebugInfo external instruction import ids, cached + // for performance. + uint32_t extinst_importid_OpenCL100DebugInfo_ = 0; + + // Common NonSemanticShader100DebugInfo external instruction import ids, + // cached for performance. + uint32_t extinst_importid_Shader100DebugInfo_ = 0; + + friend class IRContext; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_FEATURE_MANAGER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/fix_func_call_arguments.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/fix_func_call_arguments.cpp new file mode 100644 index 000000000000..f3486bed3151 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/fix_func_call_arguments.cpp @@ -0,0 +1,91 @@ +// Copyright (c) 2022 Advanced Micro Devices, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "fix_func_call_arguments.h" + +#include "ir_builder.h" + +using namespace spvtools; +using namespace opt; + +bool FixFuncCallArgumentsPass::ModuleHasASingleFunction() { + auto funcsNum = get_module()->end() - get_module()->begin(); + return funcsNum == 1; +} + +Pass::Status FixFuncCallArgumentsPass::Process() { + bool modified = false; + if (ModuleHasASingleFunction()) return Status::SuccessWithoutChange; + for (auto& func : *get_module()) { + func.ForEachInst([this, &modified](Instruction* inst) { + if (inst->opcode() == spv::Op::OpFunctionCall) { + modified |= FixFuncCallArguments(inst); + } + }); + } + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool FixFuncCallArgumentsPass::FixFuncCallArguments( + Instruction* func_call_inst) { + bool modified = false; + for (uint32_t i = 0; i < func_call_inst->NumInOperands(); ++i) { + Operand& op = func_call_inst->GetInOperand(i); + if (op.type != SPV_OPERAND_TYPE_ID) continue; + Instruction* operand_inst = get_def_use_mgr()->GetDef(op.AsId()); + if (operand_inst->opcode() == spv::Op::OpAccessChain) { + uint32_t var_id = + ReplaceAccessChainFuncCallArguments(func_call_inst, operand_inst); + func_call_inst->SetInOperand(i, {var_id}); + modified = true; + } + } + if (modified) { + context()->UpdateDefUse(func_call_inst); + } + return modified; +} + +uint32_t FixFuncCallArgumentsPass::ReplaceAccessChainFuncCallArguments( + Instruction* func_call_inst, Instruction* operand_inst) { + InstructionBuilder builder( + context(), func_call_inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + Instruction* next_insert_point = func_call_inst->NextNode(); + // Get Variable insertion point + Function* func = context()->get_instr_block(func_call_inst)->GetParent(); + Instruction* variable_insertion_point = &*(func->begin()->begin()); + Instruction* op_ptr_type = get_def_use_mgr()->GetDef(operand_inst->type_id()); + Instruction* op_type = + get_def_use_mgr()->GetDef(op_ptr_type->GetSingleWordInOperand(1)); + uint32_t varType = context()->get_type_mgr()->FindPointerToType( + op_type->result_id(), spv::StorageClass::Function); + // Create new variable + builder.SetInsertPoint(variable_insertion_point); + Instruction* var = + builder.AddVariable(varType, uint32_t(spv::StorageClass::Function)); + // Load access chain to the new variable before function call + builder.SetInsertPoint(func_call_inst); + + uint32_t operand_id = operand_inst->result_id(); + Instruction* load = builder.AddLoad(op_type->result_id(), operand_id); + builder.AddStore(var->result_id(), load->result_id()); + // Load return value to the acesschain after function call + builder.SetInsertPoint(next_insert_point); + load = builder.AddLoad(op_type->result_id(), var->result_id()); + builder.AddStore(operand_id, load->result_id()); + + return var->result_id(); +} diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/fix_func_call_arguments.h b/thirdparty/glslang/External/spirv-tools/source/opt/fix_func_call_arguments.h new file mode 100644 index 000000000000..15781b8c6b5d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/fix_func_call_arguments.h @@ -0,0 +1,47 @@ +// Copyright (c) 2022 Advanced Micro Devices, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _VAR_FUNC_CALL_PASS_H +#define _VAR_FUNC_CALL_PASS_H + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { +class FixFuncCallArgumentsPass : public Pass { + public: + FixFuncCallArgumentsPass() {} + const char* name() const override { return "fix-for-funcall-param"; } + Status Process() override; + // Returns true if the module has one one function. + bool ModuleHasASingleFunction(); + // Copies from the memory pointed to by |operand_inst| to a new function scope + // variable created before |func_call_inst|, and + // copies the value of the new variable back to the memory pointed to by + // |operand_inst| after |funct_call_inst| Returns the id of + // the new variable. + uint32_t ReplaceAccessChainFuncCallArguments(Instruction* func_call_inst, + Instruction* operand_inst); + + // Fix function call |func_call_inst| non memory object arguments + bool FixFuncCallArguments(Instruction* func_call_inst); + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisTypes; + } +}; +} // namespace opt +} // namespace spvtools + +#endif // _VAR_FUNC_CALL_PASS_H \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/fix_storage_class.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/fix_storage_class.cpp new file mode 100644 index 000000000000..564cd1b8a3e4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/fix_storage_class.cpp @@ -0,0 +1,346 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "fix_storage_class.h" + +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +Pass::Status FixStorageClass::Process() { + bool modified = false; + + get_module()->ForEachInst([this, &modified](Instruction* inst) { + if (inst->opcode() == spv::Op::OpVariable) { + std::set seen; + std::vector> uses; + get_def_use_mgr()->ForEachUse(inst, + [&uses](Instruction* use, uint32_t op_idx) { + uses.push_back({use, op_idx}); + }); + + for (auto& use : uses) { + modified |= PropagateStorageClass( + use.first, + static_cast(inst->GetSingleWordInOperand(0)), + &seen); + assert(seen.empty() && "Seen was not properly reset."); + modified |= + PropagateType(use.first, inst->type_id(), use.second, &seen); + assert(seen.empty() && "Seen was not properly reset."); + } + } + }); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool FixStorageClass::PropagateStorageClass(Instruction* inst, + spv::StorageClass storage_class, + std::set* seen) { + if (!IsPointerResultType(inst)) { + return false; + } + + if (IsPointerToStorageClass(inst, storage_class)) { + if (inst->opcode() == spv::Op::OpPhi) { + if (!seen->insert(inst->result_id()).second) { + return false; + } + } + + bool modified = false; + std::vector uses; + get_def_use_mgr()->ForEachUser( + inst, [&uses](Instruction* use) { uses.push_back(use); }); + for (Instruction* use : uses) { + modified |= PropagateStorageClass(use, storage_class, seen); + } + + if (inst->opcode() == spv::Op::OpPhi) { + seen->erase(inst->result_id()); + } + return modified; + } + + switch (inst->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpCopyObject: + case spv::Op::OpPhi: + case spv::Op::OpSelect: + FixInstructionStorageClass(inst, storage_class, seen); + return true; + case spv::Op::OpFunctionCall: + // We cannot be sure of the actual connection between the storage class + // of the parameter and the storage class of the result, so we should not + // do anything. If the result type needs to be fixed, the function call + // should be inlined. + return false; + case spv::Op::OpImageTexelPointer: + case spv::Op::OpLoad: + case spv::Op::OpStore: + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + case spv::Op::OpVariable: + case spv::Op::OpBitcast: + // Nothing to change for these opcode. The result type is the same + // regardless of the storage class of the operand. + return false; + default: + assert(false && + "Not expecting instruction to have a pointer result type."); + return false; + } +} + +void FixStorageClass::FixInstructionStorageClass( + Instruction* inst, spv::StorageClass storage_class, + std::set* seen) { + assert(IsPointerResultType(inst) && + "The result type of the instruction must be a pointer."); + + ChangeResultStorageClass(inst, storage_class); + + std::vector uses; + get_def_use_mgr()->ForEachUser( + inst, [&uses](Instruction* use) { uses.push_back(use); }); + for (Instruction* use : uses) { + PropagateStorageClass(use, storage_class, seen); + } +} + +void FixStorageClass::ChangeResultStorageClass( + Instruction* inst, spv::StorageClass storage_class) const { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + Instruction* result_type_inst = get_def_use_mgr()->GetDef(inst->type_id()); + assert(result_type_inst->opcode() == spv::Op::OpTypePointer); + uint32_t pointee_type_id = result_type_inst->GetSingleWordInOperand(1); + uint32_t new_result_type_id = + type_mgr->FindPointerToType(pointee_type_id, storage_class); + inst->SetResultType(new_result_type_id); + context()->UpdateDefUse(inst); +} + +bool FixStorageClass::IsPointerResultType(Instruction* inst) { + if (inst->type_id() == 0) { + return false; + } + const analysis::Type* ret_type = + context()->get_type_mgr()->GetType(inst->type_id()); + return ret_type->AsPointer() != nullptr; +} + +bool FixStorageClass::IsPointerToStorageClass(Instruction* inst, + spv::StorageClass storage_class) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Type* pType = type_mgr->GetType(inst->type_id()); + const analysis::Pointer* result_type = pType->AsPointer(); + + if (result_type == nullptr) { + return false; + } + + return (result_type->storage_class() == storage_class); +} + +bool FixStorageClass::ChangeResultType(Instruction* inst, + uint32_t new_type_id) { + if (inst->type_id() == new_type_id) { + return false; + } + + context()->ForgetUses(inst); + inst->SetResultType(new_type_id); + context()->AnalyzeUses(inst); + return true; +} + +bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, + uint32_t op_idx, std::set* seen) { + assert(type_id != 0 && "Not given a valid type in PropagateType"); + bool modified = false; + + // If the type of operand |op_idx| forces the result type of |inst| to a + // particular type, then we want find that type. + uint32_t new_type_id = 0; + switch (inst->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + if (op_idx == 2) { + new_type_id = WalkAccessChainType(inst, type_id); + } + break; + case spv::Op::OpCopyObject: + new_type_id = type_id; + break; + case spv::Op::OpPhi: + if (seen->insert(inst->result_id()).second) { + new_type_id = type_id; + } + break; + case spv::Op::OpSelect: + if (op_idx > 2) { + new_type_id = type_id; + } + break; + case spv::Op::OpFunctionCall: + // We cannot be sure of the actual connection between the type + // of the parameter and the type of the result, so we should not + // do anything. If the result type needs to be fixed, the function call + // should be inlined. + return false; + case spv::Op::OpLoad: { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + new_type_id = type_inst->GetSingleWordInOperand(1); + break; + } + case spv::Op::OpStore: { + uint32_t obj_id = inst->GetSingleWordInOperand(1); + Instruction* obj_inst = get_def_use_mgr()->GetDef(obj_id); + uint32_t obj_type_id = obj_inst->type_id(); + + uint32_t ptr_id = inst->GetSingleWordInOperand(0); + Instruction* ptr_inst = get_def_use_mgr()->GetDef(ptr_id); + uint32_t pointee_type_id = GetPointeeTypeId(ptr_inst); + + if (obj_type_id != pointee_type_id) { + if (context()->get_type_mgr()->GetType(obj_type_id)->AsImage() && + context()->get_type_mgr()->GetType(pointee_type_id)->AsImage()) { + // When storing an image, allow the type mismatch + // and let the later legalization passes eliminate the OpStore. + // This is to support assigning an image to a variable, + // where the assigned image does not have a pre-defined + // image format. + return false; + } + + uint32_t copy_id = GenerateCopy(obj_inst, pointee_type_id, inst); + inst->SetInOperand(1, {copy_id}); + context()->UpdateDefUse(inst); + } + } break; + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + // TODO: May need to expand the copy as we do with the stores. + break; + case spv::Op::OpCompositeConstruct: + case spv::Op::OpCompositeExtract: + case spv::Op::OpCompositeInsert: + // TODO: DXC does not seem to generate code that will require changes to + // these opcode. The can be implemented when they come up. + break; + case spv::Op::OpImageTexelPointer: + case spv::Op::OpBitcast: + // Nothing to change for these opcode. The result type is the same + // regardless of the type of the operand. + return false; + default: + // I expect the remaining instructions to act on types that are guaranteed + // to be unique, so no change will be necessary. + break; + } + + // If the operand forces the result type, then make sure the result type + // matches, and update the uses of |inst|. We do not have to check the uses + // of |inst| in the result type is not forced because we are only looking for + // issue that come from mismatches between function formal and actual + // parameters after the function has been inlined. These parameters are + // pointers. Once the type no longer depends on the type of the parameter, + // then the types should have be correct. + if (new_type_id != 0) { + modified = ChangeResultType(inst, new_type_id); + + std::vector> uses; + get_def_use_mgr()->ForEachUse(inst, + [&uses](Instruction* use, uint32_t idx) { + uses.push_back({use, idx}); + }); + + for (auto& use : uses) { + PropagateType(use.first, new_type_id, use.second, seen); + } + + if (inst->opcode() == spv::Op::OpPhi) { + seen->erase(inst->result_id()); + } + } + return modified; +} + +uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) { + uint32_t start_idx = 0; + switch (inst->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + start_idx = 1; + break; + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + start_idx = 2; + break; + default: + assert(false); + break; + } + + Instruction* orig_type_inst = get_def_use_mgr()->GetDef(id); + assert(orig_type_inst->opcode() == spv::Op::OpTypePointer); + id = orig_type_inst->GetSingleWordInOperand(1); + + for (uint32_t i = start_idx; i < inst->NumInOperands(); ++i) { + Instruction* type_inst = get_def_use_mgr()->GetDef(id); + switch (type_inst->opcode()) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: + id = type_inst->GetSingleWordInOperand(0); + break; + case spv::Op::OpTypeStruct: { + const analysis::Constant* index_const = + context()->get_constant_mgr()->FindDeclaredConstant( + inst->GetSingleWordInOperand(i)); + // It is highly unlikely that any type would have more fields than could + // be indexed by a 32-bit integer, and GetSingleWordInOperand only takes + // a 32-bit value, so we would not be able to handle it anyway. But the + // specification does allow any scalar integer type, treated as signed, + // so we simply downcast the index to 32-bits. + uint32_t index = + static_cast(index_const->GetSignExtendedValue()); + id = type_inst->GetSingleWordInOperand(index); + break; + } + default: + break; + } + assert(id != 0 && + "Tried to extract from an object where it cannot be done."); + } + + return context()->get_type_mgr()->FindPointerToType( + id, static_cast( + orig_type_inst->GetSingleWordInOperand(0))); +} + +// namespace opt + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/fix_storage_class.h b/thirdparty/glslang/External/spirv-tools/source/opt/fix_storage_class.h new file mode 100644 index 000000000000..6c67acd37a8a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/fix_storage_class.h @@ -0,0 +1,93 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_FIX_STORAGE_CLASS_H_ +#define SOURCE_OPT_FIX_STORAGE_CLASS_H_ + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// This pass tries to fix validation error due to a mismatch of storage classes +// in instructions. There is no guarantee that all such error will be fixed, +// and it is possible that in fixing these errors, it could lead to other +// errors. +class FixStorageClass : public Pass { + public: + const char* name() const override { return "fix-storage-class"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Changes the storage class of the result of |inst| to |storage_class| in + // appropriate, and propagates the change to the users of |inst| as well. + // Returns true of any changes were made. + // |seen| is used to track OpPhi instructions that should not be processed. + bool PropagateStorageClass(Instruction* inst, spv::StorageClass storage_class, + std::set* seen); + + // Changes the storage class of the result of |inst| to |storage_class|. + // Is it assumed that the result type of |inst| is a pointer type. + // Propagates the change to the users of |inst| as well. + // Returns true of any changes were made. + // |seen| is used to track OpPhi instructions that should not be processed by + // |PropagateStorageClass| + void FixInstructionStorageClass(Instruction* inst, + spv::StorageClass storage_class, + std::set* seen); + + // Changes the storage class of the result of |inst| to |storage_class|. The + // result type of |inst| must be a pointer. + void ChangeResultStorageClass(Instruction* inst, + spv::StorageClass storage_class) const; + + // Returns true if the result type of |inst| is a pointer. + bool IsPointerResultType(Instruction* inst); + + // Returns true if the result of |inst| is a pointer to storage class + // |storage_class|. + bool IsPointerToStorageClass(Instruction* inst, + spv::StorageClass storage_class); + + // Change |inst| to match that operand |op_idx| now has type |type_id|, and + // adjust any uses of |inst| accordingly. Returns true if the code changed. + bool PropagateType(Instruction* inst, uint32_t type_id, uint32_t op_idx, + std::set* seen); + + // Changes the result type of |inst| to |new_type_id|. + bool ChangeResultType(Instruction* inst, uint32_t new_type_id); + + // Returns the type id of the member of the type |id| that would be returned + // by following the indices of the access chain instruction |inst|. + uint32_t WalkAccessChainType(Instruction* inst, uint32_t id); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_FIX_STORAGE_CLASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/flatten_decoration_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/flatten_decoration_pass.cpp new file mode 100644 index 000000000000..c878c097e852 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/flatten_decoration_pass.cpp @@ -0,0 +1,165 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/flatten_decoration_pass.h" + +#include +#include +#include +#include +#include +#include + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +using Words = std::vector; +using OrderedUsesMap = std::unordered_map; + +Pass::Status FlattenDecorationPass::Process() { + bool modified = false; + + // The target Id of OpDecorationGroup instructions. + // We have to track this separately from its uses, in case it + // has no uses. + std::unordered_set group_ids; + // Maps a decoration group Id to its GroupDecorate targets, in order + // of appearance. + OrderedUsesMap normal_uses; + // Maps a decoration group Id to its GroupMemberDecorate targets and + // their indices, in of appearance. + OrderedUsesMap member_uses; + + auto annotations = context()->annotations(); + + // On the first pass, record each OpDecorationGroup with its ordered uses. + // Rely on unordered_map::operator[] to create its entries on first access. + for (const auto& inst : annotations) { + switch (inst.opcode()) { + case spv::Op::OpDecorationGroup: + group_ids.insert(inst.result_id()); + break; + case spv::Op::OpGroupDecorate: { + Words& words = normal_uses[inst.GetSingleWordInOperand(0)]; + for (uint32_t i = 1; i < inst.NumInOperandWords(); i++) { + words.push_back(inst.GetSingleWordInOperand(i)); + } + } break; + case spv::Op::OpGroupMemberDecorate: { + Words& words = member_uses[inst.GetSingleWordInOperand(0)]; + for (uint32_t i = 1; i < inst.NumInOperandWords(); i++) { + words.push_back(inst.GetSingleWordInOperand(i)); + } + } break; + default: + break; + } + } + + // On the second pass, replace OpDecorationGroup and its uses with + // equivalent normal and struct member uses. + auto inst_iter = annotations.begin(); + // We have to re-evaluate the end pointer + while (inst_iter != context()->annotations().end()) { + // Should we replace this instruction? + bool replace = false; + switch (inst_iter->opcode()) { + case spv::Op::OpDecorationGroup: + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: + replace = true; + break; + case spv::Op::OpDecorate: { + // If this decoration targets a group, then replace it + // by sets of normal and member decorations. + const uint32_t group = inst_iter->GetSingleWordOperand(0); + const auto normal_uses_iter = normal_uses.find(group); + if (normal_uses_iter != normal_uses.end()) { + for (auto target : normal_uses[group]) { + std::unique_ptr new_inst(inst_iter->Clone(context())); + new_inst->SetInOperand(0, Words{target}); + inst_iter = inst_iter.InsertBefore(std::move(new_inst)); + ++inst_iter; + replace = true; + } + } + const auto member_uses_iter = member_uses.find(group); + if (member_uses_iter != member_uses.end()) { + const Words& member_id_pairs = (*member_uses_iter).second; + // The collection is a sequence of pairs. + assert((member_id_pairs.size() % 2) == 0); + for (size_t i = 0; i < member_id_pairs.size(); i += 2) { + // Make an OpMemberDecorate instruction for each (target, member) + // pair. + const uint32_t target = member_id_pairs[i]; + const uint32_t member = member_id_pairs[i + 1]; + std::vector operands; + operands.push_back(Operand(SPV_OPERAND_TYPE_ID, {target})); + operands.push_back( + Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {member})); + auto decoration_operands_iter = inst_iter->begin(); + decoration_operands_iter++; // Skip the group target. + operands.insert(operands.end(), decoration_operands_iter, + inst_iter->end()); + std::unique_ptr new_inst(new Instruction( + context(), spv::Op::OpMemberDecorate, 0, 0, operands)); + inst_iter = inst_iter.InsertBefore(std::move(new_inst)); + ++inst_iter; + replace = true; + } + } + // If this is an OpDecorate targeting the OpDecorationGroup itself, + // remove it even if that decoration group itself is not the target of + // any OpGroupDecorate or OpGroupMemberDecorate. + if (!replace && group_ids.count(group)) { + replace = true; + } + } break; + default: + break; + } + if (replace) { + inst_iter = inst_iter.Erase(); + modified = true; + } else { + // Handle the case of decorations unrelated to decoration groups. + ++inst_iter; + } + } + + // Remove OpName instructions which reference the removed group decorations. + // An OpDecorationGroup instruction might not have been used by an + // OpGroupDecorate or OpGroupMemberDecorate instruction. + if (!group_ids.empty()) { + for (auto debug_inst_iter = context()->debug2_begin(); + debug_inst_iter != context()->debug2_end();) { + if (debug_inst_iter->opcode() == spv::Op::OpName) { + const uint32_t target = debug_inst_iter->GetSingleWordOperand(0); + if (group_ids.count(target)) { + debug_inst_iter = debug_inst_iter.Erase(); + modified = true; + } else { + ++debug_inst_iter; + } + } + } + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/flatten_decoration_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/flatten_decoration_pass.h new file mode 100644 index 000000000000..6a34f5bb294a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/flatten_decoration_pass.h @@ -0,0 +1,35 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_FLATTEN_DECORATION_PASS_H_ +#define SOURCE_OPT_FLATTEN_DECORATION_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class FlattenDecorationPass : public Pass { + public: + const char* name() const override { return "flatten-decorations"; } + Status Process() override; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_FLATTEN_DECORATION_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/fold.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/fold.cpp new file mode 100644 index 000000000000..942da6835f90 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/fold.cpp @@ -0,0 +1,701 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/fold.h" + +#include +#include +#include + +#include "source/opt/const_folding_rules.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/folding_rules.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { + +#ifndef INT32_MIN +#define INT32_MIN (-2147483648) +#endif + +#ifndef INT32_MAX +#define INT32_MAX 2147483647 +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX 0xffffffff /* 4294967295U */ +#endif + +} // namespace + +uint32_t InstructionFolder::UnaryOperate(spv::Op opcode, + uint32_t operand) const { + switch (opcode) { + // Arthimetics + case spv::Op::OpSNegate: { + int32_t s_operand = static_cast(operand); + if (s_operand == std::numeric_limits::min()) { + return s_operand; + } + return -s_operand; + } + case spv::Op::OpNot: + return ~operand; + case spv::Op::OpLogicalNot: + return !static_cast(operand); + case spv::Op::OpUConvert: + return operand; + case spv::Op::OpSConvert: + return operand; + default: + assert(false && + "Unsupported unary operation for OpSpecConstantOp instruction"); + return 0u; + } +} + +uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, + uint32_t b) const { + switch (opcode) { + // Shifting + case spv::Op::OpShiftRightLogical: + if (b >= 32) { + // This is undefined behaviour when |b| > 32. Choose 0 for consistency. + // When |b| == 32, doing the shift in C++ in undefined, but the result + // will be 0, so just return that value. + return 0; + } + return a >> b; + case spv::Op::OpShiftRightArithmetic: + if (b > 32) { + // This is undefined behaviour. Choose 0 for consistency. + return 0; + } + if (b == 32) { + // Doing the shift in C++ is undefined, but the result is defined in the + // spir-v spec. Find that value another way. + if (static_cast(a) >= 0) { + return 0; + } else { + return static_cast(-1); + } + } + return (static_cast(a)) >> b; + case spv::Op::OpShiftLeftLogical: + if (b >= 32) { + // This is undefined behaviour when |b| > 32. Choose 0 for consistency. + // When |b| == 32, doing the shift in C++ in undefined, but the result + // will be 0, so just return that value. + return 0; + } + return a << b; + + // Bitwise operations + case spv::Op::OpBitwiseOr: + return a | b; + case spv::Op::OpBitwiseAnd: + return a & b; + case spv::Op::OpBitwiseXor: + return a ^ b; + + // Logical + case spv::Op::OpLogicalEqual: + return (static_cast(a)) == (static_cast(b)); + case spv::Op::OpLogicalNotEqual: + return (static_cast(a)) != (static_cast(b)); + case spv::Op::OpLogicalOr: + return (static_cast(a)) || (static_cast(b)); + case spv::Op::OpLogicalAnd: + return (static_cast(a)) && (static_cast(b)); + + // Comparison + case spv::Op::OpIEqual: + return a == b; + case spv::Op::OpINotEqual: + return a != b; + case spv::Op::OpULessThan: + return a < b; + case spv::Op::OpSLessThan: + return (static_cast(a)) < (static_cast(b)); + case spv::Op::OpUGreaterThan: + return a > b; + case spv::Op::OpSGreaterThan: + return (static_cast(a)) > (static_cast(b)); + case spv::Op::OpULessThanEqual: + return a <= b; + case spv::Op::OpSLessThanEqual: + return (static_cast(a)) <= (static_cast(b)); + case spv::Op::OpUGreaterThanEqual: + return a >= b; + case spv::Op::OpSGreaterThanEqual: + return (static_cast(a)) >= (static_cast(b)); + default: + assert(false && + "Unsupported binary operation for OpSpecConstantOp instruction"); + return 0u; + } +} + +uint32_t InstructionFolder::TernaryOperate(spv::Op opcode, uint32_t a, + uint32_t b, uint32_t c) const { + switch (opcode) { + case spv::Op::OpSelect: + return (static_cast(a)) ? b : c; + default: + assert(false && + "Unsupported ternary operation for OpSpecConstantOp instruction"); + return 0u; + } +} + +uint32_t InstructionFolder::OperateWords( + spv::Op opcode, const std::vector& operand_words) const { + switch (operand_words.size()) { + case 1: + return UnaryOperate(opcode, operand_words.front()); + case 2: + return BinaryOperate(opcode, operand_words.front(), operand_words.back()); + case 3: + return TernaryOperate(opcode, operand_words[0], operand_words[1], + operand_words[2]); + default: + assert(false && "Invalid number of operands"); + return 0; + } +} + +bool InstructionFolder::FoldInstructionInternal(Instruction* inst) const { + auto identity_map = [](uint32_t id) { return id; }; + Instruction* folded_inst = FoldInstructionToConstant(inst, identity_map); + if (folded_inst != nullptr) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {folded_inst->result_id()}}}); + return true; + } + + analysis::ConstantManager* const_manager = context_->get_constant_mgr(); + std::vector constants = + const_manager->GetOperandConstants(inst); + + for (const FoldingRule& rule : + GetFoldingRules().GetRulesForInstruction(inst)) { + if (rule(context_, inst, constants)) { + return true; + } + } + return false; +} + +// Returns the result of performing an operation on scalar constant operands. +// This function extracts the operand values as 32 bit words and returns the +// result in 32 bit word. Scalar constants with longer than 32-bit width are +// not accepted in this function. +uint32_t InstructionFolder::FoldScalars( + spv::Op opcode, + const std::vector& operands) const { + assert(IsFoldableOpcode(opcode) && + "Unhandled instruction opcode in FoldScalars"); + std::vector operand_values_in_raw_words; + for (const auto& operand : operands) { + if (const analysis::ScalarConstant* scalar = operand->AsScalarConstant()) { + const auto& scalar_words = scalar->words(); + assert(scalar_words.size() == 1 && + "Scalar constants with longer than 32-bit width are not allowed " + "in FoldScalars()"); + operand_values_in_raw_words.push_back(scalar_words.front()); + } else if (operand->AsNullConstant()) { + operand_values_in_raw_words.push_back(0u); + } else { + assert(false && + "FoldScalars() only accepts ScalarConst or NullConst type of " + "constant"); + } + } + return OperateWords(opcode, operand_values_in_raw_words); +} + +bool InstructionFolder::FoldBinaryIntegerOpToConstant( + Instruction* inst, const std::function& id_map, + uint32_t* result) const { + spv::Op opcode = inst->opcode(); + analysis::ConstantManager* const_manger = context_->get_constant_mgr(); + + uint32_t ids[2]; + const analysis::IntConstant* constants[2]; + for (uint32_t i = 0; i < 2; i++) { + const Operand* operand = &inst->GetInOperand(i); + if (operand->type != SPV_OPERAND_TYPE_ID) { + return false; + } + ids[i] = id_map(operand->words[0]); + const analysis::Constant* constant = + const_manger->FindDeclaredConstant(ids[i]); + constants[i] = (constant != nullptr ? constant->AsIntConstant() : nullptr); + } + + switch (opcode) { + // Arthimetics + case spv::Op::OpIMul: + for (uint32_t i = 0; i < 2; i++) { + if (constants[i] != nullptr && constants[i]->IsZero()) { + *result = 0; + return true; + } + } + break; + case spv::Op::OpUDiv: + case spv::Op::OpSDiv: + case spv::Op::OpSRem: + case spv::Op::OpSMod: + case spv::Op::OpUMod: + // This changes undefined behaviour (ie divide by 0) into a 0. + for (uint32_t i = 0; i < 2; i++) { + if (constants[i] != nullptr && constants[i]->IsZero()) { + *result = 0; + return true; + } + } + break; + + // Shifting + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftLeftLogical: + if (constants[1] != nullptr) { + // When shifting by a value larger than the size of the result, the + // result is undefined. We are setting the undefined behaviour to a + // result of 0. If the shift amount is the same as the size of the + // result, then the result is defined, and it 0. + uint32_t shift_amount = constants[1]->GetU32BitValue(); + if (shift_amount >= 32) { + *result = 0; + return true; + } + } + break; + + // Bitwise operations + case spv::Op::OpBitwiseOr: + for (uint32_t i = 0; i < 2; i++) { + if (constants[i] != nullptr) { + // TODO: Change the mask against a value based on the bit width of the + // instruction result type. This way we can handle say 16-bit values + // as well. + uint32_t mask = constants[i]->GetU32BitValue(); + if (mask == 0xFFFFFFFF) { + *result = 0xFFFFFFFF; + return true; + } + } + } + break; + case spv::Op::OpBitwiseAnd: + for (uint32_t i = 0; i < 2; i++) { + if (constants[i] != nullptr) { + if (constants[i]->IsZero()) { + *result = 0; + return true; + } + } + } + break; + + // Comparison + case spv::Op::OpULessThan: + if (constants[0] != nullptr && + constants[0]->GetU32BitValue() == UINT32_MAX) { + *result = false; + return true; + } + if (constants[1] != nullptr && constants[1]->GetU32BitValue() == 0) { + *result = false; + return true; + } + break; + case spv::Op::OpSLessThan: + if (constants[0] != nullptr && + constants[0]->GetS32BitValue() == INT32_MAX) { + *result = false; + return true; + } + if (constants[1] != nullptr && + constants[1]->GetS32BitValue() == INT32_MIN) { + *result = false; + return true; + } + break; + case spv::Op::OpUGreaterThan: + if (constants[0] != nullptr && constants[0]->IsZero()) { + *result = false; + return true; + } + if (constants[1] != nullptr && + constants[1]->GetU32BitValue() == UINT32_MAX) { + *result = false; + return true; + } + break; + case spv::Op::OpSGreaterThan: + if (constants[0] != nullptr && + constants[0]->GetS32BitValue() == INT32_MIN) { + *result = false; + return true; + } + if (constants[1] != nullptr && + constants[1]->GetS32BitValue() == INT32_MAX) { + *result = false; + return true; + } + break; + case spv::Op::OpULessThanEqual: + if (constants[0] != nullptr && constants[0]->IsZero()) { + *result = true; + return true; + } + if (constants[1] != nullptr && + constants[1]->GetU32BitValue() == UINT32_MAX) { + *result = true; + return true; + } + break; + case spv::Op::OpSLessThanEqual: + if (constants[0] != nullptr && + constants[0]->GetS32BitValue() == INT32_MIN) { + *result = true; + return true; + } + if (constants[1] != nullptr && + constants[1]->GetS32BitValue() == INT32_MAX) { + *result = true; + return true; + } + break; + case spv::Op::OpUGreaterThanEqual: + if (constants[0] != nullptr && + constants[0]->GetU32BitValue() == UINT32_MAX) { + *result = true; + return true; + } + if (constants[1] != nullptr && constants[1]->GetU32BitValue() == 0) { + *result = true; + return true; + } + break; + case spv::Op::OpSGreaterThanEqual: + if (constants[0] != nullptr && + constants[0]->GetS32BitValue() == INT32_MAX) { + *result = true; + return true; + } + if (constants[1] != nullptr && + constants[1]->GetS32BitValue() == INT32_MIN) { + *result = true; + return true; + } + break; + default: + break; + } + return false; +} + +bool InstructionFolder::FoldBinaryBooleanOpToConstant( + Instruction* inst, const std::function& id_map, + uint32_t* result) const { + spv::Op opcode = inst->opcode(); + analysis::ConstantManager* const_manger = context_->get_constant_mgr(); + + uint32_t ids[2]; + const analysis::BoolConstant* constants[2]; + for (uint32_t i = 0; i < 2; i++) { + const Operand* operand = &inst->GetInOperand(i); + if (operand->type != SPV_OPERAND_TYPE_ID) { + return false; + } + ids[i] = id_map(operand->words[0]); + const analysis::Constant* constant = + const_manger->FindDeclaredConstant(ids[i]); + constants[i] = (constant != nullptr ? constant->AsBoolConstant() : nullptr); + } + + switch (opcode) { + // Logical + case spv::Op::OpLogicalOr: + for (uint32_t i = 0; i < 2; i++) { + if (constants[i] != nullptr) { + if (constants[i]->value()) { + *result = true; + return true; + } + } + } + break; + case spv::Op::OpLogicalAnd: + for (uint32_t i = 0; i < 2; i++) { + if (constants[i] != nullptr) { + if (!constants[i]->value()) { + *result = false; + return true; + } + } + } + break; + + default: + break; + } + return false; +} + +bool InstructionFolder::FoldIntegerOpToConstant( + Instruction* inst, const std::function& id_map, + uint32_t* result) const { + assert(IsFoldableOpcode(inst->opcode()) && + "Unhandled instruction opcode in FoldScalars"); + switch (inst->NumInOperands()) { + case 2: + return FoldBinaryIntegerOpToConstant(inst, id_map, result) || + FoldBinaryBooleanOpToConstant(inst, id_map, result); + default: + return false; + } +} + +std::vector InstructionFolder::FoldVectors( + spv::Op opcode, uint32_t num_dims, + const std::vector& operands) const { + assert(IsFoldableOpcode(opcode) && + "Unhandled instruction opcode in FoldVectors"); + std::vector result; + for (uint32_t d = 0; d < num_dims; d++) { + std::vector operand_values_for_one_dimension; + for (const auto& operand : operands) { + if (const analysis::VectorConstant* vector_operand = + operand->AsVectorConstant()) { + // Extract the raw value of the scalar component constants + // in 32-bit words here. The reason of not using FoldScalars() here + // is that we do not create temporary null constants as components + // when the vector operand is a NullConstant because Constant creation + // may need extra checks for the validity and that is not managed in + // here. + if (const analysis::ScalarConstant* scalar_component = + vector_operand->GetComponents().at(d)->AsScalarConstant()) { + const auto& scalar_words = scalar_component->words(); + assert( + scalar_words.size() == 1 && + "Vector components with longer than 32-bit width are not allowed " + "in FoldVectors()"); + operand_values_for_one_dimension.push_back(scalar_words.front()); + } else if (operand->AsNullConstant()) { + operand_values_for_one_dimension.push_back(0u); + } else { + assert(false && + "VectorConst should only has ScalarConst or NullConst as " + "components"); + } + } else if (operand->AsNullConstant()) { + operand_values_for_one_dimension.push_back(0u); + } else { + assert(false && + "FoldVectors() only accepts VectorConst or NullConst type of " + "constant"); + } + } + result.push_back(OperateWords(opcode, operand_values_for_one_dimension)); + } + return result; +} + +bool InstructionFolder::IsFoldableOpcode(spv::Op opcode) const { + // NOTE: Extend to more opcodes as new cases are handled in the folder + // functions. + switch (opcode) { + case spv::Op::OpBitwiseAnd: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpIAdd: + case spv::Op::OpIEqual: + case spv::Op::OpIMul: + case spv::Op::OpINotEqual: + case spv::Op::OpISub: + case spv::Op::OpLogicalAnd: + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNot: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpNot: + case spv::Op::OpSDiv: + case spv::Op::OpSelect: + case spv::Op::OpSGreaterThan: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftRightLogical: + case spv::Op::OpSLessThan: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpSMod: + case spv::Op::OpSNegate: + case spv::Op::OpSRem: + case spv::Op::OpSConvert: + case spv::Op::OpUConvert: + case spv::Op::OpUDiv: + case spv::Op::OpUGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpUMod: + return true; + default: + return false; + } +} + +bool InstructionFolder::IsFoldableConstant( + const analysis::Constant* cst) const { + // Currently supported constants are 32-bit values or null constants. + if (const analysis::ScalarConstant* scalar = cst->AsScalarConstant()) + return scalar->words().size() == 1; + else + return cst->AsNullConstant() != nullptr; +} + +Instruction* InstructionFolder::FoldInstructionToConstant( + Instruction* inst, std::function id_map) const { + analysis::ConstantManager* const_mgr = context_->get_constant_mgr(); + + if (!inst->IsFoldableByFoldScalar() && !inst->IsFoldableByFoldVector() && + !GetConstantFoldingRules().HasFoldingRule(inst)) { + return nullptr; + } + // Collect the values of the constant parameters. + std::vector constants; + bool missing_constants = false; + inst->ForEachInId([&constants, &missing_constants, const_mgr, + &id_map](uint32_t* op_id) { + uint32_t id = id_map(*op_id); + const analysis::Constant* const_op = const_mgr->FindDeclaredConstant(id); + if (!const_op) { + constants.push_back(nullptr); + missing_constants = true; + } else { + constants.push_back(const_op); + } + }); + + const analysis::Constant* folded_const = nullptr; + for (auto rule : GetConstantFoldingRules().GetRulesForInstruction(inst)) { + folded_const = rule(context_, inst, constants); + if (folded_const != nullptr) { + Instruction* const_inst = + const_mgr->GetDefiningInstruction(folded_const, inst->type_id()); + if (const_inst == nullptr) { + return nullptr; + } + assert(const_inst->type_id() == inst->type_id()); + // May be a new instruction that needs to be analysed. + context_->UpdateDefUse(const_inst); + return const_inst; + } + } + + bool successful = false; + + // If all parameters are constant, fold the instruction to a constant. + if (inst->IsFoldableByFoldScalar()) { + uint32_t result_val = 0; + + if (!missing_constants) { + result_val = FoldScalars(inst->opcode(), constants); + successful = true; + } + + if (!successful) { + successful = FoldIntegerOpToConstant(inst, id_map, &result_val); + } + + if (successful) { + const analysis::Constant* result_const = + const_mgr->GetConstant(const_mgr->GetType(inst), {result_val}); + Instruction* folded_inst = + const_mgr->GetDefiningInstruction(result_const, inst->type_id()); + return folded_inst; + } + } else if (inst->IsFoldableByFoldVector()) { + std::vector result_val; + + if (!missing_constants) { + if (Instruction* inst_type = + context_->get_def_use_mgr()->GetDef(inst->type_id())) { + result_val = FoldVectors( + inst->opcode(), inst_type->GetSingleWordInOperand(1), constants); + successful = true; + } + } + + if (successful) { + const analysis::Constant* result_const = + const_mgr->GetNumericVectorConstantWithWords( + const_mgr->GetType(inst)->AsVector(), result_val); + Instruction* folded_inst = + const_mgr->GetDefiningInstruction(result_const, inst->type_id()); + return folded_inst; + } + } + + return nullptr; +} + +bool InstructionFolder::IsFoldableType(Instruction* type_inst) const { + return IsFoldableScalarType(type_inst) || IsFoldableVectorType(type_inst); +} + +bool InstructionFolder::IsFoldableScalarType(Instruction* type_inst) const { + // Support 32-bit integers. + if (type_inst->opcode() == spv::Op::OpTypeInt) { + return type_inst->GetSingleWordInOperand(0) == 32; + } + // Support booleans. + if (type_inst->opcode() == spv::Op::OpTypeBool) { + return true; + } + // Nothing else yet. + return false; +} + +bool InstructionFolder::IsFoldableVectorType(Instruction* type_inst) const { + // Support vectors with foldable components + if (type_inst->opcode() == spv::Op::OpTypeVector) { + uint32_t component_type_id = type_inst->GetSingleWordInOperand(0); + Instruction* def_component_type = + context_->get_def_use_mgr()->GetDef(component_type_id); + return def_component_type != nullptr && + IsFoldableScalarType(def_component_type); + } + // Nothing else yet. + return false; +} + +bool InstructionFolder::FoldInstruction(Instruction* inst) const { + bool modified = false; + Instruction* folded_inst(inst); + while (folded_inst->opcode() != spv::Op::OpCopyObject && + FoldInstructionInternal(&*folded_inst)) { + modified = true; + } + return modified; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/fold.h b/thirdparty/glslang/External/spirv-tools/source/opt/fold.h new file mode 100644 index 000000000000..42da65e4d2f4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/fold.h @@ -0,0 +1,195 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_FOLD_H_ +#define SOURCE_OPT_FOLD_H_ + +#include +#include + +#include "source/opt/const_folding_rules.h" +#include "source/opt/constants.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/folding_rules.h" + +namespace spvtools { +namespace opt { + +class InstructionFolder { + public: + explicit InstructionFolder(IRContext* context) + : context_(context), + const_folding_rules_(new ConstantFoldingRules(context)), + folding_rules_(new FoldingRules(context)) { + folding_rules_->AddFoldingRules(); + const_folding_rules_->AddFoldingRules(); + } + + explicit InstructionFolder( + IRContext* context, std::unique_ptr&& folding_rules, + std::unique_ptr&& constant_folding_rules) + : context_(context), + const_folding_rules_(std::move(constant_folding_rules)), + folding_rules_(std::move(folding_rules)) { + folding_rules_->AddFoldingRules(); + const_folding_rules_->AddFoldingRules(); + } + + // Returns the result of folding a scalar instruction with the given |opcode| + // and |operands|. Each entry in |operands| is a pointer to an + // analysis::Constant instance, which should've been created with the constant + // manager (See IRContext::get_constant_mgr). + // + // It is an error to call this function with an opcode that does not pass the + // IsFoldableOpcode test. If any error occurs during folding, the folder will + // fail with a call to assert. + uint32_t FoldScalars( + spv::Op opcode, + const std::vector& operands) const; + + // Returns the result of performing an operation with the given |opcode| over + // constant vectors with |num_dims| dimensions. Each entry in |operands| is a + // pointer to an analysis::Constant instance, which should've been created + // with the constant manager (See IRContext::get_constant_mgr). + // + // This function iterates through the given vector type constant operands and + // calculates the result for each element of the result vector to return. + // Vectors with longer than 32-bit scalar components are not accepted in this + // function. + // + // It is an error to call this function with an opcode that does not pass the + // IsFoldableOpcode test. If any error occurs during folding, the folder will + // fail with a call to assert. + std::vector FoldVectors( + spv::Op opcode, uint32_t num_dims, + const std::vector& operands) const; + + // Returns true if |opcode| represents an operation handled by FoldScalars or + // FoldVectors. + bool IsFoldableOpcode(spv::Op opcode) const; + + // Returns true if |cst| is supported by FoldScalars and FoldVectors. + bool IsFoldableConstant(const analysis::Constant* cst) const; + + // Returns true if |FoldInstructionToConstant| could fold an instruction whose + // result type is |type_inst|. + bool IsFoldableType(Instruction* type_inst) const; + + // Returns true if |FoldInstructionToConstant| could fold an instruction whose + // result type is |type_inst|. + bool IsFoldableScalarType(Instruction* type_inst) const; + + // Returns true if |FoldInstructionToConstant| could fold an instruction whose + // result type is |type_inst|. + bool IsFoldableVectorType(Instruction* type_inst) const; + + // Tries to fold |inst| to a single constant, when the input ids to |inst| + // have been substituted using |id_map|. Returns a pointer to the OpConstant* + // instruction if successful. If necessary, a new constant instruction is + // created and placed in the global values section. + // + // |id_map| is a function that takes one result id and returns another. It + // can be used for things like CCP where it is known that some ids contain a + // constant, but the instruction itself has not been updated yet. This can + // map those ids to the appropriate constants. + Instruction* FoldInstructionToConstant( + Instruction* inst, std::function id_map) const; + // Returns true if |inst| can be folded into a simpler instruction. + // If |inst| can be simplified, |inst| is overwritten with the simplified + // instruction reusing the same result id. + // + // If |inst| is simplified, it is possible that the resulting code in invalid + // because the instruction is in a bad location. Callers of this function + // have to handle the following cases: + // + // 1) An OpPhi becomes and OpCopyObject - If there are OpPhi instruction after + // |inst| in a basic block then this is invalid. The caller must fix this + // up. + bool FoldInstruction(Instruction* inst) const; + + // Return true if this opcode has a const folding rule associtated with it. + bool HasConstFoldingRule(const Instruction* inst) const { + return GetConstantFoldingRules().HasFoldingRule(inst); + } + + private: + // Returns a reference to the ConstnatFoldingRules instance. + const ConstantFoldingRules& GetConstantFoldingRules() const { + return *const_folding_rules_; + } + + // Returns a reference to the FoldingRules instance. + const FoldingRules& GetFoldingRules() const { return *folding_rules_; } + + // Returns the single-word result from performing the given unary operation on + // the operand value which is passed in as a 32-bit word. + uint32_t UnaryOperate(spv::Op opcode, uint32_t operand) const; + + // Returns the single-word result from performing the given binary operation + // on the operand values which are passed in as two 32-bit word. + uint32_t BinaryOperate(spv::Op opcode, uint32_t a, uint32_t b) const; + + // Returns the single-word result from performing the given ternary operation + // on the operand values which are passed in as three 32-bit word. + uint32_t TernaryOperate(spv::Op opcode, uint32_t a, uint32_t b, + uint32_t c) const; + + // Returns the single-word result from performing the given operation on the + // operand words. This only works with 32-bit operations and uses boolean + // convention that 0u is false, and anything else is boolean true. + // TODO(qining): Support operands other than 32-bit wide. + uint32_t OperateWords(spv::Op opcode, + const std::vector& operand_words) const; + + bool FoldInstructionInternal(Instruction* inst) const; + + // Returns true if |inst| is a binary operation that takes two integers as + // parameters and folds to a constant that can be represented as an unsigned + // 32-bit value when the ids have been replaced by |id_map|. If |inst| can be + // folded, the resulting value is returned in |*result|. Valid result types + // for the instruction are any integer (signed or unsigned) with 32-bits or + // less, or a boolean value. + bool FoldBinaryIntegerOpToConstant( + Instruction* inst, const std::function& id_map, + uint32_t* result) const; + + // Returns true if |inst| is a binary operation on two boolean values, and + // folds + // to a constant boolean value when the ids have been replaced using |id_map|. + // If |inst| can be folded, the result value is returned in |*result|. + bool FoldBinaryBooleanOpToConstant( + Instruction* inst, const std::function& id_map, + uint32_t* result) const; + + // Returns true if |inst| can be folded to an constant when the ids have been + // substituted using id_map. If it can, the value is returned in |result|. If + // not, |result| is unchanged. It is assumed that not all operands are + // constant. Those cases are handled by |FoldScalar|. + bool FoldIntegerOpToConstant(Instruction* inst, + const std::function& id_map, + uint32_t* result) const; + + IRContext* context_; + + // Folding rules used by |FoldInstructionToConstant| and |FoldInstruction|. + std::unique_ptr const_folding_rules_; + + // Folding rules used by |FoldInstruction|. + std::unique_ptr folding_rules_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_FOLD_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp new file mode 100644 index 000000000000..c568027d2aa0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp @@ -0,0 +1,341 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/fold_spec_constant_op_and_composite_pass.h" + +#include +#include + +#include "source/opt/constants.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { + +Pass::Status FoldSpecConstantOpAndCompositePass::Process() { + bool modified = false; + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + // Traverse through all the constant defining instructions. For Normal + // Constants whose values are determined and do not depend on OpUndef + // instructions, records their values in two internal maps: id_to_const_val_ + // and const_val_to_id_ so that we can use them to infer the value of Spec + // Constants later. + // For Spec Constants defined with OpSpecConstantComposite instructions, if + // all of their components are Normal Constants, they will be turned into + // Normal Constants too. For Spec Constants defined with OpSpecConstantOp + // instructions, we check if they only depends on Normal Constants and fold + // them when possible. The two maps for Normal Constants: id_to_const_val_ + // and const_val_to_id_ will be updated along the traversal so that the new + // Normal Constants generated from folding can be used to fold following Spec + // Constants. + // This algorithm depends on the SSA property of SPIR-V when + // defining constants. The dependent constants must be defined before the + // dependee constants. So a dependent Spec Constant must be defined and + // will be processed before its dependee Spec Constant. When we encounter + // the dependee Spec Constants, all its dependent constants must have been + // processed and all its dependent Spec Constants should have been folded if + // possible. + Module::inst_iterator next_inst = context()->types_values_begin(); + for (Module::inst_iterator inst_iter = next_inst; + // Need to re-evaluate the end iterator since we may modify the list of + // instructions in this section of the module as the process goes. + inst_iter != context()->types_values_end(); inst_iter = next_inst) { + ++next_inst; + Instruction* inst = &*inst_iter; + // Collect constant values of normal constants and process the + // OpSpecConstantOp and OpSpecConstantComposite instructions if possible. + // The constant values will be stored in analysis::Constant instances. + // OpConstantSampler instruction is not collected here because it cannot be + // used in OpSpecConstant{Composite|Op} instructions. + // TODO(qining): If the constant or its type has decoration, we may need + // to skip it. + if (const_mgr->GetType(inst) && + !const_mgr->GetType(inst)->decoration_empty()) + continue; + switch (spv::Op opcode = inst->opcode()) { + // Records the values of Normal Constants. + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: + case spv::Op::OpConstant: + case spv::Op::OpConstantNull: + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: { + // A Constant instance will be created if the given instruction is a + // Normal Constant whose value(s) are fixed. Note that for a composite + // Spec Constant defined with OpSpecConstantComposite instruction, if + // all of its components are Normal Constants already, the Spec + // Constant will be turned in to a Normal Constant. In that case, a + // Constant instance should also be created successfully and recorded + // in the id_to_const_val_ and const_val_to_id_ mapps. + if (auto const_value = const_mgr->GetConstantFromInst(inst)) { + // Need to replace the OpSpecConstantComposite instruction with a + // corresponding OpConstantComposite instruction. + if (opcode == spv::Op::OpSpecConstantComposite) { + inst->SetOpcode(spv::Op::OpConstantComposite); + modified = true; + } + const_mgr->MapConstantToInst(const_value, inst); + } + break; + } + // For a Spec Constants defined with OpSpecConstantOp instruction, check + // if it only depends on Normal Constants. If so, the Spec Constant will + // be folded. The original Spec Constant defining instruction will be + // replaced by Normal Constant defining instructions, and the new Normal + // Constants will be added to id_to_const_val_ and const_val_to_id_ so + // that we can use the new Normal Constants when folding following Spec + // Constants. + case spv::Op::OpSpecConstantOp: + modified |= ProcessOpSpecConstantOp(&inst_iter); + break; + default: + break; + } + } + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool FoldSpecConstantOpAndCompositePass::ProcessOpSpecConstantOp( + Module::inst_iterator* pos) { + Instruction* inst = &**pos; + Instruction* folded_inst = nullptr; + assert(inst->GetInOperand(0).type == + SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER && + "The first in-operand of OpSpecConstantOp instruction must be of " + "SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER type"); + + folded_inst = FoldWithInstructionFolder(pos); + if (!folded_inst) { + folded_inst = DoComponentWiseOperation(pos); + } + if (!folded_inst) return false; + + // Replace the original constant with the new folded constant, kill the + // original constant. + uint32_t new_id = folded_inst->result_id(); + uint32_t old_id = inst->result_id(); + context()->ReplaceAllUsesWith(old_id, new_id); + context()->KillDef(old_id); + return true; +} + +Instruction* FoldSpecConstantOpAndCompositePass::FoldWithInstructionFolder( + Module::inst_iterator* inst_iter_ptr) { + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + // If one of operands to the instruction is not a + // constant, then we cannot fold this spec constant. + for (uint32_t i = 1; i < (*inst_iter_ptr)->NumInOperands(); i++) { + const Operand& operand = (*inst_iter_ptr)->GetInOperand(i); + if (operand.type != SPV_OPERAND_TYPE_ID && + operand.type != SPV_OPERAND_TYPE_OPTIONAL_ID) { + continue; + } + uint32_t id = operand.words[0]; + if (const_mgr->FindDeclaredConstant(id) == nullptr) { + return nullptr; + } + } + + // All of the operands are constant. Construct a regular version of the + // instruction and pass it to the instruction folder. + std::unique_ptr inst((*inst_iter_ptr)->Clone(context())); + inst->SetOpcode( + static_cast((*inst_iter_ptr)->GetSingleWordInOperand(0))); + inst->RemoveOperand(2); + + // We want the current instruction to be replaced by an |OpConstant*| + // instruction in the same position. We need to keep track of which constants + // the instruction folder creates, so we can move them into the correct place. + auto last_type_value_iter = (context()->types_values_end()); + --last_type_value_iter; + Instruction* last_type_value = &*last_type_value_iter; + + auto identity_map = [](uint32_t id) { return id; }; + Instruction* new_const_inst = + context()->get_instruction_folder().FoldInstructionToConstant( + inst.get(), identity_map); + + // new_const_inst == null indicates we cannot fold this spec constant + if (!new_const_inst) return nullptr; + + // Get the instruction before |pos| to insert after. |pos| cannot be the + // first instruction in the list because its type has to come first. + Instruction* insert_pos = (*inst_iter_ptr)->PreviousNode(); + assert(insert_pos != nullptr && + "pos is the first instruction in the types and values."); + bool need_to_clone = true; + for (Instruction* i = last_type_value->NextNode(); i != nullptr; + i = last_type_value->NextNode()) { + if (i == new_const_inst) { + need_to_clone = false; + } + i->InsertAfter(insert_pos); + insert_pos = insert_pos->NextNode(); + } + + if (need_to_clone) { + new_const_inst = new_const_inst->Clone(context()); + new_const_inst->SetResultId(TakeNextId()); + new_const_inst->InsertAfter(insert_pos); + get_def_use_mgr()->AnalyzeInstDefUse(new_const_inst); + } + const_mgr->MapInst(new_const_inst); + return new_const_inst; +} + +namespace { +// A helper function to check the type for component wise operations. Returns +// true if the type: +// 1) is bool type; +// 2) is 32-bit int type; +// 3) is vector of bool type; +// 4) is vector of 32-bit integer type. +// Otherwise returns false. +bool IsValidTypeForComponentWiseOperation(const analysis::Type* type) { + if (type->AsBool()) { + return true; + } else if (auto* it = type->AsInteger()) { + if (it->width() == 32) return true; + } else if (auto* vt = type->AsVector()) { + if (vt->element_type()->AsBool()) { + return true; + } else if (auto* vit = vt->element_type()->AsInteger()) { + if (vit->width() == 32) return true; + } + } + return false; +} + +// Encodes the integer |value| of in a word vector format appropriate for +// representing this value as a operands for a constant definition. Performs +// zero-extension/sign-extension/truncation when needed, based on the signess of +// the given target type. +// +// Note: type |type| argument must be either Integer or Bool. +utils::SmallVector EncodeIntegerAsWords(const analysis::Type& type, + uint32_t value) { + const uint32_t all_ones = ~0; + uint32_t bit_width = 0; + uint32_t pad_value = 0; + bool result_type_signed = false; + if (auto* int_ty = type.AsInteger()) { + bit_width = int_ty->width(); + result_type_signed = int_ty->IsSigned(); + if (result_type_signed && static_cast(value) < 0) { + pad_value = all_ones; + } + } else if (type.AsBool()) { + bit_width = 1; + } else { + assert(false && "type must be Integer or Bool"); + } + + assert(bit_width > 0); + uint32_t first_word = value; + const uint32_t bits_per_word = 32; + + // Truncate first_word if the |type| has width less than uint32. + if (bit_width < bits_per_word) { + const uint32_t num_high_bits_to_mask = bits_per_word - bit_width; + const bool is_negative_after_truncation = + result_type_signed && + utils::IsBitAtPositionSet(first_word, bit_width - 1); + + if (is_negative_after_truncation) { + // Truncate and sign-extend |first_word|. No padding words will be + // added and |pad_value| can be left as-is. + first_word = utils::SetHighBits(first_word, num_high_bits_to_mask); + } else { + first_word = utils::ClearHighBits(first_word, num_high_bits_to_mask); + } + } + + utils::SmallVector words = {first_word}; + for (uint32_t current_bit = bits_per_word; current_bit < bit_width; + current_bit += bits_per_word) { + words.push_back(pad_value); + } + + return words; +} +} // namespace + +Instruction* FoldSpecConstantOpAndCompositePass::DoComponentWiseOperation( + Module::inst_iterator* pos) { + const Instruction* inst = &**pos; + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + const analysis::Type* result_type = const_mgr->GetType(inst); + spv::Op spec_opcode = static_cast(inst->GetSingleWordInOperand(0)); + // Check and collect operands. + std::vector operands; + + if (!std::all_of( + inst->cbegin(), inst->cend(), [&operands, this](const Operand& o) { + // skip the operands that is not an id. + if (o.type != spv_operand_type_t::SPV_OPERAND_TYPE_ID) return true; + uint32_t id = o.words.front(); + if (auto c = + context()->get_constant_mgr()->FindDeclaredConstant(id)) { + if (IsValidTypeForComponentWiseOperation(c->type())) { + operands.push_back(c); + return true; + } + } + return false; + })) + return nullptr; + + if (result_type->AsInteger() || result_type->AsBool()) { + // Scalar operation + const uint32_t result_val = + context()->get_instruction_folder().FoldScalars(spec_opcode, operands); + auto result_const = const_mgr->GetConstant( + result_type, EncodeIntegerAsWords(*result_type, result_val)); + return const_mgr->BuildInstructionAndAddToModule(result_const, pos); + } else if (result_type->AsVector()) { + // Vector operation + const analysis::Type* element_type = + result_type->AsVector()->element_type(); + uint32_t num_dims = result_type->AsVector()->element_count(); + std::vector result_vec = + context()->get_instruction_folder().FoldVectors(spec_opcode, num_dims, + operands); + std::vector result_vector_components; + for (const uint32_t r : result_vec) { + if (auto rc = const_mgr->GetConstant( + element_type, EncodeIntegerAsWords(*element_type, r))) { + result_vector_components.push_back(rc); + if (!const_mgr->BuildInstructionAndAddToModule(rc, pos)) { + assert(false && + "Failed to build and insert constant declaring instruction " + "for the given vector component constant"); + } + } else { + assert(false && "Failed to create constants with 32-bit word"); + } + } + auto new_vec_const = MakeUnique( + result_type->AsVector(), result_vector_components); + auto reg_vec_const = const_mgr->RegisterConstant(std::move(new_vec_const)); + return const_mgr->BuildInstructionAndAddToModule(reg_vec_const, pos); + } else { + // Cannot process invalid component wise operation. The result of component + // wise operation must be of integer or bool scalar or vector of + // integer/bool type. + return nullptr; + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.h new file mode 100644 index 000000000000..9a8fb403d7c4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.h @@ -0,0 +1,71 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_FOLD_SPEC_CONSTANT_OP_AND_COMPOSITE_PASS_H_ +#define SOURCE_OPT_FOLD_SPEC_CONSTANT_OP_AND_COMPOSITE_PASS_H_ + +#include +#include +#include + +#include "source/opt/constants.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" +#include "source/opt/type_manager.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class FoldSpecConstantOpAndCompositePass : public Pass { + public: + FoldSpecConstantOpAndCompositePass() = default; + + const char* name() const override { return "fold-spec-const-op-composite"; } + + // Iterates through the types-constants-globals section of the given module, + // finds the Spec Constants defined with OpSpecConstantOp and + // OpSpecConstantComposite instructions. If the result value of those spec + // constants can be folded, fold them to their corresponding normal constants. + Status Process() override; + + private: + // Processes the OpSpecConstantOp instruction pointed by the given + // instruction iterator, folds it to normal constants if possible. Returns + // true if the spec constant is folded to normal constants. New instructions + // will be inserted before the OpSpecConstantOp instruction pointed by the + // instruction iterator. The instruction iterator, which is passed by + // pointer, will still point to the original OpSpecConstantOp instruction. If + // folding is done successfully, the original OpSpecConstantOp instruction + // will be changed to Nop and new folded instruction will be inserted before + // it. + bool ProcessOpSpecConstantOp(Module::inst_iterator* pos); + + // Returns the result of folding the OpSpecConstantOp instruction + // |inst_iter_ptr| using the instruction folder. + Instruction* FoldWithInstructionFolder(Module::inst_iterator* inst_iter_ptr); + + // Try to fold the OpSpecConstantOp instruction + // pointed by the given instruction iterator to a normal constant defining + // instruction. Returns the pointer to the new constant defining instruction + // if succeeded, otherwise return nullptr. + Instruction* DoComponentWiseOperation(Module::inst_iterator* inst_iter_ptr); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_FOLD_SPEC_CONSTANT_OP_AND_COMPOSITE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/folding_rules.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/folding_rules.cpp new file mode 100644 index 000000000000..5c68e291cdc6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/folding_rules.cpp @@ -0,0 +1,3044 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/folding_rules.h" + +#include +#include +#include + +#include "ir_builder.h" +#include "source/latest_version_glsl_std_450_header.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { + +constexpr uint32_t kExtractCompositeIdInIdx = 0; +constexpr uint32_t kInsertObjectIdInIdx = 0; +constexpr uint32_t kInsertCompositeIdInIdx = 1; +constexpr uint32_t kExtInstSetIdInIdx = 0; +constexpr uint32_t kExtInstInstructionInIdx = 1; +constexpr uint32_t kFMixXIdInIdx = 2; +constexpr uint32_t kFMixYIdInIdx = 3; +constexpr uint32_t kFMixAIdInIdx = 4; +constexpr uint32_t kStoreObjectInIdx = 1; + +// Some image instructions may contain an "image operands" argument. +// Returns the operand index for the "image operands". +// Returns -1 if the instruction does not have image operands. +int32_t ImageOperandsMaskInOperandIndex(Instruction* inst) { + const auto opcode = inst->opcode(); + switch (opcode) { + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageFetch: + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageSparseRead: + return inst->NumOperands() > 4 ? 2 : -1; + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + return inst->NumOperands() > 5 ? 3 : -1; + case spv::Op::OpImageWrite: + return inst->NumOperands() > 3 ? 3 : -1; + default: + return -1; + } +} + +// Returns the element width of |type|. +uint32_t ElementWidth(const analysis::Type* type) { + if (const analysis::Vector* vec_type = type->AsVector()) { + return ElementWidth(vec_type->element_type()); + } else if (const analysis::Float* float_type = type->AsFloat()) { + return float_type->width(); + } else { + assert(type->AsInteger()); + return type->AsInteger()->width(); + } +} + +// Returns true if |type| is Float or a vector of Float. +bool HasFloatingPoint(const analysis::Type* type) { + if (type->AsFloat()) { + return true; + } else if (const analysis::Vector* vec_type = type->AsVector()) { + return vec_type->element_type()->AsFloat() != nullptr; + } + + return false; +} + +// Returns false if |val| is NaN, infinite or subnormal. +template +bool IsValidResult(T val) { + int classified = std::fpclassify(val); + switch (classified) { + case FP_NAN: + case FP_INFINITE: + case FP_SUBNORMAL: + return false; + default: + return true; + } +} + +const analysis::Constant* ConstInput( + const std::vector& constants) { + return constants[0] ? constants[0] : constants[1]; +} + +Instruction* NonConstInput(IRContext* context, const analysis::Constant* c, + Instruction* inst) { + uint32_t in_op = c ? 1u : 0u; + return context->get_def_use_mgr()->GetDef( + inst->GetSingleWordInOperand(in_op)); +} + +std::vector ExtractInts(uint64_t val) { + std::vector words; + words.push_back(static_cast(val)); + words.push_back(static_cast(val >> 32)); + return words; +} + +std::vector GetWordsFromScalarIntConstant( + const analysis::IntConstant* c) { + assert(c != nullptr); + uint32_t width = c->type()->AsInteger()->width(); + assert(width == 8 || width == 16 || width == 32 || width == 64); + if (width == 64) { + uint64_t uval = static_cast(c->GetU64()); + return ExtractInts(uval); + } + // Section 2.2.1 of the SPIR-V spec guarantees that all integer types + // smaller than 32-bits are automatically zero or sign extended to 32-bits. + return {c->GetU32BitValue()}; +} + +std::vector GetWordsFromScalarFloatConstant( + const analysis::FloatConstant* c) { + assert(c != nullptr); + uint32_t width = c->type()->AsFloat()->width(); + assert(width == 16 || width == 32 || width == 64); + if (width == 64) { + utils::FloatProxy result(c->GetDouble()); + return result.GetWords(); + } + // Section 2.2.1 of the SPIR-V spec guarantees that all floating-point types + // smaller than 32-bits are automatically zero extended to 32-bits. + return {c->GetU32BitValue()}; +} + +std::vector GetWordsFromNumericScalarOrVectorConstant( + analysis::ConstantManager* const_mgr, const analysis::Constant* c) { + if (const auto* float_constant = c->AsFloatConstant()) { + return GetWordsFromScalarFloatConstant(float_constant); + } else if (const auto* int_constant = c->AsIntConstant()) { + return GetWordsFromScalarIntConstant(int_constant); + } else if (const auto* vec_constant = c->AsVectorConstant()) { + std::vector words; + for (const auto* comp : vec_constant->GetComponents()) { + auto comp_in_words = + GetWordsFromNumericScalarOrVectorConstant(const_mgr, comp); + words.insert(words.end(), comp_in_words.begin(), comp_in_words.end()); + } + return words; + } + return {}; +} + +const analysis::Constant* ConvertWordsToNumericScalarOrVectorConstant( + analysis::ConstantManager* const_mgr, const std::vector& words, + const analysis::Type* type) { + if (type->AsInteger() || type->AsFloat()) + return const_mgr->GetConstant(type, words); + if (const auto* vec_type = type->AsVector()) + return const_mgr->GetNumericVectorConstantWithWords(vec_type, words); + return nullptr; +} + +// Returns the negation of |c|. |c| must be a 32 or 64 bit floating point +// constant. +uint32_t NegateFloatingPointConstant(analysis::ConstantManager* const_mgr, + const analysis::Constant* c) { + assert(c); + assert(c->type()->AsFloat()); + uint32_t width = c->type()->AsFloat()->width(); + assert(width == 32 || width == 64); + std::vector words; + if (width == 64) { + utils::FloatProxy result(c->GetDouble() * -1.0); + words = result.GetWords(); + } else { + utils::FloatProxy result(c->GetFloat() * -1.0f); + words = result.GetWords(); + } + + const analysis::Constant* negated_const = + const_mgr->GetConstant(c->type(), std::move(words)); + return const_mgr->GetDefiningInstruction(negated_const)->result_id(); +} + +// Negates the integer constant |c|. Returns the id of the defining instruction. +uint32_t NegateIntegerConstant(analysis::ConstantManager* const_mgr, + const analysis::Constant* c) { + assert(c); + assert(c->type()->AsInteger()); + uint32_t width = c->type()->AsInteger()->width(); + assert(width == 32 || width == 64); + std::vector words; + if (width == 64) { + uint64_t uval = static_cast(0 - c->GetU64()); + words = ExtractInts(uval); + } else { + words.push_back(static_cast(0 - c->GetU32())); + } + + const analysis::Constant* negated_const = + const_mgr->GetConstant(c->type(), std::move(words)); + return const_mgr->GetDefiningInstruction(negated_const)->result_id(); +} + +// Negates the vector constant |c|. Returns the id of the defining instruction. +uint32_t NegateVectorConstant(analysis::ConstantManager* const_mgr, + const analysis::Constant* c) { + assert(const_mgr && c); + assert(c->type()->AsVector()); + if (c->AsNullConstant()) { + // 0.0 vs -0.0 shouldn't matter. + return const_mgr->GetDefiningInstruction(c)->result_id(); + } else { + const analysis::Type* component_type = + c->AsVectorConstant()->component_type(); + std::vector words; + for (auto& comp : c->AsVectorConstant()->GetComponents()) { + if (component_type->AsFloat()) { + words.push_back(NegateFloatingPointConstant(const_mgr, comp)); + } else { + assert(component_type->AsInteger()); + words.push_back(NegateIntegerConstant(const_mgr, comp)); + } + } + + const analysis::Constant* negated_const = + const_mgr->GetConstant(c->type(), std::move(words)); + return const_mgr->GetDefiningInstruction(negated_const)->result_id(); + } +} + +// Negates |c|. Returns the id of the defining instruction. +uint32_t NegateConstant(analysis::ConstantManager* const_mgr, + const analysis::Constant* c) { + if (c->type()->AsVector()) { + return NegateVectorConstant(const_mgr, c); + } else if (c->type()->AsFloat()) { + return NegateFloatingPointConstant(const_mgr, c); + } else { + assert(c->type()->AsInteger()); + return NegateIntegerConstant(const_mgr, c); + } +} + +// Takes the reciprocal of |c|. |c|'s type must be Float or a vector of Float. +// Returns 0 if the reciprocal is NaN, infinite or subnormal. +uint32_t Reciprocal(analysis::ConstantManager* const_mgr, + const analysis::Constant* c) { + assert(const_mgr && c); + assert(c->type()->AsFloat()); + + uint32_t width = c->type()->AsFloat()->width(); + assert(width == 32 || width == 64); + std::vector words; + + if (c->IsZero()) { + return 0; + } + + if (width == 64) { + spvtools::utils::FloatProxy result(1.0 / c->GetDouble()); + if (!IsValidResult(result.getAsFloat())) return 0; + words = result.GetWords(); + } else { + spvtools::utils::FloatProxy result(1.0f / c->GetFloat()); + if (!IsValidResult(result.getAsFloat())) return 0; + words = result.GetWords(); + } + + const analysis::Constant* negated_const = + const_mgr->GetConstant(c->type(), std::move(words)); + return const_mgr->GetDefiningInstruction(negated_const)->result_id(); +} + +// Replaces fdiv where second operand is constant with fmul. +FoldingRule ReciprocalFDiv() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFDiv); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (!inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + if (constants[1] != nullptr) { + uint32_t id = 0; + if (const analysis::VectorConstant* vector_const = + constants[1]->AsVectorConstant()) { + std::vector neg_ids; + for (auto& comp : vector_const->GetComponents()) { + id = Reciprocal(const_mgr, comp); + if (id == 0) return false; + neg_ids.push_back(id); + } + const analysis::Constant* negated_const = + const_mgr->GetConstant(constants[1]->type(), std::move(neg_ids)); + id = const_mgr->GetDefiningInstruction(negated_const)->result_id(); + } else if (constants[1]->AsFloatConstant()) { + id = Reciprocal(const_mgr, constants[1]); + if (id == 0) return false; + } else { + // Don't fold a null constant. + return false; + } + inst->SetOpcode(spv::Op::OpFMul); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0u)}}, + {SPV_OPERAND_TYPE_ID, {id}}}); + return true; + } + + return false; + }; +} + +// Elides consecutive negate instructions. +FoldingRule MergeNegateArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFNegate || + inst->opcode() == spv::Op::OpSNegate); + (void)constants; + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed()) + return false; + + Instruction* op_inst = + context->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0u)); + if (HasFloatingPoint(type) && !op_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (op_inst->opcode() == inst->opcode()) { + // Elide negates. + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op_inst->GetSingleWordInOperand(0u)}}}); + return true; + } + + return false; + }; +} + +// Merges negate into a mul or div operation if that operation contains a +// constant operand. +// Cases: +// -(x * 2) = x * -2 +// -(2 * x) = x * -2 +// -(x / 2) = x / -2 +// -(2 / x) = -2 / x +FoldingRule MergeNegateMulDivArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFNegate || + inst->opcode() == spv::Op::OpSNegate); + (void)constants; + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed()) + return false; + + Instruction* op_inst = + context->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0u)); + if (HasFloatingPoint(type) && !op_inst->IsFloatingPointFoldingAllowed()) + return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + spv::Op opcode = op_inst->opcode(); + if (opcode == spv::Op::OpFMul || opcode == spv::Op::OpFDiv || + opcode == spv::Op::OpIMul || opcode == spv::Op::OpSDiv || + opcode == spv::Op::OpUDiv) { + std::vector op_constants = + const_mgr->GetOperandConstants(op_inst); + // Merge negate into mul or div if one operand is constant. + if (op_constants[0] || op_constants[1]) { + bool zero_is_variable = op_constants[0] == nullptr; + const analysis::Constant* c = ConstInput(op_constants); + uint32_t neg_id = NegateConstant(const_mgr, c); + uint32_t non_const_id = zero_is_variable + ? op_inst->GetSingleWordInOperand(0u) + : op_inst->GetSingleWordInOperand(1u); + // Change this instruction to a mul/div. + inst->SetOpcode(op_inst->opcode()); + if (opcode == spv::Op::OpFDiv || opcode == spv::Op::OpUDiv || + opcode == spv::Op::OpSDiv) { + uint32_t op0 = zero_is_variable ? non_const_id : neg_id; + uint32_t op1 = zero_is_variable ? neg_id : non_const_id; + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op0}}, {SPV_OPERAND_TYPE_ID, {op1}}}); + } else { + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {non_const_id}}, + {SPV_OPERAND_TYPE_ID, {neg_id}}}); + } + return true; + } + } + + return false; + }; +} + +// Merges negate into a add or sub operation if that operation contains a +// constant operand. +// Cases: +// -(x + 2) = -2 - x +// -(2 + x) = -2 - x +// -(x - 2) = 2 - x +// -(2 - x) = x - 2 +FoldingRule MergeNegateAddSubArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFNegate || + inst->opcode() == spv::Op::OpSNegate); + (void)constants; + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed()) + return false; + + Instruction* op_inst = + context->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0u)); + if (HasFloatingPoint(type) && !op_inst->IsFloatingPointFoldingAllowed()) + return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + if (op_inst->opcode() == spv::Op::OpFAdd || + op_inst->opcode() == spv::Op::OpFSub || + op_inst->opcode() == spv::Op::OpIAdd || + op_inst->opcode() == spv::Op::OpISub) { + std::vector op_constants = + const_mgr->GetOperandConstants(op_inst); + if (op_constants[0] || op_constants[1]) { + bool zero_is_variable = op_constants[0] == nullptr; + bool is_add = (op_inst->opcode() == spv::Op::OpFAdd) || + (op_inst->opcode() == spv::Op::OpIAdd); + bool swap_operands = !is_add || zero_is_variable; + bool negate_const = is_add; + const analysis::Constant* c = ConstInput(op_constants); + uint32_t const_id = 0; + if (negate_const) { + const_id = NegateConstant(const_mgr, c); + } else { + const_id = zero_is_variable ? op_inst->GetSingleWordInOperand(1u) + : op_inst->GetSingleWordInOperand(0u); + } + + // Swap operands if necessary and make the instruction a subtraction. + uint32_t op0 = + zero_is_variable ? op_inst->GetSingleWordInOperand(0u) : const_id; + uint32_t op1 = + zero_is_variable ? const_id : op_inst->GetSingleWordInOperand(1u); + if (swap_operands) std::swap(op0, op1); + inst->SetOpcode(HasFloatingPoint(type) ? spv::Op::OpFSub + : spv::Op::OpISub); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op0}}, {SPV_OPERAND_TYPE_ID, {op1}}}); + return true; + } + } + + return false; + }; +} + +// Returns true if |c| has a zero element. +bool HasZero(const analysis::Constant* c) { + if (c->AsNullConstant()) { + return true; + } + if (const analysis::VectorConstant* vec_const = c->AsVectorConstant()) { + for (auto& comp : vec_const->GetComponents()) + if (HasZero(comp)) return true; + } else { + assert(c->AsScalarConstant()); + return c->AsScalarConstant()->IsZero(); + } + + return false; +} + +// Performs |input1| |opcode| |input2| and returns the merged constant result +// id. Returns 0 if the result is not a valid value. The input types must be +// Float. +uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr, + spv::Op opcode, + const analysis::Constant* input1, + const analysis::Constant* input2) { + const analysis::Type* type = input1->type(); + assert(type->AsFloat()); + uint32_t width = type->AsFloat()->width(); + assert(width == 32 || width == 64); + std::vector words; +#define FOLD_OP(op) \ + if (width == 64) { \ + utils::FloatProxy val = \ + input1->GetDouble() op input2->GetDouble(); \ + double dval = val.getAsFloat(); \ + if (!IsValidResult(dval)) return 0; \ + words = val.GetWords(); \ + } else { \ + utils::FloatProxy val = input1->GetFloat() op input2->GetFloat(); \ + float fval = val.getAsFloat(); \ + if (!IsValidResult(fval)) return 0; \ + words = val.GetWords(); \ + } \ + static_assert(true, "require extra semicolon") + switch (opcode) { + case spv::Op::OpFMul: + FOLD_OP(*); + break; + case spv::Op::OpFDiv: + if (HasZero(input2)) return 0; + FOLD_OP(/); + break; + case spv::Op::OpFAdd: + FOLD_OP(+); + break; + case spv::Op::OpFSub: + FOLD_OP(-); + break; + default: + assert(false && "Unexpected operation"); + break; + } +#undef FOLD_OP + const analysis::Constant* merged_const = const_mgr->GetConstant(type, words); + return const_mgr->GetDefiningInstruction(merged_const)->result_id(); +} + +// Performs |input1| |opcode| |input2| and returns the merged constant result +// id. Returns 0 if the result is not a valid value. The input types must be +// Integers. +uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr, + spv::Op opcode, + const analysis::Constant* input1, + const analysis::Constant* input2) { + assert(input1->type()->AsInteger()); + const analysis::Integer* type = input1->type()->AsInteger(); + uint32_t width = type->AsInteger()->width(); + assert(width == 32 || width == 64); + std::vector words; + // Regardless of the sign of the constant, folding is performed on an unsigned + // interpretation of the constant data. This avoids signed integer overflow + // while folding, and works because sign is irrelevant for the IAdd, ISub and + // IMul instructions. +#define FOLD_OP(op) \ + if (width == 64) { \ + uint64_t val = input1->GetU64() op input2->GetU64(); \ + words = ExtractInts(val); \ + } else { \ + uint32_t val = input1->GetU32() op input2->GetU32(); \ + words.push_back(val); \ + } \ + static_assert(true, "require extra semicolon") + switch (opcode) { + case spv::Op::OpIMul: + FOLD_OP(*); + break; + case spv::Op::OpSDiv: + case spv::Op::OpUDiv: + assert(false && "Should not merge integer division"); + break; + case spv::Op::OpIAdd: + FOLD_OP(+); + break; + case spv::Op::OpISub: + FOLD_OP(-); + break; + default: + assert(false && "Unexpected operation"); + break; + } +#undef FOLD_OP + const analysis::Constant* merged_const = const_mgr->GetConstant(type, words); + return const_mgr->GetDefiningInstruction(merged_const)->result_id(); +} + +// Performs |input1| |opcode| |input2| and returns the merged constant result +// id. Returns 0 if the result is not a valid value. The input types must be +// Integers, Floats or Vectors of such. +uint32_t PerformOperation(analysis::ConstantManager* const_mgr, spv::Op opcode, + const analysis::Constant* input1, + const analysis::Constant* input2) { + assert(input1 && input2); + const analysis::Type* type = input1->type(); + std::vector words; + if (const analysis::Vector* vector_type = type->AsVector()) { + const analysis::Type* ele_type = vector_type->element_type(); + for (uint32_t i = 0; i != vector_type->element_count(); ++i) { + uint32_t id = 0; + + const analysis::Constant* input1_comp = nullptr; + if (const analysis::VectorConstant* input1_vector = + input1->AsVectorConstant()) { + input1_comp = input1_vector->GetComponents()[i]; + } else { + assert(input1->AsNullConstant()); + input1_comp = const_mgr->GetConstant(ele_type, {}); + } + + const analysis::Constant* input2_comp = nullptr; + if (const analysis::VectorConstant* input2_vector = + input2->AsVectorConstant()) { + input2_comp = input2_vector->GetComponents()[i]; + } else { + assert(input2->AsNullConstant()); + input2_comp = const_mgr->GetConstant(ele_type, {}); + } + + if (ele_type->AsFloat()) { + id = PerformFloatingPointOperation(const_mgr, opcode, input1_comp, + input2_comp); + } else { + assert(ele_type->AsInteger()); + id = PerformIntegerOperation(const_mgr, opcode, input1_comp, + input2_comp); + } + if (id == 0) return 0; + words.push_back(id); + } + const analysis::Constant* merged_const = + const_mgr->GetConstant(type, words); + return const_mgr->GetDefiningInstruction(merged_const)->result_id(); + } else if (type->AsFloat()) { + return PerformFloatingPointOperation(const_mgr, opcode, input1, input2); + } else { + assert(type->AsInteger()); + return PerformIntegerOperation(const_mgr, opcode, input1, input2); + } +} + +// Merges consecutive multiplies where each contains one constant operand. +// Cases: +// 2 * (x * 2) = x * 4 +// 2 * (2 * x) = x * 4 +// (x * 2) * 2 = x * 4 +// (2 * x) * 2 = x * 4 +FoldingRule MergeMulMulArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFMul || + inst->opcode() == spv::Op::OpIMul); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed()) + return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + // Determine the constant input and the variable input in |inst|. + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (HasFloatingPoint(type) && !other_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (other_inst->opcode() == inst->opcode()) { + std::vector other_constants = + const_mgr->GetOperandConstants(other_inst); + const analysis::Constant* const_input2 = ConstInput(other_constants); + if (!const_input2) return false; + + bool other_first_is_variable = other_constants[0] == nullptr; + uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(), + const_input1, const_input2); + if (merged_id == 0) return false; + + uint32_t non_const_id = other_first_is_variable + ? other_inst->GetSingleWordInOperand(0u) + : other_inst->GetSingleWordInOperand(1u); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {non_const_id}}, + {SPV_OPERAND_TYPE_ID, {merged_id}}}); + return true; + } + + return false; + }; +} + +// Merges divides into subsequent multiplies if each instruction contains one +// constant operand. Does not support integer operations. +// Cases: +// 2 * (x / 2) = x * 1 +// 2 * (2 / x) = 4 / x +// (x / 2) * 2 = x * 1 +// (2 / x) * 2 = 4 / x +// (y / x) * x = y +// x * (y / x) = y +FoldingRule MergeMulDivArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFMul); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (!inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + for (uint32_t i = 0; i < 2; i++) { + uint32_t op_id = inst->GetSingleWordInOperand(i); + Instruction* op_inst = def_use_mgr->GetDef(op_id); + if (op_inst->opcode() == spv::Op::OpFDiv) { + if (op_inst->GetSingleWordInOperand(1) == + inst->GetSingleWordInOperand(1 - i)) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op_inst->GetSingleWordInOperand(0)}}}); + return true; + } + } + } + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (!other_inst->IsFloatingPointFoldingAllowed()) return false; + + if (other_inst->opcode() == spv::Op::OpFDiv) { + std::vector other_constants = + const_mgr->GetOperandConstants(other_inst); + const analysis::Constant* const_input2 = ConstInput(other_constants); + if (!const_input2 || HasZero(const_input2)) return false; + + bool other_first_is_variable = other_constants[0] == nullptr; + // If the variable value is the second operand of the divide, multiply + // the constants together. Otherwise divide the constants. + uint32_t merged_id = PerformOperation( + const_mgr, + other_first_is_variable ? other_inst->opcode() : inst->opcode(), + const_input1, const_input2); + if (merged_id == 0) return false; + + uint32_t non_const_id = other_first_is_variable + ? other_inst->GetSingleWordInOperand(0u) + : other_inst->GetSingleWordInOperand(1u); + + // If the variable value is on the second operand of the div, then this + // operation is a div. Otherwise it should be a multiply. + inst->SetOpcode(other_first_is_variable ? inst->opcode() + : other_inst->opcode()); + if (other_first_is_variable) { + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {non_const_id}}, + {SPV_OPERAND_TYPE_ID, {merged_id}}}); + } else { + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {merged_id}}, + {SPV_OPERAND_TYPE_ID, {non_const_id}}}); + } + return true; + } + + return false; + }; +} + +// Merges multiply of constant and negation. +// Cases: +// (-x) * 2 = x * -2 +// 2 * (-x) = x * -2 +FoldingRule MergeMulNegateArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFMul || + inst->opcode() == spv::Op::OpIMul); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (other_inst->opcode() == spv::Op::OpFNegate || + other_inst->opcode() == spv::Op::OpSNegate) { + uint32_t neg_id = NegateConstant(const_mgr, const_input1); + + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {other_inst->GetSingleWordInOperand(0u)}}, + {SPV_OPERAND_TYPE_ID, {neg_id}}}); + return true; + } + + return false; + }; +} + +// Merges consecutive divides if each instruction contains one constant operand. +// Does not support integer division. +// Cases: +// 2 / (x / 2) = 4 / x +// 4 / (2 / x) = 2 * x +// (4 / x) / 2 = 2 / x +// (x / 2) / 2 = x / 4 +FoldingRule MergeDivDivArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFDiv); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (!inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1 || HasZero(const_input1)) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (!other_inst->IsFloatingPointFoldingAllowed()) return false; + + bool first_is_variable = constants[0] == nullptr; + if (other_inst->opcode() == inst->opcode()) { + std::vector other_constants = + const_mgr->GetOperandConstants(other_inst); + const analysis::Constant* const_input2 = ConstInput(other_constants); + if (!const_input2 || HasZero(const_input2)) return false; + + bool other_first_is_variable = other_constants[0] == nullptr; + + spv::Op merge_op = inst->opcode(); + if (other_first_is_variable) { + // Constants magnify. + merge_op = spv::Op::OpFMul; + } + + // This is an x / (*) case. Swap the inputs. Doesn't harm multiply + // because it is commutative. + if (first_is_variable) std::swap(const_input1, const_input2); + uint32_t merged_id = + PerformOperation(const_mgr, merge_op, const_input1, const_input2); + if (merged_id == 0) return false; + + uint32_t non_const_id = other_first_is_variable + ? other_inst->GetSingleWordInOperand(0u) + : other_inst->GetSingleWordInOperand(1u); + + spv::Op op = inst->opcode(); + if (!first_is_variable && !other_first_is_variable) { + // Effectively div of 1/x, so change to multiply. + op = spv::Op::OpFMul; + } + + uint32_t op1 = merged_id; + uint32_t op2 = non_const_id; + if (first_is_variable && other_first_is_variable) std::swap(op1, op2); + inst->SetOpcode(op); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}); + return true; + } + + return false; + }; +} + +// Fold multiplies succeeded by divides where each instruction contains a +// constant operand. Does not support integer divide. +// Cases: +// 4 / (x * 2) = 2 / x +// 4 / (2 * x) = 2 / x +// (x * 4) / 2 = x * 2 +// (4 * x) / 2 = x * 2 +// (x * y) / x = y +// (y * x) / x = y +FoldingRule MergeDivMulArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFDiv); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (!inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + uint32_t op_id = inst->GetSingleWordInOperand(0); + Instruction* op_inst = def_use_mgr->GetDef(op_id); + + if (op_inst->opcode() == spv::Op::OpFMul) { + for (uint32_t i = 0; i < 2; i++) { + if (op_inst->GetSingleWordInOperand(i) == + inst->GetSingleWordInOperand(1)) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, + {op_inst->GetSingleWordInOperand(1 - i)}}}); + return true; + } + } + } + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1 || HasZero(const_input1)) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (!other_inst->IsFloatingPointFoldingAllowed()) return false; + + bool first_is_variable = constants[0] == nullptr; + if (other_inst->opcode() == spv::Op::OpFMul) { + std::vector other_constants = + const_mgr->GetOperandConstants(other_inst); + const analysis::Constant* const_input2 = ConstInput(other_constants); + if (!const_input2) return false; + + bool other_first_is_variable = other_constants[0] == nullptr; + + // This is an x / (*) case. Swap the inputs. + if (first_is_variable) std::swap(const_input1, const_input2); + uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(), + const_input1, const_input2); + if (merged_id == 0) return false; + + uint32_t non_const_id = other_first_is_variable + ? other_inst->GetSingleWordInOperand(0u) + : other_inst->GetSingleWordInOperand(1u); + + uint32_t op1 = merged_id; + uint32_t op2 = non_const_id; + if (first_is_variable) std::swap(op1, op2); + + // Convert to multiply + if (first_is_variable) inst->SetOpcode(other_inst->opcode()); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}); + return true; + } + + return false; + }; +} + +// Fold divides of a constant and a negation. +// Cases: +// (-x) / 2 = x / -2 +// 2 / (-x) = -2 / x +FoldingRule MergeDivNegateArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFDiv); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + if (!inst->IsFloatingPointFoldingAllowed()) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (!other_inst->IsFloatingPointFoldingAllowed()) return false; + + bool first_is_variable = constants[0] == nullptr; + if (other_inst->opcode() == spv::Op::OpFNegate) { + uint32_t neg_id = NegateConstant(const_mgr, const_input1); + + if (first_is_variable) { + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {other_inst->GetSingleWordInOperand(0u)}}, + {SPV_OPERAND_TYPE_ID, {neg_id}}}); + } else { + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {neg_id}}, + {SPV_OPERAND_TYPE_ID, {other_inst->GetSingleWordInOperand(0u)}}}); + } + return true; + } + + return false; + }; +} + +// Folds addition of a constant and a negation. +// Cases: +// (-x) + 2 = 2 - x +// 2 + (-x) = 2 - x +FoldingRule MergeAddNegateArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (other_inst->opcode() == spv::Op::OpSNegate || + other_inst->opcode() == spv::Op::OpFNegate) { + inst->SetOpcode(HasFloatingPoint(type) ? spv::Op::OpFSub + : spv::Op::OpISub); + uint32_t const_id = constants[0] ? inst->GetSingleWordInOperand(0u) + : inst->GetSingleWordInOperand(1u); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {const_id}}, + {SPV_OPERAND_TYPE_ID, {other_inst->GetSingleWordInOperand(0u)}}}); + return true; + } + return false; + }; +} + +// Folds subtraction of a constant and a negation. +// Cases: +// (-x) - 2 = -2 - x +// 2 - (-x) = x + 2 +FoldingRule MergeSubNegateArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFSub || + inst->opcode() == spv::Op::OpISub); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (other_inst->opcode() == spv::Op::OpSNegate || + other_inst->opcode() == spv::Op::OpFNegate) { + uint32_t op1 = 0; + uint32_t op2 = 0; + spv::Op opcode = inst->opcode(); + if (constants[0] != nullptr) { + op1 = other_inst->GetSingleWordInOperand(0u); + op2 = inst->GetSingleWordInOperand(0u); + opcode = HasFloatingPoint(type) ? spv::Op::OpFAdd : spv::Op::OpIAdd; + } else { + op1 = NegateConstant(const_mgr, const_input1); + op2 = other_inst->GetSingleWordInOperand(0u); + } + + inst->SetOpcode(opcode); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}); + return true; + } + return false; + }; +} + +// Folds addition of an addition where each operation has a constant operand. +// Cases: +// (x + 2) + 2 = x + 4 +// (2 + x) + 2 = x + 4 +// 2 + (x + 2) = x + 4 +// 2 + (2 + x) = x + 4 +FoldingRule MergeAddAddArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (other_inst->opcode() == spv::Op::OpFAdd || + other_inst->opcode() == spv::Op::OpIAdd) { + std::vector other_constants = + const_mgr->GetOperandConstants(other_inst); + const analysis::Constant* const_input2 = ConstInput(other_constants); + if (!const_input2) return false; + + Instruction* non_const_input = + NonConstInput(context, other_constants[0], other_inst); + uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(), + const_input1, const_input2); + if (merged_id == 0) return false; + + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {non_const_input->result_id()}}, + {SPV_OPERAND_TYPE_ID, {merged_id}}}); + return true; + } + return false; + }; +} + +// Folds addition of a subtraction where each operation has a constant operand. +// Cases: +// (x - 2) + 2 = x + 0 +// (2 - x) + 2 = 4 - x +// 2 + (x - 2) = x + 0 +// 2 + (2 - x) = 4 - x +FoldingRule MergeAddSubArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (other_inst->opcode() == spv::Op::OpFSub || + other_inst->opcode() == spv::Op::OpISub) { + std::vector other_constants = + const_mgr->GetOperandConstants(other_inst); + const analysis::Constant* const_input2 = ConstInput(other_constants); + if (!const_input2) return false; + + bool first_is_variable = other_constants[0] == nullptr; + spv::Op op = inst->opcode(); + uint32_t op1 = 0; + uint32_t op2 = 0; + if (first_is_variable) { + // Subtract constants. Non-constant operand is first. + op1 = other_inst->GetSingleWordInOperand(0u); + op2 = PerformOperation(const_mgr, other_inst->opcode(), const_input1, + const_input2); + } else { + // Add constants. Constant operand is first. Change the opcode. + op1 = PerformOperation(const_mgr, inst->opcode(), const_input1, + const_input2); + op2 = other_inst->GetSingleWordInOperand(1u); + op = other_inst->opcode(); + } + if (op1 == 0 || op2 == 0) return false; + + inst->SetOpcode(op); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}); + return true; + } + return false; + }; +} + +// Folds subtraction of an addition where each operand has a constant operand. +// Cases: +// (x + 2) - 2 = x + 0 +// (2 + x) - 2 = x + 0 +// 2 - (x + 2) = 0 - x +// 2 - (2 + x) = 0 - x +FoldingRule MergeSubAddArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFSub || + inst->opcode() == spv::Op::OpISub); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (other_inst->opcode() == spv::Op::OpFAdd || + other_inst->opcode() == spv::Op::OpIAdd) { + std::vector other_constants = + const_mgr->GetOperandConstants(other_inst); + const analysis::Constant* const_input2 = ConstInput(other_constants); + if (!const_input2) return false; + + Instruction* non_const_input = + NonConstInput(context, other_constants[0], other_inst); + + // If the first operand of the sub is not a constant, swap the constants + // so the subtraction has the correct operands. + if (constants[0] == nullptr) std::swap(const_input1, const_input2); + // Subtract the constants. + uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(), + const_input1, const_input2); + spv::Op op = inst->opcode(); + uint32_t op1 = 0; + uint32_t op2 = 0; + if (constants[0] == nullptr) { + // Non-constant operand is first. Change the opcode. + op1 = non_const_input->result_id(); + op2 = merged_id; + op = other_inst->opcode(); + } else { + // Constant operand is first. + op1 = merged_id; + op2 = non_const_input->result_id(); + } + if (op1 == 0 || op2 == 0) return false; + + inst->SetOpcode(op); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}); + return true; + } + return false; + }; +} + +// Folds subtraction of a subtraction where each operand has a constant operand. +// Cases: +// (x - 2) - 2 = x - 4 +// (2 - x) - 2 = 0 - x +// 2 - (x - 2) = 4 - x +// 2 - (2 - x) = x + 0 +FoldingRule MergeSubSubArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFSub || + inst->opcode() == spv::Op::OpISub); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + const analysis::Constant* const_input1 = ConstInput(constants); + if (!const_input1) return false; + Instruction* other_inst = NonConstInput(context, constants[0], inst); + if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) + return false; + + if (other_inst->opcode() == spv::Op::OpFSub || + other_inst->opcode() == spv::Op::OpISub) { + std::vector other_constants = + const_mgr->GetOperandConstants(other_inst); + const analysis::Constant* const_input2 = ConstInput(other_constants); + if (!const_input2) return false; + + Instruction* non_const_input = + NonConstInput(context, other_constants[0], other_inst); + + // Merge the constants. + uint32_t merged_id = 0; + spv::Op merge_op = inst->opcode(); + if (other_constants[0] == nullptr) { + merge_op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd; + } else if (constants[0] == nullptr) { + std::swap(const_input1, const_input2); + } + merged_id = + PerformOperation(const_mgr, merge_op, const_input1, const_input2); + if (merged_id == 0) return false; + + spv::Op op = inst->opcode(); + if (constants[0] != nullptr && other_constants[0] != nullptr) { + // Change the operation. + op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd; + } + + uint32_t op1 = 0; + uint32_t op2 = 0; + if ((constants[0] == nullptr) ^ (other_constants[0] == nullptr)) { + op1 = merged_id; + op2 = non_const_input->result_id(); + } else { + op1 = non_const_input->result_id(); + op2 = merged_id; + } + + inst->SetOpcode(op); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}); + return true; + } + return false; + }; +} + +// Helper function for MergeGenericAddSubArithmetic. If |addend| and +// subtrahend of |sub| is the same, merge to copy of minuend of |sub|. +bool MergeGenericAddendSub(uint32_t addend, uint32_t sub, Instruction* inst) { + IRContext* context = inst->context(); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + Instruction* sub_inst = def_use_mgr->GetDef(sub); + if (sub_inst->opcode() != spv::Op::OpFSub && + sub_inst->opcode() != spv::Op::OpISub) + return false; + if (sub_inst->opcode() == spv::Op::OpFSub && + !sub_inst->IsFloatingPointFoldingAllowed()) + return false; + if (addend != sub_inst->GetSingleWordInOperand(1)) return false; + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {sub_inst->GetSingleWordInOperand(0)}}}); + context->UpdateDefUse(inst); + return true; +} + +// Folds addition of a subtraction where the subtrahend is equal to the +// other addend. Return a copy of the minuend. Accepts generic (const and +// non-const) operands. +// Cases: +// (a - b) + b = a +// b + (a - b) = a +FoldingRule MergeGenericAddSubArithmetic() { + return [](IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + uint32_t width = ElementWidth(type); + if (width != 32 && width != 64) return false; + + uint32_t add_op0 = inst->GetSingleWordInOperand(0); + uint32_t add_op1 = inst->GetSingleWordInOperand(1); + if (MergeGenericAddendSub(add_op0, add_op1, inst)) return true; + return MergeGenericAddendSub(add_op1, add_op0, inst); + }; +} + +// Helper function for FactorAddMuls. If |factor0_0| is the same as |factor1_0|, +// generate |factor0_0| * (|factor0_1| + |factor1_1|). +bool FactorAddMulsOpnds(uint32_t factor0_0, uint32_t factor0_1, + uint32_t factor1_0, uint32_t factor1_1, + Instruction* inst) { + IRContext* context = inst->context(); + if (factor0_0 != factor1_0) return false; + InstructionBuilder ir_builder( + context, inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + Instruction* new_add_inst = ir_builder.AddBinaryOp( + inst->type_id(), inst->opcode(), factor0_1, factor1_1); + inst->SetOpcode(inst->opcode() == spv::Op::OpFAdd ? spv::Op::OpFMul + : spv::Op::OpIMul); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {factor0_0}}, + {SPV_OPERAND_TYPE_ID, {new_add_inst->result_id()}}}); + context->UpdateDefUse(inst); + return true; +} + +// Perform the following factoring identity, handling all operand order +// combinations: (a * b) + (a * c) = a * (b + c) +FoldingRule FactorAddMuls() { + return [](IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpFAdd || + inst->opcode() == spv::Op::OpIAdd); + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + bool uses_float = HasFloatingPoint(type); + if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false; + + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + uint32_t add_op0 = inst->GetSingleWordInOperand(0); + Instruction* add_op0_inst = def_use_mgr->GetDef(add_op0); + if (add_op0_inst->opcode() != spv::Op::OpFMul && + add_op0_inst->opcode() != spv::Op::OpIMul) + return false; + uint32_t add_op1 = inst->GetSingleWordInOperand(1); + Instruction* add_op1_inst = def_use_mgr->GetDef(add_op1); + if (add_op1_inst->opcode() != spv::Op::OpFMul && + add_op1_inst->opcode() != spv::Op::OpIMul) + return false; + + // Only perform this optimization if both of the muls only have one use. + // Otherwise this is a deoptimization in size and performance. + if (def_use_mgr->NumUses(add_op0_inst) > 1) return false; + if (def_use_mgr->NumUses(add_op1_inst) > 1) return false; + + if (add_op0_inst->opcode() == spv::Op::OpFMul && + (!add_op0_inst->IsFloatingPointFoldingAllowed() || + !add_op1_inst->IsFloatingPointFoldingAllowed())) + return false; + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + // Check if operand i in add_op0_inst matches operand j in add_op1_inst. + if (FactorAddMulsOpnds(add_op0_inst->GetSingleWordInOperand(i), + add_op0_inst->GetSingleWordInOperand(1 - i), + add_op1_inst->GetSingleWordInOperand(j), + add_op1_inst->GetSingleWordInOperand(1 - j), + inst)) + return true; + } + } + return false; + }; +} + +// Replaces |inst| inplace with an FMA instruction |(x*y)+a|. +void ReplaceWithFma(Instruction* inst, uint32_t x, uint32_t y, uint32_t a) { + uint32_t ext = + inst->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + + if (ext == 0) { + inst->context()->AddExtInstImport("GLSL.std.450"); + ext = inst->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + assert(ext != 0 && + "Could not add the GLSL.std.450 extended instruction set"); + } + + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {ext}}); + operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {GLSLstd450Fma}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {x}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {a}}); + + inst->SetOpcode(spv::Op::OpExtInst); + inst->SetInOperands(std::move(operands)); +} + +// Folds a multiple and add into an Fma. +// +// Cases: +// (x * y) + a = Fma x y a +// a + (x * y) = Fma x y a +bool MergeMulAddArithmetic(IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpFAdd); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return false; + } + + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + for (int i = 0; i < 2; i++) { + uint32_t op_id = inst->GetSingleWordInOperand(i); + Instruction* op_inst = def_use_mgr->GetDef(op_id); + + if (op_inst->opcode() != spv::Op::OpFMul) { + continue; + } + + if (!op_inst->IsFloatingPointFoldingAllowed()) { + continue; + } + + uint32_t x = op_inst->GetSingleWordInOperand(0); + uint32_t y = op_inst->GetSingleWordInOperand(1); + uint32_t a = inst->GetSingleWordInOperand((i + 1) % 2); + ReplaceWithFma(inst, x, y, a); + return true; + } + return false; +} + +// Replaces |sub| inplace with an FMA instruction |(x*y)+a| where |a| first gets +// negated if |negate_addition| is true, otherwise |x| gets negated. +void ReplaceWithFmaAndNegate(Instruction* sub, uint32_t x, uint32_t y, + uint32_t a, bool negate_addition) { + uint32_t ext = + sub->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + + if (ext == 0) { + sub->context()->AddExtInstImport("GLSL.std.450"); + ext = sub->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + assert(ext != 0 && + "Could not add the GLSL.std.450 extended instruction set"); + } + + InstructionBuilder ir_builder( + sub->context(), sub, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + Instruction* neg = ir_builder.AddUnaryOp(sub->type_id(), spv::Op::OpFNegate, + negate_addition ? a : x); + uint32_t neg_op = neg->result_id(); // -a : -x + + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {ext}}); + operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {GLSLstd450Fma}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {negate_addition ? x : neg_op}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {negate_addition ? neg_op : a}}); + + sub->SetOpcode(spv::Op::OpExtInst); + sub->SetInOperands(std::move(operands)); +} + +// Folds a multiply and subtract into an Fma and negation. +// +// Cases: +// (x * y) - a = Fma x y -a +// a - (x * y) = Fma -x y a +bool MergeMulSubArithmetic(IRContext* context, Instruction* sub, + const std::vector&) { + assert(sub->opcode() == spv::Op::OpFSub); + + if (!sub->IsFloatingPointFoldingAllowed()) { + return false; + } + + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + for (int i = 0; i < 2; i++) { + uint32_t op_id = sub->GetSingleWordInOperand(i); + Instruction* mul = def_use_mgr->GetDef(op_id); + + if (mul->opcode() != spv::Op::OpFMul) { + continue; + } + + if (!mul->IsFloatingPointFoldingAllowed()) { + continue; + } + + uint32_t x = mul->GetSingleWordInOperand(0); + uint32_t y = mul->GetSingleWordInOperand(1); + uint32_t a = sub->GetSingleWordInOperand((i + 1) % 2); + ReplaceWithFmaAndNegate(sub, x, y, a, i == 0); + return true; + } + return false; +} + +FoldingRule IntMultipleBy1() { + return [](IRContext*, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpIMul && + "Wrong opcode. Should be OpIMul."); + for (uint32_t i = 0; i < 2; i++) { + if (constants[i] == nullptr) { + continue; + } + const analysis::IntConstant* int_constant = constants[i]->AsIntConstant(); + if (int_constant) { + uint32_t width = ElementWidth(int_constant->type()); + if (width != 32 && width != 64) return false; + bool is_one = (width == 32) ? int_constant->GetU32BitValue() == 1u + : int_constant->GetU64BitValue() == 1ull; + if (is_one) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(1 - i)}}}); + return true; + } + } + } + return false; + }; +} + +// Returns the number of elements that the |index|th in operand in |inst| +// contributes to the result of |inst|. |inst| must be an +// OpCompositeConstructInstruction. +uint32_t GetNumOfElementsContributedByOperand(IRContext* context, + const Instruction* inst, + uint32_t index) { + assert(inst->opcode() == spv::Op::OpCompositeConstruct); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + + analysis::Vector* result_type = + type_mgr->GetType(inst->type_id())->AsVector(); + if (result_type == nullptr) { + // If the result of the OpCompositeConstruct is not a vector then every + // operands corresponds to a single element in the result. + return 1; + } + + // If the result type is a vector then the operands are either scalars or + // vectors. If it is a scalar, then it corresponds to a single element. If it + // is a vector, then each element in the vector will be an element in the + // result. + uint32_t id = inst->GetSingleWordInOperand(index); + Instruction* def = def_use_mgr->GetDef(id); + analysis::Vector* type = type_mgr->GetType(def->type_id())->AsVector(); + if (type == nullptr) { + return 1; + } + return type->element_count(); +} + +// Returns the in-operands for an OpCompositeExtract instruction that are needed +// to extract the |result_index|th element in the result of |inst| without using +// the result of |inst|. Returns the empty vector if |result_index| is +// out-of-bounds. |inst| must be an |OpCompositeConstruct| instruction. +std::vector GetExtractOperandsForElementOfCompositeConstruct( + IRContext* context, const Instruction* inst, uint32_t result_index) { + assert(inst->opcode() == spv::Op::OpCompositeConstruct); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + + analysis::Type* result_type = type_mgr->GetType(inst->type_id()); + if (result_type->AsVector() == nullptr) { + if (result_index < inst->NumInOperands()) { + uint32_t id = inst->GetSingleWordInOperand(result_index); + return {Operand(SPV_OPERAND_TYPE_ID, {id})}; + } + return {}; + } + + // If the result type is a vector, then vector operands are concatenated. + uint32_t total_element_count = 0; + for (uint32_t idx = 0; idx < inst->NumInOperands(); ++idx) { + uint32_t element_count = + GetNumOfElementsContributedByOperand(context, inst, idx); + total_element_count += element_count; + if (result_index < total_element_count) { + std::vector operands; + uint32_t id = inst->GetSingleWordInOperand(idx); + Instruction* operand_def = def_use_mgr->GetDef(id); + analysis::Type* operand_type = type_mgr->GetType(operand_def->type_id()); + + operands.push_back({SPV_OPERAND_TYPE_ID, {id}}); + if (operand_type->AsVector()) { + uint32_t start_index_of_id = total_element_count - element_count; + uint32_t index_into_id = result_index - start_index_of_id; + operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {index_into_id}}); + } + return operands; + } + } + return {}; +} + +bool CompositeConstructFeedingExtract( + IRContext* context, Instruction* inst, + const std::vector&) { + // If the input to an OpCompositeExtract is an OpCompositeConstruct, + // then we can simply use the appropriate element in the construction. + assert(inst->opcode() == spv::Op::OpCompositeExtract && + "Wrong opcode. Should be OpCompositeExtract."); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + + // If there are no index operands, then this rule cannot do anything. + if (inst->NumInOperands() <= 1) { + return false; + } + + uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); + Instruction* cinst = def_use_mgr->GetDef(cid); + + if (cinst->opcode() != spv::Op::OpCompositeConstruct) { + return false; + } + + uint32_t index_into_result = inst->GetSingleWordInOperand(1); + std::vector operands = + GetExtractOperandsForElementOfCompositeConstruct(context, cinst, + index_into_result); + + if (operands.empty()) { + return false; + } + + // Add the remaining indices for extraction. + for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { + operands.push_back( + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {inst->GetSingleWordInOperand(i)}}); + } + + if (operands.size() == 1) { + // If there were no extra indices, then we have the final object. No need + // to extract any more. + inst->SetOpcode(spv::Op::OpCopyObject); + } + + inst->SetInOperands(std::move(operands)); + return true; +} + +// Walks the indexes chain from |start| to |end| of an OpCompositeInsert or +// OpCompositeExtract instruction, and returns the type of the final element +// being accessed. +const analysis::Type* GetElementType(uint32_t type_id, + Instruction::iterator start, + Instruction::iterator end, + const analysis::TypeManager* type_mgr) { + const analysis::Type* type = type_mgr->GetType(type_id); + for (auto index : make_range(std::move(start), std::move(end))) { + assert(index.type == SPV_OPERAND_TYPE_LITERAL_INTEGER && + index.words.size() == 1); + if (auto* array_type = type->AsArray()) { + type = array_type->element_type(); + } else if (auto* matrix_type = type->AsMatrix()) { + type = matrix_type->element_type(); + } else if (auto* struct_type = type->AsStruct()) { + type = struct_type->element_types()[index.words[0]]; + } else { + type = nullptr; + } + } + return type; +} + +// Returns true of |inst_1| and |inst_2| have the same indexes that will be used +// to index into a composite object, excluding the last index. The two +// instructions must have the same opcode, and be either OpCompositeExtract or +// OpCompositeInsert instructions. +bool HaveSameIndexesExceptForLast(Instruction* inst_1, Instruction* inst_2) { + assert(inst_1->opcode() == inst_2->opcode() && + "Expecting the opcodes to be the same."); + assert((inst_1->opcode() == spv::Op::OpCompositeInsert || + inst_1->opcode() == spv::Op::OpCompositeExtract) && + "Instructions must be OpCompositeInsert or OpCompositeExtract."); + + if (inst_1->NumInOperands() != inst_2->NumInOperands()) { + return false; + } + + uint32_t first_index_position = + (inst_1->opcode() == spv::Op::OpCompositeInsert ? 2 : 1); + for (uint32_t i = first_index_position; i < inst_1->NumInOperands() - 1; + i++) { + if (inst_1->GetSingleWordInOperand(i) != + inst_2->GetSingleWordInOperand(i)) { + return false; + } + } + return true; +} + +// If the OpCompositeConstruct is simply putting back together elements that +// where extracted from the same source, we can simply reuse the source. +// +// This is a common code pattern because of the way that scalar replacement +// works. +bool CompositeExtractFeedingConstruct( + IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpCompositeConstruct && + "Wrong opcode. Should be OpCompositeConstruct."); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + uint32_t original_id = 0; + + if (inst->NumInOperands() == 0) { + // The struct being constructed has no members. + return false; + } + + // Check each element to make sure they are: + // - extractions + // - extracting the same position they are inserting + // - all extract from the same id. + Instruction* first_element_inst = nullptr; + for (uint32_t i = 0; i < inst->NumInOperands(); ++i) { + const uint32_t element_id = inst->GetSingleWordInOperand(i); + Instruction* element_inst = def_use_mgr->GetDef(element_id); + if (first_element_inst == nullptr) { + first_element_inst = element_inst; + } + + if (element_inst->opcode() != spv::Op::OpCompositeExtract) { + return false; + } + + if (!HaveSameIndexesExceptForLast(element_inst, first_element_inst)) { + return false; + } + + if (element_inst->GetSingleWordInOperand(element_inst->NumInOperands() - + 1) != i) { + return false; + } + + if (i == 0) { + original_id = + element_inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); + } else if (original_id != + element_inst->GetSingleWordInOperand(kExtractCompositeIdInIdx)) { + return false; + } + } + + // The last check it to see that the object being extracted from is the + // correct type. + Instruction* original_inst = def_use_mgr->GetDef(original_id); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + const analysis::Type* original_type = + GetElementType(original_inst->type_id(), first_element_inst->begin() + 3, + first_element_inst->end() - 1, type_mgr); + + if (original_type == nullptr) { + return false; + } + + if (inst->type_id() != type_mgr->GetId(original_type)) { + return false; + } + + if (first_element_inst->NumInOperands() == 2) { + // Simplify by using the original object. + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {original_id}}}); + return true; + } + + // Copies the original id and all indexes except for the last to the new + // extract instruction. + inst->SetOpcode(spv::Op::OpCompositeExtract); + inst->SetInOperands(std::vector(first_element_inst->begin() + 2, + first_element_inst->end() - 1)); + return true; +} + +FoldingRule InsertFeedingExtract() { + return [](IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpCompositeExtract && + "Wrong opcode. Should be OpCompositeExtract."); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); + Instruction* cinst = def_use_mgr->GetDef(cid); + + if (cinst->opcode() != spv::Op::OpCompositeInsert) { + return false; + } + + // Find the first position where the list of insert and extract indicies + // differ, if at all. + uint32_t i; + for (i = 1; i < inst->NumInOperands(); ++i) { + if (i + 1 >= cinst->NumInOperands()) { + break; + } + + if (inst->GetSingleWordInOperand(i) != + cinst->GetSingleWordInOperand(i + 1)) { + break; + } + } + + // We are extracting the element that was inserted. + if (i == inst->NumInOperands() && i + 1 == cinst->NumInOperands()) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, + {cinst->GetSingleWordInOperand(kInsertObjectIdInIdx)}}}); + return true; + } + + // Extracting the value that was inserted along with values for the base + // composite. Cannot do anything. + if (i == inst->NumInOperands()) { + return false; + } + + // Extracting an element of the value that was inserted. Extract from + // that value directly. + if (i + 1 == cinst->NumInOperands()) { + std::vector operands; + operands.push_back( + {SPV_OPERAND_TYPE_ID, + {cinst->GetSingleWordInOperand(kInsertObjectIdInIdx)}}); + for (; i < inst->NumInOperands(); ++i) { + operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, + {inst->GetSingleWordInOperand(i)}}); + } + inst->SetInOperands(std::move(operands)); + return true; + } + + // Extracting a value that is disjoint from the element being inserted. + // Rewrite the extract to use the composite input to the insert. + std::vector operands; + operands.push_back( + {SPV_OPERAND_TYPE_ID, + {cinst->GetSingleWordInOperand(kInsertCompositeIdInIdx)}}); + for (i = 1; i < inst->NumInOperands(); ++i) { + operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, + {inst->GetSingleWordInOperand(i)}}); + } + inst->SetInOperands(std::move(operands)); + return true; + }; +} + +// When a VectorShuffle is feeding an Extract, we can extract from one of the +// operands of the VectorShuffle. We just need to adjust the index in the +// extract instruction. +FoldingRule VectorShuffleFeedingExtract() { + return [](IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpCompositeExtract && + "Wrong opcode. Should be OpCompositeExtract."); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); + Instruction* cinst = def_use_mgr->GetDef(cid); + + if (cinst->opcode() != spv::Op::OpVectorShuffle) { + return false; + } + + // Find the size of the first vector operand of the VectorShuffle + Instruction* first_input = + def_use_mgr->GetDef(cinst->GetSingleWordInOperand(0)); + analysis::Type* first_input_type = + type_mgr->GetType(first_input->type_id()); + assert(first_input_type->AsVector() && + "Input to vector shuffle should be vectors."); + uint32_t first_input_size = first_input_type->AsVector()->element_count(); + + // Get index of the element the vector shuffle is placing in the position + // being extracted. + uint32_t new_index = + cinst->GetSingleWordInOperand(2 + inst->GetSingleWordInOperand(1)); + + // Extracting an undefined value so fold this extract into an undef. + const uint32_t undef_literal_value = 0xffffffff; + if (new_index == undef_literal_value) { + inst->SetOpcode(spv::Op::OpUndef); + inst->SetInOperands({}); + return true; + } + + // Get the id of the of the vector the elemtent comes from, and update the + // index if needed. + uint32_t new_vector = 0; + if (new_index < first_input_size) { + new_vector = cinst->GetSingleWordInOperand(0); + } else { + new_vector = cinst->GetSingleWordInOperand(1); + new_index -= first_input_size; + } + + // Update the extract instruction. + inst->SetInOperand(kExtractCompositeIdInIdx, {new_vector}); + inst->SetInOperand(1, {new_index}); + return true; + }; +} + +// When an FMix with is feeding an Extract that extracts an element whose +// corresponding |a| in the FMix is 0 or 1, we can extract from one of the +// operands of the FMix. +FoldingRule FMixFeedingExtract() { + return [](IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpCompositeExtract && + "Wrong opcode. Should be OpCompositeExtract."); + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + + uint32_t composite_id = + inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); + Instruction* composite_inst = def_use_mgr->GetDef(composite_id); + + if (composite_inst->opcode() != spv::Op::OpExtInst) { + return false; + } + + uint32_t inst_set_id = + context->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + + if (composite_inst->GetSingleWordInOperand(kExtInstSetIdInIdx) != + inst_set_id || + composite_inst->GetSingleWordInOperand(kExtInstInstructionInIdx) != + GLSLstd450FMix) { + return false; + } + + // Get the |a| for the FMix instruction. + uint32_t a_id = composite_inst->GetSingleWordInOperand(kFMixAIdInIdx); + std::unique_ptr a(inst->Clone(context)); + a->SetInOperand(kExtractCompositeIdInIdx, {a_id}); + context->get_instruction_folder().FoldInstruction(a.get()); + + if (a->opcode() != spv::Op::OpCopyObject) { + return false; + } + + const analysis::Constant* a_const = + const_mgr->FindDeclaredConstant(a->GetSingleWordInOperand(0)); + + if (!a_const) { + return false; + } + + bool use_x = false; + + assert(a_const->type()->AsFloat()); + double element_value = a_const->GetValueAsDouble(); + if (element_value == 0.0) { + use_x = true; + } else if (element_value == 1.0) { + use_x = false; + } else { + return false; + } + + // Get the id of the of the vector the element comes from. + uint32_t new_vector = 0; + if (use_x) { + new_vector = composite_inst->GetSingleWordInOperand(kFMixXIdInIdx); + } else { + new_vector = composite_inst->GetSingleWordInOperand(kFMixYIdInIdx); + } + + // Update the extract instruction. + inst->SetInOperand(kExtractCompositeIdInIdx, {new_vector}); + return true; + }; +} + +// Returns the number of elements in the composite type |type|. Returns 0 if +// |type| is a scalar value. Return UINT32_MAX when the size is unknown at +// compile time. +uint32_t GetNumberOfElements(const analysis::Type* type) { + if (auto* vector_type = type->AsVector()) { + return vector_type->element_count(); + } + if (auto* matrix_type = type->AsMatrix()) { + return matrix_type->element_count(); + } + if (auto* struct_type = type->AsStruct()) { + return static_cast(struct_type->element_types().size()); + } + if (auto* array_type = type->AsArray()) { + if (array_type->length_info().words[0] == + analysis::Array::LengthInfo::kConstant && + array_type->length_info().words.size() == 2) { + return array_type->length_info().words[1]; + } + return UINT32_MAX; + } + return 0; +} + +// Returns a map with the set of values that were inserted into an object by +// the chain of OpCompositeInsertInstruction starting with |inst|. +// The map will map the index to the value inserted at that index. An empty map +// will be returned if the map could not be properly generated. +std::map GetInsertedValues(Instruction* inst) { + analysis::DefUseManager* def_use_mgr = inst->context()->get_def_use_mgr(); + std::map values_inserted; + Instruction* current_inst = inst; + while (current_inst->opcode() == spv::Op::OpCompositeInsert) { + if (current_inst->NumInOperands() > inst->NumInOperands()) { + // This is to catch the case + // %2 = OpCompositeInsert %m2x2int %v2int_1_0 %m2x2int_undef 0 + // %3 = OpCompositeInsert %m2x2int %int_4 %2 0 0 + // %4 = OpCompositeInsert %m2x2int %v2int_2_3 %3 1 + // In this case we cannot do a single construct to get the matrix. + uint32_t partially_inserted_element_index = + current_inst->GetSingleWordInOperand(inst->NumInOperands() - 1); + if (values_inserted.count(partially_inserted_element_index) == 0) + return {}; + } + if (HaveSameIndexesExceptForLast(inst, current_inst)) { + values_inserted.insert( + {current_inst->GetSingleWordInOperand(current_inst->NumInOperands() - + 1), + current_inst->GetSingleWordInOperand(kInsertObjectIdInIdx)}); + } + current_inst = def_use_mgr->GetDef( + current_inst->GetSingleWordInOperand(kInsertCompositeIdInIdx)); + } + return values_inserted; +} + +// Returns true of there is an entry in |values_inserted| for every element of +// |Type|. +bool DoInsertedValuesCoverEntireObject( + const analysis::Type* type, std::map& values_inserted) { + uint32_t container_size = GetNumberOfElements(type); + if (container_size != values_inserted.size()) { + return false; + } + + if (values_inserted.rbegin()->first >= container_size) { + return false; + } + return true; +} + +// Returns the type of the element that immediately contains the element being +// inserted by the OpCompositeInsert instruction |inst|. +const analysis::Type* GetContainerType(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpCompositeInsert); + analysis::TypeManager* type_mgr = inst->context()->get_type_mgr(); + return GetElementType(inst->type_id(), inst->begin() + 4, inst->end() - 1, + type_mgr); +} + +// Returns an OpCompositeConstruct instruction that build an object with +// |type_id| out of the values in |values_inserted|. Each value will be +// placed at the index corresponding to the value. The new instruction will +// be placed before |insert_before|. +Instruction* BuildCompositeConstruct( + uint32_t type_id, const std::map& values_inserted, + Instruction* insert_before) { + InstructionBuilder ir_builder( + insert_before->context(), insert_before, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + std::vector ids_in_order; + for (auto it : values_inserted) { + ids_in_order.push_back(it.second); + } + Instruction* construct = + ir_builder.AddCompositeConstruct(type_id, ids_in_order); + return construct; +} + +// Replaces the OpCompositeInsert |inst| that inserts |construct| into the same +// object as |inst| with final index removed. If the resulting +// OpCompositeInsert instruction would have no remaining indexes, the +// instruction is replaced with an OpCopyObject instead. +void InsertConstructedObject(Instruction* inst, const Instruction* construct) { + if (inst->NumInOperands() == 3) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {construct->result_id()}}}); + } else { + inst->SetInOperand(kInsertObjectIdInIdx, {construct->result_id()}); + inst->RemoveOperand(inst->NumOperands() - 1); + } +} + +// Replaces a series of |OpCompositeInsert| instruction that cover the entire +// object with an |OpCompositeConstruct|. +bool CompositeInsertToCompositeConstruct( + IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpCompositeInsert && + "Wrong opcode. Should be OpCompositeInsert."); + if (inst->NumInOperands() < 3) return false; + + std::map values_inserted = GetInsertedValues(inst); + const analysis::Type* container_type = GetContainerType(inst); + if (container_type == nullptr) { + return false; + } + + if (!DoInsertedValuesCoverEntireObject(container_type, values_inserted)) { + return false; + } + + analysis::TypeManager* type_mgr = context->get_type_mgr(); + Instruction* construct = BuildCompositeConstruct( + type_mgr->GetId(container_type), values_inserted, inst); + InsertConstructedObject(inst, construct); + return true; +} + +FoldingRule RedundantPhi() { + // An OpPhi instruction where all values are the same or the result of the phi + // itself, can be replaced by the value itself. + return [](IRContext*, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpPhi && + "Wrong opcode. Should be OpPhi."); + + uint32_t incoming_value = 0; + + for (uint32_t i = 0; i < inst->NumInOperands(); i += 2) { + uint32_t op_id = inst->GetSingleWordInOperand(i); + if (op_id == inst->result_id()) { + continue; + } + + if (incoming_value == 0) { + incoming_value = op_id; + } else if (op_id != incoming_value) { + // Found two possible value. Can't simplify. + return false; + } + } + + if (incoming_value == 0) { + // Code looks invalid. Don't do anything. + return false; + } + + // We have a single incoming value. Simplify using that value. + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {incoming_value}}}); + return true; + }; +} + +FoldingRule BitCastScalarOrVector() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpBitcast && constants.size() == 1); + if (constants[0] == nullptr) return false; + + const analysis::Type* type = + context->get_type_mgr()->GetType(inst->type_id()); + if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed()) + return false; + + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + std::vector words = + GetWordsFromNumericScalarOrVectorConstant(const_mgr, constants[0]); + if (words.size() == 0) return false; + + const analysis::Constant* bitcasted_constant = + ConvertWordsToNumericScalarOrVectorConstant(const_mgr, words, type); + if (!bitcasted_constant) return false; + + auto new_feeder_id = + const_mgr->GetDefiningInstruction(bitcasted_constant, inst->type_id()) + ->result_id(); + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {new_feeder_id}}}); + return true; + }; +} + +FoldingRule RedundantSelect() { + // An OpSelect instruction where both values are the same or the condition is + // constant can be replaced by one of the values + return [](IRContext*, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpSelect && + "Wrong opcode. Should be OpSelect."); + assert(inst->NumInOperands() == 3); + assert(constants.size() == 3); + + uint32_t true_id = inst->GetSingleWordInOperand(1); + uint32_t false_id = inst->GetSingleWordInOperand(2); + + if (true_id == false_id) { + // Both results are the same, condition doesn't matter + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {true_id}}}); + return true; + } else if (constants[0]) { + const analysis::Type* type = constants[0]->type(); + if (type->AsBool()) { + // Scalar constant value, select the corresponding value. + inst->SetOpcode(spv::Op::OpCopyObject); + if (constants[0]->AsNullConstant() || + !constants[0]->AsBoolConstant()->value()) { + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {false_id}}}); + } else { + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {true_id}}}); + } + return true; + } else { + assert(type->AsVector()); + if (constants[0]->AsNullConstant()) { + // All values come from false id. + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {false_id}}}); + return true; + } else { + // Convert to a vector shuffle. + std::vector ops; + ops.push_back({SPV_OPERAND_TYPE_ID, {true_id}}); + ops.push_back({SPV_OPERAND_TYPE_ID, {false_id}}); + const analysis::VectorConstant* vector_const = + constants[0]->AsVectorConstant(); + uint32_t size = + static_cast(vector_const->GetComponents().size()); + for (uint32_t i = 0; i != size; ++i) { + const analysis::Constant* component = + vector_const->GetComponents()[i]; + if (component->AsNullConstant() || + !component->AsBoolConstant()->value()) { + // Selecting from the false vector which is the second input + // vector to the shuffle. Offset the index by |size|. + ops.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {i + size}}); + } else { + // Selecting from true vector which is the first input vector to + // the shuffle. + ops.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}); + } + } + + inst->SetOpcode(spv::Op::OpVectorShuffle); + inst->SetInOperands(std::move(ops)); + return true; + } + } + } + + return false; + }; +} + +enum class FloatConstantKind { Unknown, Zero, One }; + +FloatConstantKind getFloatConstantKind(const analysis::Constant* constant) { + if (constant == nullptr) { + return FloatConstantKind::Unknown; + } + + assert(HasFloatingPoint(constant->type()) && "Unexpected constant type"); + + if (constant->AsNullConstant()) { + return FloatConstantKind::Zero; + } else if (const analysis::VectorConstant* vc = + constant->AsVectorConstant()) { + const std::vector& components = + vc->GetComponents(); + assert(!components.empty()); + + FloatConstantKind kind = getFloatConstantKind(components[0]); + + for (size_t i = 1; i < components.size(); ++i) { + if (getFloatConstantKind(components[i]) != kind) { + return FloatConstantKind::Unknown; + } + } + + return kind; + } else if (const analysis::FloatConstant* fc = constant->AsFloatConstant()) { + if (fc->IsZero()) return FloatConstantKind::Zero; + + uint32_t width = fc->type()->AsFloat()->width(); + if (width != 32 && width != 64) return FloatConstantKind::Unknown; + + double value = (width == 64) ? fc->GetDoubleValue() : fc->GetFloatValue(); + + if (value == 0.0) { + return FloatConstantKind::Zero; + } else if (value == 1.0) { + return FloatConstantKind::One; + } else { + return FloatConstantKind::Unknown; + } + } else { + return FloatConstantKind::Unknown; + } +} + +FoldingRule RedundantFAdd() { + return [](IRContext*, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFAdd && + "Wrong opcode. Should be OpFAdd."); + assert(constants.size() == 2); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return false; + } + + FloatConstantKind kind0 = getFloatConstantKind(constants[0]); + FloatConstantKind kind1 = getFloatConstantKind(constants[1]); + + if (kind0 == FloatConstantKind::Zero || kind1 == FloatConstantKind::Zero) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, + {inst->GetSingleWordInOperand( + kind0 == FloatConstantKind::Zero ? 1 : 0)}}}); + return true; + } + + return false; + }; +} + +FoldingRule RedundantFSub() { + return [](IRContext*, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFSub && + "Wrong opcode. Should be OpFSub."); + assert(constants.size() == 2); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return false; + } + + FloatConstantKind kind0 = getFloatConstantKind(constants[0]); + FloatConstantKind kind1 = getFloatConstantKind(constants[1]); + + if (kind0 == FloatConstantKind::Zero) { + inst->SetOpcode(spv::Op::OpFNegate); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(1)}}}); + return true; + } + + if (kind1 == FloatConstantKind::Zero) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); + return true; + } + + return false; + }; +} + +FoldingRule RedundantFMul() { + return [](IRContext*, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFMul && + "Wrong opcode. Should be OpFMul."); + assert(constants.size() == 2); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return false; + } + + FloatConstantKind kind0 = getFloatConstantKind(constants[0]); + FloatConstantKind kind1 = getFloatConstantKind(constants[1]); + + if (kind0 == FloatConstantKind::Zero || kind1 == FloatConstantKind::Zero) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, + {inst->GetSingleWordInOperand( + kind0 == FloatConstantKind::Zero ? 0 : 1)}}}); + return true; + } + + if (kind0 == FloatConstantKind::One || kind1 == FloatConstantKind::One) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, + {inst->GetSingleWordInOperand( + kind0 == FloatConstantKind::One ? 1 : 0)}}}); + return true; + } + + return false; + }; +} + +FoldingRule RedundantFDiv() { + return [](IRContext*, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpFDiv && + "Wrong opcode. Should be OpFDiv."); + assert(constants.size() == 2); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return false; + } + + FloatConstantKind kind0 = getFloatConstantKind(constants[0]); + FloatConstantKind kind1 = getFloatConstantKind(constants[1]); + + if (kind0 == FloatConstantKind::Zero) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); + return true; + } + + if (kind1 == FloatConstantKind::One) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); + return true; + } + + return false; + }; +} + +FoldingRule RedundantFMix() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpExtInst && + "Wrong opcode. Should be OpExtInst."); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return false; + } + + uint32_t instSetId = + context->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + + if (inst->GetSingleWordInOperand(kExtInstSetIdInIdx) == instSetId && + inst->GetSingleWordInOperand(kExtInstInstructionInIdx) == + GLSLstd450FMix) { + assert(constants.size() == 5); + + FloatConstantKind kind4 = getFloatConstantKind(constants[4]); + + if (kind4 == FloatConstantKind::Zero || kind4 == FloatConstantKind::One) { + inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetInOperands( + {{SPV_OPERAND_TYPE_ID, + {inst->GetSingleWordInOperand(kind4 == FloatConstantKind::Zero + ? kFMixXIdInIdx + : kFMixYIdInIdx)}}}); + return true; + } + } + + return false; + }; +} + +// This rule handles addition of zero for integers. +FoldingRule RedundantIAdd() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpIAdd && + "Wrong opcode. Should be OpIAdd."); + + uint32_t operand = std::numeric_limits::max(); + const analysis::Type* operand_type = nullptr; + if (constants[0] && constants[0]->IsZero()) { + operand = inst->GetSingleWordInOperand(1); + operand_type = constants[0]->type(); + } else if (constants[1] && constants[1]->IsZero()) { + operand = inst->GetSingleWordInOperand(0); + operand_type = constants[1]->type(); + } + + if (operand != std::numeric_limits::max()) { + const analysis::Type* inst_type = + context->get_type_mgr()->GetType(inst->type_id()); + if (inst_type->IsSame(operand_type)) { + inst->SetOpcode(spv::Op::OpCopyObject); + } else { + inst->SetOpcode(spv::Op::OpBitcast); + } + inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {operand}}}); + return true; + } + return false; + }; +} + +// This rule look for a dot with a constant vector containing a single 1 and +// the rest 0s. This is the same as doing an extract. +FoldingRule DotProductDoingExtract() { + return [](IRContext* context, Instruction* inst, + const std::vector& constants) { + assert(inst->opcode() == spv::Op::OpDot && + "Wrong opcode. Should be OpDot."); + + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + + if (!inst->IsFloatingPointFoldingAllowed()) { + return false; + } + + for (int i = 0; i < 2; ++i) { + if (!constants[i]) { + continue; + } + + const analysis::Vector* vector_type = constants[i]->type()->AsVector(); + assert(vector_type && "Inputs to OpDot must be vectors."); + const analysis::Float* element_type = + vector_type->element_type()->AsFloat(); + assert(element_type && "Inputs to OpDot must be vectors of floats."); + uint32_t element_width = element_type->width(); + if (element_width != 32 && element_width != 64) { + return false; + } + + std::vector components; + components = constants[i]->GetVectorComponents(const_mgr); + + constexpr uint32_t kNotFound = std::numeric_limits::max(); + + uint32_t component_with_one = kNotFound; + bool all_others_zero = true; + for (uint32_t j = 0; j < components.size(); ++j) { + const analysis::Constant* element = components[j]; + double value = + (element_width == 32 ? element->GetFloat() : element->GetDouble()); + if (value == 0.0) { + continue; + } else if (value == 1.0) { + if (component_with_one == kNotFound) { + component_with_one = j; + } else { + component_with_one = kNotFound; + break; + } + } else { + all_others_zero = false; + break; + } + } + + if (!all_others_zero || component_with_one == kNotFound) { + continue; + } + + std::vector operands; + operands.push_back( + {SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(1u - i)}}); + operands.push_back( + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {component_with_one}}); + + inst->SetOpcode(spv::Op::OpCompositeExtract); + inst->SetInOperands(std::move(operands)); + return true; + } + return false; + }; +} + +// If we are storing an undef, then we can remove the store. +// +// TODO: We can do something similar for OpImageWrite, but checking for volatile +// is complicated. Waiting to see if it is needed. +FoldingRule StoringUndef() { + return [](IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpStore && + "Wrong opcode. Should be OpStore."); + + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + + // If this is a volatile store, the store cannot be removed. + if (inst->NumInOperands() == 3) { + if (inst->GetSingleWordInOperand(2) & + uint32_t(spv::MemoryAccessMask::Volatile)) { + return false; + } + } + + uint32_t object_id = inst->GetSingleWordInOperand(kStoreObjectInIdx); + Instruction* object_inst = def_use_mgr->GetDef(object_id); + if (object_inst->opcode() == spv::Op::OpUndef) { + inst->ToNop(); + return true; + } + return false; + }; +} + +FoldingRule VectorShuffleFeedingShuffle() { + return [](IRContext* context, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpVectorShuffle && + "Wrong opcode. Should be OpVectorShuffle."); + + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context->get_type_mgr(); + + Instruction* feeding_shuffle_inst = + def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); + analysis::Vector* op0_type = + type_mgr->GetType(feeding_shuffle_inst->type_id())->AsVector(); + uint32_t op0_length = op0_type->element_count(); + + bool feeder_is_op0 = true; + if (feeding_shuffle_inst->opcode() != spv::Op::OpVectorShuffle) { + feeding_shuffle_inst = + def_use_mgr->GetDef(inst->GetSingleWordInOperand(1)); + feeder_is_op0 = false; + } + + if (feeding_shuffle_inst->opcode() != spv::Op::OpVectorShuffle) { + return false; + } + + Instruction* feeder2 = + def_use_mgr->GetDef(feeding_shuffle_inst->GetSingleWordInOperand(0)); + analysis::Vector* feeder_op0_type = + type_mgr->GetType(feeder2->type_id())->AsVector(); + uint32_t feeder_op0_length = feeder_op0_type->element_count(); + + uint32_t new_feeder_id = 0; + std::vector new_operands; + new_operands.resize( + 2, {SPV_OPERAND_TYPE_ID, {0}}); // Place holders for vector operands. + const uint32_t undef_literal = 0xffffffff; + for (uint32_t op = 2; op < inst->NumInOperands(); ++op) { + uint32_t component_index = inst->GetSingleWordInOperand(op); + + // Do not interpret the undefined value literal as coming from operand 1. + if (component_index != undef_literal && + feeder_is_op0 == (component_index < op0_length)) { + // This component comes from the feeding_shuffle_inst. Update + // |component_index| to be the index into the operand of the feeder. + + // Adjust component_index to get the index into the operands of the + // feeding_shuffle_inst. + if (component_index >= op0_length) { + component_index -= op0_length; + } + component_index = + feeding_shuffle_inst->GetSingleWordInOperand(component_index + 2); + + // Check if we are using a component from the first or second operand of + // the feeding instruction. + if (component_index < feeder_op0_length) { + if (new_feeder_id == 0) { + // First time through, save the id of the operand the element comes + // from. + new_feeder_id = feeding_shuffle_inst->GetSingleWordInOperand(0); + } else if (new_feeder_id != + feeding_shuffle_inst->GetSingleWordInOperand(0)) { + // We need both elements of the feeding_shuffle_inst, so we cannot + // fold. + return false; + } + } else if (component_index != undef_literal) { + if (new_feeder_id == 0) { + // First time through, save the id of the operand the element comes + // from. + new_feeder_id = feeding_shuffle_inst->GetSingleWordInOperand(1); + } else if (new_feeder_id != + feeding_shuffle_inst->GetSingleWordInOperand(1)) { + // We need both elements of the feeding_shuffle_inst, so we cannot + // fold. + return false; + } + component_index -= feeder_op0_length; + } + + if (!feeder_is_op0 && component_index != undef_literal) { + component_index += op0_length; + } + } + new_operands.push_back( + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {component_index}}); + } + + if (new_feeder_id == 0) { + analysis::ConstantManager* const_mgr = context->get_constant_mgr(); + const analysis::Type* type = + type_mgr->GetType(feeding_shuffle_inst->type_id()); + const analysis::Constant* null_const = const_mgr->GetConstant(type, {}); + new_feeder_id = + const_mgr->GetDefiningInstruction(null_const, 0)->result_id(); + } + + if (feeder_is_op0) { + // If the size of the first vector operand changed then the indices + // referring to the second operand need to be adjusted. + Instruction* new_feeder_inst = def_use_mgr->GetDef(new_feeder_id); + analysis::Type* new_feeder_type = + type_mgr->GetType(new_feeder_inst->type_id()); + uint32_t new_op0_size = new_feeder_type->AsVector()->element_count(); + int32_t adjustment = op0_length - new_op0_size; + + if (adjustment != 0) { + for (uint32_t i = 2; i < new_operands.size(); i++) { + uint32_t operand = inst->GetSingleWordInOperand(i); + if (operand >= op0_length && operand != undef_literal) { + new_operands[i].words[0] -= adjustment; + } + } + } + + new_operands[0].words[0] = new_feeder_id; + new_operands[1] = inst->GetInOperand(1); + } else { + new_operands[1].words[0] = new_feeder_id; + new_operands[0] = inst->GetInOperand(0); + } + + inst->SetInOperands(std::move(new_operands)); + return true; + }; +} + +// Removes duplicate ids from the interface list of an OpEntryPoint +// instruction. +FoldingRule RemoveRedundantOperands() { + return [](IRContext*, Instruction* inst, + const std::vector&) { + assert(inst->opcode() == spv::Op::OpEntryPoint && + "Wrong opcode. Should be OpEntryPoint."); + bool has_redundant_operand = false; + std::unordered_set seen_operands; + std::vector new_operands; + + new_operands.emplace_back(inst->GetOperand(0)); + new_operands.emplace_back(inst->GetOperand(1)); + new_operands.emplace_back(inst->GetOperand(2)); + for (uint32_t i = 3; i < inst->NumOperands(); ++i) { + if (seen_operands.insert(inst->GetSingleWordOperand(i)).second) { + new_operands.emplace_back(inst->GetOperand(i)); + } else { + has_redundant_operand = true; + } + } + + if (!has_redundant_operand) { + return false; + } + + inst->SetInOperands(std::move(new_operands)); + return true; + }; +} + +// If an image instruction's operand is a constant, updates the image operand +// flag from Offset to ConstOffset. +FoldingRule UpdateImageOperands() { + return [](IRContext*, Instruction* inst, + const std::vector& constants) { + const auto opcode = inst->opcode(); + (void)opcode; + assert((opcode == spv::Op::OpImageSampleImplicitLod || + opcode == spv::Op::OpImageSampleExplicitLod || + opcode == spv::Op::OpImageSampleDrefImplicitLod || + opcode == spv::Op::OpImageSampleDrefExplicitLod || + opcode == spv::Op::OpImageSampleProjImplicitLod || + opcode == spv::Op::OpImageSampleProjExplicitLod || + opcode == spv::Op::OpImageSampleProjDrefImplicitLod || + opcode == spv::Op::OpImageSampleProjDrefExplicitLod || + opcode == spv::Op::OpImageFetch || + opcode == spv::Op::OpImageGather || + opcode == spv::Op::OpImageDrefGather || + opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite || + opcode == spv::Op::OpImageSparseSampleImplicitLod || + opcode == spv::Op::OpImageSparseSampleExplicitLod || + opcode == spv::Op::OpImageSparseSampleDrefImplicitLod || + opcode == spv::Op::OpImageSparseSampleDrefExplicitLod || + opcode == spv::Op::OpImageSparseSampleProjImplicitLod || + opcode == spv::Op::OpImageSparseSampleProjExplicitLod || + opcode == spv::Op::OpImageSparseSampleProjDrefImplicitLod || + opcode == spv::Op::OpImageSparseSampleProjDrefExplicitLod || + opcode == spv::Op::OpImageSparseFetch || + opcode == spv::Op::OpImageSparseGather || + opcode == spv::Op::OpImageSparseDrefGather || + opcode == spv::Op::OpImageSparseRead) && + "Wrong opcode. Should be an image instruction."); + + int32_t operand_index = ImageOperandsMaskInOperandIndex(inst); + if (operand_index >= 0) { + auto image_operands = inst->GetSingleWordInOperand(operand_index); + if (image_operands & uint32_t(spv::ImageOperandsMask::Offset)) { + uint32_t offset_operand_index = operand_index + 1; + if (image_operands & uint32_t(spv::ImageOperandsMask::Bias)) + offset_operand_index++; + if (image_operands & uint32_t(spv::ImageOperandsMask::Lod)) + offset_operand_index++; + if (image_operands & uint32_t(spv::ImageOperandsMask::Grad)) + offset_operand_index += 2; + assert(((image_operands & + uint32_t(spv::ImageOperandsMask::ConstOffset)) == 0) && + "Offset and ConstOffset may not be used together"); + if (offset_operand_index < inst->NumOperands()) { + if (constants[offset_operand_index]) { + if (constants[offset_operand_index]->IsZero()) { + inst->RemoveInOperand(offset_operand_index); + } else { + image_operands = image_operands | + uint32_t(spv::ImageOperandsMask::ConstOffset); + } + image_operands = + image_operands & ~uint32_t(spv::ImageOperandsMask::Offset); + inst->SetInOperand(operand_index, {image_operands}); + return true; + } + } + } + } + + return false; + }; +} + +} // namespace + +void FoldingRules::AddFoldingRules() { + // Add all folding rules to the list for the opcodes to which they apply. + // Note that the order in which rules are added to the list matters. If a rule + // applies to the instruction, the rest of the rules will not be attempted. + // Take that into consideration. + rules_[spv::Op::OpBitcast].push_back(BitCastScalarOrVector()); + + rules_[spv::Op::OpCompositeConstruct].push_back( + CompositeExtractFeedingConstruct); + + rules_[spv::Op::OpCompositeExtract].push_back(InsertFeedingExtract()); + rules_[spv::Op::OpCompositeExtract].push_back( + CompositeConstructFeedingExtract); + rules_[spv::Op::OpCompositeExtract].push_back(VectorShuffleFeedingExtract()); + rules_[spv::Op::OpCompositeExtract].push_back(FMixFeedingExtract()); + + rules_[spv::Op::OpCompositeInsert].push_back( + CompositeInsertToCompositeConstruct); + + rules_[spv::Op::OpDot].push_back(DotProductDoingExtract()); + + rules_[spv::Op::OpEntryPoint].push_back(RemoveRedundantOperands()); + + rules_[spv::Op::OpFAdd].push_back(RedundantFAdd()); + rules_[spv::Op::OpFAdd].push_back(MergeAddNegateArithmetic()); + rules_[spv::Op::OpFAdd].push_back(MergeAddAddArithmetic()); + rules_[spv::Op::OpFAdd].push_back(MergeAddSubArithmetic()); + rules_[spv::Op::OpFAdd].push_back(MergeGenericAddSubArithmetic()); + rules_[spv::Op::OpFAdd].push_back(FactorAddMuls()); + rules_[spv::Op::OpFAdd].push_back(MergeMulAddArithmetic); + + rules_[spv::Op::OpFDiv].push_back(RedundantFDiv()); + rules_[spv::Op::OpFDiv].push_back(ReciprocalFDiv()); + rules_[spv::Op::OpFDiv].push_back(MergeDivDivArithmetic()); + rules_[spv::Op::OpFDiv].push_back(MergeDivMulArithmetic()); + rules_[spv::Op::OpFDiv].push_back(MergeDivNegateArithmetic()); + + rules_[spv::Op::OpFMul].push_back(RedundantFMul()); + rules_[spv::Op::OpFMul].push_back(MergeMulMulArithmetic()); + rules_[spv::Op::OpFMul].push_back(MergeMulDivArithmetic()); + rules_[spv::Op::OpFMul].push_back(MergeMulNegateArithmetic()); + + rules_[spv::Op::OpFNegate].push_back(MergeNegateArithmetic()); + rules_[spv::Op::OpFNegate].push_back(MergeNegateAddSubArithmetic()); + rules_[spv::Op::OpFNegate].push_back(MergeNegateMulDivArithmetic()); + + rules_[spv::Op::OpFSub].push_back(RedundantFSub()); + rules_[spv::Op::OpFSub].push_back(MergeSubNegateArithmetic()); + rules_[spv::Op::OpFSub].push_back(MergeSubAddArithmetic()); + rules_[spv::Op::OpFSub].push_back(MergeSubSubArithmetic()); + rules_[spv::Op::OpFSub].push_back(MergeMulSubArithmetic); + + rules_[spv::Op::OpIAdd].push_back(RedundantIAdd()); + rules_[spv::Op::OpIAdd].push_back(MergeAddNegateArithmetic()); + rules_[spv::Op::OpIAdd].push_back(MergeAddAddArithmetic()); + rules_[spv::Op::OpIAdd].push_back(MergeAddSubArithmetic()); + rules_[spv::Op::OpIAdd].push_back(MergeGenericAddSubArithmetic()); + rules_[spv::Op::OpIAdd].push_back(FactorAddMuls()); + + rules_[spv::Op::OpIMul].push_back(IntMultipleBy1()); + rules_[spv::Op::OpIMul].push_back(MergeMulMulArithmetic()); + rules_[spv::Op::OpIMul].push_back(MergeMulNegateArithmetic()); + + rules_[spv::Op::OpISub].push_back(MergeSubNegateArithmetic()); + rules_[spv::Op::OpISub].push_back(MergeSubAddArithmetic()); + rules_[spv::Op::OpISub].push_back(MergeSubSubArithmetic()); + + rules_[spv::Op::OpPhi].push_back(RedundantPhi()); + + rules_[spv::Op::OpSNegate].push_back(MergeNegateArithmetic()); + rules_[spv::Op::OpSNegate].push_back(MergeNegateMulDivArithmetic()); + rules_[spv::Op::OpSNegate].push_back(MergeNegateAddSubArithmetic()); + + rules_[spv::Op::OpSelect].push_back(RedundantSelect()); + + rules_[spv::Op::OpStore].push_back(StoringUndef()); + + rules_[spv::Op::OpVectorShuffle].push_back(VectorShuffleFeedingShuffle()); + + rules_[spv::Op::OpImageSampleImplicitLod].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSampleExplicitLod].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSampleDrefImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSampleDrefExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSampleProjImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSampleProjExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSampleProjDrefImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSampleProjDrefExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageFetch].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageGather].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageDrefGather].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageRead].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageWrite].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleDrefImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleDrefExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleProjImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleProjExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleProjDrefImplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseSampleProjDrefExplicitLod].push_back( + UpdateImageOperands()); + rules_[spv::Op::OpImageSparseFetch].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSparseGather].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSparseDrefGather].push_back(UpdateImageOperands()); + rules_[spv::Op::OpImageSparseRead].push_back(UpdateImageOperands()); + + FeatureManager* feature_manager = context_->get_feature_mgr(); + // Add rules for GLSLstd450 + uint32_t ext_inst_glslstd450_id = + feature_manager->GetExtInstImportId_GLSLstd450(); + if (ext_inst_glslstd450_id != 0) { + ext_rules_[{ext_inst_glslstd450_id, GLSLstd450FMix}].push_back( + RedundantFMix()); + } +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/folding_rules.h b/thirdparty/glslang/External/spirv-tools/source/opt/folding_rules.h new file mode 100644 index 000000000000..b51e0ce4aec8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/folding_rules.h @@ -0,0 +1,124 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_FOLDING_RULES_H_ +#define SOURCE_OPT_FOLDING_RULES_H_ + +#include +#include +#include + +#include "source/opt/constants.h" + +namespace spvtools { +namespace opt { + +// Folding Rules: +// +// The folding mechanism is built around the concept of a |FoldingRule|. A +// folding rule is a function that implements a method of simplifying an +// instruction. +// +// The inputs to a folding rule are: +// |inst| - the instruction to be simplified. +// |constants| - if an in-operands is an id of a constant, then the +// corresponding value in |constants| contains that +// constant value. Otherwise, the corresponding entry in +// |constants| is |nullptr|. +// +// A folding rule returns true if |inst| can be simplified using this rule. If +// the instruction can be simplified, then |inst| is changed to the simplified +// instruction. Otherwise, |inst| remains the same. +// +// See folding_rules.cpp for examples on how to write a folding rule. It is +// important to note that if |inst| can be folded to the result of an +// instruction that feed it, then |inst| should be changed to an OpCopyObject +// that copies that id. +// +// Be sure to add new folding rules to the table of folding rules in the +// constructor for FoldingRules. The new rule should be added to the list for +// every opcode that it applies to. Note that earlier rules in the list are +// given priority. That is, if an earlier rule is able to fold an instruction, +// the later rules will not be attempted. + +using FoldingRule = std::function& constants)>; + +class FoldingRules { + public: + using FoldingRuleSet = std::vector; + + explicit FoldingRules(IRContext* ctx) : context_(ctx) {} + virtual ~FoldingRules() = default; + + const FoldingRuleSet& GetRulesForInstruction(Instruction* inst) const { + if (inst->opcode() != spv::Op::OpExtInst) { + auto it = rules_.find(inst->opcode()); + if (it != rules_.end()) { + return it->second; + } + } else { + uint32_t ext_inst_id = inst->GetSingleWordInOperand(0); + uint32_t ext_opcode = inst->GetSingleWordInOperand(1); + auto it = ext_rules_.find({ext_inst_id, ext_opcode}); + if (it != ext_rules_.end()) { + return it->second; + } + } + return empty_vector_; + } + + IRContext* context() { return context_; } + + // Adds the folding rules for the object. + virtual void AddFoldingRules(); + + protected: + struct hasher { + size_t operator()(const spv::Op& op) const noexcept { + return std::hash()(uint32_t(op)); + } + }; + + // The folding rules for core instructions. + std::unordered_map rules_; + + // The folding rules for extended instructions. + struct Key { + uint32_t instruction_set; + uint32_t opcode; + }; + + friend bool operator<(const Key& a, const Key& b) { + if (a.instruction_set < b.instruction_set) { + return true; + } + if (a.instruction_set > b.instruction_set) { + return false; + } + return a.opcode < b.opcode; + } + + std::map ext_rules_; + + private: + IRContext* context_; + FoldingRuleSet empty_vector_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_FOLDING_RULES_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/freeze_spec_constant_value_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/freeze_spec_constant_value_pass.cpp new file mode 100644 index 000000000000..3f89e56c0724 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/freeze_spec_constant_value_pass.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/freeze_spec_constant_value_pass.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +Pass::Status FreezeSpecConstantValuePass::Process() { + bool modified = false; + auto ctx = context(); + ctx->module()->ForEachInst([&modified, ctx](Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpSpecConstant: + inst->SetOpcode(spv::Op::OpConstant); + modified = true; + break; + case spv::Op::OpSpecConstantTrue: + inst->SetOpcode(spv::Op::OpConstantTrue); + modified = true; + break; + case spv::Op::OpSpecConstantFalse: + inst->SetOpcode(spv::Op::OpConstantFalse); + modified = true; + break; + case spv::Op::OpDecorate: + if (spv::Decoration(inst->GetSingleWordInOperand(1)) == + spv::Decoration::SpecId) { + ctx->KillInst(inst); + modified = true; + } + break; + default: + break; + } + }); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/freeze_spec_constant_value_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/freeze_spec_constant_value_pass.h new file mode 100644 index 000000000000..0663adf401c9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/freeze_spec_constant_value_pass.h @@ -0,0 +1,35 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_FREEZE_SPEC_CONSTANT_VALUE_PASS_H_ +#define SOURCE_OPT_FREEZE_SPEC_CONSTANT_VALUE_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class FreezeSpecConstantValuePass : public Pass { + public: + const char* name() const override { return "freeze-spec-const"; } + Status Process() override; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_FREEZE_SPEC_CONSTANT_VALUE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/function.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/function.cpp new file mode 100644 index 000000000000..2ee88eca8e36 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/function.cpp @@ -0,0 +1,280 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/function.h" + +#include + +#include "ir_context.h" +#include "source/util/bit_vector.h" + +namespace spvtools { +namespace opt { + +Function* Function::Clone(IRContext* ctx) const { + Function* clone = + new Function(std::unique_ptr(DefInst().Clone(ctx))); + clone->params_.reserve(params_.size()); + ForEachParam( + [clone, ctx](const Instruction* inst) { + clone->AddParameter(std::unique_ptr(inst->Clone(ctx))); + }, + true); + + for (const auto& i : debug_insts_in_header_) { + clone->AddDebugInstructionInHeader( + std::unique_ptr(i.Clone(ctx))); + } + + clone->blocks_.reserve(blocks_.size()); + for (const auto& b : blocks_) { + std::unique_ptr bb(b->Clone(ctx)); + clone->AddBasicBlock(std::move(bb)); + } + + clone->SetFunctionEnd(std::unique_ptr(EndInst()->Clone(ctx))); + + clone->non_semantic_.reserve(non_semantic_.size()); + for (auto& non_semantic : non_semantic_) { + clone->AddNonSemanticInstruction( + std::unique_ptr(non_semantic->Clone(ctx))); + } + return clone; +} + +void Function::ForEachInst(const std::function& f, + bool run_on_debug_line_insts, + bool run_on_non_semantic_insts) { + WhileEachInst( + [&f](Instruction* inst) { + f(inst); + return true; + }, + run_on_debug_line_insts, run_on_non_semantic_insts); +} + +void Function::ForEachInst(const std::function& f, + bool run_on_debug_line_insts, + bool run_on_non_semantic_insts) const { + WhileEachInst( + [&f](const Instruction* inst) { + f(inst); + return true; + }, + run_on_debug_line_insts, run_on_non_semantic_insts); +} + +bool Function::WhileEachInst(const std::function& f, + bool run_on_debug_line_insts, + bool run_on_non_semantic_insts) { + if (def_inst_) { + if (!def_inst_->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + + for (auto& param : params_) { + if (!param->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + + if (!debug_insts_in_header_.empty()) { + Instruction* di = &debug_insts_in_header_.front(); + while (di != nullptr) { + Instruction* next_instruction = di->NextNode(); + if (!di->WhileEachInst(f, run_on_debug_line_insts)) return false; + di = next_instruction; + } + } + + for (auto& bb : blocks_) { + if (!bb->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + + if (end_inst_) { + if (!end_inst_->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + + if (run_on_non_semantic_insts) { + for (auto& non_semantic : non_semantic_) { + if (!non_semantic->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + } + + return true; +} + +bool Function::WhileEachInst(const std::function& f, + bool run_on_debug_line_insts, + bool run_on_non_semantic_insts) const { + if (def_inst_) { + if (!static_cast(def_inst_.get()) + ->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + + for (const auto& param : params_) { + if (!static_cast(param.get()) + ->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + + for (const auto& di : debug_insts_in_header_) { + if (!static_cast(&di)->WhileEachInst( + f, run_on_debug_line_insts)) + return false; + } + + for (const auto& bb : blocks_) { + if (!static_cast(bb.get())->WhileEachInst( + f, run_on_debug_line_insts)) { + return false; + } + } + + if (end_inst_) { + if (!static_cast(end_inst_.get()) + ->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + + if (run_on_non_semantic_insts) { + for (auto& non_semantic : non_semantic_) { + if (!static_cast(non_semantic.get()) + ->WhileEachInst(f, run_on_debug_line_insts)) { + return false; + } + } + } + + return true; +} + +void Function::ForEachParam(const std::function& f, + bool run_on_debug_line_insts) { + for (auto& param : params_) + static_cast(param.get()) + ->ForEachInst(f, run_on_debug_line_insts); +} + +void Function::ForEachParam(const std::function& f, + bool run_on_debug_line_insts) const { + for (const auto& param : params_) + static_cast(param.get()) + ->ForEachInst(f, run_on_debug_line_insts); +} + +void Function::ForEachDebugInstructionsInHeader( + const std::function& f) { + if (debug_insts_in_header_.empty()) return; + + Instruction* di = &debug_insts_in_header_.front(); + while (di != nullptr) { + Instruction* next_instruction = di->NextNode(); + di->ForEachInst(f); + di = next_instruction; + } +} + +BasicBlock* Function::InsertBasicBlockAfter( + std::unique_ptr&& new_block, BasicBlock* position) { + for (auto bb_iter = begin(); bb_iter != end(); ++bb_iter) { + if (&*bb_iter == position) { + new_block->SetParent(this); + ++bb_iter; + bb_iter = bb_iter.InsertBefore(std::move(new_block)); + return &*bb_iter; + } + } + assert(false && "Could not find insertion point."); + return nullptr; +} + +BasicBlock* Function::InsertBasicBlockBefore( + std::unique_ptr&& new_block, BasicBlock* position) { + for (auto bb_iter = begin(); bb_iter != end(); ++bb_iter) { + if (&*bb_iter == position) { + new_block->SetParent(this); + bb_iter = bb_iter.InsertBefore(std::move(new_block)); + return &*bb_iter; + } + } + assert(false && "Could not find insertion point."); + return nullptr; +} + +bool Function::HasEarlyReturn() const { + auto post_dominator_analysis = + blocks_.front()->GetLabel()->context()->GetPostDominatorAnalysis(this); + for (auto& block : blocks_) { + if (spvOpcodeIsReturn(block->tail()->opcode()) && + !post_dominator_analysis->Dominates(block.get(), entry().get())) { + return true; + } + } + return false; +} + +bool Function::IsRecursive() const { + IRContext* ctx = blocks_.front()->GetLabel()->context(); + IRContext::ProcessFunction mark_visited = [this](Function* fp) { + return fp == this; + }; + + // Process the call tree from all of the function called by |this|. If it get + // back to |this|, then we have a recursive function. + std::queue roots; + ctx->AddCalls(this, &roots); + return ctx->ProcessCallTreeFromRoots(mark_visited, &roots); +} + +std::ostream& operator<<(std::ostream& str, const Function& func) { + str << func.PrettyPrint(); + return str; +} + +void Function::Dump() const { + std::cerr << "Function #" << result_id() << "\n" << *this << "\n"; +} + +std::string Function::PrettyPrint(uint32_t options) const { + std::ostringstream str; + ForEachInst([&str, options](const Instruction* inst) { + str << inst->PrettyPrint(options); + if (inst->opcode() != spv::Op::OpFunctionEnd) { + str << std::endl; + } + }); + return str.str(); +} + +void Function::ReorderBasicBlocksInStructuredOrder() { + std::list order; + IRContext* context = this->def_inst_->context(); + context->cfg()->ComputeStructuredOrder(this, blocks_[0].get(), &order); + ReorderBasicBlocks(order.begin(), order.end()); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/function.h b/thirdparty/glslang/External/spirv-tools/source/opt/function.h new file mode 100644 index 000000000000..8c0472cd29dd --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/function.h @@ -0,0 +1,309 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_FUNCTION_H_ +#define SOURCE_OPT_FUNCTION_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/instruction.h" +#include "source/opt/iterator.h" + +namespace spvtools { +namespace opt { + +class CFG; +class IRContext; +class Module; + +// A SPIR-V function. +class Function { + public: + using iterator = UptrVectorIterator; + using const_iterator = UptrVectorIterator; + + // Creates a function instance declared by the given OpFunction instruction + // |def_inst|. + inline explicit Function(std::unique_ptr def_inst); + + explicit Function(const Function& f) = delete; + + // Creates a clone of the instruction in the given |context| + // + // The parent module will default to null and needs to be explicitly set by + // the user. + Function* Clone(IRContext*) const; + // The OpFunction instruction that begins the definition of this function. + Instruction& DefInst() { return *def_inst_; } + const Instruction& DefInst() const { return *def_inst_; } + + // Appends a parameter to this function. + inline void AddParameter(std::unique_ptr p); + // Appends a debug instruction in function header to this function. + inline void AddDebugInstructionInHeader(std::unique_ptr p); + // Appends a basic block to this function. + inline void AddBasicBlock(std::unique_ptr b); + // Appends a basic block to this function at the position |ip|. + inline void AddBasicBlock(std::unique_ptr b, iterator ip); + template + inline void AddBasicBlocks(T begin, T end, iterator ip); + + // Move basic block with |id| to the position after |ip|. Both have to be + // contained in this function. + inline void MoveBasicBlockToAfter(uint32_t id, BasicBlock* ip); + + // Delete all basic blocks that contain no instructions. + inline void RemoveEmptyBlocks(); + + // Removes a parameter from the function with result id equal to |id|. + // Does nothing if the function doesn't have such a parameter. + inline void RemoveParameter(uint32_t id); + + // Saves the given function end instruction. + inline void SetFunctionEnd(std::unique_ptr end_inst); + + // Add a non-semantic instruction that succeeds this function in the module. + // These instructions are maintained in the order they are added. + inline void AddNonSemanticInstruction( + std::unique_ptr non_semantic); + + // Returns the given function end instruction. + inline Instruction* EndInst() { return end_inst_.get(); } + inline const Instruction* EndInst() const { return end_inst_.get(); } + + // Returns function's id + inline uint32_t result_id() const { return def_inst_->result_id(); } + + // Returns function's return type id + inline uint32_t type_id() const { return def_inst_->type_id(); } + + // Returns the function's control mask + inline uint32_t control_mask() const { return def_inst_->GetSingleWordInOperand(0); } + + // Returns the entry basic block for this function. + const std::unique_ptr& entry() const { return blocks_.front(); } + + // Returns the last basic block in this function. + BasicBlock* tail() { return blocks_.back().get(); } + const BasicBlock* tail() const { return blocks_.back().get(); } + + iterator begin() { return iterator(&blocks_, blocks_.begin()); } + iterator end() { return iterator(&blocks_, blocks_.end()); } + const_iterator begin() const { return cbegin(); } + const_iterator end() const { return cend(); } + const_iterator cbegin() const { + return const_iterator(&blocks_, blocks_.cbegin()); + } + const_iterator cend() const { + return const_iterator(&blocks_, blocks_.cend()); + } + + // Returns an iterator to the basic block |id|. + iterator FindBlock(uint32_t bb_id) { + return std::find_if(begin(), end(), [bb_id](const BasicBlock& it_bb) { + return bb_id == it_bb.id(); + }); + } + + // Runs the given function |f| on instructions in this function, in order, + // and optionally on debug line instructions that might precede them and + // non-semantic instructions that succceed the function. + void ForEachInst(const std::function& f, + bool run_on_debug_line_insts = false, + bool run_on_non_semantic_insts = false); + void ForEachInst(const std::function& f, + bool run_on_debug_line_insts = false, + bool run_on_non_semantic_insts = false) const; + // Runs the given function |f| on instructions in this function, in order, + // and optionally on debug line instructions that might precede them and + // non-semantic instructions that succeed the function. If |f| returns + // false, iteration is terminated and this function returns false. + bool WhileEachInst(const std::function& f, + bool run_on_debug_line_insts = false, + bool run_on_non_semantic_insts = false); + bool WhileEachInst(const std::function& f, + bool run_on_debug_line_insts = false, + bool run_on_non_semantic_insts = false) const; + + // Runs the given function |f| on each parameter instruction in this function, + // in order, and optionally on debug line instructions that might precede + // them. + void ForEachParam(const std::function& f, + bool run_on_debug_line_insts = false) const; + void ForEachParam(const std::function& f, + bool run_on_debug_line_insts = false); + + // Runs the given function |f| on each debug instruction in this function's + // header in order. + void ForEachDebugInstructionsInHeader( + const std::function& f); + + BasicBlock* InsertBasicBlockAfter(std::unique_ptr&& new_block, + BasicBlock* position); + + BasicBlock* InsertBasicBlockBefore(std::unique_ptr&& new_block, + BasicBlock* position); + + // Returns true if the function has a return block other than the exit block. + bool HasEarlyReturn() const; + + // Returns true if the function calls itself either directly or indirectly. + bool IsRecursive() const; + + // Pretty-prints all the basic blocks in this function into a std::string. + // + // |options| are the disassembly options. SPV_BINARY_TO_TEXT_OPTION_NO_HEADER + // is always added to |options|. + std::string PrettyPrint(uint32_t options = 0u) const; + + // Dump this function on stderr. Useful when running interactive + // debuggers. + void Dump() const; + + // Returns true is a function declaration and not a function definition. + bool IsDeclaration() { return begin() == end(); } + + // Reorders the basic blocks in the function to match the structured order. + void ReorderBasicBlocksInStructuredOrder(); + + private: + // Reorders the basic blocks in the function to match the order given by the + // range |{begin,end}|. The range must contain every basic block in the + // function, and no extras. + template + void ReorderBasicBlocks(It begin, It end); + + template + bool ContainsAllBlocksInTheFunction(It begin, It end); + + // The OpFunction instruction that begins the definition of this function. + std::unique_ptr def_inst_; + // All parameters to this function. + std::vector> params_; + // All debug instructions in this function's header. + InstructionList debug_insts_in_header_; + // All basic blocks inside this function in specification order + std::vector> blocks_; + // The OpFunctionEnd instruction. + std::unique_ptr end_inst_; + // Non-semantic instructions succeeded by this function. + std::vector> non_semantic_; +}; + +// Pretty-prints |func| to |str|. Returns |str|. +std::ostream& operator<<(std::ostream& str, const Function& func); + +inline Function::Function(std::unique_ptr def_inst) + : def_inst_(std::move(def_inst)), end_inst_() {} + +inline void Function::AddParameter(std::unique_ptr p) { + params_.emplace_back(std::move(p)); +} + +inline void Function::AddDebugInstructionInHeader( + std::unique_ptr p) { + debug_insts_in_header_.push_back(std::move(p)); +} + +inline void Function::AddBasicBlock(std::unique_ptr b) { + AddBasicBlock(std::move(b), end()); +} + +inline void Function::AddBasicBlock(std::unique_ptr b, + iterator ip) { + b->SetParent(this); + ip.InsertBefore(std::move(b)); +} + +template +inline void Function::AddBasicBlocks(T src_begin, T src_end, iterator ip) { + blocks_.insert(ip.Get(), std::make_move_iterator(src_begin), + std::make_move_iterator(src_end)); +} + +inline void Function::MoveBasicBlockToAfter(uint32_t id, BasicBlock* ip) { + std::unique_ptr block_to_move = std::move(*FindBlock(id).Get()); + blocks_.erase(std::find(std::begin(blocks_), std::end(blocks_), nullptr)); + + assert(block_to_move->GetParent() == ip->GetParent() && + "Both blocks have to be in the same function."); + + InsertBasicBlockAfter(std::move(block_to_move), ip); +} + +inline void Function::RemoveEmptyBlocks() { + auto first_empty = + std::remove_if(std::begin(blocks_), std::end(blocks_), + [](const std::unique_ptr& bb) -> bool { + return bb->GetLabelInst()->opcode() == spv::Op::OpNop; + }); + blocks_.erase(first_empty, std::end(blocks_)); +} + +inline void Function::RemoveParameter(uint32_t id) { + params_.erase(std::remove_if(params_.begin(), params_.end(), + [id](const std::unique_ptr& param) { + return param->result_id() == id; + }), + params_.end()); +} + +inline void Function::SetFunctionEnd(std::unique_ptr end_inst) { + end_inst_ = std::move(end_inst); +} + +inline void Function::AddNonSemanticInstruction( + std::unique_ptr non_semantic) { + non_semantic_.emplace_back(std::move(non_semantic)); +} + +template +void Function::ReorderBasicBlocks(It begin, It end) { + // Asserts to make sure every node in the function is in new_order. + assert(ContainsAllBlocksInTheFunction(begin, end)); + + // We have a pointer to all the elements in order, so we can release all + // pointers in |block_|, and then create the new unique pointers from |{begin, + // end}|. + std::for_each(blocks_.begin(), blocks_.end(), + [](std::unique_ptr& bb) { bb.release(); }); + std::transform(begin, end, blocks_.begin(), [](BasicBlock* bb) { + return std::unique_ptr(bb); + }); +} + +template +bool Function::ContainsAllBlocksInTheFunction(It begin, It end) { + std::unordered_multiset range(begin, end); + if (range.size() != blocks_.size()) { + return false; + } + + for (auto& bb : blocks_) { + if (range.count(bb.get()) == 0) return false; + } + return true; +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_FUNCTION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/graphics_robust_access_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/graphics_robust_access_pass.cpp new file mode 100644 index 000000000000..e765c397604c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/graphics_robust_access_pass.cpp @@ -0,0 +1,1054 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This pass injects code in a graphics shader to implement guarantees +// satisfying Vulkan's robustBufferAccess rules. Robust access rules permit +// an out-of-bounds access to be redirected to an access of the same type +// (load, store, etc.) but within the same root object. +// +// We assume baseline functionality in Vulkan, i.e. the module uses +// logical addressing mode, without VK_KHR_variable_pointers. +// +// - Logical addressing mode implies: +// - Each root pointer (a pointer that exists other than by the +// execution of a shader instruction) is the result of an OpVariable. +// +// - Instructions that result in pointers are: +// OpVariable +// OpAccessChain +// OpInBoundsAccessChain +// OpFunctionParameter +// OpImageTexelPointer +// OpCopyObject +// +// - Instructions that use a pointer are: +// OpLoad +// OpStore +// OpAccessChain +// OpInBoundsAccessChain +// OpFunctionCall +// OpImageTexelPointer +// OpCopyMemory +// OpCopyObject +// all OpAtomic* instructions +// +// We classify pointer-users into: +// - Accesses: +// - OpLoad +// - OpStore +// - OpAtomic* +// - OpCopyMemory +// +// - Address calculations: +// - OpAccessChain +// - OpInBoundsAccessChain +// +// - Pass-through: +// - OpFunctionCall +// - OpFunctionParameter +// - OpCopyObject +// +// The strategy is: +// +// - Handle only logical addressing mode. In particular, don't handle a module +// if it uses one of the variable-pointers capabilities. +// +// - Don't handle modules using capability RuntimeDescriptorArrayEXT. So the +// only runtime arrays are those that are the last member in a +// Block-decorated struct. This allows us to feasibly/easily compute the +// length of the runtime array. See below. +// +// - The memory locations accessed by OpLoad, OpStore, OpCopyMemory, and +// OpAtomic* are determined by their pointer parameter or parameters. +// Pointers are always (correctly) typed and so the address and number of +// consecutive locations are fully determined by the pointer. +// +// - A pointer value originates as one of few cases: +// +// - OpVariable for an interface object or an array of them: image, +// buffer (UBO or SSBO), sampler, sampled-image, push-constant, input +// variable, output variable. The execution environment is responsible for +// allocating the correct amount of storage for these, and for ensuring +// each resource bound to such a variable is big enough to contain the +// SPIR-V pointee type of the variable. +// +// - OpVariable for a non-interface object. These are variables in +// Workgroup, Private, and Function storage classes. The compiler ensures +// the underlying allocation is big enough to store the entire SPIR-V +// pointee type of the variable. +// +// - An OpFunctionParameter. This always maps to a pointer parameter to an +// OpFunctionCall. +// +// - In logical addressing mode, these are severely limited: +// "Any pointer operand to an OpFunctionCall must be: +// - a memory object declaration, or +// - a pointer to an element in an array that is a memory object +// declaration, where the element type is OpTypeSampler or OpTypeImage" +// +// - This has an important simplifying consequence: +// +// - When looking for a pointer to the structure containing a runtime +// array, you begin with a pointer to the runtime array and trace +// backward in the function. You never have to trace back beyond +// your function call boundary. So you can't take a partial access +// chain into an SSBO, then pass that pointer into a function. So +// we don't resort to using fat pointers to compute array length. +// We can trace back to a pointer to the containing structure, +// and use that in an OpArrayLength instruction. (The structure type +// gives us the member index of the runtime array.) +// +// - Otherwise, the pointer type fully encodes the range of valid +// addresses. In particular, the type of a pointer to an aggregate +// value fully encodes the range of indices when indexing into +// that aggregate. +// +// - The pointer is the result of an access chain instruction. We clamp +// indices contributing to address calculations. As noted above, the +// valid ranges are either bound by the length of a runtime array, or +// by the type of the base pointer. The length of a runtime array is +// the result of an OpArrayLength instruction acting on the pointer of +// the containing structure as noted above. +// +// - Access chain indices are always treated as signed, so: +// - Clamp the upper bound at the signed integer maximum. +// - Use SClamp for all clamping. +// +// - TODO(dneto): OpImageTexelPointer: +// - Clamp coordinate to the image size returned by OpImageQuerySize +// - If multi-sampled, clamp the sample index to the count returned by +// OpImageQuerySamples. +// - If not multi-sampled, set the sample index to 0. +// +// - Rely on the external validator to check that pointers are only +// used by the instructions as above. +// +// - Handles OpTypeRuntimeArray +// Track pointer back to original resource (pointer to struct), so we can +// query the runtime array size. +// + +#include "graphics_robust_access_pass.h" + +#include +#include +#include + +#include "function.h" +#include "ir_context.h" +#include "pass.h" +#include "source/diagnostic.h" +#include "source/util/make_unique.h" +#include "spirv-tools/libspirv.h" +#include "spirv/unified1/GLSL.std.450.h" +#include "type_manager.h" +#include "types.h" + +namespace spvtools { +namespace opt { + +using opt::Instruction; +using opt::Operand; +using spvtools::MakeUnique; + +GraphicsRobustAccessPass::GraphicsRobustAccessPass() : module_status_() {} + +Pass::Status GraphicsRobustAccessPass::Process() { + module_status_ = PerModuleState(); + + ProcessCurrentModule(); + + auto result = module_status_.failed + ? Status::Failure + : (module_status_.modified ? Status::SuccessWithChange + : Status::SuccessWithoutChange); + + return result; +} + +spvtools::DiagnosticStream GraphicsRobustAccessPass::Fail() { + module_status_.failed = true; + // We don't really have a position, and we'll ignore the result. + return std::move( + spvtools::DiagnosticStream({}, consumer(), "", SPV_ERROR_INVALID_BINARY) + << name() << ": "); +} + +spv_result_t GraphicsRobustAccessPass::IsCompatibleModule() { + auto* feature_mgr = context()->get_feature_mgr(); + if (!feature_mgr->HasCapability(spv::Capability::Shader)) + return Fail() << "Can only process Shader modules"; + if (feature_mgr->HasCapability(spv::Capability::VariablePointers)) + return Fail() << "Can't process modules with VariablePointers capability"; + if (feature_mgr->HasCapability( + spv::Capability::VariablePointersStorageBuffer)) + return Fail() << "Can't process modules with VariablePointersStorageBuffer " + "capability"; + if (feature_mgr->HasCapability(spv::Capability::RuntimeDescriptorArrayEXT)) { + // These have a RuntimeArray outside of Block-decorated struct. There + // is no way to compute the array length from within SPIR-V. + return Fail() << "Can't process modules with RuntimeDescriptorArrayEXT " + "capability"; + } + + { + auto* inst = context()->module()->GetMemoryModel(); + const auto addressing_model = + spv::AddressingModel(inst->GetSingleWordOperand(0)); + if (addressing_model != spv::AddressingModel::Logical) + return Fail() << "Addressing model must be Logical. Found " + << inst->PrettyPrint(); + } + return SPV_SUCCESS; +} + +spv_result_t GraphicsRobustAccessPass::ProcessCurrentModule() { + auto err = IsCompatibleModule(); + if (err != SPV_SUCCESS) return err; + + ProcessFunction fn = [this](opt::Function* f) { return ProcessAFunction(f); }; + module_status_.modified |= context()->ProcessReachableCallTree(fn); + + // Need something here. It's the price we pay for easier failure paths. + return SPV_SUCCESS; +} + +bool GraphicsRobustAccessPass::ProcessAFunction(opt::Function* function) { + // Ensure that all pointers computed inside a function are within bounds. + // Find the access chains in this block before trying to modify them. + std::vector access_chains; + std::vector image_texel_pointers; + for (auto& block : *function) { + for (auto& inst : block) { + switch (inst.opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + access_chains.push_back(&inst); + break; + case spv::Op::OpImageTexelPointer: + image_texel_pointers.push_back(&inst); + break; + default: + break; + } + } + } + for (auto* inst : access_chains) { + ClampIndicesForAccessChain(inst); + if (module_status_.failed) return module_status_.modified; + } + + for (auto* inst : image_texel_pointers) { + if (SPV_SUCCESS != ClampCoordinateForImageTexelPointer(inst)) break; + } + return module_status_.modified; +} + +void GraphicsRobustAccessPass::ClampIndicesForAccessChain( + Instruction* access_chain) { + Instruction& inst = *access_chain; + + auto* constant_mgr = context()->get_constant_mgr(); + auto* def_use_mgr = context()->get_def_use_mgr(); + auto* type_mgr = context()->get_type_mgr(); + const bool have_int64_cap = + context()->get_feature_mgr()->HasCapability(spv::Capability::Int64); + + // Replaces one of the OpAccessChain index operands with a new value. + // Updates def-use analysis. + auto replace_index = [this, &inst, def_use_mgr](uint32_t operand_index, + Instruction* new_value) { + inst.SetOperand(operand_index, {new_value->result_id()}); + def_use_mgr->AnalyzeInstUse(&inst); + module_status_.modified = true; + return SPV_SUCCESS; + }; + + // Replaces one of the OpAccesssChain index operands with a clamped value. + // Replace the operand at |operand_index| with the value computed from + // signed_clamp(%old_value, %min_value, %max_value). It also analyzes + // the new instruction and records that them module is modified. + // Assumes %min_value is signed-less-or-equal than %max_value. (All callees + // use 0 for %min_value). + auto clamp_index = [&inst, type_mgr, this, &replace_index]( + uint32_t operand_index, Instruction* old_value, + Instruction* min_value, Instruction* max_value) { + auto* clamp_inst = + MakeSClampInst(*type_mgr, old_value, min_value, max_value, &inst); + return replace_index(operand_index, clamp_inst); + }; + + // Ensures the specified index of access chain |inst| has a value that is + // at most |count| - 1. If the index is already a constant value less than + // |count| then no change is made. + auto clamp_to_literal_count = + [&inst, this, &constant_mgr, &type_mgr, have_int64_cap, &replace_index, + &clamp_index](uint32_t operand_index, uint64_t count) -> spv_result_t { + Instruction* index_inst = + this->GetDef(inst.GetSingleWordOperand(operand_index)); + const auto* index_type = + type_mgr->GetType(index_inst->type_id())->AsInteger(); + assert(index_type); + const auto index_width = index_type->width(); + + if (count <= 1) { + // Replace the index with 0. + return replace_index(operand_index, GetValueForType(0, index_type)); + } + + uint64_t maxval = count - 1; + + // Compute the bit width of a viable type to hold |maxval|. + // Look for a bit width, up to 64 bits wide, to fit maxval. + uint32_t maxval_width = index_width; + while ((maxval_width < 64) && (0 != (maxval >> maxval_width))) { + maxval_width *= 2; + } + // Determine the type for |maxval|. + uint32_t next_id = context()->module()->IdBound(); + analysis::Integer signed_type_for_query(maxval_width, true); + auto* maxval_type = + type_mgr->GetRegisteredType(&signed_type_for_query)->AsInteger(); + if (next_id != context()->module()->IdBound()) { + module_status_.modified = true; + } + // Access chain indices are treated as signed, so limit the maximum value + // of the index so it will always be positive for a signed clamp operation. + maxval = std::min(maxval, ((uint64_t(1) << (maxval_width - 1)) - 1)); + + if (index_width > 64) { + return this->Fail() << "Can't handle indices wider than 64 bits, found " + "constant index with " + << index_width << " bits as index number " + << operand_index << " of access chain " + << inst.PrettyPrint(); + } + + // Split into two cases: the current index is a constant, or not. + + // If the index is a constant then |index_constant| will not be a null + // pointer. (If index is an |OpConstantNull| then it |index_constant| will + // not be a null pointer.) Since access chain indices must be scalar + // integers, this can't be a spec constant. + if (auto* index_constant = constant_mgr->GetConstantFromInst(index_inst)) { + auto* int_index_constant = index_constant->AsIntConstant(); + int64_t value = 0; + // OpAccessChain indices are treated as signed. So get the signed + // constant value here. + if (index_width <= 32) { + value = int64_t(int_index_constant->GetS32BitValue()); + } else if (index_width <= 64) { + value = int_index_constant->GetS64BitValue(); + } + if (value < 0) { + return replace_index(operand_index, GetValueForType(0, index_type)); + } else if (uint64_t(value) <= maxval) { + // Nothing to do. + return SPV_SUCCESS; + } else { + // Replace with maxval. + assert(count > 0); // Already took care of this case above. + return replace_index(operand_index, + GetValueForType(maxval, maxval_type)); + } + } else { + // Generate a clamp instruction. + assert(maxval >= 1); + assert(index_width <= 64); // Otherwise, already returned above. + if (index_width >= 64 && !have_int64_cap) { + // An inconsistent module. + return Fail() << "Access chain index is wider than 64 bits, but Int64 " + "is not declared: " + << index_inst->PrettyPrint(); + } + // Widen the index value if necessary + if (maxval_width > index_width) { + // Find the wider type. We only need this case if a constant array + // bound is too big. + + // From how we calculated maxval_width, widening won't require adding + // the Int64 capability. + assert(have_int64_cap || maxval_width <= 32); + if (!have_int64_cap && maxval_width >= 64) { + // Be defensive, but this shouldn't happen. + return this->Fail() + << "Clamping index would require adding Int64 capability. " + << "Can't clamp 32-bit index " << operand_index + << " of access chain " << inst.PrettyPrint(); + } + index_inst = WidenInteger(index_type->IsSigned(), maxval_width, + index_inst, &inst); + } + + // Finally, clamp the index. + return clamp_index(operand_index, index_inst, + GetValueForType(0, maxval_type), + GetValueForType(maxval, maxval_type)); + } + return SPV_SUCCESS; + }; + + // Ensures the specified index of access chain |inst| has a value that is at + // most the value of |count_inst| minus 1, where |count_inst| is treated as an + // unsigned integer. This can log a failure. + auto clamp_to_count = [&inst, this, &constant_mgr, &clamp_to_literal_count, + &clamp_index, + &type_mgr](uint32_t operand_index, + Instruction* count_inst) -> spv_result_t { + Instruction* index_inst = + this->GetDef(inst.GetSingleWordOperand(operand_index)); + const auto* index_type = + type_mgr->GetType(index_inst->type_id())->AsInteger(); + const auto* count_type = + type_mgr->GetType(count_inst->type_id())->AsInteger(); + assert(index_type); + if (const auto* count_constant = + constant_mgr->GetConstantFromInst(count_inst)) { + uint64_t value = 0; + const auto width = count_constant->type()->AsInteger()->width(); + if (width <= 32) { + value = count_constant->AsIntConstant()->GetU32BitValue(); + } else if (width <= 64) { + value = count_constant->AsIntConstant()->GetU64BitValue(); + } else { + return this->Fail() << "Can't handle indices wider than 64 bits, found " + "constant index with " + << index_type->width() << "bits"; + } + return clamp_to_literal_count(operand_index, value); + } else { + // Widen them to the same width. + const auto index_width = index_type->width(); + const auto count_width = count_type->width(); + const auto target_width = std::max(index_width, count_width); + // UConvert requires the result type to have 0 signedness. So enforce + // that here. + auto* wider_type = index_width < count_width ? count_type : index_type; + if (index_type->width() < target_width) { + // Access chain indices are treated as signed integers. + index_inst = WidenInteger(true, target_width, index_inst, &inst); + } else if (count_type->width() < target_width) { + // Assume type sizes are treated as unsigned. + count_inst = WidenInteger(false, target_width, count_inst, &inst); + } + // Compute count - 1. + // It doesn't matter if 1 is signed or unsigned. + auto* one = GetValueForType(1, wider_type); + auto* count_minus_1 = InsertInst( + &inst, spv::Op::OpISub, type_mgr->GetId(wider_type), TakeNextId(), + {{SPV_OPERAND_TYPE_ID, {count_inst->result_id()}}, + {SPV_OPERAND_TYPE_ID, {one->result_id()}}}); + auto* zero = GetValueForType(0, wider_type); + // Make sure we clamp to an upper bound that is at most the signed max + // for the target type. + const uint64_t max_signed_value = + ((uint64_t(1) << (target_width - 1)) - 1); + // Use unsigned-min to ensure that the result is always non-negative. + // That ensures we satisfy the invariant for SClamp, where the "min" + // argument we give it (zero), is no larger than the third argument. + auto* upper_bound = + MakeUMinInst(*type_mgr, count_minus_1, + GetValueForType(max_signed_value, wider_type), &inst); + // Now clamp the index to this upper bound. + return clamp_index(operand_index, index_inst, zero, upper_bound); + } + return SPV_SUCCESS; + }; + + const Instruction* base_inst = GetDef(inst.GetSingleWordInOperand(0)); + const Instruction* base_type = GetDef(base_inst->type_id()); + Instruction* pointee_type = GetDef(base_type->GetSingleWordInOperand(1)); + + // Walk the indices from earliest to latest, replacing indices with a + // clamped value, and updating the pointee_type. The order matters for + // the case when we have to compute the length of a runtime array. In + // that the algorithm relies on the fact that that the earlier indices + // have already been clamped. + const uint32_t num_operands = inst.NumOperands(); + for (uint32_t idx = 3; !module_status_.failed && idx < num_operands; ++idx) { + const uint32_t index_id = inst.GetSingleWordOperand(idx); + Instruction* index_inst = GetDef(index_id); + + switch (pointee_type->opcode()) { + case spv::Op::OpTypeMatrix: // Use column count + case spv::Op::OpTypeVector: // Use component count + { + const uint32_t count = pointee_type->GetSingleWordOperand(2); + clamp_to_literal_count(idx, count); + pointee_type = GetDef(pointee_type->GetSingleWordOperand(1)); + } break; + + case spv::Op::OpTypeArray: { + // The array length can be a spec constant, so go through the general + // case. + Instruction* array_len = GetDef(pointee_type->GetSingleWordOperand(2)); + clamp_to_count(idx, array_len); + pointee_type = GetDef(pointee_type->GetSingleWordOperand(1)); + } break; + + case spv::Op::OpTypeStruct: { + // SPIR-V requires the index to be an OpConstant. + // We need to know the index literal value so we can compute the next + // pointee type. + if (index_inst->opcode() != spv::Op::OpConstant || + !constant_mgr->GetConstantFromInst(index_inst) + ->type() + ->AsInteger()) { + Fail() << "Member index into struct is not a constant integer: " + << index_inst->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) + << "\nin access chain: " + << inst.PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + return; + } + const auto num_members = pointee_type->NumInOperands(); + const auto* index_constant = + constant_mgr->GetConstantFromInst(index_inst); + // Get the sign-extended value, since access index is always treated as + // signed. + const auto index_value = index_constant->GetSignExtendedValue(); + if (index_value < 0 || index_value >= num_members) { + Fail() << "Member index " << index_value + << " is out of bounds for struct type: " + << pointee_type->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) + << "\nin access chain: " + << inst.PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + return; + } + pointee_type = GetDef(pointee_type->GetSingleWordInOperand( + static_cast(index_value))); + // No need to clamp this index. We just checked that it's valid. + } break; + + case spv::Op::OpTypeRuntimeArray: { + auto* array_len = MakeRuntimeArrayLengthInst(&inst, idx); + if (!array_len) { // We've already signaled an error. + return; + } + clamp_to_count(idx, array_len); + if (module_status_.failed) return; + pointee_type = GetDef(pointee_type->GetSingleWordOperand(1)); + } break; + + default: + Fail() << " Unhandled pointee type for access chain " + << pointee_type->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + } + } +} + +uint32_t GraphicsRobustAccessPass::GetGlslInsts() { + if (module_status_.glsl_insts_id == 0) { + // This string serves double-duty as raw data for a string and for a vector + // of 32-bit words + const char glsl[] = "GLSL.std.450"; + // Use an existing import if we can. + for (auto& inst : context()->module()->ext_inst_imports()) { + if (inst.GetInOperand(0).AsString() == glsl) { + module_status_.glsl_insts_id = inst.result_id(); + } + } + if (module_status_.glsl_insts_id == 0) { + // Make a new import instruction. + module_status_.glsl_insts_id = TakeNextId(); + std::vector words = spvtools::utils::MakeVector(glsl); + auto import_inst = MakeUnique( + context(), spv::Op::OpExtInstImport, 0, module_status_.glsl_insts_id, + std::initializer_list{ + Operand{SPV_OPERAND_TYPE_LITERAL_STRING, std::move(words)}}); + Instruction* inst = import_inst.get(); + context()->module()->AddExtInstImport(std::move(import_inst)); + module_status_.modified = true; + context()->AnalyzeDefUse(inst); + // Invalidates the feature manager, since we added an extended instruction + // set import. + context()->ResetFeatureManager(); + } + } + return module_status_.glsl_insts_id; +} + +opt::Instruction* opt::GraphicsRobustAccessPass::GetValueForType( + uint64_t value, const analysis::Integer* type) { + auto* mgr = context()->get_constant_mgr(); + assert(type->width() <= 64); + std::vector words; + words.push_back(uint32_t(value)); + if (type->width() > 32) { + words.push_back(uint32_t(value >> 32u)); + } + const auto* constant = mgr->GetConstant(type, words); + return mgr->GetDefiningInstruction( + constant, context()->get_type_mgr()->GetTypeInstruction(type)); +} + +opt::Instruction* opt::GraphicsRobustAccessPass::WidenInteger( + bool sign_extend, uint32_t bit_width, Instruction* value, + Instruction* before_inst) { + analysis::Integer unsigned_type_for_query(bit_width, false); + auto* type_mgr = context()->get_type_mgr(); + auto* unsigned_type = type_mgr->GetRegisteredType(&unsigned_type_for_query); + auto type_id = context()->get_type_mgr()->GetId(unsigned_type); + auto conversion_id = TakeNextId(); + auto* conversion = InsertInst( + before_inst, (sign_extend ? spv::Op::OpSConvert : spv::Op::OpUConvert), + type_id, conversion_id, {{SPV_OPERAND_TYPE_ID, {value->result_id()}}}); + return conversion; +} + +Instruction* GraphicsRobustAccessPass::MakeUMinInst( + const analysis::TypeManager& tm, Instruction* x, Instruction* y, + Instruction* where) { + // Get IDs of instructions we'll be referencing. Evaluate them before calling + // the function so we force a deterministic ordering in case both of them need + // to take a new ID. + const uint32_t glsl_insts_id = GetGlslInsts(); + uint32_t smin_id = TakeNextId(); + const auto xwidth = tm.GetType(x->type_id())->AsInteger()->width(); + const auto ywidth = tm.GetType(y->type_id())->AsInteger()->width(); + assert(xwidth == ywidth); + (void)xwidth; + (void)ywidth; + auto* smin_inst = InsertInst( + where, spv::Op::OpExtInst, x->type_id(), smin_id, + { + {SPV_OPERAND_TYPE_ID, {glsl_insts_id}}, + {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, {GLSLstd450UMin}}, + {SPV_OPERAND_TYPE_ID, {x->result_id()}}, + {SPV_OPERAND_TYPE_ID, {y->result_id()}}, + }); + return smin_inst; +} + +Instruction* GraphicsRobustAccessPass::MakeSClampInst( + const analysis::TypeManager& tm, Instruction* x, Instruction* min, + Instruction* max, Instruction* where) { + // Get IDs of instructions we'll be referencing. Evaluate them before calling + // the function so we force a deterministic ordering in case both of them need + // to take a new ID. + const uint32_t glsl_insts_id = GetGlslInsts(); + uint32_t clamp_id = TakeNextId(); + const auto xwidth = tm.GetType(x->type_id())->AsInteger()->width(); + const auto minwidth = tm.GetType(min->type_id())->AsInteger()->width(); + const auto maxwidth = tm.GetType(max->type_id())->AsInteger()->width(); + assert(xwidth == minwidth); + assert(xwidth == maxwidth); + (void)xwidth; + (void)minwidth; + (void)maxwidth; + auto* clamp_inst = InsertInst( + where, spv::Op::OpExtInst, x->type_id(), clamp_id, + { + {SPV_OPERAND_TYPE_ID, {glsl_insts_id}}, + {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, {GLSLstd450SClamp}}, + {SPV_OPERAND_TYPE_ID, {x->result_id()}}, + {SPV_OPERAND_TYPE_ID, {min->result_id()}}, + {SPV_OPERAND_TYPE_ID, {max->result_id()}}, + }); + return clamp_inst; +} + +Instruction* GraphicsRobustAccessPass::MakeRuntimeArrayLengthInst( + Instruction* access_chain, uint32_t operand_index) { + // The Index parameter to the access chain at |operand_index| is indexing + // *into* the runtime-array. To get the number of elements in the runtime + // array we need a pointer to the Block-decorated struct that contains the + // runtime array. So conceptually we have to go 2 steps backward in the + // access chain. The two steps backward might forces us to traverse backward + // across multiple dominating instructions. + auto* type_mgr = context()->get_type_mgr(); + + // How many access chain indices do we have to unwind to find the pointer + // to the struct containing the runtime array? + uint32_t steps_remaining = 2; + // Find or create an instruction computing the pointer to the structure + // containing the runtime array. + // Walk backward through pointer address calculations until we either get + // to exactly the right base pointer, or to an access chain instruction + // that we can replicate but truncate to compute the address of the right + // struct. + Instruction* current_access_chain = access_chain; + Instruction* pointer_to_containing_struct = nullptr; + while (steps_remaining > 0) { + switch (current_access_chain->opcode()) { + case spv::Op::OpCopyObject: + // Whoops. Walk right through this one. + current_access_chain = + GetDef(current_access_chain->GetSingleWordInOperand(0)); + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: { + const int first_index_operand = 3; + // How many indices in this access chain contribute to getting us + // to an element in the runtime array? + const auto num_contributing_indices = + current_access_chain == access_chain + ? operand_index - (first_index_operand - 1) + : current_access_chain->NumInOperands() - 1 /* skip the base */; + Instruction* base = + GetDef(current_access_chain->GetSingleWordInOperand(0)); + if (num_contributing_indices == steps_remaining) { + // The base pointer points to the structure. + pointer_to_containing_struct = base; + steps_remaining = 0; + break; + } else if (num_contributing_indices < steps_remaining) { + // Peel off the index and keep going backward. + steps_remaining -= num_contributing_indices; + current_access_chain = base; + } else { + // This access chain has more indices than needed. Generate a new + // access chain instruction, but truncating the list of indices. + const int base_operand = 2; + // We'll use the base pointer and the indices up to but not including + // the one indexing into the runtime array. + Instruction::OperandList ops; + // Use the base pointer + ops.push_back(current_access_chain->GetOperand(base_operand)); + const uint32_t num_indices_to_keep = + num_contributing_indices - steps_remaining - 1; + for (uint32_t i = 0; i <= num_indices_to_keep; i++) { + ops.push_back( + current_access_chain->GetOperand(first_index_operand + i)); + } + // Compute the type of the result of the new access chain. Start at + // the base and walk the indices in a forward direction. + auto* constant_mgr = context()->get_constant_mgr(); + std::vector indices_for_type; + for (uint32_t i = 0; i < ops.size() - 1; i++) { + uint32_t index_for_type_calculation = 0; + Instruction* index = + GetDef(current_access_chain->GetSingleWordOperand( + first_index_operand + i)); + if (auto* index_constant = + constant_mgr->GetConstantFromInst(index)) { + // We only need 32 bits. For the type calculation, it's sufficient + // to take the zero-extended value. It only matters for the struct + // case, and struct member indices are unsigned. + index_for_type_calculation = + uint32_t(index_constant->GetZeroExtendedValue()); + } else { + // Indexing into a variably-sized thing like an array. Use 0. + index_for_type_calculation = 0; + } + indices_for_type.push_back(index_for_type_calculation); + } + auto* base_ptr_type = type_mgr->GetType(base->type_id())->AsPointer(); + auto* base_pointee_type = base_ptr_type->pointee_type(); + auto* new_access_chain_result_pointee_type = + type_mgr->GetMemberType(base_pointee_type, indices_for_type); + const uint32_t new_access_chain_type_id = type_mgr->FindPointerToType( + type_mgr->GetId(new_access_chain_result_pointee_type), + base_ptr_type->storage_class()); + + // Create the instruction and insert it. + const auto new_access_chain_id = TakeNextId(); + auto* new_access_chain = + InsertInst(current_access_chain, current_access_chain->opcode(), + new_access_chain_type_id, new_access_chain_id, ops); + pointer_to_containing_struct = new_access_chain; + steps_remaining = 0; + break; + } + } break; + default: + Fail() << "Unhandled access chain in logical addressing mode passes " + "through " + << current_access_chain->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET | + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + return nullptr; + } + } + assert(pointer_to_containing_struct); + auto* pointee_type = + type_mgr->GetType(pointer_to_containing_struct->type_id()) + ->AsPointer() + ->pointee_type(); + + auto* struct_type = pointee_type->AsStruct(); + const uint32_t member_index_of_runtime_array = + uint32_t(struct_type->element_types().size() - 1); + // Create the length-of-array instruction before the original access chain, + // but after the generation of the pointer to the struct. + const auto array_len_id = TakeNextId(); + analysis::Integer uint_type_for_query(32, false); + auto* uint_type = type_mgr->GetRegisteredType(&uint_type_for_query); + auto* array_len = InsertInst( + access_chain, spv::Op::OpArrayLength, type_mgr->GetId(uint_type), + array_len_id, + {{SPV_OPERAND_TYPE_ID, {pointer_to_containing_struct->result_id()}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index_of_runtime_array}}}); + return array_len; +} + +spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( + opt::Instruction* image_texel_pointer) { + // TODO(dneto): Write tests for this code. + // TODO(dneto): Use signed-clamp + (void)(image_texel_pointer); + return SPV_SUCCESS; + + // Do not compile this code until it is ready to be used. +#if 0 + // Example: + // %texel_ptr = OpImageTexelPointer %texel_ptr_type %image_ptr %coord + // %sample + // + // We want to clamp %coord components between vector-0 and the result + // of OpImageQuerySize acting on the underlying image. So insert: + // %image = OpLoad %image_type %image_ptr + // %query_size = OpImageQuerySize %query_size_type %image + // + // For a multi-sampled image, %sample is the sample index, and we need + // to clamp it between zero and the number of samples in the image. + // %sample_count = OpImageQuerySamples %uint %image + // %max_sample_index = OpISub %uint %sample_count %uint_1 + // For non-multi-sampled images, the sample index must be constant zero. + + auto* def_use_mgr = context()->get_def_use_mgr(); + auto* type_mgr = context()->get_type_mgr(); + auto* constant_mgr = context()->get_constant_mgr(); + + auto* image_ptr = GetDef(image_texel_pointer->GetSingleWordInOperand(0)); + auto* image_ptr_type = GetDef(image_ptr->type_id()); + auto image_type_id = image_ptr_type->GetSingleWordInOperand(1); + auto* image_type = GetDef(image_type_id); + auto* coord = GetDef(image_texel_pointer->GetSingleWordInOperand(1)); + auto* samples = GetDef(image_texel_pointer->GetSingleWordInOperand(2)); + + // We will modify the module, at least by adding image query instructions. + module_status_.modified = true; + + // Declare the ImageQuery capability if the module doesn't already have it. + auto* feature_mgr = context()->get_feature_mgr(); + if (!feature_mgr->HasCapability(spv::Capability::ImageQuery)) { + auto cap = MakeUnique( + context(), spv::Op::OpCapability, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_CAPABILITY, {spv::Capability::ImageQuery}}}); + def_use_mgr->AnalyzeInstDefUse(cap.get()); + context()->AddCapability(std::move(cap)); + feature_mgr->Analyze(context()->module()); + } + + // OpImageTexelPointer is used to translate a coordinate and sample index + // into an address for use with an atomic operation. That is, it may only + // used with what Vulkan calls a "storage image" + // (OpTypeImage parameter Sampled=2). + // Note: A storage image never has a level-of-detail associated with it. + + // Constraints on the sample id: + // - Only 2D images can be multi-sampled: OpTypeImage parameter MS=1 + // only if Dim=2D. + // - Non-multi-sampled images (OpTypeImage parameter MS=0) must use + // sample ID to a constant 0. + + // The coordinate is treated as unsigned, and should be clamped against the + // image "size", returned by OpImageQuerySize. (Note: OpImageQuerySizeLod + // is only usable with a sampled image, i.e. its image type has Sampled=1). + + // Determine the result type for the OpImageQuerySize. + // For non-arrayed images: + // non-Cube: + // - Always the same as the coordinate type + // Cube: + // - Use all but the last component of the coordinate (which is the face + // index from 0 to 5). + // For arrayed images (in Vulkan the Dim is 1D, 2D, or Cube): + // non-Cube: + // - A vector with the components in the coordinate, and one more for + // the layer index. + // Cube: + // - The same as the coordinate type: 3-element integer vector. + // - The third component from the size query is the layer count. + // - The third component in the texel pointer calculation is + // 6 * layer + face, where 0 <= face < 6. + // Cube: Use all but the last component of the coordinate (which is the face + // index from 0 to 5). + const auto dim = SpvDim(image_type->GetSingleWordInOperand(1)); + const bool arrayed = image_type->GetSingleWordInOperand(3) == 1; + const bool multisampled = image_type->GetSingleWordInOperand(4) != 0; + const auto query_num_components = [dim, arrayed, this]() -> int { + const int arrayness_bonus = arrayed ? 1 : 0; + int num_coords = 0; + switch (dim) { + case spv::Dim::Buffer: + case SpvDim1D: + num_coords = 1; + break; + case spv::Dim::Cube: + // For cube, we need bounds for x, y, but not face. + case spv::Dim::Rect: + case SpvDim2D: + num_coords = 2; + break; + case SpvDim3D: + num_coords = 3; + break; + case spv::Dim::SubpassData: + case spv::Dim::Max: + return Fail() << "Invalid image dimension for OpImageTexelPointer: " + << int(dim); + break; + } + return num_coords + arrayness_bonus; + }(); + const auto* coord_component_type = [type_mgr, coord]() { + const analysis::Type* coord_type = type_mgr->GetType(coord->type_id()); + if (auto* vector_type = coord_type->AsVector()) { + return vector_type->element_type()->AsInteger(); + } + return coord_type->AsInteger(); + }(); + // For now, only handle 32-bit case for coordinates. + if (!coord_component_type) { + return Fail() << " Coordinates for OpImageTexelPointer are not integral: " + << image_texel_pointer->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + } + if (coord_component_type->width() != 32) { + return Fail() << " Expected OpImageTexelPointer coordinate components to " + "be 32-bits wide. They are " + << coord_component_type->width() << " bits. " + << image_texel_pointer->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + } + const auto* query_size_type = + [type_mgr, coord_component_type, + query_num_components]() -> const analysis::Type* { + if (query_num_components == 1) return coord_component_type; + analysis::Vector proposed(coord_component_type, query_num_components); + return type_mgr->GetRegisteredType(&proposed); + }(); + + const uint32_t image_id = TakeNextId(); + auto* image = + InsertInst(image_texel_pointer, spv::Op::OpLoad, image_type_id, image_id, + {{SPV_OPERAND_TYPE_ID, {image_ptr->result_id()}}}); + + const uint32_t query_size_id = TakeNextId(); + auto* query_size = + InsertInst(image_texel_pointer, spv::Op::OpImageQuerySize, + type_mgr->GetTypeInstruction(query_size_type), query_size_id, + {{SPV_OPERAND_TYPE_ID, {image->result_id()}}}); + + auto* component_1 = constant_mgr->GetConstant(coord_component_type, {1}); + const uint32_t component_1_id = + constant_mgr->GetDefiningInstruction(component_1)->result_id(); + auto* component_0 = constant_mgr->GetConstant(coord_component_type, {0}); + const uint32_t component_0_id = + constant_mgr->GetDefiningInstruction(component_0)->result_id(); + + // If the image is a cube array, then the last component of the queried + // size is the layer count. In the query, we have to accommodate folding + // in the face index ranging from 0 through 5. The inclusive upper bound + // on the third coordinate therefore is multiplied by 6. + auto* query_size_including_faces = query_size; + if (arrayed && (dim == spv::Dim::Cube)) { + // Multiply the last coordinate by 6. + auto* component_6 = constant_mgr->GetConstant(coord_component_type, {6}); + const uint32_t component_6_id = + constant_mgr->GetDefiningInstruction(component_6)->result_id(); + assert(query_num_components == 3); + auto* multiplicand = constant_mgr->GetConstant( + query_size_type, {component_1_id, component_1_id, component_6_id}); + auto* multiplicand_inst = + constant_mgr->GetDefiningInstruction(multiplicand); + const auto query_size_including_faces_id = TakeNextId(); + query_size_including_faces = InsertInst( + image_texel_pointer, spv::Op::OpIMul, + type_mgr->GetTypeInstruction(query_size_type), + query_size_including_faces_id, + {{SPV_OPERAND_TYPE_ID, {query_size_including_faces->result_id()}}, + {SPV_OPERAND_TYPE_ID, {multiplicand_inst->result_id()}}}); + } + + // Make a coordinate-type with all 1 components. + auto* coordinate_1 = + query_num_components == 1 + ? component_1 + : constant_mgr->GetConstant( + query_size_type, + std::vector(query_num_components, component_1_id)); + // Make a coordinate-type with all 1 components. + auto* coordinate_0 = + query_num_components == 0 + ? component_0 + : constant_mgr->GetConstant( + query_size_type, + std::vector(query_num_components, component_0_id)); + + const uint32_t query_max_including_faces_id = TakeNextId(); + auto* query_max_including_faces = InsertInst( + image_texel_pointer, spv::Op::OpISub, + type_mgr->GetTypeInstruction(query_size_type), + query_max_including_faces_id, + {{SPV_OPERAND_TYPE_ID, {query_size_including_faces->result_id()}}, + {SPV_OPERAND_TYPE_ID, + {constant_mgr->GetDefiningInstruction(coordinate_1)->result_id()}}}); + + // Clamp the coordinate + auto* clamp_coord = MakeSClampInst( + *type_mgr, coord, constant_mgr->GetDefiningInstruction(coordinate_0), + query_max_including_faces, image_texel_pointer); + image_texel_pointer->SetInOperand(1, {clamp_coord->result_id()}); + + // Clamp the sample index + if (multisampled) { + // Get the sample count via OpImageQuerySamples + const auto query_samples_id = TakeNextId(); + auto* query_samples = InsertInst( + image_texel_pointer, spv::Op::OpImageQuerySamples, + constant_mgr->GetDefiningInstruction(component_0)->type_id(), + query_samples_id, {{SPV_OPERAND_TYPE_ID, {image->result_id()}}}); + + const auto max_samples_id = TakeNextId(); + auto* max_samples = InsertInst(image_texel_pointer, spv::Op::OpImageQuerySamples, + query_samples->type_id(), max_samples_id, + {{SPV_OPERAND_TYPE_ID, {query_samples_id}}, + {SPV_OPERAND_TYPE_ID, {component_1_id}}}); + + auto* clamp_samples = MakeSClampInst( + *type_mgr, samples, constant_mgr->GetDefiningInstruction(coordinate_0), + max_samples, image_texel_pointer); + image_texel_pointer->SetInOperand(2, {clamp_samples->result_id()}); + + } else { + // Just replace it with 0. Don't even check what was there before. + image_texel_pointer->SetInOperand(2, {component_0_id}); + } + + def_use_mgr->AnalyzeInstUse(image_texel_pointer); + + return SPV_SUCCESS; +#endif +} + +opt::Instruction* GraphicsRobustAccessPass::InsertInst( + opt::Instruction* where_inst, spv::Op opcode, uint32_t type_id, + uint32_t result_id, const Instruction::OperandList& operands) { + module_status_.modified = true; + auto* result = where_inst->InsertBefore( + MakeUnique(context(), opcode, type_id, result_id, operands)); + context()->get_def_use_mgr()->AnalyzeInstDefUse(result); + auto* basic_block = context()->get_instr_block(where_inst); + context()->set_instr_block(result, basic_block); + return result; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/graphics_robust_access_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/graphics_robust_access_pass.h new file mode 100644 index 000000000000..a7ffe115bfba --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/graphics_robust_access_pass.h @@ -0,0 +1,156 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_GRAPHICS_ROBUST_ACCESS_PASS_H_ +#define SOURCE_OPT_GRAPHICS_ROBUST_ACCESS_PASS_H_ + +#include +#include + +#include "constants.h" +#include "def_use_manager.h" +#include "instruction.h" +#include "module.h" +#include "pass.h" +#include "source/diagnostic.h" +#include "type_manager.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class GraphicsRobustAccessPass : public Pass { + public: + GraphicsRobustAccessPass(); + const char* name() const override { return "graphics-robust-access"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes | + IRContext::kAnalysisIdToFuncMapping; + } + + private: + // Records failure for the current module, and returns a stream + // that can be used to provide user error information to the message + // consumer. + spvtools::DiagnosticStream Fail(); + + // Returns SPV_SUCCESS if this pass can correctly process the module, + // as far as we can tell from capabilities and the memory model. + // Otherwise logs a message and returns a failure code. + spv_result_t IsCompatibleModule(); + + // Transform the current module, if possible. Failure and modification + // status is recorded in the |_| member. On failure, error information is + // posted to the message consumer. The return value has no significance. + spv_result_t ProcessCurrentModule(); + + // Process the given function. Updates the state value |_|. Returns true + // if the module was modified. This can log a failure. + bool ProcessAFunction(opt::Function*); + + // Clamps indices in the OpAccessChain or OpInBoundsAccessChain instruction + // |access_chain|. Inserts instructions before the given instruction. Updates + // analyses and records that the module is modified. This can log a failure. + void ClampIndicesForAccessChain(Instruction* access_chain); + + // Returns the id of the instruction importing the "GLSL.std.450" extended + // instruction set. If it does not yet exist, the import instruction is + // created and inserted into the module, and updates |_.modified| and + // |_.glsl_insts_id|. + uint32_t GetGlslInsts(); + + // Returns an instruction which is constant with the given value of the given + // type. Ignores any value bits beyond the width of the type. + Instruction* GetValueForType(uint64_t value, const analysis::Integer* type); + + // Converts an integer value to an unsigned wider integer type, using either + // sign extension or zero extension. The new instruction is inserted + // immediately before |before_inst|, and is analyzed for definitions and uses. + // Returns the newly inserted instruction. Assumes the |value| is an integer + // scalar of a narrower type than |bit_width| bits. + Instruction* WidenInteger(bool sign_extend, uint32_t bit_width, + Instruction* value, Instruction* before_inst); + + // Returns a new instruction that invokes the UMin GLSL.std.450 extended + // instruction with the two given operands. That is, the result of the + // instruction is: + // - |x| if |x| is unsigned-less than |y| + // - |y| otherwise + // We assume that |x| and |y| are scalar integer types with the same + // width. The instruction is inserted before |where|. + opt::Instruction* MakeUMinInst(const analysis::TypeManager& tm, + Instruction* x, Instruction* y, + Instruction* where); + + // Returns a new instruction that invokes the SClamp GLSL.std.450 extended + // instruction with the three given operands. That is, the result of the + // instruction is: + // - |min| if |x| is signed-less than |min| + // - |max| if |x| is signed-more than |max| + // - |x| otherwise. + // We assume that |min| is signed-less-or-equal to |max|, and that the + // operands all have the same scalar integer type. The instruction is + // inserted before |where|. + opt::Instruction* MakeSClampInst(const analysis::TypeManager& tm, + Instruction* x, Instruction* min, + Instruction* max, Instruction* where); + + // Returns a new instruction which evaluates to the length the runtime array + // referenced by the access chain at the specified index. The instruction is + // inserted before the access chain instruction. Returns a null pointer in + // some cases if assumptions are violated (rather than asserting out). + opt::Instruction* MakeRuntimeArrayLengthInst(Instruction* access_chain, + uint32_t operand_index); + + // Clamps the coordinate for an OpImageTexelPointer so it stays within + // the bounds of the size of the image. Updates analyses and records that + // the module is modified. Returns a status code to indicate success + // or failure. If assumptions are not met, returns an error status code + // and emits a diagnostic. + spv_result_t ClampCoordinateForImageTexelPointer( + opt::Instruction* image_texel_pointer); + + // Gets the instruction that defines the given id. + opt::Instruction* GetDef(uint32_t id) { + return context()->get_def_use_mgr()->GetDef(id); + } + + // Returns a new instruction inserted before |where_inst|, and created from + // the remaining arguments. Registers the definitions and uses of the new + // instruction and also records its block. + opt::Instruction* InsertInst(opt::Instruction* where_inst, spv::Op opcode, + uint32_t type_id, uint32_t result_id, + const Instruction::OperandList& operands); + + // State required for the current module. + struct PerModuleState { + // This pass modified the module. + bool modified = false; + // True if there is an error processing the current module, e.g. if + // preconditions are not met. + bool failed = false; + // The id of the GLSL.std.450 extended instruction set. Zero if it does + // not exist. + uint32_t glsl_insts_id = 0; + } module_status_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_GRAPHICS_ROBUST_ACCESS_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/if_conversion.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/if_conversion.cpp new file mode 100644 index 000000000000..5912cf12da0a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/if_conversion.cpp @@ -0,0 +1,297 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/if_conversion.h" + +#include +#include + +#include "source/opt/value_number_table.h" + +namespace spvtools { +namespace opt { + +Pass::Status IfConversion::Process() { + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { + return Status::SuccessWithoutChange; + } + + const ValueNumberTable& vn_table = *context()->GetValueNumberTable(); + bool modified = false; + std::vector to_kill; + for (auto& func : *get_module()) { + DominatorAnalysis* dominators = context()->GetDominatorAnalysis(&func); + for (auto& block : func) { + // Check if it is possible for |block| to have phis that can be + // transformed. + BasicBlock* common = nullptr; + if (!CheckBlock(&block, dominators, &common)) continue; + + // Get an insertion point. + auto iter = block.begin(); + while (iter != block.end() && iter->opcode() == spv::Op::OpPhi) { + ++iter; + } + + InstructionBuilder builder( + context(), &*iter, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + block.ForEachPhiInst([this, &builder, &modified, &common, &to_kill, + dominators, &block, &vn_table](Instruction* phi) { + // This phi is not compatible, but subsequent phis might be. + if (!CheckType(phi->type_id())) return; + + // We cannot transform cases where the phi is used by another phi in the + // same block due to instruction ordering restrictions. + // TODO(alan-baker): If all inappropriate uses could also be + // transformed, we could still remove this phi. + if (!CheckPhiUsers(phi, &block)) return; + + // Identify the incoming values associated with the true and false + // branches. If |then_block| dominates |inc0| or if the true edge + // branches straight to this block and |common| is |inc0|, then |inc0| + // is on the true branch. Otherwise the |inc1| is on the true branch. + BasicBlock* inc0 = GetIncomingBlock(phi, 0u); + Instruction* branch = common->terminator(); + uint32_t condition = branch->GetSingleWordInOperand(0u); + BasicBlock* then_block = GetBlock(branch->GetSingleWordInOperand(1u)); + Instruction* true_value = nullptr; + Instruction* false_value = nullptr; + if ((then_block == &block && inc0 == common) || + dominators->Dominates(then_block, inc0)) { + true_value = GetIncomingValue(phi, 0u); + false_value = GetIncomingValue(phi, 1u); + } else { + true_value = GetIncomingValue(phi, 1u); + false_value = GetIncomingValue(phi, 0u); + } + + BasicBlock* true_def_block = context()->get_instr_block(true_value); + BasicBlock* false_def_block = context()->get_instr_block(false_value); + + uint32_t true_vn = vn_table.GetValueNumber(true_value); + uint32_t false_vn = vn_table.GetValueNumber(false_value); + if (true_vn != 0 && true_vn == false_vn) { + Instruction* inst_to_use = nullptr; + + // Try to pick an instruction that is not in a side node. If we can't + // pick either the true for false branch as long as they can be + // legally moved. + if (!true_def_block || + dominators->Dominates(true_def_block, &block)) { + inst_to_use = true_value; + } else if (!false_def_block || + dominators->Dominates(false_def_block, &block)) { + inst_to_use = false_value; + } else if (CanHoistInstruction(true_value, common, dominators)) { + inst_to_use = true_value; + } else if (CanHoistInstruction(false_value, common, dominators)) { + inst_to_use = false_value; + } + + if (inst_to_use != nullptr) { + modified = true; + HoistInstruction(inst_to_use, common, dominators); + context()->KillNamesAndDecorates(phi); + context()->ReplaceAllUsesWith(phi->result_id(), + inst_to_use->result_id()); + } + return; + } + + // If either incoming value is defined in a block that does not dominate + // this phi, then we cannot eliminate the phi with a select. + // TODO(alan-baker): Perform code motion where it makes sense to enable + // the transform in this case. + if (true_def_block && !dominators->Dominates(true_def_block, &block)) + return; + + if (false_def_block && !dominators->Dominates(false_def_block, &block)) + return; + + analysis::Type* data_ty = + context()->get_type_mgr()->GetType(true_value->type_id()); + if (analysis::Vector* vec_data_ty = data_ty->AsVector()) { + condition = SplatCondition(vec_data_ty, condition, &builder); + } + + Instruction* select = builder.AddSelect(phi->type_id(), condition, + true_value->result_id(), + false_value->result_id()); + context()->get_def_use_mgr()->AnalyzeInstDefUse(select); + select->UpdateDebugInfoFrom(phi); + context()->ReplaceAllUsesWith(phi->result_id(), select->result_id()); + to_kill.push_back(phi); + modified = true; + + return; + }); + } + } + + for (auto inst : to_kill) { + context()->KillInst(inst); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool IfConversion::CheckBlock(BasicBlock* block, DominatorAnalysis* dominators, + BasicBlock** common) { + const std::vector& preds = cfg()->preds(block->id()); + + // TODO(alan-baker): Extend to more than two predecessors + if (preds.size() != 2) return false; + + BasicBlock* inc0 = context()->get_instr_block(preds[0]); + if (dominators->Dominates(block, inc0)) return false; + + BasicBlock* inc1 = context()->get_instr_block(preds[1]); + if (dominators->Dominates(block, inc1)) return false; + + if (inc0 == inc1) { + // If the predecessor blocks are the same, then there is only 1 value for + // the OpPhi. Other transformation should be able to simplify that. + return false; + } + // All phis will have the same common dominator, so cache the result + // for this block. If there is no common dominator, then we cannot transform + // any phi in this basic block. + *common = dominators->CommonDominator(inc0, inc1); + if (!*common || cfg()->IsPseudoEntryBlock(*common)) return false; + Instruction* branch = (*common)->terminator(); + if (branch->opcode() != spv::Op::OpBranchConditional) return false; + auto merge = (*common)->GetMergeInst(); + if (!merge || merge->opcode() != spv::Op::OpSelectionMerge) return false; + if (spv::SelectionControlMask(merge->GetSingleWordInOperand(1)) == + spv::SelectionControlMask::DontFlatten) { + return false; + } + if ((*common)->MergeBlockIdIfAny() != block->id()) return false; + + return true; +} + +bool IfConversion::CheckPhiUsers(Instruction* phi, BasicBlock* block) { + return get_def_use_mgr()->WhileEachUser( + phi, [block, this](Instruction* user) { + if (user->opcode() == spv::Op::OpPhi && + context()->get_instr_block(user) == block) + return false; + return true; + }); +} + +uint32_t IfConversion::SplatCondition(analysis::Vector* vec_data_ty, + uint32_t cond, + InstructionBuilder* builder) { + // If the data inputs to OpSelect are vectors, the condition for + // OpSelect must be a boolean vector with the same number of + // components. So splat the condition for the branch into a vector + // type. + analysis::Bool bool_ty; + analysis::Vector bool_vec_ty(&bool_ty, vec_data_ty->element_count()); + uint32_t bool_vec_id = + context()->get_type_mgr()->GetTypeInstruction(&bool_vec_ty); + std::vector ids(vec_data_ty->element_count(), cond); + return builder->AddCompositeConstruct(bool_vec_id, ids)->result_id(); +} + +bool IfConversion::CheckType(uint32_t id) { + Instruction* type = get_def_use_mgr()->GetDef(id); + spv::Op op = type->opcode(); + if (spvOpcodeIsScalarType(op) || op == spv::Op::OpTypePointer || + op == spv::Op::OpTypeVector) + return true; + return false; +} + +BasicBlock* IfConversion::GetBlock(uint32_t id) { + return context()->get_instr_block(get_def_use_mgr()->GetDef(id)); +} + +BasicBlock* IfConversion::GetIncomingBlock(Instruction* phi, + uint32_t predecessor) { + uint32_t in_index = 2 * predecessor + 1; + return GetBlock(phi->GetSingleWordInOperand(in_index)); +} + +Instruction* IfConversion::GetIncomingValue(Instruction* phi, + uint32_t predecessor) { + uint32_t in_index = 2 * predecessor; + return get_def_use_mgr()->GetDef(phi->GetSingleWordInOperand(in_index)); +} + +void IfConversion::HoistInstruction(Instruction* inst, BasicBlock* target_block, + DominatorAnalysis* dominators) { + BasicBlock* inst_block = context()->get_instr_block(inst); + if (!inst_block) { + // This is in the header, and dominates everything. + return; + } + + if (dominators->Dominates(inst_block, target_block)) { + // Already in position. No work to do. + return; + } + + assert(inst->IsOpcodeCodeMotionSafe() && + "Trying to move an instruction that is not safe to move."); + + // First hoist all instructions it depends on. + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + inst->ForEachInId( + [this, target_block, def_use_mgr, dominators](uint32_t* id) { + Instruction* operand_inst = def_use_mgr->GetDef(*id); + HoistInstruction(operand_inst, target_block, dominators); + }); + + Instruction* insertion_pos = target_block->terminator(); + if ((insertion_pos)->PreviousNode()->opcode() == spv::Op::OpSelectionMerge) { + insertion_pos = insertion_pos->PreviousNode(); + } + inst->RemoveFromList(); + insertion_pos->InsertBefore(std::unique_ptr(inst)); + context()->set_instr_block(inst, target_block); +} + +bool IfConversion::CanHoistInstruction(Instruction* inst, + BasicBlock* target_block, + DominatorAnalysis* dominators) { + BasicBlock* inst_block = context()->get_instr_block(inst); + if (!inst_block) { + // This is in the header, and dominates everything. + return true; + } + + if (dominators->Dominates(inst_block, target_block)) { + // Already in position. No work to do. + return true; + } + + if (!inst->IsOpcodeCodeMotionSafe()) { + return false; + } + + // Check all instruction |inst| depends on. + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + return inst->WhileEachInId( + [this, target_block, def_use_mgr, dominators](uint32_t* id) { + Instruction* operand_inst = def_use_mgr->GetDef(*id); + return CanHoistInstruction(operand_inst, target_block, dominators); + }); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/if_conversion.h b/thirdparty/glslang/External/spirv-tools/source/opt/if_conversion.h new file mode 100644 index 000000000000..db84e703bd81 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/if_conversion.h @@ -0,0 +1,89 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_IF_CONVERSION_H_ +#define SOURCE_OPT_IF_CONVERSION_H_ + +#include "source/opt/basic_block.h" +#include "source/opt/ir_builder.h" +#include "source/opt/pass.h" +#include "source/opt/types.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class IfConversion : public Pass { + public: + const char* name() const override { return "if-conversion"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisInstrToBlockMapping | IRContext::kAnalysisCFG | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + // Returns true if |id| is a valid type for use with OpSelect. OpSelect only + // allows scalars, vectors and pointers as valid inputs. + bool CheckType(uint32_t id); + + // Returns the basic block containing |id|. + BasicBlock* GetBlock(uint32_t id); + + // Returns the basic block for the |predecessor|'th index predecessor of + // |phi|. + BasicBlock* GetIncomingBlock(Instruction* phi, uint32_t predecessor); + + // Returns the instruction defining the |predecessor|'th index of |phi|. + Instruction* GetIncomingValue(Instruction* phi, uint32_t predecessor); + + // Returns the id of a OpCompositeConstruct boolean vector. The composite has + // the same number of elements as |vec_data_ty| and each member is |cond|. + // |where| indicates the location in |block| to insert the composite + // construct. If necessary, this function will also construct the necessary + // type instructions for the boolean vector. + uint32_t SplatCondition(analysis::Vector* vec_data_ty, uint32_t cond, + InstructionBuilder* builder); + + // Returns true if none of |phi|'s users are in |block|. + bool CheckPhiUsers(Instruction* phi, BasicBlock* block); + + // Returns |false| if |block| is not appropriate to transform. Only + // transforms blocks with two predecessors. Neither incoming block can be + // dominated by |block|. Both predecessors must share a common dominator that + // is terminated by a conditional branch. + bool CheckBlock(BasicBlock* block, DominatorAnalysis* dominators, + BasicBlock** common); + + // Moves |inst| to |target_block| if it does not already dominate the block. + // Any instructions that |inst| depends on are move if necessary. It is + // assumed that |inst| can be hoisted to |target_block| as defined by + // |CanHoistInstruction|. |dominators| is the dominator analysis for the + // function that contains |target_block|. + void HoistInstruction(Instruction* inst, BasicBlock* target_block, + DominatorAnalysis* dominators); + + // Returns true if it is legal to move |inst| and the instructions it depends + // on to |target_block| if they do not already dominate |target_block|. + bool CanHoistInstruction(Instruction* inst, BasicBlock* target_block, + DominatorAnalysis* dominators); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_IF_CONVERSION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inline_exhaustive_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/inline_exhaustive_pass.cpp new file mode 100644 index 000000000000..bef45017f21c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inline_exhaustive_pass.cpp @@ -0,0 +1,80 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/inline_exhaustive_pass.h" + +#include + +namespace spvtools { +namespace opt { + +Pass::Status InlineExhaustivePass::InlineExhaustive(Function* func) { + bool modified = false; + // Using block iterators here because of block erasures and insertions. + for (auto bi = func->begin(); bi != func->end(); ++bi) { + for (auto ii = bi->begin(); ii != bi->end();) { + if (IsInlinableFunctionCall(&*ii)) { + // Inline call. + std::vector> newBlocks; + std::vector> newVars; + if (!GenInlineCode(&newBlocks, &newVars, ii, bi)) { + return Status::Failure; + } + // If call block is replaced with more than one block, point + // succeeding phis at new last block. + if (newBlocks.size() > 1) UpdateSucceedingPhis(newBlocks); + // Replace old calling block with new block(s). + + bi = bi.Erase(); + + for (auto& bb : newBlocks) { + bb->SetParent(func); + } + bi = bi.InsertBefore(&newBlocks); + // Insert new function variables. + if (newVars.size() > 0) + func->begin()->begin().InsertBefore(std::move(newVars)); + // Restart inlining at beginning of calling block. + ii = bi->begin(); + modified = true; + } else { + ++ii; + } + } + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +Pass::Status InlineExhaustivePass::ProcessImpl() { + Status status = Status::SuccessWithoutChange; + // Attempt exhaustive inlining on each entry point function in module + ProcessFunction pfn = [&status, this](Function* fp) { + status = CombineStatus(status, InlineExhaustive(fp)); + return false; + }; + context()->ProcessReachableCallTree(pfn); + return status; +} + +InlineExhaustivePass::InlineExhaustivePass() = default; + +Pass::Status InlineExhaustivePass::Process() { + InitializeInline(); + return ProcessImpl(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inline_exhaustive_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/inline_exhaustive_pass.h new file mode 100644 index 000000000000..c2e854731e4b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inline_exhaustive_pass.h @@ -0,0 +1,53 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_INLINE_EXHAUSTIVE_PASS_H_ +#define SOURCE_OPT_INLINE_EXHAUSTIVE_PASS_H_ + +#include +#include +#include +#include +#include + +#include "source/opt/def_use_manager.h" +#include "source/opt/inline_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class InlineExhaustivePass : public InlinePass { + public: + InlineExhaustivePass(); + Status Process() override; + + const char* name() const override { return "inline-entry-points-exhaustive"; } + + private: + // Exhaustively inline all function calls in func as well as in + // all code that is inlined into func. Returns the status. + Status InlineExhaustive(Function* func); + + void Initialize(); + Pass::Status ProcessImpl(); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_INLINE_EXHAUSTIVE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inline_opaque_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/inline_opaque_pass.cpp new file mode 100644 index 000000000000..90a4c2247a0b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inline_opaque_pass.cpp @@ -0,0 +1,118 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/inline_opaque_pass.h" + +#include + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kTypePointerTypeIdInIdx = 1; +} // namespace + +bool InlineOpaquePass::IsOpaqueType(uint32_t typeId) { + const Instruction* typeInst = get_def_use_mgr()->GetDef(typeId); + switch (typeInst->opcode()) { + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampledImage: + return true; + case spv::Op::OpTypePointer: + return IsOpaqueType( + typeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx)); + default: + break; + } + // TODO(greg-lunarg): Handle arrays containing opaque type + if (typeInst->opcode() != spv::Op::OpTypeStruct) return false; + // Return true if any member is opaque + return !typeInst->WhileEachInId([this](const uint32_t* tid) { + if (IsOpaqueType(*tid)) return false; + return true; + }); +} + +bool InlineOpaquePass::HasOpaqueArgsOrReturn(const Instruction* callInst) { + // Check return type + if (IsOpaqueType(callInst->type_id())) return true; + // Check args + int icnt = 0; + return !callInst->WhileEachInId([&icnt, this](const uint32_t* iid) { + if (icnt > 0) { + const Instruction* argInst = get_def_use_mgr()->GetDef(*iid); + if (IsOpaqueType(argInst->type_id())) return false; + } + ++icnt; + return true; + }); +} + +Pass::Status InlineOpaquePass::InlineOpaque(Function* func) { + bool modified = false; + // Using block iterators here because of block erasures and insertions. + for (auto bi = func->begin(); bi != func->end(); ++bi) { + for (auto ii = bi->begin(); ii != bi->end();) { + if (IsInlinableFunctionCall(&*ii) && HasOpaqueArgsOrReturn(&*ii)) { + // Inline call. + std::vector> newBlocks; + std::vector> newVars; + if (!GenInlineCode(&newBlocks, &newVars, ii, bi)) { + return Status::Failure; + } + + // If call block is replaced with more than one block, point + // succeeding phis at new last block. + if (newBlocks.size() > 1) UpdateSucceedingPhis(newBlocks); + // Replace old calling block with new block(s). + bi = bi.Erase(); + bi = bi.InsertBefore(&newBlocks); + // Insert new function variables. + if (newVars.size() > 0) + func->begin()->begin().InsertBefore(std::move(newVars)); + // Restart inlining at beginning of calling block. + ii = bi->begin(); + modified = true; + } else { + ++ii; + } + } + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +void InlineOpaquePass::Initialize() { InitializeInline(); } + +Pass::Status InlineOpaquePass::ProcessImpl() { + Status status = Status::SuccessWithoutChange; + // Do opaque inlining on each function in entry point call tree + ProcessFunction pfn = [&status, this](Function* fp) { + status = CombineStatus(status, InlineOpaque(fp)); + return false; + }; + context()->ProcessReachableCallTree(pfn); + return status; +} + +InlineOpaquePass::InlineOpaquePass() = default; + +Pass::Status InlineOpaquePass::Process() { + Initialize(); + return ProcessImpl(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inline_opaque_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/inline_opaque_pass.h new file mode 100644 index 000000000000..1e3081d22c26 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inline_opaque_pass.h @@ -0,0 +1,60 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_INLINE_OPAQUE_PASS_H_ +#define SOURCE_OPT_INLINE_OPAQUE_PASS_H_ + +#include +#include +#include +#include +#include + +#include "source/opt/def_use_manager.h" +#include "source/opt/inline_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class InlineOpaquePass : public InlinePass { + public: + InlineOpaquePass(); + Status Process() override; + + const char* name() const override { return "inline-entry-points-opaque"; } + + private: + // Return true if |typeId| is or contains opaque type + bool IsOpaqueType(uint32_t typeId); + + // Return true if function call |callInst| has opaque argument or return type + bool HasOpaqueArgsOrReturn(const Instruction* callInst); + + // Inline all function calls in |func| that have opaque params or return + // type. Inline similarly all code that is inlined into func. Return true + // if func is modified. + Status InlineOpaque(Function* func); + + void Initialize(); + Pass::Status ProcessImpl(); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_INLINE_OPAQUE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inline_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/inline_pass.cpp new file mode 100644 index 000000000000..3f160b24cd37 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inline_pass.cpp @@ -0,0 +1,849 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/inline_pass.h" + +#include +#include + +#include "source/cfa.h" +#include "source/opt/reflect.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { +namespace { +// Indices of operands in SPIR-V instructions +constexpr int kSpvFunctionCallFunctionId = 2; +constexpr int kSpvFunctionCallArgumentId = 3; +constexpr int kSpvReturnValueId = 0; +} // namespace + +uint32_t InlinePass::AddPointerToType(uint32_t type_id, + spv::StorageClass storage_class) { + uint32_t resultId = context()->TakeNextId(); + if (resultId == 0) { + return resultId; + } + + std::unique_ptr type_inst( + new Instruction(context(), spv::Op::OpTypePointer, 0, resultId, + {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(storage_class)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_id}}})); + context()->AddType(std::move(type_inst)); + analysis::Type* pointeeTy; + std::unique_ptr pointerTy; + std::tie(pointeeTy, pointerTy) = + context()->get_type_mgr()->GetTypeAndPointerType( + type_id, spv::StorageClass::Function); + context()->get_type_mgr()->RegisterType(resultId, *pointerTy); + return resultId; +} + +void InlinePass::AddBranch(uint32_t label_id, + std::unique_ptr* block_ptr) { + std::unique_ptr newBranch( + new Instruction(context(), spv::Op::OpBranch, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}})); + (*block_ptr)->AddInstruction(std::move(newBranch)); +} + +void InlinePass::AddBranchCond(uint32_t cond_id, uint32_t true_id, + uint32_t false_id, + std::unique_ptr* block_ptr) { + std::unique_ptr newBranch( + new Instruction(context(), spv::Op::OpBranchConditional, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {false_id}}})); + (*block_ptr)->AddInstruction(std::move(newBranch)); +} + +void InlinePass::AddLoopMerge(uint32_t merge_id, uint32_t continue_id, + std::unique_ptr* block_ptr) { + std::unique_ptr newLoopMerge(new Instruction( + context(), spv::Op::OpLoopMerge, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {continue_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LOOP_CONTROL, {0}}})); + (*block_ptr)->AddInstruction(std::move(newLoopMerge)); +} + +void InlinePass::AddStore(uint32_t ptr_id, uint32_t val_id, + std::unique_ptr* block_ptr, + const Instruction* line_inst, + const DebugScope& dbg_scope) { + std::unique_ptr newStore( + new Instruction(context(), spv::Op::OpStore, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {val_id}}})); + if (line_inst != nullptr) { + newStore->AddDebugLine(line_inst); + } + newStore->SetDebugScope(dbg_scope); + (*block_ptr)->AddInstruction(std::move(newStore)); +} + +void InlinePass::AddLoad(uint32_t type_id, uint32_t resultId, uint32_t ptr_id, + std::unique_ptr* block_ptr, + const Instruction* line_inst, + const DebugScope& dbg_scope) { + std::unique_ptr newLoad( + new Instruction(context(), spv::Op::OpLoad, type_id, resultId, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}})); + if (line_inst != nullptr) { + newLoad->AddDebugLine(line_inst); + } + newLoad->SetDebugScope(dbg_scope); + (*block_ptr)->AddInstruction(std::move(newLoad)); +} + +std::unique_ptr InlinePass::NewLabel(uint32_t label_id) { + std::unique_ptr newLabel( + new Instruction(context(), spv::Op::OpLabel, 0, label_id, {})); + return newLabel; +} + +uint32_t InlinePass::GetFalseId() { + if (false_id_ != 0) return false_id_; + false_id_ = get_module()->GetGlobalValue(spv::Op::OpConstantFalse); + if (false_id_ != 0) return false_id_; + uint32_t boolId = get_module()->GetGlobalValue(spv::Op::OpTypeBool); + if (boolId == 0) { + boolId = context()->TakeNextId(); + if (boolId == 0) { + return 0; + } + get_module()->AddGlobalValue(spv::Op::OpTypeBool, boolId, 0); + } + false_id_ = context()->TakeNextId(); + if (false_id_ == 0) { + return 0; + } + get_module()->AddGlobalValue(spv::Op::OpConstantFalse, false_id_, boolId); + return false_id_; +} + +void InlinePass::MapParams( + Function* calleeFn, BasicBlock::iterator call_inst_itr, + std::unordered_map* callee2caller) { + int param_idx = 0; + calleeFn->ForEachParam( + [&call_inst_itr, ¶m_idx, &callee2caller](const Instruction* cpi) { + const uint32_t pid = cpi->result_id(); + (*callee2caller)[pid] = call_inst_itr->GetSingleWordOperand( + kSpvFunctionCallArgumentId + param_idx); + ++param_idx; + }); +} + +bool InlinePass::CloneAndMapLocals( + Function* calleeFn, std::vector>* new_vars, + std::unordered_map* callee2caller, + analysis::DebugInlinedAtContext* inlined_at_ctx) { + auto callee_block_itr = calleeFn->begin(); + auto callee_var_itr = callee_block_itr->begin(); + while (callee_var_itr->opcode() == spv::Op::OpVariable || + callee_var_itr->GetCommonDebugOpcode() == + CommonDebugInfoDebugDeclare) { + if (callee_var_itr->opcode() != spv::Op::OpVariable) { + ++callee_var_itr; + continue; + } + + std::unique_ptr var_inst(callee_var_itr->Clone(context())); + uint32_t newId = context()->TakeNextId(); + if (newId == 0) { + return false; + } + get_decoration_mgr()->CloneDecorations(callee_var_itr->result_id(), newId); + var_inst->SetResultId(newId); + var_inst->UpdateDebugInlinedAt( + context()->get_debug_info_mgr()->BuildDebugInlinedAtChain( + callee_var_itr->GetDebugInlinedAt(), inlined_at_ctx)); + (*callee2caller)[callee_var_itr->result_id()] = newId; + new_vars->push_back(std::move(var_inst)); + ++callee_var_itr; + } + return true; +} + +uint32_t InlinePass::CreateReturnVar( + Function* calleeFn, std::vector>* new_vars) { + uint32_t returnVarId = 0; + const uint32_t calleeTypeId = calleeFn->type_id(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + assert(type_mgr->GetType(calleeTypeId)->AsVoid() == nullptr && + "Cannot create a return variable of type void."); + // Find or create ptr to callee return type. + uint32_t returnVarTypeId = + type_mgr->FindPointerToType(calleeTypeId, spv::StorageClass::Function); + + if (returnVarTypeId == 0) { + returnVarTypeId = + AddPointerToType(calleeTypeId, spv::StorageClass::Function); + if (returnVarTypeId == 0) { + return 0; + } + } + + // Add return var to new function scope variables. + returnVarId = context()->TakeNextId(); + if (returnVarId == 0) { + return 0; + } + + std::unique_ptr var_inst(new Instruction( + context(), spv::Op::OpVariable, returnVarTypeId, returnVarId, + {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, + {(uint32_t)spv::StorageClass::Function}}})); + new_vars->push_back(std::move(var_inst)); + get_decoration_mgr()->CloneDecorations(calleeFn->result_id(), returnVarId); + return returnVarId; +} + +bool InlinePass::IsSameBlockOp(const Instruction* inst) const { + return inst->opcode() == spv::Op::OpSampledImage || + inst->opcode() == spv::Op::OpImage; +} + +bool InlinePass::CloneSameBlockOps( + std::unique_ptr* inst, + std::unordered_map* postCallSB, + std::unordered_map* preCallSB, + std::unique_ptr* block_ptr) { + return (*inst)->WhileEachInId([&postCallSB, &preCallSB, &block_ptr, + this](uint32_t* iid) { + const auto mapItr = (*postCallSB).find(*iid); + if (mapItr == (*postCallSB).end()) { + const auto mapItr2 = (*preCallSB).find(*iid); + if (mapItr2 != (*preCallSB).end()) { + // Clone pre-call same-block ops, map result id. + const Instruction* inInst = mapItr2->second; + std::unique_ptr sb_inst(inInst->Clone(context())); + if (!CloneSameBlockOps(&sb_inst, postCallSB, preCallSB, block_ptr)) { + return false; + } + + const uint32_t rid = sb_inst->result_id(); + const uint32_t nid = context()->TakeNextId(); + if (nid == 0) { + return false; + } + get_decoration_mgr()->CloneDecorations(rid, nid); + sb_inst->SetResultId(nid); + (*postCallSB)[rid] = nid; + *iid = nid; + (*block_ptr)->AddInstruction(std::move(sb_inst)); + } + } else { + // Reset same-block op operand. + *iid = mapItr->second; + } + return true; + }); +} + +void InlinePass::MoveInstsBeforeEntryBlock( + std::unordered_map* preCallSB, + BasicBlock* new_blk_ptr, BasicBlock::iterator call_inst_itr, + UptrVectorIterator call_block_itr) { + for (auto cii = call_block_itr->begin(); cii != call_inst_itr; + cii = call_block_itr->begin()) { + Instruction* inst = &*cii; + inst->RemoveFromList(); + std::unique_ptr cp_inst(inst); + // Remember same-block ops for possible regeneration. + if (IsSameBlockOp(&*cp_inst)) { + auto* sb_inst_ptr = cp_inst.get(); + (*preCallSB)[cp_inst->result_id()] = sb_inst_ptr; + } + new_blk_ptr->AddInstruction(std::move(cp_inst)); + } +} + +std::unique_ptr InlinePass::AddGuardBlock( + std::vector>* new_blocks, + std::unordered_map* callee2caller, + std::unique_ptr new_blk_ptr, uint32_t entry_blk_label_id) { + const auto guard_block_id = context()->TakeNextId(); + if (guard_block_id == 0) { + return nullptr; + } + AddBranch(guard_block_id, &new_blk_ptr); + new_blocks->push_back(std::move(new_blk_ptr)); + // Start the next block. + new_blk_ptr = MakeUnique(NewLabel(guard_block_id)); + // Reset the mapping of the callee's entry block to point to + // the guard block. Do this so we can fix up phis later on to + // satisfy dominance. + (*callee2caller)[entry_blk_label_id] = guard_block_id; + return new_blk_ptr; +} + +InstructionList::iterator InlinePass::AddStoresForVariableInitializers( + const std::unordered_map& callee2caller, + analysis::DebugInlinedAtContext* inlined_at_ctx, + std::unique_ptr* new_blk_ptr, + UptrVectorIterator callee_first_block_itr) { + auto callee_itr = callee_first_block_itr->begin(); + while (callee_itr->opcode() == spv::Op::OpVariable || + callee_itr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { + if (callee_itr->opcode() == spv::Op::OpVariable && + callee_itr->NumInOperands() == 2) { + assert(callee2caller.count(callee_itr->result_id()) && + "Expected the variable to have already been mapped."); + uint32_t new_var_id = callee2caller.at(callee_itr->result_id()); + + // The initializer must be a constant or global value. No mapped + // should be used. + uint32_t val_id = callee_itr->GetSingleWordInOperand(1); + AddStore(new_var_id, val_id, new_blk_ptr, callee_itr->dbg_line_inst(), + context()->get_debug_info_mgr()->BuildDebugScope( + callee_itr->GetDebugScope(), inlined_at_ctx)); + } + if (callee_itr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { + InlineSingleInstruction( + callee2caller, new_blk_ptr->get(), &*callee_itr, + context()->get_debug_info_mgr()->BuildDebugInlinedAtChain( + callee_itr->GetDebugScope().GetInlinedAt(), inlined_at_ctx)); + } + ++callee_itr; + } + return callee_itr; +} + +bool InlinePass::InlineSingleInstruction( + const std::unordered_map& callee2caller, + BasicBlock* new_blk_ptr, const Instruction* inst, uint32_t dbg_inlined_at) { + // If we have return, it must be at the end of the callee. We will handle + // it at the end. + if (inst->opcode() == spv::Op::OpReturnValue || + inst->opcode() == spv::Op::OpReturn) + return true; + + // Copy callee instruction and remap all input Ids. + std::unique_ptr cp_inst(inst->Clone(context())); + cp_inst->ForEachInId([&callee2caller](uint32_t* iid) { + const auto mapItr = callee2caller.find(*iid); + if (mapItr != callee2caller.end()) { + *iid = mapItr->second; + } + }); + + // If result id is non-zero, remap it. + const uint32_t rid = cp_inst->result_id(); + if (rid != 0) { + const auto mapItr = callee2caller.find(rid); + if (mapItr == callee2caller.end()) { + return false; + } + uint32_t nid = mapItr->second; + cp_inst->SetResultId(nid); + get_decoration_mgr()->CloneDecorations(rid, nid); + } + + cp_inst->UpdateDebugInlinedAt(dbg_inlined_at); + new_blk_ptr->AddInstruction(std::move(cp_inst)); + return true; +} + +std::unique_ptr InlinePass::InlineReturn( + const std::unordered_map& callee2caller, + std::vector>* new_blocks, + std::unique_ptr new_blk_ptr, + analysis::DebugInlinedAtContext* inlined_at_ctx, Function* calleeFn, + const Instruction* inst, uint32_t returnVarId) { + // Store return value to return variable. + if (inst->opcode() == spv::Op::OpReturnValue) { + assert(returnVarId != 0); + uint32_t valId = inst->GetInOperand(kSpvReturnValueId).words[0]; + const auto mapItr = callee2caller.find(valId); + if (mapItr != callee2caller.end()) { + valId = mapItr->second; + } + AddStore(returnVarId, valId, &new_blk_ptr, inst->dbg_line_inst(), + context()->get_debug_info_mgr()->BuildDebugScope( + inst->GetDebugScope(), inlined_at_ctx)); + } + + uint32_t returnLabelId = 0; + for (auto callee_block_itr = calleeFn->begin(); + callee_block_itr != calleeFn->end(); ++callee_block_itr) { + if (spvOpcodeIsAbort(callee_block_itr->tail()->opcode())) { + returnLabelId = context()->TakeNextId(); + break; + } + } + if (returnLabelId == 0) return new_blk_ptr; + + if (inst->opcode() == spv::Op::OpReturn || + inst->opcode() == spv::Op::OpReturnValue) + AddBranch(returnLabelId, &new_blk_ptr); + new_blocks->push_back(std::move(new_blk_ptr)); + return MakeUnique(NewLabel(returnLabelId)); +} + +bool InlinePass::InlineEntryBlock( + const std::unordered_map& callee2caller, + std::unique_ptr* new_blk_ptr, + UptrVectorIterator callee_first_block, + analysis::DebugInlinedAtContext* inlined_at_ctx) { + auto callee_inst_itr = AddStoresForVariableInitializers( + callee2caller, inlined_at_ctx, new_blk_ptr, callee_first_block); + + while (callee_inst_itr != callee_first_block->end()) { + // Don't inline function definition links, the calling function is not a + // definition. + if (callee_inst_itr->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugFunctionDefinition) { + ++callee_inst_itr; + continue; + } + + if (!InlineSingleInstruction( + callee2caller, new_blk_ptr->get(), &*callee_inst_itr, + context()->get_debug_info_mgr()->BuildDebugInlinedAtChain( + callee_inst_itr->GetDebugScope().GetInlinedAt(), + inlined_at_ctx))) { + return false; + } + ++callee_inst_itr; + } + return true; +} + +std::unique_ptr InlinePass::InlineBasicBlocks( + std::vector>* new_blocks, + const std::unordered_map& callee2caller, + std::unique_ptr new_blk_ptr, + analysis::DebugInlinedAtContext* inlined_at_ctx, Function* calleeFn) { + auto callee_block_itr = calleeFn->begin(); + ++callee_block_itr; + + while (callee_block_itr != calleeFn->end()) { + new_blocks->push_back(std::move(new_blk_ptr)); + const auto mapItr = + callee2caller.find(callee_block_itr->GetLabelInst()->result_id()); + if (mapItr == callee2caller.end()) return nullptr; + new_blk_ptr = MakeUnique(NewLabel(mapItr->second)); + + auto tail_inst_itr = callee_block_itr->end(); + for (auto inst_itr = callee_block_itr->begin(); inst_itr != tail_inst_itr; + ++inst_itr) { + // Don't inline function definition links, the calling function is not a + // definition + if (inst_itr->GetShader100DebugOpcode() == + NonSemanticShaderDebugInfo100DebugFunctionDefinition) + continue; + if (!InlineSingleInstruction( + callee2caller, new_blk_ptr.get(), &*inst_itr, + context()->get_debug_info_mgr()->BuildDebugInlinedAtChain( + inst_itr->GetDebugScope().GetInlinedAt(), inlined_at_ctx))) { + return nullptr; + } + } + + ++callee_block_itr; + } + return new_blk_ptr; +} + +bool InlinePass::MoveCallerInstsAfterFunctionCall( + std::unordered_map* preCallSB, + std::unordered_map* postCallSB, + std::unique_ptr* new_blk_ptr, + BasicBlock::iterator call_inst_itr, bool multiBlocks) { + // Copy remaining instructions from caller block. + for (Instruction* inst = call_inst_itr->NextNode(); inst; + inst = call_inst_itr->NextNode()) { + inst->RemoveFromList(); + std::unique_ptr cp_inst(inst); + // If multiple blocks generated, regenerate any same-block + // instruction that has not been seen in this last block. + if (multiBlocks) { + if (!CloneSameBlockOps(&cp_inst, postCallSB, preCallSB, new_blk_ptr)) { + return false; + } + + // Remember same-block ops in this block. + if (IsSameBlockOp(&*cp_inst)) { + const uint32_t rid = cp_inst->result_id(); + (*postCallSB)[rid] = rid; + } + } + new_blk_ptr->get()->AddInstruction(std::move(cp_inst)); + } + + return true; +} + +void InlinePass::MoveLoopMergeInstToFirstBlock( + std::vector>* new_blocks) { + // Move the OpLoopMerge from the last block back to the first, where + // it belongs. + auto& first = new_blocks->front(); + auto& last = new_blocks->back(); + assert(first != last); + + // Insert a modified copy of the loop merge into the first block. + auto loop_merge_itr = last->tail(); + --loop_merge_itr; + assert(loop_merge_itr->opcode() == spv::Op::OpLoopMerge); + std::unique_ptr cp_inst(loop_merge_itr->Clone(context())); + first->tail().InsertBefore(std::move(cp_inst)); + + // Remove the loop merge from the last block. + loop_merge_itr->RemoveFromList(); + delete &*loop_merge_itr; +} + +void InlinePass::UpdateSingleBlockLoopContinueTarget( + uint32_t new_id, std::vector>* new_blocks) { + auto& header = new_blocks->front(); + auto* merge_inst = header->GetLoopMergeInst(); + + // The back-edge block is split at the branch to create a new back-edge + // block. The old block is modified to branch to the new block. The loop + // merge instruction is updated to declare the new block as the continue + // target. This has the effect of changing the loop from being a large + // continue construct and an empty loop construct to being a loop with a loop + // construct and a trivial continue construct. This change is made to satisfy + // structural dominance. + + // Add the new basic block. + std::unique_ptr new_block = + MakeUnique(NewLabel(new_id)); + auto& old_backedge = new_blocks->back(); + auto old_branch = old_backedge->tail(); + + // Move the old back edge into the new block. + std::unique_ptr br(&*old_branch); + new_block->AddInstruction(std::move(br)); + + // Add a branch to the new block from the old back-edge block. + AddBranch(new_id, &old_backedge); + new_blocks->push_back(std::move(new_block)); + + // Update the loop's continue target to the new block. + merge_inst->SetInOperand(1u, {new_id}); +} + +bool InlinePass::GenInlineCode( + std::vector>* new_blocks, + std::vector>* new_vars, + BasicBlock::iterator call_inst_itr, + UptrVectorIterator call_block_itr) { + // Map from all ids in the callee to their equivalent id in the caller + // as callee instructions are copied into caller. + std::unordered_map callee2caller; + // Pre-call same-block insts + std::unordered_map preCallSB; + // Post-call same-block op ids + std::unordered_map postCallSB; + + analysis::DebugInlinedAtContext inlined_at_ctx(&*call_inst_itr); + + // Invalidate the def-use chains. They are not kept up to date while + // inlining. However, certain calls try to keep them up-to-date if they are + // valid. These operations can fail. + context()->InvalidateAnalyses(IRContext::kAnalysisDefUse); + + // If the caller is a loop header and the callee has multiple blocks, then the + // normal inlining logic will place the OpLoopMerge in the last of several + // blocks in the loop. Instead, it should be placed at the end of the first + // block. We'll wait to move the OpLoopMerge until the end of the regular + // inlining logic, and only if necessary. + bool caller_is_loop_header = call_block_itr->GetLoopMergeInst() != nullptr; + + // Single-trip loop continue block + std::unique_ptr single_trip_loop_cont_blk; + + Function* calleeFn = id2function_[call_inst_itr->GetSingleWordOperand( + kSpvFunctionCallFunctionId)]; + + // Map parameters to actual arguments. + MapParams(calleeFn, call_inst_itr, &callee2caller); + + // Define caller local variables for all callee variables and create map to + // them. + if (!CloneAndMapLocals(calleeFn, new_vars, &callee2caller, &inlined_at_ctx)) { + return false; + } + + // First block needs to use label of original block + // but map callee label in case of phi reference. + uint32_t entry_blk_label_id = calleeFn->begin()->GetLabelInst()->result_id(); + callee2caller[entry_blk_label_id] = call_block_itr->id(); + std::unique_ptr new_blk_ptr = + MakeUnique(NewLabel(call_block_itr->id())); + + // Move instructions of original caller block up to call instruction. + MoveInstsBeforeEntryBlock(&preCallSB, new_blk_ptr.get(), call_inst_itr, + call_block_itr); + + if (caller_is_loop_header && + (*(calleeFn->begin())).GetMergeInst() != nullptr) { + // We can't place both the caller's merge instruction and + // another merge instruction in the same block. So split the + // calling block. Insert an unconditional branch to a new guard + // block. Later, once we know the ID of the last block, we + // will move the caller's OpLoopMerge from the last generated + // block into the first block. We also wait to avoid + // invalidating various iterators. + new_blk_ptr = AddGuardBlock(new_blocks, &callee2caller, + std::move(new_blk_ptr), entry_blk_label_id); + if (new_blk_ptr == nullptr) return false; + } + + // Create return var if needed. + const uint32_t calleeTypeId = calleeFn->type_id(); + uint32_t returnVarId = 0; + analysis::Type* calleeType = context()->get_type_mgr()->GetType(calleeTypeId); + if (calleeType->AsVoid() == nullptr) { + returnVarId = CreateReturnVar(calleeFn, new_vars); + if (returnVarId == 0) { + return false; + } + } + + calleeFn->WhileEachInst([&callee2caller, this](const Instruction* cpi) { + // Create set of callee result ids. Used to detect forward references + const uint32_t rid = cpi->result_id(); + if (rid != 0 && callee2caller.find(rid) == callee2caller.end()) { + const uint32_t nid = context()->TakeNextId(); + if (nid == 0) return false; + callee2caller[rid] = nid; + } + return true; + }); + + // Inline DebugClare instructions in the callee's header. + calleeFn->ForEachDebugInstructionsInHeader( + [&new_blk_ptr, &callee2caller, &inlined_at_ctx, this](Instruction* inst) { + InlineSingleInstruction( + callee2caller, new_blk_ptr.get(), inst, + context()->get_debug_info_mgr()->BuildDebugInlinedAtChain( + inst->GetDebugScope().GetInlinedAt(), &inlined_at_ctx)); + }); + + // Inline the entry block of the callee function. + if (!InlineEntryBlock(callee2caller, &new_blk_ptr, calleeFn->begin(), + &inlined_at_ctx)) { + return false; + } + + // Inline blocks of the callee function other than the entry block. + new_blk_ptr = + InlineBasicBlocks(new_blocks, callee2caller, std::move(new_blk_ptr), + &inlined_at_ctx, calleeFn); + if (new_blk_ptr == nullptr) return false; + + new_blk_ptr = InlineReturn(callee2caller, new_blocks, std::move(new_blk_ptr), + &inlined_at_ctx, calleeFn, + &*(calleeFn->tail()->tail()), returnVarId); + + // Load return value into result id of call, if it exists. + if (returnVarId != 0) { + const uint32_t resId = call_inst_itr->result_id(); + assert(resId != 0); + AddLoad(calleeTypeId, resId, returnVarId, &new_blk_ptr, + call_inst_itr->dbg_line_inst(), call_inst_itr->GetDebugScope()); + } + + // Move instructions of original caller block after call instruction. + if (!MoveCallerInstsAfterFunctionCall(&preCallSB, &postCallSB, &new_blk_ptr, + call_inst_itr, + calleeFn->begin() != calleeFn->end())) + return false; + + // Finalize inline code. + new_blocks->push_back(std::move(new_blk_ptr)); + + if (caller_is_loop_header && (new_blocks->size() > 1)) { + MoveLoopMergeInstToFirstBlock(new_blocks); + + // If the loop was a single basic block previously, update it's structure. + auto& header = new_blocks->front(); + auto* merge_inst = header->GetLoopMergeInst(); + if (merge_inst->GetSingleWordInOperand(1u) == header->id()) { + auto new_id = context()->TakeNextId(); + if (new_id == 0) return false; + UpdateSingleBlockLoopContinueTarget(new_id, new_blocks); + } + } + + // Update block map given replacement blocks. + for (auto& blk : *new_blocks) { + id2block_[blk->id()] = &*blk; + } + + // We need to kill the name and decorations for the call, which will be + // deleted. + context()->KillNamesAndDecorates(&*call_inst_itr); + + return true; +} + +bool InlinePass::IsInlinableFunctionCall(const Instruction* inst) { + if (inst->opcode() != spv::Op::OpFunctionCall) return false; + const uint32_t calleeFnId = + inst->GetSingleWordOperand(kSpvFunctionCallFunctionId); + const auto ci = inlinable_.find(calleeFnId); + if (ci == inlinable_.cend()) return false; + + if (early_return_funcs_.find(calleeFnId) != early_return_funcs_.end()) { + // We rely on the merge-return pass to handle the early return case + // in advance. + std::string message = + "The function '" + id2function_[calleeFnId]->DefInst().PrettyPrint() + + "' could not be inlined because the return instruction " + "is not at the end of the function. This could be fixed by " + "running merge-return before inlining."; + consumer()(SPV_MSG_WARNING, "", {0, 0, 0}, message.c_str()); + return false; + } + + return true; +} + +void InlinePass::UpdateSucceedingPhis( + std::vector>& new_blocks) { + const auto firstBlk = new_blocks.begin(); + const auto lastBlk = new_blocks.end() - 1; + const uint32_t firstId = (*firstBlk)->id(); + const uint32_t lastId = (*lastBlk)->id(); + const BasicBlock& const_last_block = *lastBlk->get(); + const_last_block.ForEachSuccessorLabel( + [&firstId, &lastId, this](const uint32_t succ) { + BasicBlock* sbp = this->id2block_[succ]; + sbp->ForEachPhiInst([&firstId, &lastId](Instruction* phi) { + phi->ForEachInId([&firstId, &lastId](uint32_t* id) { + if (*id == firstId) *id = lastId; + }); + }); + }); +} + +bool InlinePass::HasNoReturnInLoop(Function* func) { + // If control not structured, do not do loop/return analysis + // TODO: Analyze returns in non-structured control flow + if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return false; + const auto structured_analysis = context()->GetStructuredCFGAnalysis(); + // Search for returns in structured construct. + bool return_in_loop = false; + for (auto& blk : *func) { + auto terminal_ii = blk.cend(); + --terminal_ii; + if (spvOpcodeIsReturn(terminal_ii->opcode()) && + structured_analysis->ContainingLoop(blk.id()) != 0) { + return_in_loop = true; + break; + } + } + return !return_in_loop; +} + +void InlinePass::AnalyzeReturns(Function* func) { + // Analyze functions without a return in loop. + if (HasNoReturnInLoop(func)) { + no_return_in_loop_.insert(func->result_id()); + } + // Analyze functions with a return before its tail basic block. + for (auto& blk : *func) { + auto terminal_ii = blk.cend(); + --terminal_ii; + if (spvOpcodeIsReturn(terminal_ii->opcode()) && &blk != func->tail()) { + early_return_funcs_.insert(func->result_id()); + break; + } + } +} + +bool InlinePass::IsInlinableFunction(Function* func) { + // We can only inline a function if it has blocks. + if (func->cbegin() == func->cend()) return false; + + // Do not inline functions with DontInline flag. + if (func->control_mask() & uint32_t(spv::FunctionControlMask::DontInline)) { + return false; + } + + // Do not inline functions with returns in loops. Currently early return + // functions are inlined by wrapping them in a one trip loop and implementing + // the returns as a branch to the loop's merge block. However, this can only + // done validly if the return was not in a loop in the original function. + // Also remember functions with multiple (early) returns. + AnalyzeReturns(func); + if (no_return_in_loop_.find(func->result_id()) == no_return_in_loop_.cend()) { + return false; + } + + if (func->IsRecursive()) { + return false; + } + + // Do not inline functions with an abort instruction if they are called from a + // continue construct. If it is inlined into a continue construct the backedge + // will no longer post-dominate the continue target, which is invalid. An + // `OpUnreachable` is acceptable because it will not change post-dominance if + // it is statically unreachable. + bool func_is_called_from_continue = + funcs_called_from_continue_.count(func->result_id()) != 0; + + if (func_is_called_from_continue && ContainsAbortOtherThanUnreachable(func)) { + return false; + } + + return true; +} + +bool InlinePass::ContainsAbortOtherThanUnreachable(Function* func) const { + return !func->WhileEachInst([](Instruction* inst) { + return inst->opcode() == spv::Op::OpUnreachable || + !spvOpcodeIsAbort(inst->opcode()); + }); +} + +void InlinePass::InitializeInline() { + false_id_ = 0; + + // clear collections + id2function_.clear(); + id2block_.clear(); + inlinable_.clear(); + no_return_in_loop_.clear(); + early_return_funcs_.clear(); + funcs_called_from_continue_ = + context()->GetStructuredCFGAnalysis()->FindFuncsCalledFromContinue(); + + for (auto& fn : *get_module()) { + // Initialize function and block maps. + id2function_[fn.result_id()] = &fn; + for (auto& blk : fn) { + id2block_[blk.id()] = &blk; + } + // Compute inlinability + if (IsInlinableFunction(&fn)) inlinable_.insert(fn.result_id()); + } +} + +InlinePass::InlinePass() {} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inline_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/inline_pass.h new file mode 100644 index 000000000000..1c9d60e32d73 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inline_pass.h @@ -0,0 +1,249 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_INLINE_PASS_H_ +#define SOURCE_OPT_INLINE_PASS_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/debug_info_manager.h" +#include "source/opt/decoration_manager.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class InlinePass : public Pass { + using cbb_ptr = const BasicBlock*; + + public: + virtual ~InlinePass() override = default; + + protected: + InlinePass(); + + // Add pointer to type to module and return resultId. Returns 0 if the type + // could not be created. + uint32_t AddPointerToType(uint32_t type_id, spv::StorageClass storage_class); + + // Add unconditional branch to labelId to end of block block_ptr. + void AddBranch(uint32_t labelId, std::unique_ptr* block_ptr); + + // Add conditional branch to end of block |block_ptr|. + void AddBranchCond(uint32_t cond_id, uint32_t true_id, uint32_t false_id, + std::unique_ptr* block_ptr); + + // Add unconditional branch to labelId to end of block block_ptr. + void AddLoopMerge(uint32_t merge_id, uint32_t continue_id, + std::unique_ptr* block_ptr); + + // Add store of valId to ptrId to end of block block_ptr. + void AddStore(uint32_t ptrId, uint32_t valId, + std::unique_ptr* block_ptr, + const Instruction* line_inst, const DebugScope& dbg_scope); + + // Add load of ptrId into resultId to end of block block_ptr. + void AddLoad(uint32_t typeId, uint32_t resultId, uint32_t ptrId, + std::unique_ptr* block_ptr, + const Instruction* line_inst, const DebugScope& dbg_scope); + + // Return new label. + std::unique_ptr NewLabel(uint32_t label_id); + + // Returns the id for the boolean false value. Looks in the module first + // and creates it if not found. Remembers it for future calls. Returns 0 if + // the value could not be created. + uint32_t GetFalseId(); + + // Map callee params to caller args + void MapParams(Function* calleeFn, BasicBlock::iterator call_inst_itr, + std::unordered_map* callee2caller); + + // Clone and map callee locals. Return true if successful. + bool CloneAndMapLocals(Function* calleeFn, + std::vector>* new_vars, + std::unordered_map* callee2caller, + analysis::DebugInlinedAtContext* inlined_at_ctx); + + // Create return variable for callee clone code. The return type of + // |calleeFn| must not be void. Returns the id of the return variable if + // created. Returns 0 if the return variable could not be created. + uint32_t CreateReturnVar(Function* calleeFn, + std::vector>* new_vars); + + // Return true if instruction must be in the same block that its result + // is used. + bool IsSameBlockOp(const Instruction* inst) const; + + // Clone operands which must be in same block as consumer instructions. + // Look in preCallSB for instructions that need cloning. Look in + // postCallSB for instructions already cloned. Add cloned instruction + // to postCallSB. + bool CloneSameBlockOps(std::unique_ptr* inst, + std::unordered_map* postCallSB, + std::unordered_map* preCallSB, + std::unique_ptr* block_ptr); + + // Return in new_blocks the result of inlining the call at call_inst_itr + // within its block at call_block_itr. The block at call_block_itr can + // just be replaced with the blocks in new_blocks. Any additional branches + // are avoided. Debug instructions are cloned along with their callee + // instructions. Early returns are replaced by a store to a local return + // variable and a branch to a (created) exit block where the local variable + // is returned. Formal parameters are trivially mapped to their actual + // parameters. Note that the first block in new_blocks retains the label + // of the original calling block. Also note that if an exit block is + // created, it is the last block of new_blocks. + // + // Also return in new_vars additional OpVariable instructions required by + // and to be inserted into the caller function after the block at + // call_block_itr is replaced with new_blocks. + // + // Returns true if successful. + bool GenInlineCode(std::vector>* new_blocks, + std::vector>* new_vars, + BasicBlock::iterator call_inst_itr, + UptrVectorIterator call_block_itr); + + // Return true if |inst| is a function call that can be inlined. + bool IsInlinableFunctionCall(const Instruction* inst); + + // Return true if |func| has no return in a loop. The current analysis + // requires structured control flow, so return false if control flow not + // structured ie. module is not a shader. + bool HasNoReturnInLoop(Function* func); + + // Find all functions with multiple returns and no returns in loops + void AnalyzeReturns(Function* func); + + // Return true if |func| is a function that can be inlined. + bool IsInlinableFunction(Function* func); + + // Returns true if |func| contains an abort instruction that is not an + // `OpUnreachable` instruction. + bool ContainsAbortOtherThanUnreachable(Function* func) const; + + // Update phis in succeeding blocks to point to new last block + void UpdateSucceedingPhis( + std::vector>& new_blocks); + + // Initialize state for optimization of |module| + void InitializeInline(); + + // Map from function's result id to function. + std::unordered_map id2function_; + + // Map from block's label id to block. TODO(dnovillo): This is superfluous wrt + // CFG. It has functionality not present in CFG. Consolidate. + std::unordered_map id2block_; + + // Set of ids of functions with early return. + std::set early_return_funcs_; + + // Set of ids of functions with no returns in loop + std::set no_return_in_loop_; + + // Set of ids of inlinable functions + std::set inlinable_; + + // result id for OpConstantFalse + uint32_t false_id_; + + // Set of functions that are originally called directly or indirectly from a + // continue construct. + std::unordered_set funcs_called_from_continue_; + + private: + // Moves instructions of the caller function up to the call instruction + // to |new_blk_ptr|. + void MoveInstsBeforeEntryBlock( + std::unordered_map* preCallSB, + BasicBlock* new_blk_ptr, BasicBlock::iterator call_inst_itr, + UptrVectorIterator call_block_itr); + + // Returns a new guard block after adding a branch to the end of + // |new_blocks|. + std::unique_ptr AddGuardBlock( + std::vector>* new_blocks, + std::unordered_map* callee2caller, + std::unique_ptr new_blk_ptr, uint32_t entry_blk_label_id); + + // Add store instructions for initializers of variables. + InstructionList::iterator AddStoresForVariableInitializers( + const std::unordered_map& callee2caller, + analysis::DebugInlinedAtContext* inlined_at_ctx, + std::unique_ptr* new_blk_ptr, + UptrVectorIterator callee_block_itr); + + // Inlines a single instruction of the callee function. + bool InlineSingleInstruction( + const std::unordered_map& callee2caller, + BasicBlock* new_blk_ptr, const Instruction* inst, + uint32_t dbg_inlined_at); + + // Inlines the return instruction of the callee function. + std::unique_ptr InlineReturn( + const std::unordered_map& callee2caller, + std::vector>* new_blocks, + std::unique_ptr new_blk_ptr, + analysis::DebugInlinedAtContext* inlined_at_ctx, Function* calleeFn, + const Instruction* inst, uint32_t returnVarId); + + // Inlines the entry block of the callee function. + bool InlineEntryBlock( + const std::unordered_map& callee2caller, + std::unique_ptr* new_blk_ptr, + UptrVectorIterator callee_first_block, + analysis::DebugInlinedAtContext* inlined_at_ctx); + + // Inlines basic blocks of the callee function other than the entry basic + // block. + std::unique_ptr InlineBasicBlocks( + std::vector>* new_blocks, + const std::unordered_map& callee2caller, + std::unique_ptr new_blk_ptr, + analysis::DebugInlinedAtContext* inlined_at_ctx, Function* calleeFn); + + // Moves instructions of the caller function after the call instruction + // to |new_blk_ptr|. + bool MoveCallerInstsAfterFunctionCall( + std::unordered_map* preCallSB, + std::unordered_map* postCallSB, + std::unique_ptr* new_blk_ptr, + BasicBlock::iterator call_inst_itr, bool multiBlocks); + + // Move the OpLoopMerge from the last block back to the first. + void MoveLoopMergeInstToFirstBlock( + std::vector>* new_blocks); + + // Update the structure of single block loops so that the inlined code ends + // up in the loop construct and a new continue target is added to satisfy + // structural dominance. + void UpdateSingleBlockLoopContinueTarget( + uint32_t new_id, std::vector>* new_blocks); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_INLINE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inst_bindless_check_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/inst_bindless_check_pass.cpp new file mode 100644 index 000000000000..8e7d4f83e8de --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inst_bindless_check_pass.cpp @@ -0,0 +1,761 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "inst_bindless_check_pass.h" + +#include "source/spirv_constant.h" + +namespace spvtools { +namespace opt { +namespace { +// Input Operand Indices +constexpr int kSpvImageSampleImageIdInIdx = 0; +constexpr int kSpvSampledImageImageIdInIdx = 0; +constexpr int kSpvSampledImageSamplerIdInIdx = 1; +constexpr int kSpvImageSampledImageIdInIdx = 0; +constexpr int kSpvCopyObjectOperandIdInIdx = 0; +constexpr int kSpvLoadPtrIdInIdx = 0; +constexpr int kSpvAccessChainBaseIdInIdx = 0; +constexpr int kSpvAccessChainIndex0IdInIdx = 1; +constexpr int kSpvTypeArrayTypeIdInIdx = 0; +constexpr int kSpvVariableStorageClassInIdx = 0; +constexpr int kSpvTypePtrTypeIdInIdx = 1; +constexpr int kSpvTypeImageDim = 1; +constexpr int kSpvTypeImageDepth = 2; +constexpr int kSpvTypeImageArrayed = 3; +constexpr int kSpvTypeImageMS = 4; +} // namespace + +// This is a stub function for use with Import linkage +// clang-format off +// GLSL: +//bool inst_bindless_check_desc(const uint shader_id, const uint inst_num, const uvec4 stage_info, const uint desc_set, +// const uint binding, const uint desc_index, const uint byte_offset) { +//} +// clang-format on +uint32_t InstBindlessCheckPass::GenDescCheckFunctionId() { + enum { + kShaderId = 0, + kInstructionIndex = 1, + kStageInfo = 2, + kDescSet = 3, + kDescBinding = 4, + kDescIndex = 5, + kByteOffset = 6, + kNumArgs + }; + if (check_desc_func_id_ != 0) { + return check_desc_func_id_; + } + + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + const analysis::Integer* uint_type = GetInteger(32, false); + const analysis::Vector v4uint(uint_type, 4); + const analysis::Type* v4uint_type = type_mgr->GetRegisteredType(&v4uint); + std::vector param_types(kNumArgs, uint_type); + param_types[2] = v4uint_type; + + const uint32_t func_id = TakeNextId(); + std::unique_ptr func = + StartFunction(func_id, type_mgr->GetBoolType(), param_types); + + func->SetFunctionEnd(EndFunction()); + + static const std::string func_name{"inst_bindless_check_desc"}; + context()->AddFunctionDeclaration(std::move(func)); + context()->AddDebug2Inst(NewName(func_id, func_name)); + std::vector operands{ + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {func_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {uint32_t(spv::Decoration::LinkageAttributes)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_STRING, + utils::MakeVector(func_name.c_str())}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LINKAGE_TYPE, + {uint32_t(spv::LinkageType::Import)}}, + }; + get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, operands); + + check_desc_func_id_ = func_id; + // Make sure function doesn't get processed by + // InstrumentPass::InstProcessCallTreeFromRoots() + param2output_func_id_[3] = func_id; + return check_desc_func_id_; +} + +// clang-format off +// GLSL: +// result = inst_bindless_check_desc(shader_id, inst_idx, stage_info, desc_set, binding, desc_idx, offset); +// +// clang-format on +uint32_t InstBindlessCheckPass::GenDescCheckCall( + uint32_t inst_idx, uint32_t stage_idx, uint32_t var_id, + uint32_t desc_idx_id, uint32_t offset_id, InstructionBuilder* builder) { + const uint32_t func_id = GenDescCheckFunctionId(); + const std::vector args = { + builder->GetUintConstantId(shader_id_), + builder->GetUintConstantId(inst_idx), + GenStageInfo(stage_idx, builder), + builder->GetUintConstantId(var2desc_set_[var_id]), + builder->GetUintConstantId(var2binding_[var_id]), + GenUintCastCode(desc_idx_id, builder), + offset_id}; + return GenReadFunctionCall(GetBoolId(), func_id, args, builder); +} + +uint32_t InstBindlessCheckPass::CloneOriginalImage( + uint32_t old_image_id, InstructionBuilder* builder) { + Instruction* new_image_inst; + Instruction* old_image_inst = get_def_use_mgr()->GetDef(old_image_id); + if (old_image_inst->opcode() == spv::Op::OpLoad) { + new_image_inst = builder->AddLoad( + old_image_inst->type_id(), + old_image_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx)); + } else if (old_image_inst->opcode() == spv::Op::OpSampledImage) { + uint32_t clone_id = CloneOriginalImage( + old_image_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx), + builder); + new_image_inst = builder->AddBinaryOp( + old_image_inst->type_id(), spv::Op::OpSampledImage, clone_id, + old_image_inst->GetSingleWordInOperand(kSpvSampledImageSamplerIdInIdx)); + } else if (old_image_inst->opcode() == spv::Op::OpImage) { + uint32_t clone_id = CloneOriginalImage( + old_image_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx), + builder); + new_image_inst = builder->AddUnaryOp(old_image_inst->type_id(), + spv::Op::OpImage, clone_id); + } else { + assert(old_image_inst->opcode() == spv::Op::OpCopyObject && + "expecting OpCopyObject"); + uint32_t clone_id = CloneOriginalImage( + old_image_inst->GetSingleWordInOperand(kSpvCopyObjectOperandIdInIdx), + builder); + // Since we are cloning, no need to create new copy + new_image_inst = get_def_use_mgr()->GetDef(clone_id); + } + uid2offset_[new_image_inst->unique_id()] = + uid2offset_[old_image_inst->unique_id()]; + uint32_t new_image_id = new_image_inst->result_id(); + get_decoration_mgr()->CloneDecorations(old_image_id, new_image_id); + return new_image_id; +} + +uint32_t InstBindlessCheckPass::CloneOriginalReference( + RefAnalysis* ref, InstructionBuilder* builder) { + // If original is image based, start by cloning descriptor load + uint32_t new_image_id = 0; + if (ref->desc_load_id != 0) { + uint32_t old_image_id = + ref->ref_inst->GetSingleWordInOperand(kSpvImageSampleImageIdInIdx); + new_image_id = CloneOriginalImage(old_image_id, builder); + } + // Clone original reference + std::unique_ptr new_ref_inst(ref->ref_inst->Clone(context())); + uint32_t ref_result_id = ref->ref_inst->result_id(); + uint32_t new_ref_id = 0; + if (ref_result_id != 0) { + new_ref_id = TakeNextId(); + new_ref_inst->SetResultId(new_ref_id); + } + // Update new ref with new image if created + if (new_image_id != 0) + new_ref_inst->SetInOperand(kSpvImageSampleImageIdInIdx, {new_image_id}); + // Register new reference and add to new block + Instruction* added_inst = builder->AddInstruction(std::move(new_ref_inst)); + uid2offset_[added_inst->unique_id()] = + uid2offset_[ref->ref_inst->unique_id()]; + if (new_ref_id != 0) + get_decoration_mgr()->CloneDecorations(ref_result_id, new_ref_id); + return new_ref_id; +} + +uint32_t InstBindlessCheckPass::GetImageId(Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageQueryLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpImageFetch: + case spv::Op::OpImageRead: + case spv::Op::OpImageQueryFormat: + case spv::Op::OpImageQueryOrder: + case spv::Op::OpImageQuerySizeLod: + case spv::Op::OpImageQuerySize: + case spv::Op::OpImageQueryLevels: + case spv::Op::OpImageQuerySamples: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageSparseRead: + case spv::Op::OpImageWrite: + return inst->GetSingleWordInOperand(kSpvImageSampleImageIdInIdx); + default: + break; + } + return 0; +} + +Instruction* InstBindlessCheckPass::GetPointeeTypeInst(Instruction* ptr_inst) { + uint32_t pte_ty_id = GetPointeeTypeId(ptr_inst); + return get_def_use_mgr()->GetDef(pte_ty_id); +} + +bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, + RefAnalysis* ref) { + ref->ref_inst = ref_inst; + if (ref_inst->opcode() == spv::Op::OpLoad || + ref_inst->opcode() == spv::Op::OpStore) { + ref->desc_load_id = 0; + ref->ptr_id = ref_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx); + Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref->ptr_id); + if (ptr_inst->opcode() != spv::Op::OpAccessChain) return false; + ref->var_id = ptr_inst->GetSingleWordInOperand(kSpvAccessChainBaseIdInIdx); + Instruction* var_inst = get_def_use_mgr()->GetDef(ref->var_id); + if (var_inst->opcode() != spv::Op::OpVariable) return false; + spv::StorageClass storage_class = spv::StorageClass( + var_inst->GetSingleWordInOperand(kSpvVariableStorageClassInIdx)); + switch (storage_class) { + case spv::StorageClass::Uniform: + case spv::StorageClass::StorageBuffer: + break; + default: + return false; + break; + } + // Check for deprecated storage block form + if (storage_class == spv::StorageClass::Uniform) { + uint32_t var_ty_id = var_inst->type_id(); + Instruction* var_ty_inst = get_def_use_mgr()->GetDef(var_ty_id); + uint32_t ptr_ty_id = + var_ty_inst->GetSingleWordInOperand(kSpvTypePtrTypeIdInIdx); + Instruction* ptr_ty_inst = get_def_use_mgr()->GetDef(ptr_ty_id); + spv::Op ptr_ty_op = ptr_ty_inst->opcode(); + uint32_t block_ty_id = + (ptr_ty_op == spv::Op::OpTypeArray || + ptr_ty_op == spv::Op::OpTypeRuntimeArray) + ? ptr_ty_inst->GetSingleWordInOperand(kSpvTypeArrayTypeIdInIdx) + : ptr_ty_id; + assert(get_def_use_mgr()->GetDef(block_ty_id)->opcode() == + spv::Op::OpTypeStruct && + "unexpected block type"); + bool block_found = get_decoration_mgr()->FindDecoration( + block_ty_id, uint32_t(spv::Decoration::Block), + [](const Instruction&) { return true; }); + if (!block_found) { + // If block decoration not found, verify deprecated form of SSBO + bool buffer_block_found = get_decoration_mgr()->FindDecoration( + block_ty_id, uint32_t(spv::Decoration::BufferBlock), + [](const Instruction&) { return true; }); + USE_ASSERT(buffer_block_found && "block decoration not found"); + storage_class = spv::StorageClass::StorageBuffer; + } + } + ref->strg_class = uint32_t(storage_class); + Instruction* desc_type_inst = GetPointeeTypeInst(var_inst); + switch (desc_type_inst->opcode()) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + // A load through a descriptor array will have at least 3 operands. We + // do not want to instrument loads of descriptors here which are part of + // an image-based reference. + if (ptr_inst->NumInOperands() < 3) return false; + ref->desc_idx_id = + ptr_inst->GetSingleWordInOperand(kSpvAccessChainIndex0IdInIdx); + break; + default: + break; + } + auto decos = + context()->get_decoration_mgr()->GetDecorationsFor(ref->var_id, false); + for (const auto& deco : decos) { + spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u)); + if (d == spv::Decoration::DescriptorSet) { + ref->set = deco->GetSingleWordInOperand(2u); + } else if (d == spv::Decoration::Binding) { + ref->binding = deco->GetSingleWordInOperand(2u); + } + } + return true; + } + // Reference is not load or store. If not an image-based reference, return. + ref->image_id = GetImageId(ref_inst); + if (ref->image_id == 0) return false; + // Search for descriptor load + uint32_t desc_load_id = ref->image_id; + Instruction* desc_load_inst; + for (;;) { + desc_load_inst = get_def_use_mgr()->GetDef(desc_load_id); + if (desc_load_inst->opcode() == spv::Op::OpSampledImage) + desc_load_id = + desc_load_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx); + else if (desc_load_inst->opcode() == spv::Op::OpImage) + desc_load_id = + desc_load_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx); + else if (desc_load_inst->opcode() == spv::Op::OpCopyObject) + desc_load_id = + desc_load_inst->GetSingleWordInOperand(kSpvCopyObjectOperandIdInIdx); + else + break; + } + if (desc_load_inst->opcode() != spv::Op::OpLoad) { + // TODO(greg-lunarg): Handle additional possibilities? + return false; + } + ref->desc_load_id = desc_load_id; + ref->ptr_id = desc_load_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx); + Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref->ptr_id); + if (ptr_inst->opcode() == spv::Op::OpVariable) { + ref->desc_idx_id = 0; + ref->var_id = ref->ptr_id; + } else if (ptr_inst->opcode() == spv::Op::OpAccessChain) { + if (ptr_inst->NumInOperands() != 2) { + assert(false && "unexpected bindless index number"); + return false; + } + ref->desc_idx_id = + ptr_inst->GetSingleWordInOperand(kSpvAccessChainIndex0IdInIdx); + ref->var_id = ptr_inst->GetSingleWordInOperand(kSpvAccessChainBaseIdInIdx); + Instruction* var_inst = get_def_use_mgr()->GetDef(ref->var_id); + if (var_inst->opcode() != spv::Op::OpVariable) { + assert(false && "unexpected bindless base"); + return false; + } + } else { + // TODO(greg-lunarg): Handle additional possibilities? + return false; + } + auto decos = + context()->get_decoration_mgr()->GetDecorationsFor(ref->var_id, false); + for (const auto& deco : decos) { + spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u)); + if (d == spv::Decoration::DescriptorSet) { + ref->set = deco->GetSingleWordInOperand(2u); + } else if (d == spv::Decoration::Binding) { + ref->binding = deco->GetSingleWordInOperand(2u); + } + } + return true; +} + +uint32_t InstBindlessCheckPass::FindStride(uint32_t ty_id, + uint32_t stride_deco) { + uint32_t stride = 0xdeadbeef; + bool found = get_decoration_mgr()->FindDecoration( + ty_id, stride_deco, [&stride](const Instruction& deco_inst) { + stride = deco_inst.GetSingleWordInOperand(2u); + return true; + }); + USE_ASSERT(found && "stride not found"); + return stride; +} + +uint32_t InstBindlessCheckPass::ByteSize(uint32_t ty_id, uint32_t matrix_stride, + bool col_major, bool in_matrix) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + const analysis::Type* sz_ty = type_mgr->GetType(ty_id); + if (sz_ty->kind() == analysis::Type::kPointer) { + // Assuming PhysicalStorageBuffer pointer + return 8; + } + if (sz_ty->kind() == analysis::Type::kMatrix) { + assert(matrix_stride != 0 && "missing matrix stride"); + const analysis::Matrix* m_ty = sz_ty->AsMatrix(); + if (col_major) { + return m_ty->element_count() * matrix_stride; + } else { + const analysis::Vector* v_ty = m_ty->element_type()->AsVector(); + return v_ty->element_count() * matrix_stride; + } + } + uint32_t size = 1; + if (sz_ty->kind() == analysis::Type::kVector) { + const analysis::Vector* v_ty = sz_ty->AsVector(); + size = v_ty->element_count(); + const analysis::Type* comp_ty = v_ty->element_type(); + // if vector in row major matrix, the vector is strided so return the + // number of bytes spanned by the vector + if (in_matrix && !col_major && matrix_stride > 0) { + uint32_t comp_ty_id = type_mgr->GetId(comp_ty); + return (size - 1) * matrix_stride + ByteSize(comp_ty_id, 0, false, false); + } + sz_ty = comp_ty; + } + switch (sz_ty->kind()) { + case analysis::Type::kFloat: { + const analysis::Float* f_ty = sz_ty->AsFloat(); + size *= f_ty->width(); + } break; + case analysis::Type::kInteger: { + const analysis::Integer* i_ty = sz_ty->AsInteger(); + size *= i_ty->width(); + } break; + default: { assert(false && "unexpected type"); } break; + } + size /= 8; + return size; +} + +uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, + InstructionBuilder* builder) { + // Find outermost buffer type and its access chain index + Instruction* var_inst = get_def_use_mgr()->GetDef(ref->var_id); + Instruction* desc_ty_inst = GetPointeeTypeInst(var_inst); + uint32_t buff_ty_id; + uint32_t ac_in_idx = 1; + switch (desc_ty_inst->opcode()) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + buff_ty_id = desc_ty_inst->GetSingleWordInOperand(0); + ++ac_in_idx; + break; + default: + assert(desc_ty_inst->opcode() == spv::Op::OpTypeStruct && + "unexpected descriptor type"); + buff_ty_id = desc_ty_inst->result_id(); + break; + } + // Process remaining access chain indices + Instruction* ac_inst = get_def_use_mgr()->GetDef(ref->ptr_id); + uint32_t curr_ty_id = buff_ty_id; + uint32_t sum_id = 0u; + uint32_t matrix_stride = 0u; + bool col_major = false; + uint32_t matrix_stride_id = 0u; + bool in_matrix = false; + while (ac_in_idx < ac_inst->NumInOperands()) { + uint32_t curr_idx_id = ac_inst->GetSingleWordInOperand(ac_in_idx); + Instruction* curr_ty_inst = get_def_use_mgr()->GetDef(curr_ty_id); + uint32_t curr_offset_id = 0; + switch (curr_ty_inst->opcode()) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: { + // Get array stride and multiply by current index + uint32_t arr_stride = + FindStride(curr_ty_id, uint32_t(spv::Decoration::ArrayStride)); + uint32_t arr_stride_id = builder->GetUintConstantId(arr_stride); + uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); + Instruction* curr_offset_inst = builder->AddBinaryOp( + GetUintId(), spv::Op::OpIMul, arr_stride_id, curr_idx_32b_id); + curr_offset_id = curr_offset_inst->result_id(); + // Get element type for next step + curr_ty_id = curr_ty_inst->GetSingleWordInOperand(0); + } break; + case spv::Op::OpTypeMatrix: { + assert(matrix_stride != 0 && "missing matrix stride"); + matrix_stride_id = builder->GetUintConstantId(matrix_stride); + uint32_t vec_ty_id = curr_ty_inst->GetSingleWordInOperand(0); + // If column major, multiply column index by matrix stride, otherwise + // by vector component size and save matrix stride for vector (row) + // index + uint32_t col_stride_id; + if (col_major) { + col_stride_id = matrix_stride_id; + } else { + Instruction* vec_ty_inst = get_def_use_mgr()->GetDef(vec_ty_id); + uint32_t comp_ty_id = vec_ty_inst->GetSingleWordInOperand(0u); + uint32_t col_stride = ByteSize(comp_ty_id, 0u, false, false); + col_stride_id = builder->GetUintConstantId(col_stride); + } + uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); + Instruction* curr_offset_inst = builder->AddBinaryOp( + GetUintId(), spv::Op::OpIMul, col_stride_id, curr_idx_32b_id); + curr_offset_id = curr_offset_inst->result_id(); + // Get element type for next step + curr_ty_id = vec_ty_id; + in_matrix = true; + } break; + case spv::Op::OpTypeVector: { + // If inside a row major matrix type, multiply index by matrix stride, + // else multiply by component size + uint32_t comp_ty_id = curr_ty_inst->GetSingleWordInOperand(0u); + uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); + if (in_matrix && !col_major) { + Instruction* curr_offset_inst = builder->AddBinaryOp( + GetUintId(), spv::Op::OpIMul, matrix_stride_id, curr_idx_32b_id); + curr_offset_id = curr_offset_inst->result_id(); + } else { + uint32_t comp_ty_sz = ByteSize(comp_ty_id, 0u, false, false); + uint32_t comp_ty_sz_id = builder->GetUintConstantId(comp_ty_sz); + Instruction* curr_offset_inst = builder->AddBinaryOp( + GetUintId(), spv::Op::OpIMul, comp_ty_sz_id, curr_idx_32b_id); + curr_offset_id = curr_offset_inst->result_id(); + } + // Get element type for next step + curr_ty_id = comp_ty_id; + } break; + case spv::Op::OpTypeStruct: { + // Get buffer byte offset for the referenced member + Instruction* curr_idx_inst = get_def_use_mgr()->GetDef(curr_idx_id); + assert(curr_idx_inst->opcode() == spv::Op::OpConstant && + "unexpected struct index"); + uint32_t member_idx = curr_idx_inst->GetSingleWordInOperand(0); + uint32_t member_offset = 0xdeadbeef; + bool found = get_decoration_mgr()->FindDecoration( + curr_ty_id, uint32_t(spv::Decoration::Offset), + [&member_idx, &member_offset](const Instruction& deco_inst) { + if (deco_inst.GetSingleWordInOperand(1u) != member_idx) + return false; + member_offset = deco_inst.GetSingleWordInOperand(3u); + return true; + }); + USE_ASSERT(found && "member offset not found"); + curr_offset_id = builder->GetUintConstantId(member_offset); + // Look for matrix stride for this member if there is one. The matrix + // stride is not on the matrix type, but in a OpMemberDecorate on the + // enclosing struct type at the member index. If none found, reset + // stride to 0. + found = get_decoration_mgr()->FindDecoration( + curr_ty_id, uint32_t(spv::Decoration::MatrixStride), + [&member_idx, &matrix_stride](const Instruction& deco_inst) { + if (deco_inst.GetSingleWordInOperand(1u) != member_idx) + return false; + matrix_stride = deco_inst.GetSingleWordInOperand(3u); + return true; + }); + if (!found) matrix_stride = 0; + // Look for column major decoration + found = get_decoration_mgr()->FindDecoration( + curr_ty_id, uint32_t(spv::Decoration::ColMajor), + [&member_idx, &col_major](const Instruction& deco_inst) { + if (deco_inst.GetSingleWordInOperand(1u) != member_idx) + return false; + col_major = true; + return true; + }); + if (!found) col_major = false; + // Get element type for next step + curr_ty_id = curr_ty_inst->GetSingleWordInOperand(member_idx); + } break; + default: { assert(false && "unexpected non-composite type"); } break; + } + if (sum_id == 0) + sum_id = curr_offset_id; + else { + Instruction* sum_inst = + builder->AddIAdd(GetUintId(), sum_id, curr_offset_id); + sum_id = sum_inst->result_id(); + } + ++ac_in_idx; + } + // Add in offset of last byte of referenced object + uint32_t bsize = ByteSize(curr_ty_id, matrix_stride, col_major, in_matrix); + uint32_t last = bsize - 1; + uint32_t last_id = builder->GetUintConstantId(last); + Instruction* sum_inst = builder->AddIAdd(GetUintId(), sum_id, last_id); + return sum_inst->result_id(); +} + +void InstBindlessCheckPass::GenCheckCode( + uint32_t check_id, RefAnalysis* ref, + std::vector>* new_blocks) { + BasicBlock* back_blk_ptr = &*new_blocks->back(); + InstructionBuilder builder( + context(), back_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // Gen conditional branch on check_id. Valid branch generates original + // reference. Invalid generates debug output and zero result (if needed). + uint32_t merge_blk_id = TakeNextId(); + uint32_t valid_blk_id = TakeNextId(); + uint32_t invalid_blk_id = TakeNextId(); + std::unique_ptr merge_label(NewLabel(merge_blk_id)); + std::unique_ptr valid_label(NewLabel(valid_blk_id)); + std::unique_ptr invalid_label(NewLabel(invalid_blk_id)); + (void)builder.AddConditionalBranch( + check_id, valid_blk_id, invalid_blk_id, merge_blk_id, + uint32_t(spv::SelectionControlMask::MaskNone)); + // Gen valid bounds branch + std::unique_ptr new_blk_ptr( + new BasicBlock(std::move(valid_label))); + builder.SetInsertPoint(&*new_blk_ptr); + uint32_t new_ref_id = CloneOriginalReference(ref, &builder); + uint32_t null_id = 0; + uint32_t ref_type_id = ref->ref_inst->type_id(); + (void)builder.AddBranch(merge_blk_id); + new_blocks->push_back(std::move(new_blk_ptr)); + // Gen invalid block + new_blk_ptr.reset(new BasicBlock(std::move(invalid_label))); + builder.SetInsertPoint(&*new_blk_ptr); + + // Generate a ConstantNull, converting to uint64 if the type cannot be a null. + if (new_ref_id != 0) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Type* ref_type = type_mgr->GetType(ref_type_id); + if (ref_type->AsPointer() != nullptr) { + context()->AddCapability(spv::Capability::Int64); + uint32_t null_u64_id = GetNullId(GetUint64Id()); + Instruction* null_ptr_inst = builder.AddUnaryOp( + ref_type_id, spv::Op::OpConvertUToPtr, null_u64_id); + null_id = null_ptr_inst->result_id(); + } else { + null_id = GetNullId(ref_type_id); + } + } + // Remember last invalid block id + uint32_t last_invalid_blk_id = new_blk_ptr->GetLabelInst()->result_id(); + // Gen zero for invalid reference + (void)builder.AddBranch(merge_blk_id); + new_blocks->push_back(std::move(new_blk_ptr)); + // Gen merge block + new_blk_ptr.reset(new BasicBlock(std::move(merge_label))); + builder.SetInsertPoint(&*new_blk_ptr); + // Gen phi of new reference and zero, if necessary, and replace the + // result id of the original reference with that of the Phi. Kill original + // reference. + if (new_ref_id != 0) { + Instruction* phi_inst = builder.AddPhi( + ref_type_id, {new_ref_id, valid_blk_id, null_id, last_invalid_blk_id}); + context()->ReplaceAllUsesWith(ref->ref_inst->result_id(), + phi_inst->result_id()); + } + new_blocks->push_back(std::move(new_blk_ptr)); + context()->KillInst(ref->ref_inst); +} + +void InstBindlessCheckPass::GenDescCheckCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks) { + // Look for reference through descriptor. If not, return. + RefAnalysis ref; + if (!AnalyzeDescriptorReference(&*ref_inst_itr, &ref)) return; + std::unique_ptr new_blk_ptr; + // Move original block's preceding instructions into first new block + MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr); + InstructionBuilder builder( + context(), &*new_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + new_blocks->push_back(std::move(new_blk_ptr)); + // Determine if we can only do initialization check + uint32_t ref_id = builder.GetUintConstantId(0u); + spv::Op op = ref.ref_inst->opcode(); + if (ref.desc_load_id != 0) { + uint32_t num_in_oprnds = ref.ref_inst->NumInOperands(); + if ((op == spv::Op::OpImageRead && num_in_oprnds == 2) || + (op == spv::Op::OpImageFetch && num_in_oprnds == 2) || + (op == spv::Op::OpImageWrite && num_in_oprnds == 3)) { + Instruction* image_inst = get_def_use_mgr()->GetDef(ref.image_id); + uint32_t image_ty_id = image_inst->type_id(); + Instruction* image_ty_inst = get_def_use_mgr()->GetDef(image_ty_id); + if (spv::Dim(image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDim)) == + spv::Dim::Buffer) { + if ((image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDepth) == 0) && + (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageArrayed) == + 0) && + (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageMS) == 0)) { + ref_id = GenUintCastCode(ref.ref_inst->GetSingleWordInOperand(1), + &builder); + } + } + } + } else { + // For now, only do bounds check for non-aggregate types. Otherwise + // just do descriptor initialization check. + // TODO(greg-lunarg): Do bounds check for aggregate loads and stores + Instruction* ref_ptr_inst = get_def_use_mgr()->GetDef(ref.ptr_id); + Instruction* pte_type_inst = GetPointeeTypeInst(ref_ptr_inst); + spv::Op pte_type_op = pte_type_inst->opcode(); + if (pte_type_op != spv::Op::OpTypeArray && + pte_type_op != spv::Op::OpTypeRuntimeArray && + pte_type_op != spv::Op::OpTypeStruct) { + ref_id = GenLastByteIdx(&ref, &builder); + } + } + // Read initialization/bounds from debug input buffer. If index id not yet + // set, binding is single descriptor, so set index to constant 0. + if (ref.desc_idx_id == 0) ref.desc_idx_id = builder.GetUintConstantId(0u); + uint32_t check_id = + GenDescCheckCall(ref.ref_inst->unique_id(), stage_idx, ref.var_id, + ref.desc_idx_id, ref_id, &builder); + + // Generate runtime initialization/bounds test code with true branch + // being full reference and false branch being zero + // for the referenced value. + GenCheckCode(check_id, &ref, new_blocks); + + // Move original block's remaining code into remainder/merge block and add + // to new blocks + BasicBlock* back_blk_ptr = &*new_blocks->back(); + MovePostludeCode(ref_block_itr, back_blk_ptr); +} + +void InstBindlessCheckPass::InitializeInstBindlessCheck() { + // Initialize base class + InitializeInstrument(); + for (auto& anno : get_module()->annotations()) { + if (anno.opcode() == spv::Op::OpDecorate) { + if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::DescriptorSet) { + var2desc_set_[anno.GetSingleWordInOperand(0u)] = + anno.GetSingleWordInOperand(2u); + } else if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == + spv::Decoration::Binding) { + var2binding_[anno.GetSingleWordInOperand(0u)] = + anno.GetSingleWordInOperand(2u); + } + } + } +} + +Pass::Status InstBindlessCheckPass::ProcessImpl() { + // The memory model and linkage must always be updated for spirv-link to work + // correctly. + AddStorageBufferExt(); + if (!get_feature_mgr()->HasExtension(kSPV_KHR_physical_storage_buffer)) { + context()->AddExtension("SPV_KHR_physical_storage_buffer"); + } + + context()->AddCapability(spv::Capability::PhysicalStorageBufferAddresses); + Instruction* memory_model = get_module()->GetMemoryModel(); + memory_model->SetInOperand( + 0u, {uint32_t(spv::AddressingModel::PhysicalStorageBuffer64)}); + + context()->AddCapability(spv::Capability::Linkage); + + InstProcessFunction pfn = + [this](BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks) { + return GenDescCheckCode(ref_inst_itr, ref_block_itr, stage_idx, + new_blocks); + }; + + InstProcessEntryPointCallTree(pfn); + // This pass always changes the memory model, so that linking will work + // properly. + return Status::SuccessWithChange; +} + +Pass::Status InstBindlessCheckPass::Process() { + InitializeInstBindlessCheck(); + return ProcessImpl(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inst_bindless_check_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/inst_bindless_check_pass.h new file mode 100644 index 000000000000..243cba7671bd --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inst_bindless_check_pass.h @@ -0,0 +1,130 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_ +#define LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_ + +#include "instrument_pass.h" + +namespace spvtools { +namespace opt { + +// This class/pass is designed to support the bindless (descriptor indexing) +// GPU-assisted validation layer of +// https://github.com/KhronosGroup/Vulkan-ValidationLayers. Its internal and +// external design may change as the layer evolves. +class InstBindlessCheckPass : public InstrumentPass { + public: + InstBindlessCheckPass(uint32_t shader_id) + : InstrumentPass(0, shader_id, true, true) {} + + ~InstBindlessCheckPass() override = default; + + // See optimizer.hpp for pass user documentation. + Status Process() override; + + const char* name() const override { return "inst-bindless-check-pass"; } + + private: + void GenDescCheckCode(BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, + uint32_t stage_idx, + std::vector>* new_blocks); + + uint32_t GenDescCheckFunctionId(); + + uint32_t GenDescCheckCall(uint32_t inst_idx, uint32_t stage_idx, + uint32_t var_id, uint32_t index_id, + uint32_t byte_offset, InstructionBuilder* builder); + + // Analysis data for descriptor reference components, generated by + // AnalyzeDescriptorReference. It is necessary and sufficient for further + // analysis and regeneration of the reference. + typedef struct RefAnalysis { + uint32_t desc_load_id{0}; + uint32_t image_id{0}; + uint32_t load_id{0}; + uint32_t ptr_id{0}; + uint32_t var_id{0}; + uint32_t set{0}; + uint32_t binding{0}; + uint32_t desc_idx_id{0}; + uint32_t strg_class{0}; + Instruction* ref_inst{nullptr}; + } RefAnalysis; + + // Return size of type |ty_id| in bytes. Use |matrix_stride| and |col_major| + // for matrix type, or for vector type if vector is |in_matrix|. + uint32_t ByteSize(uint32_t ty_id, uint32_t matrix_stride, bool col_major, + bool in_matrix); + + // Return stride of type |ty_id| with decoration |stride_deco|. Return 0 + // if not found + uint32_t FindStride(uint32_t ty_id, uint32_t stride_deco); + + // Generate index of last byte referenced by buffer reference |ref| + uint32_t GenLastByteIdx(RefAnalysis* ref, InstructionBuilder* builder); + + // Clone original image computation starting at |image_id| into |builder|. + // This may generate more than one instruction if necessary. + uint32_t CloneOriginalImage(uint32_t image_id, InstructionBuilder* builder); + + // Clone original original reference encapsulated by |ref| into |builder|. + // This may generate more than one instruction if necessary. + uint32_t CloneOriginalReference(RefAnalysis* ref, + InstructionBuilder* builder); + + // If |inst| references through an image, return the id of the image it + // references through. Else return 0. + uint32_t GetImageId(Instruction* inst); + + // Get pointee type inst of pointer value |ptr_inst|. + Instruction* GetPointeeTypeInst(Instruction* ptr_inst); + + // Analyze descriptor reference |ref_inst| and save components into |ref|. + // Return true if |ref_inst| is a descriptor reference, false otherwise. + bool AnalyzeDescriptorReference(Instruction* ref_inst, RefAnalysis* ref); + + // Generate instrumentation code for generic test result |check_id|, starting + // with |builder| of block |new_blk_ptr|, adding new blocks to |new_blocks|. + // Generate conditional branch to a valid or invalid branch. Generate valid + // block which does original reference |ref|. Generate invalid block which + // writes debug error output utilizing |ref|, |error_id|, |length_id| and + // |stage_idx|. Generate merge block for valid and invalid branches. Kill + // original reference. + void GenCheckCode(uint32_t check_id, RefAnalysis* ref, + std::vector>* new_blocks); + + // Initialize state for instrumenting bindless checking + void InitializeInstBindlessCheck(); + + // Apply GenDescIdxCheckCode to every instruction in module. Then apply + // GenDescInitCheckCode to every instruction in module. + Pass::Status ProcessImpl(); + + // Mapping from variable to descriptor set + std::unordered_map var2desc_set_; + + // Mapping from variable to binding + std::unordered_map var2binding_; + + uint32_t check_desc_func_id_{0}; +}; + +} // namespace opt +} // namespace spvtools + +#endif // LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp new file mode 100644 index 000000000000..e6c550878a24 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp @@ -0,0 +1,331 @@ +// Copyright (c) 2019 The Khronos Group Inc. +// Copyright (c) 2019 Valve Corporation +// Copyright (c) 2019 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "inst_buff_addr_check_pass.h" + +namespace spvtools { +namespace opt { + +uint32_t InstBuffAddrCheckPass::CloneOriginalReference( + Instruction* ref_inst, InstructionBuilder* builder) { + // Clone original ref with new result id (if load) + assert((ref_inst->opcode() == spv::Op::OpLoad || + ref_inst->opcode() == spv::Op::OpStore) && + "unexpected ref"); + std::unique_ptr new_ref_inst(ref_inst->Clone(context())); + uint32_t ref_result_id = ref_inst->result_id(); + uint32_t new_ref_id = 0; + if (ref_result_id != 0) { + new_ref_id = TakeNextId(); + new_ref_inst->SetResultId(new_ref_id); + } + // Register new reference and add to new block + Instruction* added_inst = builder->AddInstruction(std::move(new_ref_inst)); + uid2offset_[added_inst->unique_id()] = uid2offset_[ref_inst->unique_id()]; + if (new_ref_id != 0) + get_decoration_mgr()->CloneDecorations(ref_result_id, new_ref_id); + return new_ref_id; +} + +bool InstBuffAddrCheckPass::IsPhysicalBuffAddrReference(Instruction* ref_inst) { + if (ref_inst->opcode() != spv::Op::OpLoad && + ref_inst->opcode() != spv::Op::OpStore) + return false; + uint32_t ptr_id = ref_inst->GetSingleWordInOperand(0); + analysis::DefUseManager* du_mgr = get_def_use_mgr(); + Instruction* ptr_inst = du_mgr->GetDef(ptr_id); + if (ptr_inst->opcode() != spv::Op::OpAccessChain) return false; + uint32_t ptr_ty_id = ptr_inst->type_id(); + Instruction* ptr_ty_inst = du_mgr->GetDef(ptr_ty_id); + if (spv::StorageClass(ptr_ty_inst->GetSingleWordInOperand(0)) != + spv::StorageClass::PhysicalStorageBufferEXT) + return false; + return true; +} + +// TODO(greg-lunarg): Refactor with InstBindlessCheckPass::GenCheckCode() ?? +void InstBuffAddrCheckPass::GenCheckCode( + uint32_t check_id, Instruction* ref_inst, + std::vector>* new_blocks) { + BasicBlock* back_blk_ptr = &*new_blocks->back(); + InstructionBuilder builder( + context(), back_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // Gen conditional branch on check_id. Valid branch generates original + // reference. Invalid generates debug output and zero result (if needed). + uint32_t merge_blk_id = TakeNextId(); + uint32_t valid_blk_id = TakeNextId(); + uint32_t invalid_blk_id = TakeNextId(); + std::unique_ptr merge_label(NewLabel(merge_blk_id)); + std::unique_ptr valid_label(NewLabel(valid_blk_id)); + std::unique_ptr invalid_label(NewLabel(invalid_blk_id)); + (void)builder.AddConditionalBranch( + check_id, valid_blk_id, invalid_blk_id, merge_blk_id, + uint32_t(spv::SelectionControlMask::MaskNone)); + // Gen valid branch + std::unique_ptr new_blk_ptr( + new BasicBlock(std::move(valid_label))); + builder.SetInsertPoint(&*new_blk_ptr); + uint32_t new_ref_id = CloneOriginalReference(ref_inst, &builder); + (void)builder.AddBranch(merge_blk_id); + new_blocks->push_back(std::move(new_blk_ptr)); + // Gen invalid block + new_blk_ptr.reset(new BasicBlock(std::move(invalid_label))); + builder.SetInsertPoint(&*new_blk_ptr); + // Gen zero for invalid load. If pointer type, need to convert uint64 + // zero to pointer; cannot create ConstantNull of pointer type. + uint32_t null_id = 0; + if (new_ref_id != 0) { + uint32_t ref_type_id = ref_inst->type_id(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Type* ref_type = type_mgr->GetType(ref_type_id); + if (ref_type->AsPointer() != nullptr) { + uint32_t null_u64_id = GetNullId(GetUint64Id()); + Instruction* null_ptr_inst = builder.AddUnaryOp( + ref_type_id, spv::Op::OpConvertUToPtr, null_u64_id); + null_id = null_ptr_inst->result_id(); + } else { + null_id = GetNullId(ref_type_id); + } + } + (void)builder.AddBranch(merge_blk_id); + new_blocks->push_back(std::move(new_blk_ptr)); + // Gen merge block + new_blk_ptr.reset(new BasicBlock(std::move(merge_label))); + builder.SetInsertPoint(&*new_blk_ptr); + // Gen phi of new reference and zero, if necessary, and replace the + // result id of the original reference with that of the Phi. Kill original + // reference. + if (new_ref_id != 0) { + Instruction* phi_inst = + builder.AddPhi(ref_inst->type_id(), + {new_ref_id, valid_blk_id, null_id, invalid_blk_id}); + context()->ReplaceAllUsesWith(ref_inst->result_id(), phi_inst->result_id()); + } + new_blocks->push_back(std::move(new_blk_ptr)); + context()->KillInst(ref_inst); +} + +uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + switch (type_inst->opcode()) { + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeInt: + return type_inst->GetSingleWordInOperand(0) / 8u; + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + return type_inst->GetSingleWordInOperand(1) * + GetTypeLength(type_inst->GetSingleWordInOperand(0)); + case spv::Op::OpTypePointer: + assert(spv::StorageClass(type_inst->GetSingleWordInOperand(0)) == + spv::StorageClass::PhysicalStorageBufferEXT && + "unexpected pointer type"); + return 8u; + case spv::Op::OpTypeArray: { + uint32_t const_id = type_inst->GetSingleWordInOperand(1); + Instruction* const_inst = get_def_use_mgr()->GetDef(const_id); + uint32_t cnt = const_inst->GetSingleWordInOperand(0); + return cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0)); + } + case spv::Op::OpTypeStruct: { + // Figure out the location of the last byte of the last member of the + // structure. + uint32_t last_offset = 0, last_len = 0; + + get_decoration_mgr()->ForEachDecoration( + type_id, uint32_t(spv::Decoration::Offset), + [&last_offset](const Instruction& deco_inst) { + last_offset = deco_inst.GetSingleWordInOperand(3); + }); + type_inst->ForEachInId([&last_len, this](const uint32_t* iid) { + last_len = GetTypeLength(*iid); + }); + return last_offset + last_len; + } + case spv::Op::OpTypeRuntimeArray: + default: + assert(false && "unexpected type"); + return 0; + } +} + +void InstBuffAddrCheckPass::AddParam(uint32_t type_id, + std::vector* param_vec, + std::unique_ptr* input_func) { + uint32_t pid = TakeNextId(); + param_vec->push_back(pid); + std::unique_ptr param_inst(new Instruction( + get_module()->context(), spv::Op::OpFunctionParameter, type_id, pid, {})); + get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst); + (*input_func)->AddParameter(std::move(param_inst)); +} + +// This is a stub function for use with Import linkage +// clang-format off +// GLSL: +//bool inst_bindless_search_and_test(const uint shader_id, const uint inst_num, const uvec4 stage_info, +// const uint64 ref_ptr, const uint length) { +//} +// clang-format on +uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() { + enum { + kShaderId = 0, + kInstructionIndex = 1, + kStageInfo = 2, + kRefPtr = 3, + kLength = 4, + kNumArgs + }; + if (search_test_func_id_ != 0) { + return search_test_func_id_; + } + // Generate function "bool search_and_test(uint64_t ref_ptr, uint32_t len)" + // which searches input buffer for buffer which most likely contains the + // pointer value |ref_ptr| and verifies that the entire reference of + // length |len| bytes is contained in the buffer. + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + const analysis::Integer* uint_type = GetInteger(32, false); + const analysis::Vector v4uint(uint_type, 4); + const analysis::Type* v4uint_type = type_mgr->GetRegisteredType(&v4uint); + + std::vector param_types = { + uint_type, uint_type, v4uint_type, type_mgr->GetType(GetUint64Id()), + uint_type}; + + const std::string func_name{"inst_buff_addr_search_and_test"}; + const uint32_t func_id = TakeNextId(); + std::unique_ptr func = + StartFunction(func_id, type_mgr->GetBoolType(), param_types); + func->SetFunctionEnd(EndFunction()); + context()->AddFunctionDeclaration(std::move(func)); + context()->AddDebug2Inst(NewName(func_id, func_name)); + + std::vector operands{ + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {func_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {uint32_t(spv::Decoration::LinkageAttributes)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_STRING, + utils::MakeVector(func_name.c_str())}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LINKAGE_TYPE, + {uint32_t(spv::LinkageType::Import)}}, + }; + get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, operands); + + search_test_func_id_ = func_id; + return search_test_func_id_; +} + +uint32_t InstBuffAddrCheckPass::GenSearchAndTest(Instruction* ref_inst, + InstructionBuilder* builder, + uint32_t* ref_uptr_id, + uint32_t stage_idx) { + // Enable Int64 if necessary + // Convert reference pointer to uint64 + const uint32_t ref_ptr_id = ref_inst->GetSingleWordInOperand(0); + Instruction* ref_uptr_inst = + builder->AddUnaryOp(GetUint64Id(), spv::Op::OpConvertPtrToU, ref_ptr_id); + *ref_uptr_id = ref_uptr_inst->result_id(); + // Compute reference length in bytes + analysis::DefUseManager* du_mgr = get_def_use_mgr(); + Instruction* ref_ptr_inst = du_mgr->GetDef(ref_ptr_id); + const uint32_t ref_ptr_ty_id = ref_ptr_inst->type_id(); + Instruction* ref_ptr_ty_inst = du_mgr->GetDef(ref_ptr_ty_id); + const uint32_t ref_len = + GetTypeLength(ref_ptr_ty_inst->GetSingleWordInOperand(1)); + // Gen call to search and test function + const uint32_t func_id = GetSearchAndTestFuncId(); + const std::vector args = { + builder->GetUintConstantId(shader_id_), + builder->GetUintConstantId(ref_inst->unique_id()), + GenStageInfo(stage_idx, builder), *ref_uptr_id, + builder->GetUintConstantId(ref_len)}; + return GenReadFunctionCall(GetBoolId(), func_id, args, builder); +} + +void InstBuffAddrCheckPass::GenBuffAddrCheckCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks) { + // Look for reference through indexed descriptor. If found, analyze and + // save components. If not, return. + Instruction* ref_inst = &*ref_inst_itr; + if (!IsPhysicalBuffAddrReference(ref_inst)) return; + // Move original block's preceding instructions into first new block + std::unique_ptr new_blk_ptr; + MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr); + InstructionBuilder builder( + context(), &*new_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + new_blocks->push_back(std::move(new_blk_ptr)); + // Generate code to do search and test if all bytes of reference + // are within a listed buffer. Return reference pointer converted to uint64. + uint32_t ref_uptr_id; + uint32_t valid_id = + GenSearchAndTest(ref_inst, &builder, &ref_uptr_id, stage_idx); + // Generate test of search results with true branch + // being full reference and false branch being debug output and zero + // for the referenced value. + GenCheckCode(valid_id, ref_inst, new_blocks); + + // Move original block's remaining code into remainder/merge block and add + // to new blocks + BasicBlock* back_blk_ptr = &*new_blocks->back(); + MovePostludeCode(ref_block_itr, back_blk_ptr); +} + +void InstBuffAddrCheckPass::InitInstBuffAddrCheck() { + // Initialize base class + InitializeInstrument(); + // Initialize class + search_test_func_id_ = 0; +} + +Pass::Status InstBuffAddrCheckPass::ProcessImpl() { + // The memory model and linkage must always be updated for spirv-link to work + // correctly. + AddStorageBufferExt(); + if (!get_feature_mgr()->HasExtension(kSPV_KHR_physical_storage_buffer)) { + context()->AddExtension("SPV_KHR_physical_storage_buffer"); + } + + context()->AddCapability(spv::Capability::PhysicalStorageBufferAddresses); + Instruction* memory_model = get_module()->GetMemoryModel(); + memory_model->SetInOperand( + 0u, {uint32_t(spv::AddressingModel::PhysicalStorageBuffer64)}); + + context()->AddCapability(spv::Capability::Int64); + context()->AddCapability(spv::Capability::Linkage); + // Perform bindless bounds check on each entry point function in module + InstProcessFunction pfn = + [this](BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks) { + return GenBuffAddrCheckCode(ref_inst_itr, ref_block_itr, stage_idx, + new_blocks); + }; + InstProcessEntryPointCallTree(pfn); + // This pass always changes the memory model, so that linking will work + // properly. + return Status::SuccessWithChange; +} + +Pass::Status InstBuffAddrCheckPass::Process() { + InitInstBuffAddrCheck(); + return ProcessImpl(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inst_buff_addr_check_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/inst_buff_addr_check_pass.h new file mode 100644 index 000000000000..f07f98a0f2a0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inst_buff_addr_check_pass.h @@ -0,0 +1,130 @@ +// Copyright (c) 2019 The Khronos Group Inc. +// Copyright (c) 2019 Valve Corporation +// Copyright (c) 2019 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBSPIRV_OPT_INST_BUFFER_ADDRESS_PASS_H_ +#define LIBSPIRV_OPT_INST_BUFFER_ADDRESS_PASS_H_ + +#include "instrument_pass.h" + +namespace spvtools { +namespace opt { + +// This class/pass is designed to support the GPU-assisted validation layer of +// the Buffer Device Address (BDA) extension in +// https://github.com/KhronosGroup/Vulkan-ValidationLayers. The internal and +// external design of this class may change as the layer evolves. +class InstBuffAddrCheckPass : public InstrumentPass { + public: + // For test harness only + InstBuffAddrCheckPass() : InstrumentPass(0, 23, false, true) {} + // For all other interfaces + InstBuffAddrCheckPass(uint32_t shader_id) + : InstrumentPass(0, shader_id, false, true) {} + + ~InstBuffAddrCheckPass() override = default; + + // See optimizer.hpp for pass user documentation. + Status Process() override; + + const char* name() const override { return "inst-buff-addr-check-pass"; } + + private: + // Return byte length of type |type_id|. Must be int, float, vector, matrix, + // struct, array or physical pointer. Uses std430 alignment and sizes. + uint32_t GetTypeLength(uint32_t type_id); + + // Add |type_id| param to |input_func| and add id to |param_vec|. + void AddParam(uint32_t type_id, std::vector* param_vec, + std::unique_ptr* input_func); + + // Return id for search and test function. Generate it if not already gen'd. + uint32_t GetSearchAndTestFuncId(); + + // Generate code into |builder| to do search of the BDA debug input buffer + // for the buffer used by |ref_inst| and test that all bytes of reference + // are within the buffer. Returns id of boolean value which is true if + // search and test is successful, false otherwise. + uint32_t GenSearchAndTest(Instruction* ref_inst, InstructionBuilder* builder, + uint32_t* ref_uptr_id, uint32_t stage_idx); + + // This function does checking instrumentation on a single + // instruction which references through a physical storage buffer address. + // GenBuffAddrCheckCode generates code that checks that all bytes that + // are referenced fall within a buffer that was queried via + // the Vulkan API call vkGetBufferDeviceAddressEXT(). + // + // The function is designed to be passed to + // InstrumentPass::InstProcessEntryPointCallTree(), which applies the + // function to each instruction in a module and replaces the instruction + // with instrumented code if warranted. + // + // If |ref_inst_itr| is a physical storage buffer reference, return in + // |new_blocks| the result of instrumenting it with validation code within + // its block at |ref_block_itr|. The validation code first executes a check + // for the specific condition called for. If the check passes, it executes + // the remainder of the reference, otherwise writes a record to the debug + // output buffer stream including |function_idx, instruction_idx, stage_idx| + // and replaces the reference with the null value of the original type. The + // block at |ref_block_itr| can just be replaced with the blocks in + // |new_blocks|, which will contain at least two blocks. The last block will + // comprise all instructions following |ref_inst_itr|, + // preceded by a phi instruction if needed. + // + // This instrumentation function utilizes GenDebugStreamWrite() to write its + // error records. The validation-specific part of the error record will + // have the format: + // + // Validation Error Code (=kInstErrorBuffAddr) + // Buffer Address (lowest 32 bits) + // Buffer Address (highest 32 bits) + // + void GenBuffAddrCheckCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks); + + // Return true if |ref_inst| is a physical buffer address reference, false + // otherwise. + bool IsPhysicalBuffAddrReference(Instruction* ref_inst); + + // Clone original reference |ref_inst| into |builder| and return id of result + uint32_t CloneOriginalReference(Instruction* ref_inst, + InstructionBuilder* builder); + + // Generate instrumentation code for boolean test result |check_id|, + // adding new blocks to |new_blocks|. Generate conditional branch to valid + // or invalid reference blocks. Generate valid reference block which does + // original reference |ref_inst|. Then generate invalid reference block which + // writes debug error output utilizing |ref_inst|, |error_id| and + // |stage_idx|. Generate merge block for valid and invalid reference blocks. + // Kill original reference. + void GenCheckCode(uint32_t check_id, Instruction* ref_inst, + std::vector>* new_blocks); + + // Initialize state for instrumenting physical buffer address checking + void InitInstBuffAddrCheck(); + + // Apply GenBuffAddrCheckCode to every instruction in module. + Pass::Status ProcessImpl(); + + // Id of search and test function, if already gen'd, else zero. + uint32_t search_test_func_id_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // LIBSPIRV_OPT_INST_BUFFER_ADDRESS_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inst_debug_printf_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/inst_debug_printf_pass.cpp new file mode 100644 index 000000000000..abd25e93961d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inst_debug_printf_pass.cpp @@ -0,0 +1,483 @@ +// Copyright (c) 2020 The Khronos Group Inc. +// Copyright (c) 2020 Valve Corporation +// Copyright (c) 2020 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "inst_debug_printf_pass.h" + +#include "source/spirv_constant.h" +#include "source/util/string_utils.h" +#include "spirv/unified1/NonSemanticDebugPrintf.h" + +namespace spvtools { +namespace opt { + +void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, + std::vector* val_ids, + InstructionBuilder* builder) { + uint32_t val_ty_id = val_inst->type_id(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Type* val_ty = type_mgr->GetType(val_ty_id); + switch (val_ty->kind()) { + case analysis::Type::kVector: { + analysis::Vector* v_ty = val_ty->AsVector(); + const analysis::Type* c_ty = v_ty->element_type(); + uint32_t c_ty_id = type_mgr->GetId(c_ty); + for (uint32_t c = 0; c < v_ty->element_count(); ++c) { + Instruction* c_inst = + builder->AddCompositeExtract(c_ty_id, val_inst->result_id(), {c}); + GenOutputValues(c_inst, val_ids, builder); + } + return; + } + case analysis::Type::kBool: { + // Select between uint32 zero or one + uint32_t zero_id = builder->GetUintConstantId(0); + uint32_t one_id = builder->GetUintConstantId(1); + Instruction* sel_inst = builder->AddSelect( + GetUintId(), val_inst->result_id(), one_id, zero_id); + val_ids->push_back(sel_inst->result_id()); + return; + } + case analysis::Type::kFloat: { + analysis::Float* f_ty = val_ty->AsFloat(); + switch (f_ty->width()) { + case 16: { + // Convert float16 to float32 and recurse + Instruction* f32_inst = builder->AddUnaryOp( + GetFloatId(), spv::Op::OpFConvert, val_inst->result_id()); + GenOutputValues(f32_inst, val_ids, builder); + return; + } + case 64: { + // Bitcast float64 to uint64 and recurse + Instruction* ui64_inst = builder->AddUnaryOp( + GetUint64Id(), spv::Op::OpBitcast, val_inst->result_id()); + GenOutputValues(ui64_inst, val_ids, builder); + return; + } + case 32: { + // Bitcase float32 to uint32 + Instruction* bc_inst = builder->AddUnaryOp( + GetUintId(), spv::Op::OpBitcast, val_inst->result_id()); + val_ids->push_back(bc_inst->result_id()); + return; + } + default: + assert(false && "unsupported float width"); + return; + } + } + case analysis::Type::kInteger: { + analysis::Integer* i_ty = val_ty->AsInteger(); + switch (i_ty->width()) { + case 64: { + Instruction* ui64_inst = val_inst; + if (i_ty->IsSigned()) { + // Bitcast sint64 to uint64 + ui64_inst = builder->AddUnaryOp(GetUint64Id(), spv::Op::OpBitcast, + val_inst->result_id()); + } + // Break uint64 into 2x uint32 + Instruction* lo_ui64_inst = builder->AddUnaryOp( + GetUintId(), spv::Op::OpUConvert, ui64_inst->result_id()); + Instruction* rshift_ui64_inst = builder->AddBinaryOp( + GetUint64Id(), spv::Op::OpShiftRightLogical, + ui64_inst->result_id(), builder->GetUintConstantId(32)); + Instruction* hi_ui64_inst = builder->AddUnaryOp( + GetUintId(), spv::Op::OpUConvert, rshift_ui64_inst->result_id()); + val_ids->push_back(lo_ui64_inst->result_id()); + val_ids->push_back(hi_ui64_inst->result_id()); + return; + } + case 8: { + Instruction* ui8_inst = val_inst; + if (i_ty->IsSigned()) { + // Bitcast sint8 to uint8 + ui8_inst = builder->AddUnaryOp(GetUint8Id(), spv::Op::OpBitcast, + val_inst->result_id()); + } + // Convert uint8 to uint32 + Instruction* ui32_inst = builder->AddUnaryOp( + GetUintId(), spv::Op::OpUConvert, ui8_inst->result_id()); + val_ids->push_back(ui32_inst->result_id()); + return; + } + case 32: { + Instruction* ui32_inst = val_inst; + if (i_ty->IsSigned()) { + // Bitcast sint32 to uint32 + ui32_inst = builder->AddUnaryOp(GetUintId(), spv::Op::OpBitcast, + val_inst->result_id()); + } + // uint32 needs no further processing + val_ids->push_back(ui32_inst->result_id()); + return; + } + default: + // TODO(greg-lunarg): Support non-32-bit int + assert(false && "unsupported int width"); + return; + } + } + default: + assert(false && "unsupported type"); + return; + } +} + +void InstDebugPrintfPass::GenOutputCode( + Instruction* printf_inst, + std::vector>* new_blocks) { + BasicBlock* back_blk_ptr = &*new_blocks->back(); + InstructionBuilder builder( + context(), back_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // Gen debug printf record validation-specific values. The format string + // will have its id written. Vectors will need to be broken down into + // component values. float16 will need to be converted to float32. Pointer + // and uint64 will need to be converted to two uint32 values. float32 will + // need to be bitcast to uint32. int32 will need to be bitcast to uint32. + std::vector val_ids; + bool is_first_operand = false; + printf_inst->ForEachInId( + [&is_first_operand, &val_ids, &builder, this](const uint32_t* iid) { + // skip set operand + if (!is_first_operand) { + is_first_operand = true; + return; + } + Instruction* opnd_inst = get_def_use_mgr()->GetDef(*iid); + if (opnd_inst->opcode() == spv::Op::OpString) { + uint32_t string_id_id = builder.GetUintConstantId(*iid); + val_ids.push_back(string_id_id); + } else { + GenOutputValues(opnd_inst, &val_ids, &builder); + } + }); + GenDebugStreamWrite( + builder.GetUintConstantId(shader_id_), + builder.GetUintConstantId(uid2offset_[printf_inst->unique_id()]), val_ids, + &builder); + context()->KillInst(printf_inst); +} + +void InstDebugPrintfPass::GenDebugPrintfCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, + std::vector>* new_blocks) { + // If not DebugPrintf OpExtInst, return. + Instruction* printf_inst = &*ref_inst_itr; + if (printf_inst->opcode() != spv::Op::OpExtInst) return; + if (printf_inst->GetSingleWordInOperand(0) != ext_inst_printf_id_) return; + if (printf_inst->GetSingleWordInOperand(1) != + NonSemanticDebugPrintfDebugPrintf) + return; + // Initialize DefUse manager before dismantling module + (void)get_def_use_mgr(); + // Move original block's preceding instructions into first new block + std::unique_ptr new_blk_ptr; + MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr); + new_blocks->push_back(std::move(new_blk_ptr)); + // Generate instructions to output printf args to printf buffer + GenOutputCode(printf_inst, new_blocks); + // Caller expects at least two blocks with last block containing remaining + // code, so end block after instrumentation, create remainder block, and + // branch to it + uint32_t rem_blk_id = TakeNextId(); + std::unique_ptr rem_label(NewLabel(rem_blk_id)); + BasicBlock* back_blk_ptr = &*new_blocks->back(); + InstructionBuilder builder( + context(), back_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + (void)builder.AddBranch(rem_blk_id); + // Gen remainder block + new_blk_ptr.reset(new BasicBlock(std::move(rem_label))); + builder.SetInsertPoint(&*new_blk_ptr); + // Move original block's remaining code into remainder block and add + // to new blocks + MovePostludeCode(ref_block_itr, &*new_blk_ptr); + new_blocks->push_back(std::move(new_blk_ptr)); +} + +// Return id for output buffer +uint32_t InstDebugPrintfPass::GetOutputBufferId() { + if (output_buffer_id_ == 0) { + // If not created yet, create one + analysis::DecorationManager* deco_mgr = get_decoration_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::RuntimeArray* reg_uint_rarr_ty = GetUintRuntimeArrayType(32); + analysis::Integer* reg_uint_ty = GetInteger(32, false); + analysis::Type* reg_buf_ty = + GetStruct({reg_uint_ty, reg_uint_ty, reg_uint_rarr_ty}); + uint32_t obufTyId = type_mgr->GetTypeInstruction(reg_buf_ty); + // By the Vulkan spec, a pre-existing struct containing a RuntimeArray + // must be a block, and will therefore be decorated with Block. Therefore + // the undecorated type returned here will not be pre-existing and can + // safely be decorated. Since this type is now decorated, it is out of + // sync with the TypeManager and therefore the TypeManager must be + // invalidated after this pass. + assert(context()->get_def_use_mgr()->NumUses(obufTyId) == 0 && + "used struct type returned"); + deco_mgr->AddDecoration(obufTyId, uint32_t(spv::Decoration::Block)); + deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputFlagsOffset, + uint32_t(spv::Decoration::Offset), 0); + deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputSizeOffset, + uint32_t(spv::Decoration::Offset), 4); + deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputDataOffset, + uint32_t(spv::Decoration::Offset), 8); + uint32_t obufTyPtrId_ = + type_mgr->FindPointerToType(obufTyId, spv::StorageClass::StorageBuffer); + output_buffer_id_ = TakeNextId(); + std::unique_ptr newVarOp(new Instruction( + context(), spv::Op::OpVariable, obufTyPtrId_, output_buffer_id_, + {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {uint32_t(spv::StorageClass::StorageBuffer)}}})); + context()->AddGlobalValue(std::move(newVarOp)); + context()->AddDebug2Inst(NewGlobalName(obufTyId, "OutputBuffer")); + context()->AddDebug2Inst(NewMemberName(obufTyId, 0, "flags")); + context()->AddDebug2Inst(NewMemberName(obufTyId, 1, "written_count")); + context()->AddDebug2Inst(NewMemberName(obufTyId, 2, "data")); + context()->AddDebug2Inst(NewGlobalName(output_buffer_id_, "output_buffer")); + deco_mgr->AddDecorationVal( + output_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_); + deco_mgr->AddDecorationVal(output_buffer_id_, + uint32_t(spv::Decoration::Binding), + GetOutputBufferBinding()); + AddStorageBufferExt(); + if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // Add the new buffer to all entry points. + for (auto& entry : get_module()->entry_points()) { + entry.AddOperand({SPV_OPERAND_TYPE_ID, {output_buffer_id_}}); + context()->AnalyzeUses(&entry); + } + } + } + return output_buffer_id_; +} + +uint32_t InstDebugPrintfPass::GetOutputBufferPtrId() { + if (output_buffer_ptr_id_ == 0) { + output_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType( + GetUintId(), spv::StorageClass::StorageBuffer); + } + return output_buffer_ptr_id_; +} + +uint32_t InstDebugPrintfPass::GetOutputBufferBinding() { + return kDebugOutputPrintfStream; +} + +void InstDebugPrintfPass::GenDebugOutputFieldCode(uint32_t base_offset_id, + uint32_t field_offset, + uint32_t field_value_id, + InstructionBuilder* builder) { + // Cast value to 32-bit unsigned if necessary + uint32_t val_id = GenUintCastCode(field_value_id, builder); + // Store value + Instruction* data_idx_inst = builder->AddIAdd( + GetUintId(), base_offset_id, builder->GetUintConstantId(field_offset)); + uint32_t buf_id = GetOutputBufferId(); + uint32_t buf_uint_ptr_id = GetOutputBufferPtrId(); + Instruction* achain_inst = builder->AddAccessChain( + buf_uint_ptr_id, buf_id, + {builder->GetUintConstantId(kDebugOutputDataOffset), + data_idx_inst->result_id()}); + (void)builder->AddStore(achain_inst->result_id(), val_id); +} + +uint32_t InstDebugPrintfPass::GetStreamWriteFunctionId(uint32_t param_cnt) { + enum { + kShaderId = 0, + kInstructionIndex = 1, + kFirstParam = 2, + }; + // Total param count is common params plus validation-specific + // params + if (param2output_func_id_[param_cnt] == 0) { + // Create function + param2output_func_id_[param_cnt] = TakeNextId(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + + const analysis::Type* uint_type = GetInteger(32, false); + + std::vector param_types(kFirstParam + param_cnt, + uint_type); + std::unique_ptr output_func = StartFunction( + param2output_func_id_[param_cnt], type_mgr->GetVoidType(), param_types); + + std::vector param_ids = AddParameters(*output_func, param_types); + + // Create first block + auto new_blk_ptr = MakeUnique(NewLabel(TakeNextId())); + + InstructionBuilder builder( + context(), &*new_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // Gen test if debug output buffer size will not be exceeded. + const uint32_t first_param_offset = kInstCommonOutInstructionIdx + 1; + const uint32_t obuf_record_sz = first_param_offset + param_cnt; + const uint32_t buf_id = GetOutputBufferId(); + const uint32_t buf_uint_ptr_id = GetOutputBufferPtrId(); + Instruction* obuf_curr_sz_ac_inst = builder.AddAccessChain( + buf_uint_ptr_id, buf_id, + {builder.GetUintConstantId(kDebugOutputSizeOffset)}); + // Fetch the current debug buffer written size atomically, adding the + // size of the record to be written. + uint32_t obuf_record_sz_id = builder.GetUintConstantId(obuf_record_sz); + uint32_t mask_none_id = + builder.GetUintConstantId(uint32_t(spv::MemoryAccessMask::MaskNone)); + uint32_t scope_invok_id = + builder.GetUintConstantId(uint32_t(spv::Scope::Invocation)); + Instruction* obuf_curr_sz_inst = builder.AddQuadOp( + GetUintId(), spv::Op::OpAtomicIAdd, obuf_curr_sz_ac_inst->result_id(), + scope_invok_id, mask_none_id, obuf_record_sz_id); + uint32_t obuf_curr_sz_id = obuf_curr_sz_inst->result_id(); + // Compute new written size + Instruction* obuf_new_sz_inst = + builder.AddIAdd(GetUintId(), obuf_curr_sz_id, + builder.GetUintConstantId(obuf_record_sz)); + // Fetch the data bound + Instruction* obuf_bnd_inst = + builder.AddIdLiteralOp(GetUintId(), spv::Op::OpArrayLength, + GetOutputBufferId(), kDebugOutputDataOffset); + // Test that new written size is less than or equal to debug output + // data bound + Instruction* obuf_safe_inst = builder.AddBinaryOp( + GetBoolId(), spv::Op::OpULessThanEqual, obuf_new_sz_inst->result_id(), + obuf_bnd_inst->result_id()); + uint32_t merge_blk_id = TakeNextId(); + uint32_t write_blk_id = TakeNextId(); + std::unique_ptr merge_label(NewLabel(merge_blk_id)); + std::unique_ptr write_label(NewLabel(write_blk_id)); + (void)builder.AddConditionalBranch( + obuf_safe_inst->result_id(), write_blk_id, merge_blk_id, merge_blk_id, + uint32_t(spv::SelectionControlMask::MaskNone)); + // Close safety test block and gen write block + output_func->AddBasicBlock(std::move(new_blk_ptr)); + new_blk_ptr = MakeUnique(std::move(write_label)); + builder.SetInsertPoint(&*new_blk_ptr); + // Generate common and stage-specific debug record members + GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutSize, + builder.GetUintConstantId(obuf_record_sz), + &builder); + // Store Shader Id + GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutShaderId, + param_ids[kShaderId], &builder); + // Store Instruction Idx + GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutInstructionIdx, + param_ids[kInstructionIndex], &builder); + // Gen writes of validation specific data + for (uint32_t i = 0; i < param_cnt; ++i) { + GenDebugOutputFieldCode(obuf_curr_sz_id, first_param_offset + i, + param_ids[kFirstParam + i], &builder); + } + // Close write block and gen merge block + (void)builder.AddBranch(merge_blk_id); + output_func->AddBasicBlock(std::move(new_blk_ptr)); + new_blk_ptr = MakeUnique(std::move(merge_label)); + builder.SetInsertPoint(&*new_blk_ptr); + // Close merge block and function and add function to module + (void)builder.AddNullaryOp(0, spv::Op::OpReturn); + + output_func->AddBasicBlock(std::move(new_blk_ptr)); + output_func->SetFunctionEnd(EndFunction()); + context()->AddFunction(std::move(output_func)); + + std::string name("stream_write_"); + name += std::to_string(param_cnt); + + context()->AddDebug2Inst( + NewGlobalName(param2output_func_id_[param_cnt], name)); + } + return param2output_func_id_[param_cnt]; +} + +void InstDebugPrintfPass::GenDebugStreamWrite( + uint32_t shader_id, uint32_t instruction_idx_id, + const std::vector& validation_ids, InstructionBuilder* builder) { + // Call debug output function. Pass func_idx, instruction_idx and + // validation ids as args. + uint32_t val_id_cnt = static_cast(validation_ids.size()); + std::vector args = {shader_id, instruction_idx_id}; + (void)args.insert(args.end(), validation_ids.begin(), validation_ids.end()); + (void)builder->AddFunctionCall(GetVoidId(), + GetStreamWriteFunctionId(val_id_cnt), args); +} + +std::unique_ptr InstDebugPrintfPass::NewGlobalName( + uint32_t id, const std::string& name_str) { + std::string prefixed_name{"inst_printf_"}; + prefixed_name += name_str; + return NewName(id, prefixed_name); +} + +std::unique_ptr InstDebugPrintfPass::NewMemberName( + uint32_t id, uint32_t member_index, const std::string& name_str) { + return MakeUnique( + context(), spv::Op::OpMemberName, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {id}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index}}, + {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}}); +} + +void InstDebugPrintfPass::InitializeInstDebugPrintf() { + // Initialize base class + InitializeInstrument(); + output_buffer_id_ = 0; + output_buffer_ptr_id_ = 0; +} + +Pass::Status InstDebugPrintfPass::ProcessImpl() { + // Perform printf instrumentation on each entry point function in module + InstProcessFunction pfn = + [this](BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, + [[maybe_unused]] uint32_t stage_idx, + std::vector>* new_blocks) { + return GenDebugPrintfCode(ref_inst_itr, ref_block_itr, new_blocks); + }; + (void)InstProcessEntryPointCallTree(pfn); + // Remove DebugPrintf OpExtInstImport instruction + Instruction* ext_inst_import_inst = + get_def_use_mgr()->GetDef(ext_inst_printf_id_); + context()->KillInst(ext_inst_import_inst); + // If no remaining non-semantic instruction sets, remove non-semantic debug + // info extension from module and feature manager + bool non_sem_set_seen = false; + for (auto c_itr = context()->module()->ext_inst_import_begin(); + c_itr != context()->module()->ext_inst_import_end(); ++c_itr) { + const std::string set_name = c_itr->GetInOperand(0).AsString(); + if (spvtools::utils::starts_with(set_name, "NonSemantic.")) { + non_sem_set_seen = true; + break; + } + } + if (!non_sem_set_seen) { + context()->RemoveExtension(kSPV_KHR_non_semantic_info); + } + return Status::SuccessWithChange; +} + +Pass::Status InstDebugPrintfPass::Process() { + ext_inst_printf_id_ = + get_module()->GetExtInstImportId("NonSemantic.DebugPrintf"); + if (ext_inst_printf_id_ == 0) return Status::SuccessWithoutChange; + InitializeInstDebugPrintf(); + return ProcessImpl(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/inst_debug_printf_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/inst_debug_printf_pass.h new file mode 100644 index 000000000000..5688d3841036 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/inst_debug_printf_pass.h @@ -0,0 +1,198 @@ +// Copyright (c) 2020 The Khronos Group Inc. +// Copyright (c) 2020 Valve Corporation +// Copyright (c) 2020 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBSPIRV_OPT_INST_DEBUG_PRINTF_PASS_H_ +#define LIBSPIRV_OPT_INST_DEBUG_PRINTF_PASS_H_ + +#include "instrument_pass.h" + +namespace spvtools { +namespace opt { + +// This class/pass is designed to support the debug printf GPU-assisted layer +// of https://github.com/KhronosGroup/Vulkan-ValidationLayers. Its internal and +// external design may change as the layer evolves. +class InstDebugPrintfPass : public InstrumentPass { + public: + // For test harness only + InstDebugPrintfPass() : InstrumentPass(7, 23, false, false) {} + // For all other interfaces + InstDebugPrintfPass(uint32_t desc_set, uint32_t shader_id) + : InstrumentPass(desc_set, shader_id, false, false) {} + + ~InstDebugPrintfPass() override = default; + + // See optimizer.hpp for pass user documentation. + Status Process() override; + + const char* name() const override { return "inst-printf-pass"; } + + private: + // Gen code into |builder| to write |field_value_id| into debug output + // buffer at |base_offset_id| + |field_offset|. + void GenDebugOutputFieldCode(uint32_t base_offset_id, uint32_t field_offset, + uint32_t field_value_id, + InstructionBuilder* builder); + + // Generate instructions in |builder| which will atomically fetch and + // increment the size of the debug output buffer stream of the current + // validation and write a record to the end of the stream, if enough space + // in the buffer remains. The record will contain the index of the function + // and instruction within that function |func_idx, instruction_idx| which + // generated the record. Finally, the record will contain validation-specific + // data contained in |validation_ids| which will identify the validation + // error as well as the values involved in the error. + // + // The output buffer binding written to by the code generated by the function + // is determined by the validation id specified when each specific + // instrumentation pass is created. + // + // The output buffer is a sequence of 32-bit values with the following + // format (where all elements are unsigned 32-bit unless otherwise noted): + // + // Size + // Record0 + // Record1 + // Record2 + // ... + // + // Size is the number of 32-bit values that have been written or + // attempted to be written to the output buffer, excluding the Size. It is + // initialized to 0. If the size of attempts to write the buffer exceeds + // the actual size of the buffer, it is possible that this field can exceed + // the actual size of the buffer. + // + // Each Record* is a variable-length sequence of 32-bit values with the + // following format defined using static const offsets in the .cpp file: + // + // Record Size + // Shader ID + // Instruction Index + // ... + // Validation Error Code + // Validation-specific Word 0 + // Validation-specific Word 1 + // Validation-specific Word 2 + // ... + // + // Each record consists of two subsections: members common across all + // validation and members specific to a + // validation. + // + // The Record Size is the number of 32-bit words in the record, including + // the Record Size word. + // + // Shader ID is a value that identifies which shader has generated the + // validation error. It is passed when the instrumentation pass is created. + // + // The Instruction Index is the position of the instruction within the + // SPIR-V file which is in error. + // + // The Validation Error Code specifies the exact error which has occurred. + // These are enumerated with the kInstError* static consts. This allows + // multiple validation layers to use the same, single output buffer. + // + // The Validation-specific Words are a validation-specific number of 32-bit + // words which give further information on the validation error that + // occurred. These are documented further in each file containing the + // validation-specific class which derives from this base class. + // + // Because the code that is generated checks against the size of the buffer + // before writing, the size of the debug out buffer can be used by the + // validation layer to control the number of error records that are written. + void GenDebugStreamWrite(uint32_t shader_id, uint32_t instruction_idx_id, + const std::vector& validation_ids, + InstructionBuilder* builder); + + // Return id for output function. Define if it doesn't exist with + // |val_spec_param_cnt| validation-specific uint32 parameters. + uint32_t GetStreamWriteFunctionId(uint32_t val_spec_param_cnt); + + // Generate instructions for OpDebugPrintf. + // + // If |ref_inst_itr| is an OpDebugPrintf, return in |new_blocks| the result + // of replacing it with buffer write instructions within its block at + // |ref_block_itr|. The instructions write a record to the printf + // output buffer stream including |function_idx, instruction_idx| + // and removes the OpDebugPrintf. The block at |ref_block_itr| can just be + // replaced with the block in |new_blocks|. Besides the buffer writes, this + // block will comprise all instructions preceding and following + // |ref_inst_itr|. + // + // This function is designed to be passed to + // InstrumentPass::InstProcessEntryPointCallTree(), which applies the + // function to each instruction in a module and replaces the instruction + // if warranted. + // + // This instrumentation function utilizes GenDebugStreamWrite() to write its + // error records. The validation-specific part of the error record will + // consist of a uint32 which is the id of the format string plus a sequence + // of uint32s representing the values of the remaining operands of the + // DebugPrintf. + void GenDebugPrintfCode(BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, + std::vector>* new_blocks); + + // Generate a sequence of uint32 instructions in |builder| (if necessary) + // representing the value of |val_inst|, which must be a buffer pointer, a + // uint64, or a scalar or vector of type uint32, float32 or float16. Append + // the ids of all values to the end of |val_ids|. + void GenOutputValues(Instruction* val_inst, std::vector* val_ids, + InstructionBuilder* builder); + + // Generate instructions to write a record containing the operands of + // |printf_inst| arguments to printf buffer, adding new code to the end of + // the last block in |new_blocks|. Kill OpDebugPrintf instruction. + void GenOutputCode(Instruction* printf_inst, + std::vector>* new_blocks); + + // Set the name for a function or global variable, names will be + // prefixed to identify which instrumentation pass generated them. + std::unique_ptr NewGlobalName(uint32_t id, + const std::string& name_str); + + // Set the name for a structure member + std::unique_ptr NewMemberName(uint32_t id, uint32_t member_index, + const std::string& name_str); + + // Return id for debug output buffer + uint32_t GetOutputBufferId(); + + // Return id for buffer uint type + uint32_t GetOutputBufferPtrId(); + + // Return binding for output buffer for current validation. + uint32_t GetOutputBufferBinding(); + + // Initialize state for instrumenting bindless checking + void InitializeInstDebugPrintf(); + + // Apply GenDebugPrintfCode to every instruction in module. + Pass::Status ProcessImpl(); + + uint32_t ext_inst_printf_id_{0}; + + // id for output buffer variable + uint32_t output_buffer_id_{0}; + + // ptr type id for output buffer element + uint32_t output_buffer_ptr_id_{0}; +}; + +} // namespace opt +} // namespace spvtools + +#endif // LIBSPIRV_OPT_INST_DEBUG_PRINTF_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/instruction.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/instruction.cpp new file mode 100644 index 000000000000..aa4ae26b6414 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/instruction.cpp @@ -0,0 +1,1090 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/instruction.h" + +#include + +#include "OpenCLDebugInfo100.h" +#include "source/disassemble.h" +#include "source/opt/fold.h" +#include "source/opt/ir_context.h" +#include "source/opt/reflect.h" + +namespace spvtools { +namespace opt { +namespace { +// Indices used to get particular operands out of instructions using InOperand. +constexpr uint32_t kTypeImageDimIndex = 1; +constexpr uint32_t kLoadBaseIndex = 0; +constexpr uint32_t kPointerTypeStorageClassIndex = 0; +constexpr uint32_t kVariableStorageClassIndex = 0; +constexpr uint32_t kTypeImageSampledIndex = 5; + +// Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100 +// extension instructions. +constexpr uint32_t kExtInstSetIdInIdx = 0; +constexpr uint32_t kExtInstInstructionInIdx = 1; +constexpr uint32_t kDebugScopeNumWords = 7; +constexpr uint32_t kDebugScopeNumWordsWithoutInlinedAt = 6; +constexpr uint32_t kDebugNoScopeNumWords = 5; + +// Number of operands of an OpBranchConditional instruction +// with weights. +constexpr uint32_t kOpBranchConditionalWithWeightsNumOperands = 5; +} // namespace + +Instruction::Instruction(IRContext* c) + : utils::IntrusiveNodeBase(), + context_(c), + opcode_(spv::Op::OpNop), + has_type_id_(false), + has_result_id_(false), + unique_id_(c->TakeNextUniqueId()), + dbg_scope_(kNoDebugScope, kNoInlinedAt) {} + +Instruction::Instruction(IRContext* c, spv::Op op) + : utils::IntrusiveNodeBase(), + context_(c), + opcode_(op), + has_type_id_(false), + has_result_id_(false), + unique_id_(c->TakeNextUniqueId()), + dbg_scope_(kNoDebugScope, kNoInlinedAt) {} + +Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst, + std::vector&& dbg_line) + : utils::IntrusiveNodeBase(), + context_(c), + opcode_(static_cast(inst.opcode)), + has_type_id_(inst.type_id != 0), + has_result_id_(inst.result_id != 0), + unique_id_(c->TakeNextUniqueId()), + dbg_line_insts_(std::move(dbg_line)), + dbg_scope_(kNoDebugScope, kNoInlinedAt) { + operands_.reserve(inst.num_operands); + for (uint32_t i = 0; i < inst.num_operands; ++i) { + const auto& current_payload = inst.operands[i]; + operands_.emplace_back( + current_payload.type, inst.words + current_payload.offset, + inst.words + current_payload.offset + current_payload.num_words); + } + assert((!IsLineInst() || dbg_line.empty()) && + "Op(No)Line attaching to Op(No)Line found"); +} + +Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst, + const DebugScope& dbg_scope) + : utils::IntrusiveNodeBase(), + context_(c), + opcode_(static_cast(inst.opcode)), + has_type_id_(inst.type_id != 0), + has_result_id_(inst.result_id != 0), + unique_id_(c->TakeNextUniqueId()), + dbg_scope_(dbg_scope) { + operands_.reserve(inst.num_operands); + for (uint32_t i = 0; i < inst.num_operands; ++i) { + const auto& current_payload = inst.operands[i]; + operands_.emplace_back( + current_payload.type, inst.words + current_payload.offset, + inst.words + current_payload.offset + current_payload.num_words); + } +} + +Instruction::Instruction(IRContext* c, spv::Op op, uint32_t ty_id, + uint32_t res_id, const OperandList& in_operands) + : utils::IntrusiveNodeBase(), + context_(c), + opcode_(op), + has_type_id_(ty_id != 0), + has_result_id_(res_id != 0), + unique_id_(c->TakeNextUniqueId()), + operands_(), + dbg_scope_(kNoDebugScope, kNoInlinedAt) { + size_t operands_size = in_operands.size(); + if (has_type_id_) { + operands_size++; + } + if (has_result_id_) { + operands_size++; + } + operands_.reserve(operands_size); + if (has_type_id_) { + operands_.emplace_back(spv_operand_type_t::SPV_OPERAND_TYPE_TYPE_ID, + std::initializer_list{ty_id}); + } + if (has_result_id_) { + operands_.emplace_back(spv_operand_type_t::SPV_OPERAND_TYPE_RESULT_ID, + std::initializer_list{res_id}); + } + operands_.insert(operands_.end(), in_operands.begin(), in_operands.end()); +} + +Instruction::Instruction(Instruction&& that) + : utils::IntrusiveNodeBase(), + context_(that.context_), + opcode_(that.opcode_), + has_type_id_(that.has_type_id_), + has_result_id_(that.has_result_id_), + unique_id_(that.unique_id_), + operands_(std::move(that.operands_)), + dbg_line_insts_(std::move(that.dbg_line_insts_)), + dbg_scope_(that.dbg_scope_) { + for (auto& i : dbg_line_insts_) { + i.dbg_scope_ = that.dbg_scope_; + } +} + +Instruction& Instruction::operator=(Instruction&& that) { + context_ = that.context_; + opcode_ = that.opcode_; + has_type_id_ = that.has_type_id_; + has_result_id_ = that.has_result_id_; + unique_id_ = that.unique_id_; + operands_ = std::move(that.operands_); + dbg_line_insts_ = std::move(that.dbg_line_insts_); + dbg_scope_ = that.dbg_scope_; + return *this; +} + +Instruction* Instruction::Clone(IRContext* c) const { + Instruction* clone = new Instruction(c); + clone->opcode_ = opcode_; + clone->has_type_id_ = has_type_id_; + clone->has_result_id_ = has_result_id_; + clone->unique_id_ = c->TakeNextUniqueId(); + clone->operands_ = operands_; + clone->dbg_line_insts_ = dbg_line_insts_; + for (auto& i : clone->dbg_line_insts_) { + i.unique_id_ = c->TakeNextUniqueId(); + if (i.IsDebugLineInst()) i.SetResultId(c->TakeNextId()); + } + clone->dbg_scope_ = dbg_scope_; + return clone; +} + +uint32_t Instruction::GetSingleWordOperand(uint32_t index) const { + const auto& words = GetOperand(index).words; + assert(words.size() == 1 && "expected the operand only taking one word"); + return words.front(); +} + +uint32_t Instruction::NumInOperandWords() const { + uint32_t size = 0; + for (uint32_t i = TypeResultIdCount(); i < operands_.size(); ++i) + size += static_cast(operands_[i].words.size()); + return size; +} + +bool Instruction::HasBranchWeights() const { + if (opcode_ == spv::Op::OpBranchConditional && + NumOperands() == kOpBranchConditionalWithWeightsNumOperands) { + return true; + } + + return false; +} + +void Instruction::ToBinaryWithoutAttachedDebugInsts( + std::vector* binary) const { + const uint32_t num_words = 1 + NumOperandWords(); + binary->push_back((num_words << 16) | static_cast(opcode_)); + for (const auto& operand : operands_) { + binary->insert(binary->end(), operand.words.begin(), operand.words.end()); + } +} + +void Instruction::ReplaceOperands(const OperandList& new_operands) { + operands_.clear(); + operands_.insert(operands_.begin(), new_operands.begin(), new_operands.end()); +} + +bool Instruction::IsReadOnlyLoad() const { + if (IsLoad()) { + Instruction* address_def = GetBaseAddress(); + if (!address_def) { + return false; + } + + if (address_def->opcode() == spv::Op::OpVariable) { + if (address_def->IsReadOnlyPointer()) { + return true; + } + } + + if (address_def->opcode() == spv::Op::OpLoad) { + const analysis::Type* address_type = + context()->get_type_mgr()->GetType(address_def->type_id()); + if (address_type->AsSampledImage() != nullptr) { + const auto* image_type = + address_type->AsSampledImage()->image_type()->AsImage(); + if (image_type->sampled() == 1) { + return true; + } + } + } + } + return false; +} + +Instruction* Instruction::GetBaseAddress() const { + uint32_t base = GetSingleWordInOperand(kLoadBaseIndex); + Instruction* base_inst = context()->get_def_use_mgr()->GetDef(base); + bool done = false; + while (!done) { + switch (base_inst->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpCopyObject: + // All of these instructions have the base pointer use a base pointer + // in in-operand 0. + base = base_inst->GetSingleWordInOperand(0); + base_inst = context()->get_def_use_mgr()->GetDef(base); + break; + default: + done = true; + break; + } + } + return base_inst; +} + +bool Instruction::IsReadOnlyPointer() const { + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + return IsReadOnlyPointerShaders(); + else + return IsReadOnlyPointerKernel(); +} + +bool Instruction::IsVulkanStorageImage() const { + if (opcode() != spv::Op::OpTypePointer) { + return false; + } + + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class != spv::StorageClass::UniformConstant) { + return false; + } + + Instruction* base_type = + context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); + + // Unpack the optional layer of arraying. + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + base_type = context()->get_def_use_mgr()->GetDef( + base_type->GetSingleWordInOperand(0)); + } + + if (base_type->opcode() != spv::Op::OpTypeImage) { + return false; + } + + if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) == + spv::Dim::Buffer) { + return false; + } + + // Check if the image is sampled. If we do not know for sure that it is, + // then assume it is a storage image. + return base_type->GetSingleWordInOperand(kTypeImageSampledIndex) != 1; +} + +bool Instruction::IsVulkanSampledImage() const { + if (opcode() != spv::Op::OpTypePointer) { + return false; + } + + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class != spv::StorageClass::UniformConstant) { + return false; + } + + Instruction* base_type = + context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); + + // Unpack the optional layer of arraying. + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + base_type = context()->get_def_use_mgr()->GetDef( + base_type->GetSingleWordInOperand(0)); + } + + if (base_type->opcode() != spv::Op::OpTypeImage) { + return false; + } + + if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) == + spv::Dim::Buffer) { + return false; + } + + // Check if the image is sampled. If we know for sure that it is, + // then return true. + return base_type->GetSingleWordInOperand(kTypeImageSampledIndex) == 1; +} + +bool Instruction::IsVulkanStorageTexelBuffer() const { + if (opcode() != spv::Op::OpTypePointer) { + return false; + } + + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class != spv::StorageClass::UniformConstant) { + return false; + } + + Instruction* base_type = + context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); + + // Unpack the optional layer of arraying. + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + base_type = context()->get_def_use_mgr()->GetDef( + base_type->GetSingleWordInOperand(0)); + } + + if (base_type->opcode() != spv::Op::OpTypeImage) { + return false; + } + + if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) != + spv::Dim::Buffer) { + return false; + } + + // Check if the image is sampled. If we do not know for sure that it is, + // then assume it is a storage texel buffer. + return base_type->GetSingleWordInOperand(kTypeImageSampledIndex) != 1; +} + +bool Instruction::IsVulkanStorageBuffer() const { + // Is there a difference between a "Storage buffer" and a "dynamic storage + // buffer" in SPIR-V and do we care about the difference? + if (opcode() != spv::Op::OpTypePointer) { + return false; + } + + Instruction* base_type = + context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); + + // Unpack the optional layer of arraying. + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + base_type = context()->get_def_use_mgr()->GetDef( + base_type->GetSingleWordInOperand(0)); + } + + if (base_type->opcode() != spv::Op::OpTypeStruct) { + return false; + } + + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class == spv::StorageClass::Uniform) { + bool is_buffer_block = false; + context()->get_decoration_mgr()->ForEachDecoration( + base_type->result_id(), uint32_t(spv::Decoration::BufferBlock), + [&is_buffer_block](const Instruction&) { is_buffer_block = true; }); + return is_buffer_block; + } else if (storage_class == spv::StorageClass::StorageBuffer) { + bool is_block = false; + context()->get_decoration_mgr()->ForEachDecoration( + base_type->result_id(), uint32_t(spv::Decoration::Block), + [&is_block](const Instruction&) { is_block = true; }); + return is_block; + } + return false; +} + +bool Instruction::IsVulkanStorageBufferVariable() const { + if (opcode() != spv::Op::OpVariable) { + return false; + } + + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kVariableStorageClassIndex)); + if (storage_class == spv::StorageClass::StorageBuffer || + storage_class == spv::StorageClass::Uniform) { + Instruction* var_type = context()->get_def_use_mgr()->GetDef(type_id()); + return var_type != nullptr && var_type->IsVulkanStorageBuffer(); + } + + return false; +} + +bool Instruction::IsVulkanUniformBuffer() const { + if (opcode() != spv::Op::OpTypePointer) { + return false; + } + + spv::StorageClass storage_class = + spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + if (storage_class != spv::StorageClass::Uniform) { + return false; + } + + Instruction* base_type = + context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); + + // Unpack the optional layer of arraying. + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + base_type = context()->get_def_use_mgr()->GetDef( + base_type->GetSingleWordInOperand(0)); + } + + if (base_type->opcode() != spv::Op::OpTypeStruct) { + return false; + } + + bool is_block = false; + context()->get_decoration_mgr()->ForEachDecoration( + base_type->result_id(), uint32_t(spv::Decoration::Block), + [&is_block](const Instruction&) { is_block = true; }); + return is_block; +} + +bool Instruction::IsReadOnlyPointerShaders() const { + if (type_id() == 0) { + return false; + } + + Instruction* type_def = context()->get_def_use_mgr()->GetDef(type_id()); + if (type_def->opcode() != spv::Op::OpTypePointer) { + return false; + } + + spv::StorageClass storage_class = spv::StorageClass( + type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + + switch (storage_class) { + case spv::StorageClass::UniformConstant: + if (!type_def->IsVulkanStorageImage() && + !type_def->IsVulkanStorageTexelBuffer()) { + return true; + } + break; + case spv::StorageClass::Uniform: + if (!type_def->IsVulkanStorageBuffer()) { + return true; + } + break; + case spv::StorageClass::PushConstant: + case spv::StorageClass::Input: + return true; + default: + break; + } + + bool is_nonwritable = false; + context()->get_decoration_mgr()->ForEachDecoration( + result_id(), uint32_t(spv::Decoration::NonWritable), + [&is_nonwritable](const Instruction&) { is_nonwritable = true; }); + return is_nonwritable; +} + +bool Instruction::IsReadOnlyPointerKernel() const { + if (type_id() == 0) { + return false; + } + + Instruction* type_def = context()->get_def_use_mgr()->GetDef(type_id()); + if (type_def->opcode() != spv::Op::OpTypePointer) { + return false; + } + + spv::StorageClass storage_class = spv::StorageClass( + type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + + return storage_class == spv::StorageClass::UniformConstant; +} + +void Instruction::UpdateLexicalScope(uint32_t scope) { + dbg_scope_.SetLexicalScope(scope); + for (auto& i : dbg_line_insts_) { + i.dbg_scope_.SetLexicalScope(scope); + } + if (!IsLineInst() && + context()->AreAnalysesValid(IRContext::kAnalysisDebugInfo)) { + context()->get_debug_info_mgr()->AnalyzeDebugInst(this); + } +} + +void Instruction::UpdateDebugInlinedAt(uint32_t new_inlined_at) { + dbg_scope_.SetInlinedAt(new_inlined_at); + for (auto& i : dbg_line_insts_) { + i.dbg_scope_.SetInlinedAt(new_inlined_at); + } + if (!IsLineInst() && + context()->AreAnalysesValid(IRContext::kAnalysisDebugInfo)) { + context()->get_debug_info_mgr()->AnalyzeDebugInst(this); + } +} + +void Instruction::ClearDbgLineInsts() { + if (context()->AreAnalysesValid(IRContext::kAnalysisDefUse)) { + auto def_use_mgr = context()->get_def_use_mgr(); + for (auto& l_inst : dbg_line_insts_) def_use_mgr->ClearInst(&l_inst); + } + clear_dbg_line_insts(); +} + +void Instruction::UpdateDebugInfoFrom(const Instruction* from) { + if (from == nullptr) return; + ClearDbgLineInsts(); + if (!from->dbg_line_insts().empty()) + AddDebugLine(&from->dbg_line_insts().back()); + SetDebugScope(from->GetDebugScope()); + if (!IsLineInst() && + context()->AreAnalysesValid(IRContext::kAnalysisDebugInfo)) { + context()->get_debug_info_mgr()->AnalyzeDebugInst(this); + } +} + +void Instruction::AddDebugLine(const Instruction* inst) { + dbg_line_insts_.push_back(*inst); + dbg_line_insts_.back().unique_id_ = context()->TakeNextUniqueId(); + if (inst->IsDebugLineInst()) + dbg_line_insts_.back().SetResultId(context_->TakeNextId()); + if (context()->AreAnalysesValid(IRContext::kAnalysisDefUse)) + context()->get_def_use_mgr()->AnalyzeInstDefUse(&dbg_line_insts_.back()); +} + +bool Instruction::IsDebugLineInst() const { + NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode(); + return ((ext_opt == NonSemanticShaderDebugInfo100DebugLine) || + (ext_opt == NonSemanticShaderDebugInfo100DebugNoLine)); +} + +bool Instruction::IsLineInst() const { return IsLine() || IsNoLine(); } + +bool Instruction::IsLine() const { + if (opcode() == spv::Op::OpLine) return true; + NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode(); + return ext_opt == NonSemanticShaderDebugInfo100DebugLine; +} + +bool Instruction::IsNoLine() const { + if (opcode() == spv::Op::OpNoLine) return true; + NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode(); + return ext_opt == NonSemanticShaderDebugInfo100DebugNoLine; +} + +Instruction* Instruction::InsertBefore(std::unique_ptr&& inst) { + inst.get()->InsertBefore(this); + return inst.release(); +} + +Instruction* Instruction::InsertBefore( + std::vector>&& list) { + Instruction* first_node = list.front().get(); + for (auto& inst : list) { + inst.release()->InsertBefore(this); + } + list.clear(); + return first_node; +} + +bool Instruction::IsValidBasePointer() const { + uint32_t tid = type_id(); + if (tid == 0) { + return false; + } + + Instruction* type = context()->get_def_use_mgr()->GetDef(tid); + if (type->opcode() != spv::Op::OpTypePointer) { + return false; + } + + auto feature_mgr = context()->get_feature_mgr(); + if (feature_mgr->HasCapability(spv::Capability::Addresses)) { + // TODO: The rules here could be more restrictive. + return true; + } + + if (opcode() == spv::Op::OpVariable || + opcode() == spv::Op::OpFunctionParameter) { + return true; + } + + // With variable pointers, there are more valid base pointer objects. + // Variable pointers implicitly declares Variable pointers storage buffer. + spv::StorageClass storage_class = + static_cast(type->GetSingleWordInOperand(0)); + if ((feature_mgr->HasCapability( + spv::Capability::VariablePointersStorageBuffer) && + storage_class == spv::StorageClass::StorageBuffer) || + (feature_mgr->HasCapability(spv::Capability::VariablePointers) && + storage_class == spv::StorageClass::Workgroup)) { + switch (opcode()) { + case spv::Op::OpPhi: + case spv::Op::OpSelect: + case spv::Op::OpFunctionCall: + case spv::Op::OpConstantNull: + return true; + default: + break; + } + } + + uint32_t pointee_type_id = type->GetSingleWordInOperand(1); + Instruction* pointee_type_inst = + context()->get_def_use_mgr()->GetDef(pointee_type_id); + + if (pointee_type_inst->IsOpaqueType()) { + return true; + } + return false; +} + +OpenCLDebugInfo100Instructions Instruction::GetOpenCL100DebugOpcode() const { + if (opcode() != spv::Op::OpExtInst) { + return OpenCLDebugInfo100InstructionsMax; + } + + if (!context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()) { + return OpenCLDebugInfo100InstructionsMax; + } + + if (GetSingleWordInOperand(kExtInstSetIdInIdx) != + context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()) { + return OpenCLDebugInfo100InstructionsMax; + } + + return OpenCLDebugInfo100Instructions( + GetSingleWordInOperand(kExtInstInstructionInIdx)); +} + +NonSemanticShaderDebugInfo100Instructions Instruction::GetShader100DebugOpcode() + const { + if (opcode() != spv::Op::OpExtInst) { + return NonSemanticShaderDebugInfo100InstructionsMax; + } + + if (!context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo()) { + return NonSemanticShaderDebugInfo100InstructionsMax; + } + + if (GetSingleWordInOperand(kExtInstSetIdInIdx) != + context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo()) { + return NonSemanticShaderDebugInfo100InstructionsMax; + } + + uint32_t opcode = GetSingleWordInOperand(kExtInstInstructionInIdx); + if (opcode >= NonSemanticShaderDebugInfo100InstructionsMax) { + return NonSemanticShaderDebugInfo100InstructionsMax; + } + + return NonSemanticShaderDebugInfo100Instructions(opcode); +} + +CommonDebugInfoInstructions Instruction::GetCommonDebugOpcode() const { + if (opcode() != spv::Op::OpExtInst) { + return CommonDebugInfoInstructionsMax; + } + + const uint32_t opencl_set_id = + context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo(); + const uint32_t shader_set_id = + context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo(); + + if (!opencl_set_id && !shader_set_id) { + return CommonDebugInfoInstructionsMax; + } + + const uint32_t used_set_id = GetSingleWordInOperand(kExtInstSetIdInIdx); + + if (used_set_id != opencl_set_id && used_set_id != shader_set_id) { + return CommonDebugInfoInstructionsMax; + } + + return CommonDebugInfoInstructions( + GetSingleWordInOperand(kExtInstInstructionInIdx)); +} + +bool Instruction::IsValidBaseImage() const { + uint32_t tid = type_id(); + if (tid == 0) { + return false; + } + + Instruction* type = context()->get_def_use_mgr()->GetDef(tid); + return (type->opcode() == spv::Op::OpTypeImage || + type->opcode() == spv::Op::OpTypeSampledImage); +} + +bool Instruction::IsOpaqueType() const { + if (opcode() == spv::Op::OpTypeStruct) { + bool is_opaque = false; + ForEachInOperand([&is_opaque, this](const uint32_t* op_id) { + Instruction* type_inst = context()->get_def_use_mgr()->GetDef(*op_id); + is_opaque |= type_inst->IsOpaqueType(); + }); + return is_opaque; + } else if (opcode() == spv::Op::OpTypeArray) { + uint32_t sub_type_id = GetSingleWordInOperand(0); + Instruction* sub_type_inst = + context()->get_def_use_mgr()->GetDef(sub_type_id); + return sub_type_inst->IsOpaqueType(); + } else { + return opcode() == spv::Op::OpTypeRuntimeArray || + spvOpcodeIsBaseOpaqueType(opcode()); + } +} + +bool Instruction::IsFoldable() const { + return IsFoldableByFoldScalar() || IsFoldableByFoldVector() || + context()->get_instruction_folder().HasConstFoldingRule(this); +} + +bool Instruction::IsFoldableByFoldScalar() const { + const InstructionFolder& folder = context()->get_instruction_folder(); + if (!folder.IsFoldableOpcode(opcode())) { + return false; + } + + Instruction* type = context()->get_def_use_mgr()->GetDef(type_id()); + if (!folder.IsFoldableScalarType(type)) { + return false; + } + + // Even if the type of the instruction is foldable, its operands may not be + // foldable (e.g., comparisons of 64bit types). Check that all operand types + // are foldable before accepting the instruction. + return WhileEachInOperand([&folder, this](const uint32_t* op_id) { + Instruction* def_inst = context()->get_def_use_mgr()->GetDef(*op_id); + Instruction* def_inst_type = + context()->get_def_use_mgr()->GetDef(def_inst->type_id()); + return folder.IsFoldableScalarType(def_inst_type); + }); +} + +bool Instruction::IsFoldableByFoldVector() const { + const InstructionFolder& folder = context()->get_instruction_folder(); + if (!folder.IsFoldableOpcode(opcode())) { + return false; + } + + Instruction* type = context()->get_def_use_mgr()->GetDef(type_id()); + if (!folder.IsFoldableVectorType(type)) { + return false; + } + + // Even if the type of the instruction is foldable, its operands may not be + // foldable (e.g., comparisons of 64bit types). Check that all operand types + // are foldable before accepting the instruction. + return WhileEachInOperand([&folder, this](const uint32_t* op_id) { + Instruction* def_inst = context()->get_def_use_mgr()->GetDef(*op_id); + Instruction* def_inst_type = + context()->get_def_use_mgr()->GetDef(def_inst->type_id()); + return folder.IsFoldableVectorType(def_inst_type); + }); +} + +bool Instruction::IsFloatingPointFoldingAllowed() const { + // TODO: Add the rules for kernels. For now it will be pessimistic. + // For now, do not support capabilities introduced by SPV_KHR_float_controls. + if (!context_->get_feature_mgr()->HasCapability(spv::Capability::Shader) || + context_->get_feature_mgr()->HasCapability( + spv::Capability::DenormPreserve) || + context_->get_feature_mgr()->HasCapability( + spv::Capability::DenormFlushToZero) || + context_->get_feature_mgr()->HasCapability( + spv::Capability::SignedZeroInfNanPreserve) || + context_->get_feature_mgr()->HasCapability( + spv::Capability::RoundingModeRTZ) || + context_->get_feature_mgr()->HasCapability( + spv::Capability::RoundingModeRTE)) { + return false; + } + + bool is_nocontract = false; + context_->get_decoration_mgr()->WhileEachDecoration( + result_id(), uint32_t(spv::Decoration::NoContraction), + [&is_nocontract](const Instruction&) { + is_nocontract = true; + return false; + }); + return !is_nocontract; +} + +std::string Instruction::PrettyPrint(uint32_t options) const { + // Convert the module to binary. + std::vector module_binary; + context()->module()->ToBinary(&module_binary, /* skip_nop = */ false); + + // Convert the instruction to binary. This is used to identify the correct + // stream of words to output from the module. + std::vector inst_binary; + ToBinaryWithoutAttachedDebugInsts(&inst_binary); + + // Do not generate a header. + return spvInstructionBinaryToText( + context()->grammar().target_env(), inst_binary.data(), inst_binary.size(), + module_binary.data(), module_binary.size(), + options | SPV_BINARY_TO_TEXT_OPTION_NO_HEADER); +} + +std::ostream& operator<<(std::ostream& str, const Instruction& inst) { + str << inst.PrettyPrint(); + return str; +} + +void Instruction::Dump() const { + std::cerr << "Instruction #" << unique_id() << "\n" << *this << "\n"; +} + +bool Instruction::IsOpcodeCodeMotionSafe() const { + switch (opcode_) { + case spv::Op::OpNop: + case spv::Op::OpUndef: + case spv::Op::OpLoad: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpArrayLength: + case spv::Op::OpVectorExtractDynamic: + case spv::Op::OpVectorInsertDynamic: + case spv::Op::OpVectorShuffle: + case spv::Op::OpCompositeConstruct: + case spv::Op::OpCompositeExtract: + case spv::Op::OpCompositeInsert: + case spv::Op::OpCopyObject: + case spv::Op::OpTranspose: + case spv::Op::OpConvertFToU: + case spv::Op::OpConvertFToS: + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertUToF: + case spv::Op::OpUConvert: + case spv::Op::OpSConvert: + case spv::Op::OpFConvert: + case spv::Op::OpQuantizeToF16: + case spv::Op::OpBitcast: + case spv::Op::OpSNegate: + case spv::Op::OpFNegate: + case spv::Op::OpIAdd: + case spv::Op::OpFAdd: + case spv::Op::OpISub: + case spv::Op::OpFSub: + case spv::Op::OpIMul: + case spv::Op::OpFMul: + case spv::Op::OpUDiv: + case spv::Op::OpSDiv: + case spv::Op::OpFDiv: + case spv::Op::OpUMod: + case spv::Op::OpSRem: + case spv::Op::OpSMod: + case spv::Op::OpFRem: + case spv::Op::OpFMod: + case spv::Op::OpVectorTimesScalar: + case spv::Op::OpMatrixTimesScalar: + case spv::Op::OpVectorTimesMatrix: + case spv::Op::OpMatrixTimesVector: + case spv::Op::OpMatrixTimesMatrix: + case spv::Op::OpOuterProduct: + case spv::Op::OpDot: + case spv::Op::OpIAddCarry: + case spv::Op::OpISubBorrow: + case spv::Op::OpUMulExtended: + case spv::Op::OpSMulExtended: + case spv::Op::OpAny: + case spv::Op::OpAll: + case spv::Op::OpIsNan: + case spv::Op::OpIsInf: + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpLogicalAnd: + case spv::Op::OpLogicalNot: + case spv::Op::OpSelect: + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpFOrdEqual: + case spv::Op::OpFUnordEqual: + case spv::Op::OpFOrdNotEqual: + case spv::Op::OpFUnordNotEqual: + case spv::Op::OpFOrdLessThan: + case spv::Op::OpFUnordLessThan: + case spv::Op::OpFOrdGreaterThan: + case spv::Op::OpFUnordGreaterThan: + case spv::Op::OpFOrdLessThanEqual: + case spv::Op::OpFUnordLessThanEqual: + case spv::Op::OpFOrdGreaterThanEqual: + case spv::Op::OpFUnordGreaterThanEqual: + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpNot: + case spv::Op::OpBitFieldInsert: + case spv::Op::OpBitFieldSExtract: + case spv::Op::OpBitFieldUExtract: + case spv::Op::OpBitReverse: + case spv::Op::OpBitCount: + case spv::Op::OpSizeOf: + return true; + default: + return false; + } +} + +bool Instruction::IsScalarizable() const { + if (spvOpcodeIsScalarizable(opcode())) { + return true; + } + + if (opcode() == spv::Op::OpExtInst) { + uint32_t instSetId = + context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + + if (GetSingleWordInOperand(kExtInstSetIdInIdx) == instSetId) { + switch (GetSingleWordInOperand(kExtInstInstructionInIdx)) { + case GLSLstd450Round: + case GLSLstd450RoundEven: + case GLSLstd450Trunc: + case GLSLstd450FAbs: + case GLSLstd450SAbs: + case GLSLstd450FSign: + case GLSLstd450SSign: + case GLSLstd450Floor: + case GLSLstd450Ceil: + case GLSLstd450Fract: + case GLSLstd450Radians: + case GLSLstd450Degrees: + case GLSLstd450Sin: + case GLSLstd450Cos: + case GLSLstd450Tan: + case GLSLstd450Asin: + case GLSLstd450Acos: + case GLSLstd450Atan: + case GLSLstd450Sinh: + case GLSLstd450Cosh: + case GLSLstd450Tanh: + case GLSLstd450Asinh: + case GLSLstd450Acosh: + case GLSLstd450Atanh: + case GLSLstd450Atan2: + case GLSLstd450Pow: + case GLSLstd450Exp: + case GLSLstd450Log: + case GLSLstd450Exp2: + case GLSLstd450Log2: + case GLSLstd450Sqrt: + case GLSLstd450InverseSqrt: + case GLSLstd450Modf: + case GLSLstd450FMin: + case GLSLstd450UMin: + case GLSLstd450SMin: + case GLSLstd450FMax: + case GLSLstd450UMax: + case GLSLstd450SMax: + case GLSLstd450FClamp: + case GLSLstd450UClamp: + case GLSLstd450SClamp: + case GLSLstd450FMix: + case GLSLstd450Step: + case GLSLstd450SmoothStep: + case GLSLstd450Fma: + case GLSLstd450Frexp: + case GLSLstd450Ldexp: + case GLSLstd450FindILsb: + case GLSLstd450FindSMsb: + case GLSLstd450FindUMsb: + case GLSLstd450NMin: + case GLSLstd450NMax: + case GLSLstd450NClamp: + return true; + default: + return false; + } + } + } + return false; +} + +bool Instruction::IsOpcodeSafeToDelete() const { + if (context()->IsCombinatorInstruction(this)) { + return true; + } + + switch (opcode()) { + case spv::Op::OpDPdx: + case spv::Op::OpDPdy: + case spv::Op::OpFwidth: + case spv::Op::OpDPdxFine: + case spv::Op::OpDPdyFine: + case spv::Op::OpFwidthFine: + case spv::Op::OpDPdxCoarse: + case spv::Op::OpDPdyCoarse: + case spv::Op::OpFwidthCoarse: + case spv::Op::OpImageQueryLod: + return true; + default: + return false; + } +} + +bool Instruction::IsNonSemanticInstruction() const { + if (!HasResultId()) return false; + if (opcode() != spv::Op::OpExtInst) return false; + + auto import_inst = + context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(0)); + std::string import_name = import_inst->GetInOperand(0).AsString(); + return import_name.find("NonSemantic.") == 0; +} + +void DebugScope::ToBinary(uint32_t type_id, uint32_t result_id, + uint32_t ext_set, + std::vector* binary) const { + uint32_t num_words = kDebugScopeNumWords; + CommonDebugInfoInstructions dbg_opcode = CommonDebugInfoDebugScope; + if (GetLexicalScope() == kNoDebugScope) { + num_words = kDebugNoScopeNumWords; + dbg_opcode = CommonDebugInfoDebugNoScope; + } else if (GetInlinedAt() == kNoInlinedAt) { + num_words = kDebugScopeNumWordsWithoutInlinedAt; + } + std::vector operands = { + (num_words << 16) | static_cast(spv::Op::OpExtInst), + type_id, + result_id, + ext_set, + static_cast(dbg_opcode), + }; + binary->insert(binary->end(), operands.begin(), operands.end()); + if (GetLexicalScope() != kNoDebugScope) { + binary->push_back(GetLexicalScope()); + if (GetInlinedAt() != kNoInlinedAt) binary->push_back(GetInlinedAt()); + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/instruction.h b/thirdparty/glslang/External/spirv-tools/source/opt/instruction.h new file mode 100644 index 000000000000..c2617fba5432 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/instruction.h @@ -0,0 +1,924 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_INSTRUCTION_H_ +#define SOURCE_OPT_INSTRUCTION_H_ + +#include +#include +#include +#include +#include +#include + +#include "NonSemanticShaderDebugInfo100.h" +#include "OpenCLDebugInfo100.h" +#include "source/binary.h" +#include "source/common_debug_info.h" +#include "source/latest_version_glsl_std_450_header.h" +#include "source/latest_version_spirv_header.h" +#include "source/opcode.h" +#include "source/operand.h" +#include "source/opt/reflect.h" +#include "source/util/ilist_node.h" +#include "source/util/small_vector.h" +#include "source/util/string_utils.h" +#include "spirv-tools/libspirv.h" + +constexpr uint32_t kNoDebugScope = 0; +constexpr uint32_t kNoInlinedAt = 0; + +namespace spvtools { +namespace opt { + +class Function; +class IRContext; +class Module; +class InstructionList; + +// Relaxed logical addressing: +// +// In the logical addressing model, pointers cannot be stored or loaded. This +// is a useful assumption because it simplifies the aliasing significantly. +// However, for the purpose of legalizing code generated from HLSL, we will have +// to allow storing and loading of pointers to opaque objects and runtime +// arrays. This relaxation of the rule still implies that function and private +// scope variables do not have any aliasing, so we can treat them as before. +// This will be call the relaxed logical addressing model. +// +// This relaxation of the rule will be allowed by |GetBaseAddress|, but it will +// enforce that no other pointers are stored or loaded. + +// About operand: +// +// In the SPIR-V specification, the term "operand" is used to mean any single +// SPIR-V word following the leading wordcount-opcode word. Here, the term +// "operand" is used to mean a *logical* operand. A logical operand may consist +// of multiple SPIR-V words, which together make up the same component. For +// example, a logical operand of a 64-bit integer needs two words to express. +// +// Further, we categorize logical operands into *in* and *out* operands. +// In operands are operands actually serve as input to operations, while out +// operands are operands that represent ids generated from operations (result +// type id or result id). For example, for "OpIAdd %rtype %rid %inop1 %inop2", +// "%inop1" and "%inop2" are in operands, while "%rtype" and "%rid" are out +// operands. + +// A *logical* operand to a SPIR-V instruction. It can be the type id, result +// id, or other additional operands carried in an instruction. +struct Operand { + using OperandData = utils::SmallVector; + Operand(spv_operand_type_t t, OperandData&& w) + : type(t), words(std::move(w)) {} + + Operand(spv_operand_type_t t, const OperandData& w) : type(t), words(w) {} + + template + Operand(spv_operand_type_t t, InputIt firstOperandData, + InputIt lastOperandData) + : type(t), words(firstOperandData, lastOperandData) {} + + spv_operand_type_t type; // Type of this logical operand. + OperandData words; // Binary segments of this logical operand. + + uint32_t AsId() const { + assert(spvIsIdType(type)); + assert(words.size() == 1); + return words[0]; + } + + // Returns a string operand as a std::string. + std::string AsString() const { + assert(type == SPV_OPERAND_TYPE_LITERAL_STRING); + return spvtools::utils::MakeString(words); + } + + // Returns a literal integer operand as a uint64_t + uint64_t AsLiteralUint64() const { + assert(type == SPV_OPERAND_TYPE_LITERAL_INTEGER || + type == SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER || + type == SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER || + type == SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER); + assert(1 <= words.size()); + assert(words.size() <= 2); + uint64_t result = 0; + if (words.size() > 0) { // Needed to avoid maybe-uninitialized GCC warning + uint32_t low = words[0]; + result = uint64_t(low); + } + if (words.size() > 1) { + uint32_t high = words[1]; + result = result | (uint64_t(high) << 32); + } + return result; + } + + friend bool operator==(const Operand& o1, const Operand& o2) { + return o1.type == o2.type && o1.words == o2.words; + } + + // TODO(antiagainst): create fields for literal number kind, width, etc. +}; + +inline bool operator!=(const Operand& o1, const Operand& o2) { + return !(o1 == o2); +} + +// This structure is used to represent a DebugScope instruction from +// the OpenCL.100.DebugInfo extended instruction set. Note that we can +// ignore the result id of DebugScope instruction because it is not +// used for anything. We do not keep it to reduce the size of +// structure. +// TODO: Let validator check that the result id is not used anywhere. +class DebugScope { + public: + DebugScope(uint32_t lexical_scope, uint32_t inlined_at) + : lexical_scope_(lexical_scope), inlined_at_(inlined_at) {} + + inline bool operator!=(const DebugScope& d) const { + return lexical_scope_ != d.lexical_scope_ || inlined_at_ != d.inlined_at_; + } + + // Accessor functions for |lexical_scope_|. + uint32_t GetLexicalScope() const { return lexical_scope_; } + void SetLexicalScope(uint32_t scope) { lexical_scope_ = scope; } + + // Accessor functions for |inlined_at_|. + uint32_t GetInlinedAt() const { return inlined_at_; } + void SetInlinedAt(uint32_t at) { inlined_at_ = at; } + + // Pushes the binary segments for this DebugScope instruction into + // the back of *|binary|. + void ToBinary(uint32_t type_id, uint32_t result_id, uint32_t ext_set, + std::vector* binary) const; + + private: + // The result id of the lexical scope in which this debug scope is + // contained. The value is kNoDebugScope if there is no scope. + uint32_t lexical_scope_; + + // The result id of DebugInlinedAt if instruction in this debug scope + // is inlined. The value is kNoInlinedAt if it is not inlined. + uint32_t inlined_at_; +}; + +// A SPIR-V instruction. It contains the opcode and any additional logical +// operand, including the result id (if any) and result type id (if any). It +// may also contain line-related debug instruction (OpLine, OpNoLine) directly +// appearing before this instruction. Note that the result id of an instruction +// should never change after the instruction being built. If the result id +// needs to change, the user should create a new instruction instead. +class Instruction : public utils::IntrusiveNodeBase { + public: + using OperandList = std::vector; + using iterator = OperandList::iterator; + using const_iterator = OperandList::const_iterator; + + // Creates a default OpNop instruction. + // This exists solely for containers that can't do without. Should be removed. + Instruction() + : utils::IntrusiveNodeBase(), + context_(nullptr), + opcode_(spv::Op::OpNop), + has_type_id_(false), + has_result_id_(false), + unique_id_(0), + dbg_scope_(kNoDebugScope, kNoInlinedAt) {} + + // Creates a default OpNop instruction. + Instruction(IRContext*); + // Creates an instruction with the given opcode |op| and no additional logical + // operands. + Instruction(IRContext*, spv::Op); + // Creates an instruction using the given spv_parsed_instruction_t |inst|. All + // the data inside |inst| will be copied and owned in this instance. And keep + // record of line-related debug instructions |dbg_line| ahead of this + // instruction, if any. + Instruction(IRContext* c, const spv_parsed_instruction_t& inst, + std::vector&& dbg_line = {}); + + Instruction(IRContext* c, const spv_parsed_instruction_t& inst, + const DebugScope& dbg_scope); + + // Creates an instruction with the given opcode |op|, type id: |ty_id|, + // result id: |res_id| and input operands: |in_operands|. + Instruction(IRContext* c, spv::Op op, uint32_t ty_id, uint32_t res_id, + const OperandList& in_operands); + + // TODO: I will want to remove these, but will first have to remove the use of + // std::vector. + Instruction(const Instruction&) = default; + Instruction& operator=(const Instruction&) = default; + + Instruction(Instruction&&); + Instruction& operator=(Instruction&&); + + ~Instruction() override = default; + + // Returns a newly allocated instruction that has the same operands, result, + // and type as |this|. The new instruction is not linked into any list. + // It is the responsibility of the caller to make sure that the storage is + // removed. It is the caller's responsibility to make sure that there is only + // one instruction for each result id. + Instruction* Clone(IRContext* c) const; + + IRContext* context() const { return context_; } + + spv::Op opcode() const { return opcode_; } + // Sets the opcode of this instruction to a specific opcode. Note this may + // invalidate the instruction. + // TODO(qining): Remove this function when instruction building and insertion + // is well implemented. + void SetOpcode(spv::Op op) { opcode_ = op; } + uint32_t type_id() const { + return has_type_id_ ? GetSingleWordOperand(0) : 0; + } + uint32_t result_id() const { + return has_result_id_ ? GetSingleWordOperand(has_type_id_ ? 1 : 0) : 0; + } + uint32_t unique_id() const { + assert(unique_id_ != 0); + return unique_id_; + } + // Returns the vector of line-related debug instructions attached to this + // instruction and the caller can directly modify them. + std::vector& dbg_line_insts() { return dbg_line_insts_; } + const std::vector& dbg_line_insts() const { + return dbg_line_insts_; + } + + const Instruction* dbg_line_inst() const { + return dbg_line_insts_.empty() ? nullptr : &dbg_line_insts_[0]; + } + + // Clear line-related debug instructions attached to this instruction. + void clear_dbg_line_insts() { dbg_line_insts_.clear(); } + + // Same semantics as in the base class except the list the InstructionList + // containing |pos| will now assume ownership of |this|. + // inline void MoveBefore(Instruction* pos); + // inline void InsertAfter(Instruction* pos); + + // Begin and end iterators for operands. + iterator begin() { return operands_.begin(); } + iterator end() { return operands_.end(); } + const_iterator begin() const { return operands_.cbegin(); } + const_iterator end() const { return operands_.cend(); } + // Const begin and end iterators for operands. + const_iterator cbegin() const { return operands_.cbegin(); } + const_iterator cend() const { return operands_.cend(); } + + // Gets the number of logical operands. + uint32_t NumOperands() const { + return static_cast(operands_.size()); + } + // Gets the number of SPIR-V words occupied by all logical operands. + uint32_t NumOperandWords() const { + return NumInOperandWords() + TypeResultIdCount(); + } + // Gets the |index|-th logical operand. + inline Operand& GetOperand(uint32_t index); + inline const Operand& GetOperand(uint32_t index) const; + // Adds |operand| to the list of operands of this instruction. + // It is the responsibility of the caller to make sure + // that the instruction remains valid. + inline void AddOperand(Operand&& operand); + // Adds a copy of |operand| to the list of operands of this instruction. + inline void AddOperand(const Operand& operand); + // Gets the |index|-th logical operand as a single SPIR-V word. This method is + // not expected to be used with logical operands consisting of multiple SPIR-V + // words. + uint32_t GetSingleWordOperand(uint32_t index) const; + // Sets the |index|-th in-operand's data to the given |data|. + inline void SetInOperand(uint32_t index, Operand::OperandData&& data); + // Sets the |index|-th operand's data to the given |data|. + // This is for in-operands modification only, but with |index| expressed in + // terms of operand index rather than in-operand index. + inline void SetOperand(uint32_t index, Operand::OperandData&& data); + // Replace all of the in operands with those in |new_operands|. + inline void SetInOperands(OperandList&& new_operands); + // Sets the result type id. + inline void SetResultType(uint32_t ty_id); + inline bool HasResultType() const { return has_type_id_; } + // Sets the result id + inline void SetResultId(uint32_t res_id); + inline bool HasResultId() const { return has_result_id_; } + // Sets DebugScope. + inline void SetDebugScope(const DebugScope& scope); + inline const DebugScope& GetDebugScope() const { return dbg_scope_; } + // Add debug line inst. Renew result id if Debug[No]Line + void AddDebugLine(const Instruction* inst); + // Updates DebugInlinedAt of DebugScope and OpLine. + void UpdateDebugInlinedAt(uint32_t new_inlined_at); + // Clear line-related debug instructions attached to this instruction + // along with def-use entries. + void ClearDbgLineInsts(); + // Return true if Shader100:Debug[No]Line + bool IsDebugLineInst() const; + // Return true if Op[No]Line or Shader100:Debug[No]Line + bool IsLineInst() const; + // Return true if OpLine or Shader100:DebugLine + bool IsLine() const; + // Return true if OpNoLine or Shader100:DebugNoLine + bool IsNoLine() const; + inline uint32_t GetDebugInlinedAt() const { + return dbg_scope_.GetInlinedAt(); + } + // Updates lexical scope of DebugScope and OpLine. + void UpdateLexicalScope(uint32_t scope); + // Updates OpLine and DebugScope based on the information of |from|. + void UpdateDebugInfoFrom(const Instruction* from); + // Remove the |index|-th operand + void RemoveOperand(uint32_t index) { + operands_.erase(operands_.begin() + index); + } + // Insert an operand before the |index|-th operand + void InsertOperand(uint32_t index, Operand&& operand) { + operands_.insert(operands_.begin() + index, operand); + } + + // The following methods are similar to the above, but are for in operands. + uint32_t NumInOperands() const { + return static_cast(operands_.size() - TypeResultIdCount()); + } + uint32_t NumInOperandWords() const; + Operand& GetInOperand(uint32_t index) { + return GetOperand(index + TypeResultIdCount()); + } + const Operand& GetInOperand(uint32_t index) const { + return GetOperand(index + TypeResultIdCount()); + } + uint32_t GetSingleWordInOperand(uint32_t index) const { + return GetSingleWordOperand(index + TypeResultIdCount()); + } + void RemoveInOperand(uint32_t index) { + operands_.erase(operands_.begin() + index + TypeResultIdCount()); + } + + // Returns true if this instruction is OpNop. + inline bool IsNop() const; + // Turns this instruction to OpNop. This does not clear out all preceding + // line-related debug instructions. + inline void ToNop(); + + // Runs the given function |f| on this instruction and optionally on the + // preceding debug line instructions. The function will always be run + // if this is itself a debug line instruction. + inline void ForEachInst(const std::function& f, + bool run_on_debug_line_insts = false); + inline void ForEachInst(const std::function& f, + bool run_on_debug_line_insts = false) const; + + // Runs the given function |f| on this instruction and optionally on the + // preceding debug line instructions. The function will always be run + // if this is itself a debug line instruction. If |f| returns false, + // iteration is terminated and this function returns false. + inline bool WhileEachInst(const std::function& f, + bool run_on_debug_line_insts = false); + inline bool WhileEachInst(const std::function& f, + bool run_on_debug_line_insts = false) const; + + // Runs the given function |f| on all operand ids. + // + // |f| should not transform an ID into 0, as 0 is an invalid ID. + inline void ForEachId(const std::function& f); + inline void ForEachId(const std::function& f) const; + + // Runs the given function |f| on all "in" operand ids. + inline void ForEachInId(const std::function& f); + inline void ForEachInId(const std::function& f) const; + + // Runs the given function |f| on all "in" operand ids. If |f| returns false, + // iteration is terminated and this function returns false. + inline bool WhileEachInId(const std::function& f); + inline bool WhileEachInId( + const std::function& f) const; + + // Runs the given function |f| on all "in" operands. + inline void ForEachInOperand(const std::function& f); + inline void ForEachInOperand( + const std::function& f) const; + + // Runs the given function |f| on all "in" operands. If |f| returns false, + // iteration is terminated and this function return false. + inline bool WhileEachInOperand(const std::function& f); + inline bool WhileEachInOperand( + const std::function& f) const; + + // Returns true if it's an OpBranchConditional instruction + // with branch weights. + bool HasBranchWeights() const; + + // Returns true if any operands can be labels + inline bool HasLabels() const; + + // Pushes the binary segments for this instruction into the back of *|binary|. + void ToBinaryWithoutAttachedDebugInsts(std::vector* binary) const; + + // Replaces the operands to the instruction with |new_operands|. The caller + // is responsible for building a complete and valid list of operands for + // this instruction. + void ReplaceOperands(const OperandList& new_operands); + + // Returns true if the instruction annotates an id with a decoration. + inline bool IsDecoration() const; + + // Returns true if the instruction is known to be a load from read-only + // memory. + bool IsReadOnlyLoad() const; + + // Returns the instruction that gives the base address of an address + // calculation. The instruction must be a load, as defined by |IsLoad|, + // store, copy, or access chain instruction. In logical addressing mode, will + // return an OpVariable or OpFunctionParameter instruction. For relaxed + // logical addressing, it would also return a load of a pointer to an opaque + // object. For physical addressing mode, could return other types of + // instructions. + Instruction* GetBaseAddress() const; + + // Returns true if the instruction loads from memory or samples an image, and + // stores the result into an id. It considers only core instructions. + // Memory-to-memory instructions are not considered loads. + inline bool IsLoad() const; + + // Returns true if the instruction generates a pointer that is definitely + // read-only. This is determined by analysing the pointer type's storage + // class and decorations that target the pointer's id. It does not analyse + // other instructions that the pointer may be derived from. Thus if 'true' is + // returned, the pointer is definitely read-only, while if 'false' is returned + // it is possible that the pointer may actually be read-only if it is derived + // from another pointer that is decorated as read-only. + bool IsReadOnlyPointer() const; + + // The following functions check for the various descriptor types defined in + // the Vulkan specification section 13.1. + + // Returns true if the instruction defines a pointer type that points to a + // storage image. + bool IsVulkanStorageImage() const; + + // Returns true if the instruction defines a pointer type that points to a + // sampled image. + bool IsVulkanSampledImage() const; + + // Returns true if the instruction defines a pointer type that points to a + // storage texel buffer. + bool IsVulkanStorageTexelBuffer() const; + + // Returns true if the instruction defines a pointer type that points to a + // storage buffer. + bool IsVulkanStorageBuffer() const; + + // Returns true if the instruction defines a variable in StorageBuffer or + // Uniform storage class with a pointer type that points to a storage buffer. + bool IsVulkanStorageBufferVariable() const; + + // Returns true if the instruction defines a pointer type that points to a + // uniform buffer. + bool IsVulkanUniformBuffer() const; + + // Returns true if the instruction is an atom operation that uses original + // value. + inline bool IsAtomicWithLoad() const; + + // Returns true if the instruction is an atom operation. + inline bool IsAtomicOp() const; + + // Returns true if this instruction is a branch or switch instruction (either + // conditional or not). + bool IsBranch() const { return spvOpcodeIsBranch(opcode()); } + + // Returns true if this instruction causes the function to finish execution + // and return to its caller + bool IsReturn() const { return spvOpcodeIsReturn(opcode()); } + + // Returns true if this instruction exits this function or aborts execution. + bool IsReturnOrAbort() const { return spvOpcodeIsReturnOrAbort(opcode()); } + + // Returns true if this instruction is a basic block terminator. + bool IsBlockTerminator() const { + return spvOpcodeIsBlockTerminator(opcode()); + } + + // Returns true if |this| is an instruction that define an opaque type. Since + // runtime array have similar characteristics they are included as opaque + // types. + bool IsOpaqueType() const; + + // Returns true if |this| is an instruction which could be folded into a + // constant value. + bool IsFoldable() const; + + // Returns true if |this| is an instruction which could be folded into a + // constant value by |FoldScalar|. + bool IsFoldableByFoldScalar() const; + + // Returns true if |this| is an instruction which could be folded into a + // constant value by |FoldVector|. + bool IsFoldableByFoldVector() const; + + // Returns true if we are allowed to fold or otherwise manipulate the + // instruction that defines |id| in the given context. This includes not + // handling NaN values. + bool IsFloatingPointFoldingAllowed() const; + + inline bool operator==(const Instruction&) const; + inline bool operator!=(const Instruction&) const; + inline bool operator<(const Instruction&) const; + + // Takes ownership of the instruction owned by |i| and inserts it immediately + // before |this|. Returns the inserted instruction. + Instruction* InsertBefore(std::unique_ptr&& i); + // Takes ownership of the instructions in |list| and inserts them in order + // immediately before |this|. Returns the first inserted instruction. + // Assumes the list is non-empty. + Instruction* InsertBefore(std::vector>&& list); + using utils::IntrusiveNodeBase::InsertBefore; + + // Returns true if |this| is an instruction defining a constant, but not a + // Spec constant. + inline bool IsConstant() const; + + // Returns true if |this| is an instruction with an opcode safe to move + bool IsOpcodeCodeMotionSafe() const; + + // Pretty-prints |inst|. + // + // Provides the disassembly of a specific instruction. Utilizes |inst|'s + // context to provide the correct interpretation of types, constants, etc. + // + // |options| are the disassembly options. SPV_BINARY_TO_TEXT_OPTION_NO_HEADER + // is always added to |options|. + std::string PrettyPrint(uint32_t options = 0u) const; + + // Returns true if the result can be a vector and the result of each component + // depends on the corresponding component of any vector inputs. + bool IsScalarizable() const; + + // Return true if the only effect of this instructions is the result. + bool IsOpcodeSafeToDelete() const; + + // Returns true if it is valid to use the result of |inst| as the base + // pointer for a load or store. In this case, valid is defined by the relaxed + // logical addressing rules when using logical addressing. Normal validation + // rules for physical addressing. + bool IsValidBasePointer() const; + + // Returns debug opcode of an OpenCL.100.DebugInfo instruction. If + // it is not an OpenCL.100.DebugInfo instruction, just returns + // OpenCLDebugInfo100InstructionsMax. + OpenCLDebugInfo100Instructions GetOpenCL100DebugOpcode() const; + + // Returns debug opcode of an NonSemantic.Shader.DebugInfo.100 instruction. If + // it is not an NonSemantic.Shader.DebugInfo.100 instruction, just return + // NonSemanticShaderDebugInfo100InstructionsMax. + NonSemanticShaderDebugInfo100Instructions GetShader100DebugOpcode() const; + + // Returns debug opcode of an OpenCL.100.DebugInfo or + // NonSemantic.Shader.DebugInfo.100 instruction. Since these overlap, we + // return the OpenCLDebugInfo code + CommonDebugInfoInstructions GetCommonDebugOpcode() const; + + // Returns true if it is an OpenCL.DebugInfo.100 instruction. + bool IsOpenCL100DebugInstr() const { + return GetOpenCL100DebugOpcode() != OpenCLDebugInfo100InstructionsMax; + } + + // Returns true if it is an NonSemantic.Shader.DebugInfo.100 instruction. + bool IsShader100DebugInstr() const { + return GetShader100DebugOpcode() != + NonSemanticShaderDebugInfo100InstructionsMax; + } + bool IsCommonDebugInstr() const { + return GetCommonDebugOpcode() != CommonDebugInfoInstructionsMax; + } + + // Returns true if this instructions a non-semantic instruction. + bool IsNonSemanticInstruction() const; + + // Dump this instruction on stderr. Useful when running interactive + // debuggers. + void Dump() const; + + private: + // Returns the total count of result type id and result id. + uint32_t TypeResultIdCount() const { + if (has_type_id_ && has_result_id_) return 2; + if (has_type_id_ || has_result_id_) return 1; + return 0; + } + + // Returns true if the instruction generates a read-only pointer, with the + // same caveats documented in the comment for IsReadOnlyPointer. The first + // version assumes the module is a shader module. The second assumes a + // kernel. + bool IsReadOnlyPointerShaders() const; + bool IsReadOnlyPointerKernel() const; + + // Returns true if the result of |inst| can be used as the base image for an + // instruction that samples a image, reads an image, or writes to an image. + bool IsValidBaseImage() const; + + IRContext* context_; // IR Context + spv::Op opcode_; // Opcode + bool has_type_id_; // True if the instruction has a type id + bool has_result_id_; // True if the instruction has a result id + uint32_t unique_id_; // Unique instruction id + // All logical operands, including result type id and result id. + OperandList operands_; + // Op[No]Line or Debug[No]Line instructions preceding this instruction. Note + // that for Instructions representing Op[No]Line or Debug[No]Line themselves, + // this field should be empty. + std::vector dbg_line_insts_; + + // DebugScope that wraps this instruction. + DebugScope dbg_scope_; + + friend InstructionList; +}; + +// Pretty-prints |inst| to |str| and returns |str|. +// +// Provides the disassembly of a specific instruction. Utilizes |inst|'s context +// to provide the correct interpretation of types, constants, etc. +// +// Disassembly uses raw ids (not pretty printed names). +std::ostream& operator<<(std::ostream& str, const Instruction& inst); + +inline bool Instruction::operator==(const Instruction& other) const { + return unique_id() == other.unique_id(); +} + +inline bool Instruction::operator!=(const Instruction& other) const { + return !(*this == other); +} + +inline bool Instruction::operator<(const Instruction& other) const { + return unique_id() < other.unique_id(); +} + +inline Operand& Instruction::GetOperand(uint32_t index) { + assert(index < operands_.size() && "operand index out of bound"); + return operands_[index]; +} + +inline const Operand& Instruction::GetOperand(uint32_t index) const { + assert(index < operands_.size() && "operand index out of bound"); + return operands_[index]; +} + +inline void Instruction::AddOperand(Operand&& operand) { + operands_.push_back(std::move(operand)); +} + +inline void Instruction::AddOperand(const Operand& operand) { + operands_.push_back(operand); +} + +inline void Instruction::SetInOperand(uint32_t index, + Operand::OperandData&& data) { + SetOperand(index + TypeResultIdCount(), std::move(data)); +} + +inline void Instruction::SetOperand(uint32_t index, + Operand::OperandData&& data) { + assert(index < operands_.size() && "operand index out of bound"); + assert(index >= TypeResultIdCount() && "operand is not a in-operand"); + operands_[index].words = std::move(data); +} + +inline void Instruction::SetInOperands(OperandList&& new_operands) { + // Remove the old in operands. + operands_.erase(operands_.begin() + TypeResultIdCount(), operands_.end()); + // Add the new in operands. + operands_.insert(operands_.end(), new_operands.begin(), new_operands.end()); +} + +inline void Instruction::SetResultId(uint32_t res_id) { + // TODO(dsinclair): Allow setting a result id if there wasn't one + // previously. Need to make room in the operands_ array to place the result, + // and update the has_result_id_ flag. + assert(has_result_id_); + + // TODO(dsinclair): Allow removing the result id. This needs to make sure, + // if there was a result id previously to remove it from the operands_ array + // and reset the has_result_id_ flag. + assert(res_id != 0); + + auto ridx = has_type_id_ ? 1 : 0; + operands_[ridx].words = {res_id}; +} + +inline void Instruction::SetDebugScope(const DebugScope& scope) { + dbg_scope_ = scope; + for (auto& i : dbg_line_insts_) { + i.dbg_scope_ = scope; + } +} + +inline void Instruction::SetResultType(uint32_t ty_id) { + // TODO(dsinclair): Allow setting a type id if there wasn't one + // previously. Need to make room in the operands_ array to place the result, + // and update the has_type_id_ flag. + assert(has_type_id_); + + // TODO(dsinclair): Allow removing the type id. This needs to make sure, + // if there was a type id previously to remove it from the operands_ array + // and reset the has_type_id_ flag. + assert(ty_id != 0); + + operands_.front().words = {ty_id}; +} + +inline bool Instruction::IsNop() const { + return opcode_ == spv::Op::OpNop && !has_type_id_ && !has_result_id_ && + operands_.empty(); +} + +inline void Instruction::ToNop() { + opcode_ = spv::Op::OpNop; + has_type_id_ = false; + has_result_id_ = false; + operands_.clear(); +} + +inline bool Instruction::WhileEachInst( + const std::function& f, bool run_on_debug_line_insts) { + if (run_on_debug_line_insts) { + for (auto& dbg_line : dbg_line_insts_) { + if (!f(&dbg_line)) return false; + } + } + return f(this); +} + +inline bool Instruction::WhileEachInst( + const std::function& f, + bool run_on_debug_line_insts) const { + if (run_on_debug_line_insts) { + for (auto& dbg_line : dbg_line_insts_) { + if (!f(&dbg_line)) return false; + } + } + return f(this); +} + +inline void Instruction::ForEachInst(const std::function& f, + bool run_on_debug_line_insts) { + WhileEachInst( + [&f](Instruction* inst) { + f(inst); + return true; + }, + run_on_debug_line_insts); +} + +inline void Instruction::ForEachInst( + const std::function& f, + bool run_on_debug_line_insts) const { + WhileEachInst( + [&f](const Instruction* inst) { + f(inst); + return true; + }, + run_on_debug_line_insts); +} + +inline void Instruction::ForEachId(const std::function& f) { + for (auto& operand : operands_) + if (spvIsIdType(operand.type)) f(&operand.words[0]); +} + +inline void Instruction::ForEachId( + const std::function& f) const { + for (const auto& operand : operands_) + if (spvIsIdType(operand.type)) f(&operand.words[0]); +} + +inline bool Instruction::WhileEachInId( + const std::function& f) { + for (auto& operand : operands_) { + if (spvIsInIdType(operand.type) && !f(&operand.words[0])) { + return false; + } + } + return true; +} + +inline bool Instruction::WhileEachInId( + const std::function& f) const { + for (const auto& operand : operands_) { + if (spvIsInIdType(operand.type) && !f(&operand.words[0])) { + return false; + } + } + return true; +} + +inline void Instruction::ForEachInId(const std::function& f) { + WhileEachInId([&f](uint32_t* id) { + f(id); + return true; + }); +} + +inline void Instruction::ForEachInId( + const std::function& f) const { + WhileEachInId([&f](const uint32_t* id) { + f(id); + return true; + }); +} + +inline bool Instruction::WhileEachInOperand( + const std::function& f) { + for (auto& operand : operands_) { + switch (operand.type) { + case SPV_OPERAND_TYPE_RESULT_ID: + case SPV_OPERAND_TYPE_TYPE_ID: + break; + default: + if (!f(&operand.words[0])) return false; + break; + } + } + return true; +} + +inline bool Instruction::WhileEachInOperand( + const std::function& f) const { + for (const auto& operand : operands_) { + switch (operand.type) { + case SPV_OPERAND_TYPE_RESULT_ID: + case SPV_OPERAND_TYPE_TYPE_ID: + break; + default: + if (!f(&operand.words[0])) return false; + break; + } + } + return true; +} + +inline void Instruction::ForEachInOperand( + const std::function& f) { + WhileEachInOperand([&f](uint32_t* operand) { + f(operand); + return true; + }); +} + +inline void Instruction::ForEachInOperand( + const std::function& f) const { + WhileEachInOperand([&f](const uint32_t* operand) { + f(operand); + return true; + }); +} + +inline bool Instruction::HasLabels() const { + switch (opcode_) { + case spv::Op::OpSelectionMerge: + case spv::Op::OpBranch: + case spv::Op::OpLoopMerge: + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: + case spv::Op::OpPhi: + return true; + break; + default: + break; + } + return false; +} + +bool Instruction::IsDecoration() const { + return spvOpcodeIsDecoration(opcode()); +} + +bool Instruction::IsLoad() const { return spvOpcodeIsLoad(opcode()); } + +bool Instruction::IsAtomicWithLoad() const { + return spvOpcodeIsAtomicWithLoad(opcode()); +} + +bool Instruction::IsAtomicOp() const { return spvOpcodeIsAtomicOp(opcode()); } + +bool Instruction::IsConstant() const { + return IsConstantInst(opcode()) && !IsSpecConstantInst(opcode()); +} +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_INSTRUCTION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/instruction_list.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/instruction_list.cpp new file mode 100644 index 000000000000..385a136ec783 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/instruction_list.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/instruction_list.h" + +namespace spvtools { +namespace opt { + +InstructionList::iterator InstructionList::iterator::InsertBefore( + std::vector>&& list) { + Instruction* first_node = list.front().get(); + for (auto& i : list) { + i.release()->InsertBefore(node_); + } + list.clear(); + return iterator(first_node); +} + +InstructionList::iterator InstructionList::iterator::InsertBefore( + std::unique_ptr&& i) { + i.get()->InsertBefore(node_); + return iterator(i.release()); +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/instruction_list.h b/thirdparty/glslang/External/spirv-tools/source/opt/instruction_list.h new file mode 100644 index 000000000000..b3e427459182 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/instruction_list.h @@ -0,0 +1,140 @@ + +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_INSTRUCTION_LIST_H_ +#define SOURCE_OPT_INSTRUCTION_LIST_H_ + +#include +#include +#include +#include +#include + +#include "source/latest_version_spirv_header.h" +#include "source/operand.h" +#include "source/opt/instruction.h" +#include "source/util/ilist.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace opt { + +// This class is intended to be the container for Instructions. This container +// owns the instructions that are in it. When removing an Instruction from the +// list, the caller is assuming responsibility for deleting the storage. +// +// TODO: Because there are a number of other data structures that will want +// pointers to instruction, ownership should probably be moved to the module. +// Because of that I have not made the ownership passing in this class fully +// explicit. For example, RemoveFromList takes ownership from the list, but +// does not return an std::unique_ptr to signal that. When we fully decide on +// ownership, this will have to be fixed up one way or the other. +class InstructionList : public utils::IntrusiveList { + public: + InstructionList() = default; + InstructionList(InstructionList&& that) + : utils::IntrusiveList(std::move(that)) {} + InstructionList& operator=(InstructionList&& that) { + auto p = static_cast*>(this); + *p = std::move(that); + return *this; + } + + // Destroy this list and any instructions in the list. + inline ~InstructionList() override; + + class iterator : public utils::IntrusiveList::iterator { + public: + iterator(const utils::IntrusiveList::iterator& i) + : utils::IntrusiveList::iterator(i) {} + iterator(Instruction* i) : utils::IntrusiveList::iterator(i) {} + + iterator& operator++() { + utils::IntrusiveList::iterator::operator++(); + return *this; + } + + iterator& operator--() { + utils::IntrusiveList::iterator::operator--(); + return *this; + } + + // DEPRECATED: Please use MoveBefore with an InstructionList instead. + // + // Moves the nodes in |list| to the list that |this| points to. The + // positions of the nodes will be immediately before the element pointed to + // by the iterator. The return value will be an iterator pointing to the + // first of the newly inserted elements. Ownership of the elements in + // |list| is now passed on to |*this|. + iterator InsertBefore(std::vector>&& list); + + // The node |i| will be inserted immediately before |this|. The return value + // will be an iterator pointing to the newly inserted node. The owner of + // |*i| becomes |*this| + iterator InsertBefore(std::unique_ptr&& i); + + // Removes the node from the list, and deletes the storage. Returns a valid + // iterator to the next node. + iterator Erase() { + iterator_template next_node = *this; + ++next_node; + node_->RemoveFromList(); + delete node_; + return next_node; + } + }; + + iterator begin() { return utils::IntrusiveList::begin(); } + iterator end() { return utils::IntrusiveList::end(); } + const_iterator begin() const { + return utils::IntrusiveList::begin(); + } + const_iterator end() const { + return utils::IntrusiveList::end(); + } + + void push_back(std::unique_ptr&& inst) { + utils::IntrusiveList::push_back(inst.release()); + } + + // Same as in the base class, except it will delete the data as well. + inline void clear(); + + // Runs the given function |f| on the instructions in the list and optionally + // on the preceding debug line instructions. + inline void ForEachInst(const std::function& f, + bool run_on_debug_line_insts) { + auto next = begin(); + for (auto i = next; i != end(); i = next) { + ++next; + i->ForEachInst(f, run_on_debug_line_insts); + } + } +}; + +InstructionList::~InstructionList() { clear(); } + +void InstructionList::clear() { + while (!empty()) { + Instruction* inst = &front(); + inst->RemoveFromList(); + delete inst; + } +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_INSTRUCTION_LIST_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/instrument_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/instrument_pass.cpp new file mode 100644 index 000000000000..b6845a5997db --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/instrument_pass.cpp @@ -0,0 +1,803 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "instrument_pass.h" + +#include "source/cfa.h" +#include "source/spirv_constant.h" + +namespace spvtools { +namespace opt { +namespace { +// Indices of operands in SPIR-V instructions +constexpr int kEntryPointFunctionIdInIdx = 1; +} // namespace + +void InstrumentPass::MovePreludeCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, + std::unique_ptr* new_blk_ptr) { + same_block_pre_.clear(); + same_block_post_.clear(); + // Initialize new block. Reuse label from original block. + new_blk_ptr->reset(new BasicBlock(std::move(ref_block_itr->GetLabel()))); + // Move contents of original ref block up to ref instruction. + for (auto cii = ref_block_itr->begin(); cii != ref_inst_itr; + cii = ref_block_itr->begin()) { + Instruction* inst = &*cii; + inst->RemoveFromList(); + std::unique_ptr mv_ptr(inst); + // Remember same-block ops for possible regeneration. + if (IsSameBlockOp(&*mv_ptr)) { + auto* sb_inst_ptr = mv_ptr.get(); + same_block_pre_[mv_ptr->result_id()] = sb_inst_ptr; + } + (*new_blk_ptr)->AddInstruction(std::move(mv_ptr)); + } +} + +void InstrumentPass::MovePostludeCode( + UptrVectorIterator ref_block_itr, BasicBlock* new_blk_ptr) { + // Move contents of original ref block. + for (auto cii = ref_block_itr->begin(); cii != ref_block_itr->end(); + cii = ref_block_itr->begin()) { + Instruction* inst = &*cii; + inst->RemoveFromList(); + std::unique_ptr mv_inst(inst); + // Regenerate any same-block instruction that has not been seen in the + // current block. + if (same_block_pre_.size() > 0) { + CloneSameBlockOps(&mv_inst, &same_block_post_, &same_block_pre_, + new_blk_ptr); + // Remember same-block ops in this block. + if (IsSameBlockOp(&*mv_inst)) { + const uint32_t rid = mv_inst->result_id(); + same_block_post_[rid] = rid; + } + } + new_blk_ptr->AddInstruction(std::move(mv_inst)); + } +} + +std::unique_ptr InstrumentPass::NewLabel(uint32_t label_id) { + auto new_label = + MakeUnique(context(), spv::Op::OpLabel, 0, label_id, + std::initializer_list{}); + get_def_use_mgr()->AnalyzeInstDefUse(&*new_label); + return new_label; +} + +std::unique_ptr InstrumentPass::StartFunction( + uint32_t func_id, const analysis::Type* return_type, + const std::vector& param_types) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Function* func_type = GetFunction(return_type, param_types); + + const std::vector operands{ + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {uint32_t(spv::FunctionControlMask::MaskNone)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_mgr->GetId(func_type)}}, + }; + auto func_inst = + MakeUnique(context(), spv::Op::OpFunction, + type_mgr->GetId(return_type), func_id, operands); + get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst); + return MakeUnique(std::move(func_inst)); +} + +std::unique_ptr InstrumentPass::EndFunction() { + auto end = MakeUnique(context(), spv::Op::OpFunctionEnd, 0, 0, + std::initializer_list{}); + get_def_use_mgr()->AnalyzeInstDefUse(end.get()); + return end; +} + +std::vector InstrumentPass::AddParameters( + Function& func, const std::vector& param_types) { + std::vector param_ids; + param_ids.reserve(param_types.size()); + for (const analysis::Type* param : param_types) { + uint32_t pid = TakeNextId(); + param_ids.push_back(pid); + auto param_inst = + MakeUnique(context(), spv::Op::OpFunctionParameter, + context()->get_type_mgr()->GetId(param), pid, + std::initializer_list{}); + get_def_use_mgr()->AnalyzeInstDefUse(param_inst.get()); + func.AddParameter(std::move(param_inst)); + } + return param_ids; +} + +std::unique_ptr InstrumentPass::NewName( + uint32_t id, const std::string& name_str) { + return MakeUnique( + context(), spv::Op::OpName, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {id}}, + {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}}); +} + +uint32_t InstrumentPass::Gen32BitCvtCode(uint32_t val_id, + InstructionBuilder* builder) { + // Convert integer value to 32-bit if necessary + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + uint32_t val_ty_id = get_def_use_mgr()->GetDef(val_id)->type_id(); + analysis::Integer* val_ty = type_mgr->GetType(val_ty_id)->AsInteger(); + if (val_ty->width() == 32) return val_id; + bool is_signed = val_ty->IsSigned(); + analysis::Integer val_32b_ty(32, is_signed); + analysis::Type* val_32b_reg_ty = type_mgr->GetRegisteredType(&val_32b_ty); + uint32_t val_32b_reg_ty_id = type_mgr->GetId(val_32b_reg_ty); + if (is_signed) + return builder->AddUnaryOp(val_32b_reg_ty_id, spv::Op::OpSConvert, val_id) + ->result_id(); + else + return builder->AddUnaryOp(val_32b_reg_ty_id, spv::Op::OpUConvert, val_id) + ->result_id(); +} + +uint32_t InstrumentPass::GenUintCastCode(uint32_t val_id, + InstructionBuilder* builder) { + // Convert value to 32-bit if necessary + uint32_t val_32b_id = Gen32BitCvtCode(val_id, builder); + // Cast value to unsigned if necessary + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + uint32_t val_ty_id = get_def_use_mgr()->GetDef(val_32b_id)->type_id(); + analysis::Integer* val_ty = type_mgr->GetType(val_ty_id)->AsInteger(); + if (!val_ty->IsSigned()) return val_32b_id; + return builder->AddUnaryOp(GetUintId(), spv::Op::OpBitcast, val_32b_id) + ->result_id(); +} + +uint32_t InstrumentPass::GenVarLoad(uint32_t var_id, + InstructionBuilder* builder) { + Instruction* var_inst = get_def_use_mgr()->GetDef(var_id); + uint32_t type_id = GetPointeeTypeId(var_inst); + Instruction* load_inst = builder->AddLoad(type_id, var_id); + return load_inst->result_id(); +} + +uint32_t InstrumentPass::GenStageInfo(uint32_t stage_idx, + InstructionBuilder* builder) { + std::vector ids(4, builder->GetUintConstantId(0)); + ids[0] = builder->GetUintConstantId(stage_idx); + // %289 = OpCompositeConstruct %v4uint %uint_0 %285 %288 %uint_0 + // TODO(greg-lunarg): Add support for all stages + switch (spv::ExecutionModel(stage_idx)) { + case spv::ExecutionModel::Vertex: { + // Load and store VertexId and InstanceId + uint32_t load_id = GenVarLoad( + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::VertexIndex)), + builder); + ids[1] = GenUintCastCode(load_id, builder); + + load_id = GenVarLoad(context()->GetBuiltinInputVarId( + uint32_t(spv::BuiltIn::InstanceIndex)), + builder); + ids[2] = GenUintCastCode(load_id, builder); + } break; + case spv::ExecutionModel::GLCompute: + case spv::ExecutionModel::TaskNV: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::TaskEXT: + case spv::ExecutionModel::MeshEXT: { + // Load and store GlobalInvocationId. + uint32_t load_id = GenVarLoad(context()->GetBuiltinInputVarId(uint32_t( + spv::BuiltIn::GlobalInvocationId)), + builder); + for (uint32_t u = 0; u < 3u; ++u) { + ids[u + 1] = builder->AddCompositeExtract(GetUintId(), load_id, {u}) + ->result_id(); + } + } break; + case spv::ExecutionModel::Geometry: { + // Load and store PrimitiveId and InvocationId. + uint32_t load_id = GenVarLoad( + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), + builder); + ids[1] = load_id; + load_id = GenVarLoad( + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)), + builder); + ids[2] = GenUintCastCode(load_id, builder); + } break; + case spv::ExecutionModel::TessellationControl: { + // Load and store InvocationId and PrimitiveId + uint32_t load_id = GenVarLoad( + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)), + builder); + ids[1] = GenUintCastCode(load_id, builder); + load_id = GenVarLoad( + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), + builder); + ids[2] = load_id; + } break; + case spv::ExecutionModel::TessellationEvaluation: { + // Load and store PrimitiveId and TessCoord.uv + uint32_t load_id = GenVarLoad( + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), + builder); + ids[1] = load_id; + load_id = GenVarLoad( + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::TessCoord)), + builder); + Instruction* uvec3_cast_inst = + builder->AddUnaryOp(GetVec3UintId(), spv::Op::OpBitcast, load_id); + uint32_t uvec3_cast_id = uvec3_cast_inst->result_id(); + for (uint32_t u = 0; u < 2u; ++u) { + ids[u + 2] = + builder->AddCompositeExtract(GetUintId(), uvec3_cast_id, {u}) + ->result_id(); + } + } break; + case spv::ExecutionModel::Fragment: { + // Load FragCoord and convert to Uint + Instruction* frag_coord_inst = builder->AddLoad( + GetVec4FloatId(), + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::FragCoord))); + Instruction* uint_frag_coord_inst = builder->AddUnaryOp( + GetVec4UintId(), spv::Op::OpBitcast, frag_coord_inst->result_id()); + for (uint32_t u = 0; u < 2u; ++u) { + ids[u + 1] = + builder + ->AddCompositeExtract(GetUintId(), + uint_frag_coord_inst->result_id(), {u}) + ->result_id(); + } + } break; + case spv::ExecutionModel::RayGenerationNV: + case spv::ExecutionModel::IntersectionNV: + case spv::ExecutionModel::AnyHitNV: + case spv::ExecutionModel::ClosestHitNV: + case spv::ExecutionModel::MissNV: + case spv::ExecutionModel::CallableNV: { + // Load and store LaunchIdNV. + uint32_t launch_id = GenVarLoad( + context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::LaunchIdNV)), + builder); + for (uint32_t u = 0; u < 3u; ++u) { + ids[u + 1] = builder->AddCompositeExtract(GetUintId(), launch_id, {u}) + ->result_id(); + } + } break; + default: { assert(false && "unsupported stage"); } break; + } + return builder->AddCompositeConstruct(GetVec4UintId(), ids)->result_id(); +} + +bool InstrumentPass::AllConstant(const std::vector& ids) { + for (auto& id : ids) { + Instruction* id_inst = context()->get_def_use_mgr()->GetDef(id); + if (!spvOpcodeIsConstant(id_inst->opcode())) return false; + } + return true; +} + +uint32_t InstrumentPass::GenReadFunctionCall( + uint32_t return_id, uint32_t func_id, + const std::vector& func_call_args, + InstructionBuilder* ref_builder) { + // If optimizing direct reads and the call has already been generated, + // use its result + if (opt_direct_reads_) { + uint32_t res_id = call2id_[func_call_args]; + if (res_id != 0) return res_id; + } + // If the function arguments are all constants, the call can be moved to the + // first block of the function where its result can be reused. One example + // where this is profitable is for uniform buffer references, of which there + // are often many. + InstructionBuilder builder(ref_builder->GetContext(), + &*ref_builder->GetInsertPoint(), + ref_builder->GetPreservedAnalysis()); + bool insert_in_first_block = opt_direct_reads_ && AllConstant(func_call_args); + if (insert_in_first_block) { + Instruction* insert_before = &*curr_func_->begin()->tail(); + builder.SetInsertPoint(insert_before); + } + uint32_t res_id = + builder.AddFunctionCall(return_id, func_id, func_call_args)->result_id(); + if (insert_in_first_block) call2id_[func_call_args] = res_id; + return res_id; +} + +bool InstrumentPass::IsSameBlockOp(const Instruction* inst) const { + return inst->opcode() == spv::Op::OpSampledImage || + inst->opcode() == spv::Op::OpImage; +} + +void InstrumentPass::CloneSameBlockOps( + std::unique_ptr* inst, + std::unordered_map* same_blk_post, + std::unordered_map* same_blk_pre, + BasicBlock* block_ptr) { + bool changed = false; + (*inst)->ForEachInId([&same_blk_post, &same_blk_pre, &block_ptr, &changed, + this](uint32_t* iid) { + const auto map_itr = (*same_blk_post).find(*iid); + if (map_itr == (*same_blk_post).end()) { + const auto map_itr2 = (*same_blk_pre).find(*iid); + if (map_itr2 != (*same_blk_pre).end()) { + // Clone pre-call same-block ops, map result id. + const Instruction* in_inst = map_itr2->second; + std::unique_ptr sb_inst(in_inst->Clone(context())); + const uint32_t rid = sb_inst->result_id(); + const uint32_t nid = this->TakeNextId(); + get_decoration_mgr()->CloneDecorations(rid, nid); + sb_inst->SetResultId(nid); + get_def_use_mgr()->AnalyzeInstDefUse(&*sb_inst); + (*same_blk_post)[rid] = nid; + *iid = nid; + changed = true; + CloneSameBlockOps(&sb_inst, same_blk_post, same_blk_pre, block_ptr); + block_ptr->AddInstruction(std::move(sb_inst)); + } + } else { + // Reset same-block op operand if necessary + if (*iid != map_itr->second) { + *iid = map_itr->second; + changed = true; + } + } + }); + if (changed) get_def_use_mgr()->AnalyzeInstUse(&**inst); +} + +void InstrumentPass::UpdateSucceedingPhis( + std::vector>& new_blocks) { + const auto first_blk = new_blocks.begin(); + const auto last_blk = new_blocks.end() - 1; + const uint32_t first_id = (*first_blk)->id(); + const uint32_t last_id = (*last_blk)->id(); + const BasicBlock& const_last_block = *last_blk->get(); + const_last_block.ForEachSuccessorLabel( + [&first_id, &last_id, this](const uint32_t succ) { + BasicBlock* sbp = this->id2block_[succ]; + sbp->ForEachPhiInst([&first_id, &last_id, this](Instruction* phi) { + bool changed = false; + phi->ForEachInId([&first_id, &last_id, &changed](uint32_t* id) { + if (*id == first_id) { + *id = last_id; + changed = true; + } + }); + if (changed) get_def_use_mgr()->AnalyzeInstUse(phi); + }); + }); +} + +analysis::Integer* InstrumentPass::GetInteger(uint32_t width, bool is_signed) { + analysis::Integer i(width, is_signed); + analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&i); + assert(type && type->AsInteger()); + return type->AsInteger(); +} + +analysis::Struct* InstrumentPass::GetStruct( + const std::vector& fields) { + analysis::Struct s(fields); + analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&s); + assert(type && type->AsStruct()); + return type->AsStruct(); +} + +analysis::RuntimeArray* InstrumentPass::GetRuntimeArray( + const analysis::Type* element) { + analysis::RuntimeArray r(element); + analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&r); + assert(type && type->AsRuntimeArray()); + return type->AsRuntimeArray(); +} + +analysis::Array* InstrumentPass::GetArray(const analysis::Type* element, + uint32_t length) { + uint32_t length_id = context()->get_constant_mgr()->GetUIntConstId(length); + analysis::Array::LengthInfo length_info{ + length_id, {analysis::Array::LengthInfo::Case::kConstant, length}}; + + analysis::Array r(element, length_info); + + analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&r); + assert(type && type->AsArray()); + return type->AsArray(); +} + +analysis::Function* InstrumentPass::GetFunction( + const analysis::Type* return_val, + const std::vector& args) { + analysis::Function func(return_val, args); + analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&func); + assert(type && type->AsFunction()); + return type->AsFunction(); +} + +analysis::RuntimeArray* InstrumentPass::GetUintXRuntimeArrayType( + uint32_t width, analysis::RuntimeArray** rarr_ty) { + if (*rarr_ty == nullptr) { + *rarr_ty = GetRuntimeArray(GetInteger(width, false)); + uint32_t uint_arr_ty_id = + context()->get_type_mgr()->GetTypeInstruction(*rarr_ty); + // By the Vulkan spec, a pre-existing RuntimeArray of uint must be part of + // a block, and will therefore be decorated with an ArrayStride. Therefore + // the undecorated type returned here will not be pre-existing and can + // safely be decorated. Since this type is now decorated, it is out of + // sync with the TypeManager and therefore the TypeManager must be + // invalidated after this pass. + assert(get_def_use_mgr()->NumUses(uint_arr_ty_id) == 0 && + "used RuntimeArray type returned"); + get_decoration_mgr()->AddDecorationVal( + uint_arr_ty_id, uint32_t(spv::Decoration::ArrayStride), width / 8u); + } + return *rarr_ty; +} + +analysis::RuntimeArray* InstrumentPass::GetUintRuntimeArrayType( + uint32_t width) { + analysis::RuntimeArray** rarr_ty = + (width == 64) ? &uint64_rarr_ty_ : &uint32_rarr_ty_; + return GetUintXRuntimeArrayType(width, rarr_ty); +} + +void InstrumentPass::AddStorageBufferExt() { + if (storage_buffer_ext_defined_) return; + if (!get_feature_mgr()->HasExtension(kSPV_KHR_storage_buffer_storage_class)) { + context()->AddExtension("SPV_KHR_storage_buffer_storage_class"); + } + storage_buffer_ext_defined_ = true; +} + +uint32_t InstrumentPass::GetFloatId() { + if (float_id_ == 0) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Float float_ty(32); + analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty); + float_id_ = type_mgr->GetTypeInstruction(reg_float_ty); + } + return float_id_; +} + +uint32_t InstrumentPass::GetVec4FloatId() { + if (v4float_id_ == 0) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Float float_ty(32); + analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty); + analysis::Vector v4float_ty(reg_float_ty, 4); + analysis::Type* reg_v4float_ty = type_mgr->GetRegisteredType(&v4float_ty); + v4float_id_ = type_mgr->GetTypeInstruction(reg_v4float_ty); + } + return v4float_id_; +} + +uint32_t InstrumentPass::GetUintId() { + if (uint_id_ == 0) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Integer uint_ty(32, false); + analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); + uint_id_ = type_mgr->GetTypeInstruction(reg_uint_ty); + } + return uint_id_; +} + +uint32_t InstrumentPass::GetUint64Id() { + if (uint64_id_ == 0) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Integer uint64_ty(64, false); + analysis::Type* reg_uint64_ty = type_mgr->GetRegisteredType(&uint64_ty); + uint64_id_ = type_mgr->GetTypeInstruction(reg_uint64_ty); + } + return uint64_id_; +} + +uint32_t InstrumentPass::GetUint8Id() { + if (uint8_id_ == 0) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Integer uint8_ty(8, false); + analysis::Type* reg_uint8_ty = type_mgr->GetRegisteredType(&uint8_ty); + uint8_id_ = type_mgr->GetTypeInstruction(reg_uint8_ty); + } + return uint8_id_; +} + +uint32_t InstrumentPass::GetVecUintId(uint32_t len) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Integer uint_ty(32, false); + analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); + analysis::Vector v_uint_ty(reg_uint_ty, len); + analysis::Type* reg_v_uint_ty = type_mgr->GetRegisteredType(&v_uint_ty); + uint32_t v_uint_id = type_mgr->GetTypeInstruction(reg_v_uint_ty); + return v_uint_id; +} + +uint32_t InstrumentPass::GetVec4UintId() { + if (v4uint_id_ == 0) v4uint_id_ = GetVecUintId(4u); + return v4uint_id_; +} + +uint32_t InstrumentPass::GetVec3UintId() { + if (v3uint_id_ == 0) v3uint_id_ = GetVecUintId(3u); + return v3uint_id_; +} + +uint32_t InstrumentPass::GetBoolId() { + if (bool_id_ == 0) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Bool bool_ty; + analysis::Type* reg_bool_ty = type_mgr->GetRegisteredType(&bool_ty); + bool_id_ = type_mgr->GetTypeInstruction(reg_bool_ty); + } + return bool_id_; +} + +uint32_t InstrumentPass::GetVoidId() { + if (void_id_ == 0) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Void void_ty; + analysis::Type* reg_void_ty = type_mgr->GetRegisteredType(&void_ty); + void_id_ = type_mgr->GetTypeInstruction(reg_void_ty); + } + return void_id_; +} + +void InstrumentPass::SplitBlock( + BasicBlock::iterator inst_itr, UptrVectorIterator block_itr, + std::vector>* new_blocks) { + // Make sure def/use analysis is done before we start moving instructions + // out of function + (void)get_def_use_mgr(); + // Move original block's preceding instructions into first new block + std::unique_ptr first_blk_ptr; + MovePreludeCode(inst_itr, block_itr, &first_blk_ptr); + InstructionBuilder builder( + context(), &*first_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + uint32_t split_blk_id = TakeNextId(); + std::unique_ptr split_label(NewLabel(split_blk_id)); + (void)builder.AddBranch(split_blk_id); + new_blocks->push_back(std::move(first_blk_ptr)); + // Move remaining instructions into split block and add to new blocks + std::unique_ptr split_blk_ptr( + new BasicBlock(std::move(split_label))); + MovePostludeCode(block_itr, &*split_blk_ptr); + new_blocks->push_back(std::move(split_blk_ptr)); +} + +bool InstrumentPass::InstrumentFunction(Function* func, uint32_t stage_idx, + InstProcessFunction& pfn) { + curr_func_ = func; + call2id_.clear(); + bool first_block_split = false; + bool modified = false; + // Apply instrumentation function to each instruction. + // Using block iterators here because of block erasures and insertions. + std::vector> new_blks; + for (auto bi = func->begin(); bi != func->end(); ++bi) { + for (auto ii = bi->begin(); ii != bi->end();) { + // Split all executable instructions out of first block into a following + // block. This will allow function calls to be inserted into the first + // block without interfering with the instrumentation algorithm. + if (opt_direct_reads_ && !first_block_split) { + if (ii->opcode() != spv::Op::OpVariable) { + SplitBlock(ii, bi, &new_blks); + first_block_split = true; + } + } else { + pfn(ii, bi, stage_idx, &new_blks); + } + // If no new code, continue + if (new_blks.size() == 0) { + ++ii; + continue; + } + // Add new blocks to label id map + for (auto& blk : new_blks) id2block_[blk->id()] = &*blk; + // If there are new blocks we know there will always be two or + // more, so update succeeding phis with label of new last block. + size_t newBlocksSize = new_blks.size(); + assert(newBlocksSize > 1); + UpdateSucceedingPhis(new_blks); + // Replace original block with new block(s) + bi = bi.Erase(); + for (auto& bb : new_blks) { + bb->SetParent(func); + } + bi = bi.InsertBefore(&new_blks); + // Reset block iterator to last new block + for (size_t i = 0; i < newBlocksSize - 1; i++) ++bi; + modified = true; + // Restart instrumenting at beginning of last new block, + // but skip over any new phi or copy instruction. + ii = bi->begin(); + if (ii->opcode() == spv::Op::OpPhi || + ii->opcode() == spv::Op::OpCopyObject) + ++ii; + new_blks.clear(); + } + } + return modified; +} + +bool InstrumentPass::InstProcessCallTreeFromRoots(InstProcessFunction& pfn, + std::queue* roots, + uint32_t stage_idx) { + bool modified = false; + std::unordered_set done; + // Don't process input and output functions + for (auto& ifn : param2input_func_id_) done.insert(ifn.second); + for (auto& ofn : param2output_func_id_) done.insert(ofn.second); + // Process all functions from roots + while (!roots->empty()) { + const uint32_t fi = roots->front(); + roots->pop(); + if (done.insert(fi).second) { + Function* fn = id2function_.at(fi); + // Add calls first so we don't add new output function + context()->AddCalls(fn, roots); + modified = InstrumentFunction(fn, stage_idx, pfn) || modified; + } + } + return modified; +} + +bool InstrumentPass::InstProcessEntryPointCallTree(InstProcessFunction& pfn) { + uint32_t stage_id; + if (use_stage_info_) { + // Make sure all entry points have the same execution model. Do not + // instrument if they do not. + // TODO(greg-lunarg): Handle mixed stages. Technically, a shader module + // can contain entry points with different execution models, although + // such modules will likely be rare as GLSL and HLSL are geared toward + // one model per module. In such cases we will need + // to clone any functions which are in the call trees of entrypoints + // with differing execution models. + spv::ExecutionModel stage = context()->GetStage(); + // Check for supported stages + if (stage != spv::ExecutionModel::Vertex && + stage != spv::ExecutionModel::Fragment && + stage != spv::ExecutionModel::Geometry && + stage != spv::ExecutionModel::GLCompute && + stage != spv::ExecutionModel::TessellationControl && + stage != spv::ExecutionModel::TessellationEvaluation && + stage != spv::ExecutionModel::TaskNV && + stage != spv::ExecutionModel::MeshNV && + stage != spv::ExecutionModel::RayGenerationNV && + stage != spv::ExecutionModel::IntersectionNV && + stage != spv::ExecutionModel::AnyHitNV && + stage != spv::ExecutionModel::ClosestHitNV && + stage != spv::ExecutionModel::MissNV && + stage != spv::ExecutionModel::CallableNV && + stage != spv::ExecutionModel::TaskEXT && + stage != spv::ExecutionModel::MeshEXT) { + if (consumer()) { + std::string message = "Stage not supported by instrumentation"; + consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); + } + return false; + } + stage_id = static_cast(stage); + } else { + stage_id = 0; + } + // Add together the roots of all entry points + std::queue roots; + for (auto& e : get_module()->entry_points()) { + roots.push(e.GetSingleWordInOperand(kEntryPointFunctionIdInIdx)); + } + bool modified = InstProcessCallTreeFromRoots(pfn, &roots, stage_id); + return modified; +} + +void InstrumentPass::InitializeInstrument() { + float_id_ = 0; + v4float_id_ = 0; + uint_id_ = 0; + uint64_id_ = 0; + uint8_id_ = 0; + v4uint_id_ = 0; + v3uint_id_ = 0; + bool_id_ = 0; + void_id_ = 0; + storage_buffer_ext_defined_ = false; + uint32_rarr_ty_ = nullptr; + uint64_rarr_ty_ = nullptr; + + // clear collections + id2function_.clear(); + id2block_.clear(); + + // clear maps + param2input_func_id_.clear(); + param2output_func_id_.clear(); + + // Initialize function and block maps. + for (auto& fn : *get_module()) { + id2function_[fn.result_id()] = &fn; + for (auto& blk : fn) { + id2block_[blk.id()] = &blk; + } + } + + // Remember original instruction offsets + uint32_t module_offset = 0; + Module* module = get_module(); + for (auto& i : context()->capabilities()) { + (void)i; + ++module_offset; + } + for (auto& i : module->extensions()) { + (void)i; + ++module_offset; + } + for (auto& i : module->ext_inst_imports()) { + (void)i; + ++module_offset; + } + ++module_offset; // memory_model + for (auto& i : module->entry_points()) { + (void)i; + ++module_offset; + } + for (auto& i : module->execution_modes()) { + (void)i; + ++module_offset; + } + for (auto& i : module->debugs1()) { + (void)i; + ++module_offset; + } + for (auto& i : module->debugs2()) { + (void)i; + ++module_offset; + } + for (auto& i : module->debugs3()) { + (void)i; + ++module_offset; + } + for (auto& i : module->ext_inst_debuginfo()) { + (void)i; + ++module_offset; + } + for (auto& i : module->annotations()) { + (void)i; + ++module_offset; + } + for (auto& i : module->types_values()) { + module_offset += 1; + module_offset += static_cast(i.dbg_line_insts().size()); + } + + auto curr_fn = get_module()->begin(); + for (; curr_fn != get_module()->end(); ++curr_fn) { + // Count function instruction + module_offset += 1; + curr_fn->ForEachParam( + [&module_offset](const Instruction*) { module_offset += 1; }, true); + for (auto& blk : *curr_fn) { + // Count label + module_offset += 1; + for (auto& inst : blk) { + module_offset += static_cast(inst.dbg_line_insts().size()); + uid2offset_[inst.unique_id()] = module_offset; + module_offset += 1; + } + } + // Count function end instruction + module_offset += 1; + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/instrument_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/instrument_pass.h new file mode 100644 index 000000000000..e4408c93ebf2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/instrument_pass.h @@ -0,0 +1,326 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// Copyright (c) 2018 Valve Corporation +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBSPIRV_OPT_INSTRUMENT_PASS_H_ +#define LIBSPIRV_OPT_INSTRUMENT_PASS_H_ + +#include +#include +#include + +#include "source/opt/ir_builder.h" +#include "source/opt/pass.h" +#include "spirv-tools/instrument.hpp" + +// This is a base class to assist in the creation of passes which instrument +// shader modules. More specifically, passes which replace instructions with a +// larger and more capable set of instructions. Commonly, these new +// instructions will add testing of operands and execute different +// instructions depending on the outcome, including outputting of debug +// information into a buffer created especially for that purpose. +// +// This class contains helper functions to create an InstProcessFunction, +// which is the heart of any derived class implementing a specific +// instrumentation pass. It takes an instruction as an argument, decides +// if it should be instrumented, and generates code to replace it. This class +// also supplies function InstProcessEntryPointCallTree which applies the +// InstProcessFunction to every reachable instruction in a module and replaces +// the instruction with new instructions if generated. +// +// Chief among the helper functions are output code generation functions, +// used to generate code in the shader which writes data to output buffers +// associated with that validation. Currently one such function, +// GenDebugStreamWrite, exists. Other such functions may be added in the +// future. Each is accompanied by documentation describing the format of +// its output buffer. +// +// A validation pass may read or write multiple buffers. All such buffers +// are located in a single debug descriptor set whose index is passed at the +// creation of the instrumentation pass. The bindings of the buffers used by +// a validation pass are permanently assigned and fixed and documented by +// the kDebugOutput* static consts. + +namespace spvtools { +namespace opt { + +class InstrumentPass : public Pass { + using cbb_ptr = const BasicBlock*; + + public: + using InstProcessFunction = + std::function, + uint32_t, std::vector>*)>; + + ~InstrumentPass() override = default; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisDecorations | + IRContext::kAnalysisCombinators | IRContext::kAnalysisNameMap | + IRContext::kAnalysisBuiltinVarId | IRContext::kAnalysisConstants; + } + + protected: + // Create instrumentation pass for |validation_id| which utilizes descriptor + // set |desc_set| for debug input and output buffers and writes |shader_id| + // into debug output records. |opt_direct_reads| indicates that the pass + // will see direct input buffer reads and should prepare to optimize them. + InstrumentPass(uint32_t desc_set, uint32_t shader_id, bool opt_direct_reads, + bool use_stage_info) + : Pass(), + desc_set_(desc_set), + shader_id_(shader_id), + opt_direct_reads_(opt_direct_reads), + use_stage_info_(use_stage_info) {} + + // Initialize state for instrumentation of module. + void InitializeInstrument(); + + // Call |pfn| on all instructions in all functions in the call tree of the + // entry points in |module|. If code is generated for an instruction, replace + // the instruction's block with the new blocks that are generated. Continue + // processing at the top of the last new block. + bool InstProcessEntryPointCallTree(InstProcessFunction& pfn); + + // Move all code in |ref_block_itr| preceding the instruction |ref_inst_itr| + // to be instrumented into block |new_blk_ptr|. + void MovePreludeCode(BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, + std::unique_ptr* new_blk_ptr); + + // Move all code in |ref_block_itr| succeeding the instruction |ref_inst_itr| + // to be instrumented into block |new_blk_ptr|. + void MovePostludeCode(UptrVectorIterator ref_block_itr, + BasicBlock* new_blk_ptr); + + // Return true if all instructions in |ids| are constants or spec constants. + bool AllConstant(const std::vector& ids); + + uint32_t GenReadFunctionCall(uint32_t return_id, uint32_t func_id, + const std::vector& args, + InstructionBuilder* builder); + + // Generate code to convert integer |value_id| to 32bit, if needed. Return + // an id to the 32bit equivalent. + uint32_t Gen32BitCvtCode(uint32_t value_id, InstructionBuilder* builder); + + // Generate code to cast integer |value_id| to 32bit unsigned, if needed. + // Return an id to the Uint equivalent. + uint32_t GenUintCastCode(uint32_t value_id, InstructionBuilder* builder); + + std::unique_ptr StartFunction( + uint32_t func_id, const analysis::Type* return_type, + const std::vector& param_types); + + std::vector AddParameters( + Function& func, const std::vector& param_types); + + std::unique_ptr EndFunction(); + + // Return new label. + std::unique_ptr NewLabel(uint32_t label_id); + + // Set the name function parameter or local variable + std::unique_ptr NewName(uint32_t id, + const std::string& name_str); + + // Return id for 32-bit unsigned type + uint32_t GetUintId(); + + // Return id for 64-bit unsigned type + uint32_t GetUint64Id(); + + // Return id for 8-bit unsigned type + uint32_t GetUint8Id(); + + // Return id for 32-bit unsigned type + uint32_t GetBoolId(); + + // Return id for void type + uint32_t GetVoidId(); + + // Get registered type structures + analysis::Integer* GetInteger(uint32_t width, bool is_signed); + analysis::Struct* GetStruct(const std::vector& fields); + analysis::RuntimeArray* GetRuntimeArray(const analysis::Type* element); + analysis::Array* GetArray(const analysis::Type* element, uint32_t size); + analysis::Function* GetFunction( + const analysis::Type* return_val, + const std::vector& args); + + // Return pointer to type for runtime array of uint + analysis::RuntimeArray* GetUintXRuntimeArrayType( + uint32_t width, analysis::RuntimeArray** rarr_ty); + + // Return pointer to type for runtime array of uint + analysis::RuntimeArray* GetUintRuntimeArrayType(uint32_t width); + + // Add storage buffer extension if needed + void AddStorageBufferExt(); + + // Return id for 32-bit float type + uint32_t GetFloatId(); + + // Return id for v4float type + uint32_t GetVec4FloatId(); + + // Return id for uint vector type of |length| + uint32_t GetVecUintId(uint32_t length); + + // Return id for v4uint type + uint32_t GetVec4UintId(); + + // Return id for v3uint type + uint32_t GetVec3UintId(); + + // Split block |block_itr| into two new blocks where the second block + // contains |inst_itr| and place in |new_blocks|. + void SplitBlock(BasicBlock::iterator inst_itr, + UptrVectorIterator block_itr, + std::vector>* new_blocks); + + // Apply instrumentation function |pfn| to every instruction in |func|. + // If code is generated for an instruction, replace the instruction's + // block with the new blocks that are generated. Continue processing at the + // top of the last new block. + virtual bool InstrumentFunction(Function* func, uint32_t stage_idx, + InstProcessFunction& pfn); + + // Call |pfn| on all functions in the call tree of the function + // ids in |roots|. + bool InstProcessCallTreeFromRoots(InstProcessFunction& pfn, + std::queue* roots, + uint32_t stage_idx); + + // Generate instructions into |builder| which will load |var_id| and return + // its result id. + uint32_t GenVarLoad(uint32_t var_id, InstructionBuilder* builder); + + uint32_t GenStageInfo(uint32_t stage_idx, InstructionBuilder* builder); + + // Return true if instruction must be in the same block that its result + // is used. + bool IsSameBlockOp(const Instruction* inst) const; + + // Clone operands which must be in same block as consumer instructions. + // Look in same_blk_pre for instructions that need cloning. Look in + // same_blk_post for instructions already cloned. Add cloned instruction + // to same_blk_post. + void CloneSameBlockOps( + std::unique_ptr* inst, + std::unordered_map* same_blk_post, + std::unordered_map* same_blk_pre, + BasicBlock* block_ptr); + + // Update phis in succeeding blocks to point to new last block + void UpdateSucceedingPhis( + std::vector>& new_blocks); + + // Debug descriptor set index + uint32_t desc_set_; + + // Shader module ID written into output record + uint32_t shader_id_; + + // Map from function id to function pointer. + std::unordered_map id2function_; + + // Map from block's label id to block. TODO(dnovillo): This is superfluous wrt + // CFG. It has functionality not present in CFG. Consolidate. + std::unordered_map id2block_; + + // Map from instruction's unique id to offset in original file. + std::unordered_map uid2offset_; + + // id for debug output function + std::unordered_map param2output_func_id_; + + // ids for debug input functions + std::unordered_map param2input_func_id_; + + // id for 32-bit float type + uint32_t float_id_{0}; + + // id for v4float type + uint32_t v4float_id_{0}; + + // id for v4uint type + uint32_t v4uint_id_{0}; + + // id for v3uint type + uint32_t v3uint_id_{0}; + + // id for 32-bit unsigned type + uint32_t uint_id_{0}; + + // id for 64-bit unsigned type + uint32_t uint64_id_{0}; + + // id for 8-bit unsigned type + uint32_t uint8_id_{0}; + + // id for bool type + uint32_t bool_id_{0}; + + // id for void type + uint32_t void_id_{0}; + + // boolean to remember storage buffer extension + bool storage_buffer_ext_defined_{false}; + + // runtime array of uint type + analysis::RuntimeArray* uint64_rarr_ty_{nullptr}; + + // runtime array of uint type + analysis::RuntimeArray* uint32_rarr_ty_{nullptr}; + + // Pre-instrumentation same-block insts + std::unordered_map same_block_pre_; + + // Post-instrumentation same-block op ids + std::unordered_map same_block_post_; + + // Map function calls to result id. Clear for every function. + // This is for debug input reads with constant arguments that + // have been generated into the first block of the function. + // This mechanism is used to avoid multiple identical debug + // input buffer reads. + struct vector_hash_ { + std::size_t operator()(const std::vector& v) const { + std::size_t hash = v.size(); + for (auto& u : v) { + hash ^= u + 0x9e3779b9 + (hash << 11) + (hash >> 21); + } + return hash; + } + }; + std::unordered_map, uint32_t, vector_hash_> call2id_; + + // Function currently being instrumented + Function* curr_func_{nullptr}; + + // Optimize direct debug input buffer reads. Specifically, move all such + // reads with constant args to first block and reuse them. + const bool opt_direct_reads_; + + // Set true if the instrumentation needs to know the current stage. + // Note that this does not work with multi-stage modules. + const bool use_stage_info_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // LIBSPIRV_OPT_INSTRUMENT_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/interface_var_sroa.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/interface_var_sroa.cpp new file mode 100644 index 000000000000..08477cbddba0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/interface_var_sroa.cpp @@ -0,0 +1,968 @@ +// Copyright (c) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/interface_var_sroa.h" + +#include + +#include "source/opt/decoration_manager.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/function.h" +#include "source/opt/log.h" +#include "source/opt/type_manager.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kOpDecorateDecorationInOperandIndex = 1; +constexpr uint32_t kOpDecorateLiteralInOperandIndex = 2; +constexpr uint32_t kOpEntryPointInOperandInterface = 3; +constexpr uint32_t kOpVariableStorageClassInOperandIndex = 0; +constexpr uint32_t kOpTypeArrayElemTypeInOperandIndex = 0; +constexpr uint32_t kOpTypeArrayLengthInOperandIndex = 1; +constexpr uint32_t kOpTypeMatrixColCountInOperandIndex = 1; +constexpr uint32_t kOpTypeMatrixColTypeInOperandIndex = 0; +constexpr uint32_t kOpTypePtrTypeInOperandIndex = 1; +constexpr uint32_t kOpConstantValueInOperandIndex = 0; + +// Get the length of the OpTypeArray |array_type|. +uint32_t GetArrayLength(analysis::DefUseManager* def_use_mgr, + Instruction* array_type) { + assert(array_type->opcode() == spv::Op::OpTypeArray); + uint32_t const_int_id = + array_type->GetSingleWordInOperand(kOpTypeArrayLengthInOperandIndex); + Instruction* array_length_inst = def_use_mgr->GetDef(const_int_id); + assert(array_length_inst->opcode() == spv::Op::OpConstant); + return array_length_inst->GetSingleWordInOperand( + kOpConstantValueInOperandIndex); +} + +// Get the element type instruction of the OpTypeArray |array_type|. +Instruction* GetArrayElementType(analysis::DefUseManager* def_use_mgr, + Instruction* array_type) { + assert(array_type->opcode() == spv::Op::OpTypeArray); + uint32_t elem_type_id = + array_type->GetSingleWordInOperand(kOpTypeArrayElemTypeInOperandIndex); + return def_use_mgr->GetDef(elem_type_id); +} + +// Get the column type instruction of the OpTypeMatrix |matrix_type|. +Instruction* GetMatrixColumnType(analysis::DefUseManager* def_use_mgr, + Instruction* matrix_type) { + assert(matrix_type->opcode() == spv::Op::OpTypeMatrix); + uint32_t column_type_id = + matrix_type->GetSingleWordInOperand(kOpTypeMatrixColTypeInOperandIndex); + return def_use_mgr->GetDef(column_type_id); +} + +// Traverses the component type of OpTypeArray or OpTypeMatrix. Repeats it +// |depth_to_component| times recursively and returns the component type. +// |type_id| is the result id of the OpTypeArray or OpTypeMatrix instruction. +uint32_t GetComponentTypeOfArrayMatrix(analysis::DefUseManager* def_use_mgr, + uint32_t type_id, + uint32_t depth_to_component) { + if (depth_to_component == 0) return type_id; + + Instruction* type_inst = def_use_mgr->GetDef(type_id); + if (type_inst->opcode() == spv::Op::OpTypeArray) { + uint32_t elem_type_id = + type_inst->GetSingleWordInOperand(kOpTypeArrayElemTypeInOperandIndex); + return GetComponentTypeOfArrayMatrix(def_use_mgr, elem_type_id, + depth_to_component - 1); + } + + assert(type_inst->opcode() == spv::Op::OpTypeMatrix); + uint32_t column_type_id = + type_inst->GetSingleWordInOperand(kOpTypeMatrixColTypeInOperandIndex); + return GetComponentTypeOfArrayMatrix(def_use_mgr, column_type_id, + depth_to_component - 1); +} + +// Creates an OpDecorate instruction whose Target is |var_id| and Decoration is +// |decoration|. Adds |literal| as an extra operand of the instruction. +void CreateDecoration(analysis::DecorationManager* decoration_mgr, + uint32_t var_id, spv::Decoration decoration, + uint32_t literal) { + std::vector operands({ + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {var_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_DECORATION, + {static_cast(decoration)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {literal}}, + }); + decoration_mgr->AddDecoration(spv::Op::OpDecorate, std::move(operands)); +} + +// Replaces load instructions with composite construct instructions in all the +// users of the loads. |loads_to_composites| is the mapping from each load to +// its corresponding OpCompositeConstruct. +void ReplaceLoadWithCompositeConstruct( + IRContext* context, + const std::unordered_map& loads_to_composites) { + for (const auto& load_and_composite : loads_to_composites) { + Instruction* load = load_and_composite.first; + Instruction* composite_construct = load_and_composite.second; + + std::vector users; + context->get_def_use_mgr()->ForEachUse( + load, [&users, composite_construct](Instruction* user, uint32_t index) { + user->GetOperand(index).words[0] = composite_construct->result_id(); + users.push_back(user); + }); + + for (Instruction* user : users) + context->get_def_use_mgr()->AnalyzeInstUse(user); + } +} + +// Returns the storage class of the instruction |var|. +spv::StorageClass GetStorageClass(Instruction* var) { + return static_cast( + var->GetSingleWordInOperand(kOpVariableStorageClassInOperandIndex)); +} + +} // namespace + +bool InterfaceVariableScalarReplacement::HasExtraArrayness( + Instruction& entry_point, Instruction* var) { + spv::ExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); + if (execution_model != spv::ExecutionModel::TessellationEvaluation && + execution_model != spv::ExecutionModel::TessellationControl) { + return false; + } + if (!context()->get_decoration_mgr()->HasDecoration( + var->result_id(), uint32_t(spv::Decoration::Patch))) { + if (execution_model == spv::ExecutionModel::TessellationControl) + return true; + return GetStorageClass(var) != spv::StorageClass::Output; + } + return false; +} + +bool InterfaceVariableScalarReplacement:: + CheckExtraArraynessConflictBetweenEntries(Instruction* interface_var, + bool has_extra_arrayness) { + if (has_extra_arrayness) { + return !ReportErrorIfHasNoExtraArraynessForOtherEntry(interface_var); + } + return !ReportErrorIfHasExtraArraynessForOtherEntry(interface_var); +} + +bool InterfaceVariableScalarReplacement::GetVariableLocation( + Instruction* var, uint32_t* location) { + return !context()->get_decoration_mgr()->WhileEachDecoration( + var->result_id(), uint32_t(spv::Decoration::Location), + [location](const Instruction& inst) { + *location = + inst.GetSingleWordInOperand(kOpDecorateLiteralInOperandIndex); + return false; + }); +} + +bool InterfaceVariableScalarReplacement::GetVariableComponent( + Instruction* var, uint32_t* component) { + return !context()->get_decoration_mgr()->WhileEachDecoration( + var->result_id(), uint32_t(spv::Decoration::Component), + [component](const Instruction& inst) { + *component = + inst.GetSingleWordInOperand(kOpDecorateLiteralInOperandIndex); + return false; + }); +} + +std::vector +InterfaceVariableScalarReplacement::CollectInterfaceVariables( + Instruction& entry_point) { + std::vector interface_vars; + for (uint32_t i = kOpEntryPointInOperandInterface; + i < entry_point.NumInOperands(); ++i) { + Instruction* interface_var = context()->get_def_use_mgr()->GetDef( + entry_point.GetSingleWordInOperand(i)); + assert(interface_var->opcode() == spv::Op::OpVariable); + + spv::StorageClass storage_class = GetStorageClass(interface_var); + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + continue; + } + + interface_vars.push_back(interface_var); + } + return interface_vars; +} + +void InterfaceVariableScalarReplacement::KillInstructionAndUsers( + Instruction* inst) { + if (inst->opcode() == spv::Op::OpEntryPoint) { + return; + } + if (inst->opcode() != spv::Op::OpAccessChain) { + context()->KillInst(inst); + return; + } + std::vector users; + context()->get_def_use_mgr()->ForEachUser( + inst, [&users](Instruction* user) { users.push_back(user); }); + for (auto user : users) { + context()->KillInst(user); + } + context()->KillInst(inst); +} + +void InterfaceVariableScalarReplacement::KillInstructionsAndUsers( + const std::vector& insts) { + for (Instruction* inst : insts) { + KillInstructionAndUsers(inst); + } +} + +void InterfaceVariableScalarReplacement::KillLocationAndComponentDecorations( + uint32_t var_id) { + context()->get_decoration_mgr()->RemoveDecorationsFrom( + var_id, [](const Instruction& inst) { + spv::Decoration decoration = spv::Decoration( + inst.GetSingleWordInOperand(kOpDecorateDecorationInOperandIndex)); + return decoration == spv::Decoration::Location || + decoration == spv::Decoration::Component; + }); +} + +bool InterfaceVariableScalarReplacement::ReplaceInterfaceVariableWithScalars( + Instruction* interface_var, Instruction* interface_var_type, + uint32_t location, uint32_t component, uint32_t extra_array_length) { + NestedCompositeComponents scalar_interface_vars = + CreateScalarInterfaceVarsForReplacement(interface_var_type, + GetStorageClass(interface_var), + extra_array_length); + + AddLocationAndComponentDecorations(scalar_interface_vars, &location, + component); + KillLocationAndComponentDecorations(interface_var->result_id()); + + if (!ReplaceInterfaceVarWith(interface_var, extra_array_length, + scalar_interface_vars)) { + return false; + } + + context()->KillInst(interface_var); + return true; +} + +bool InterfaceVariableScalarReplacement::ReplaceInterfaceVarWith( + Instruction* interface_var, uint32_t extra_array_length, + const NestedCompositeComponents& scalar_interface_vars) { + std::vector users; + context()->get_def_use_mgr()->ForEachUser( + interface_var, [&users](Instruction* user) { users.push_back(user); }); + + std::vector interface_var_component_indices; + std::unordered_map loads_to_composites; + std::unordered_map + loads_for_access_chain_to_composites; + if (extra_array_length != 0) { + // Note that the extra arrayness is the first dimension of the array + // interface variable. + for (uint32_t index = 0; index < extra_array_length; ++index) { + std::unordered_map loads_to_component_values; + if (!ReplaceComponentsOfInterfaceVarWith( + interface_var, users, scalar_interface_vars, + interface_var_component_indices, &index, + &loads_to_component_values, + &loads_for_access_chain_to_composites)) { + return false; + } + AddComponentsToCompositesForLoads(loads_to_component_values, + &loads_to_composites, 0); + } + } else if (!ReplaceComponentsOfInterfaceVarWith( + interface_var, users, scalar_interface_vars, + interface_var_component_indices, nullptr, &loads_to_composites, + &loads_for_access_chain_to_composites)) { + return false; + } + + ReplaceLoadWithCompositeConstruct(context(), loads_to_composites); + ReplaceLoadWithCompositeConstruct(context(), + loads_for_access_chain_to_composites); + + KillInstructionsAndUsers(users); + return true; +} + +void InterfaceVariableScalarReplacement::AddLocationAndComponentDecorations( + const NestedCompositeComponents& vars, uint32_t* location, + uint32_t component) { + if (!vars.HasMultipleComponents()) { + uint32_t var_id = vars.GetComponentVariable()->result_id(); + CreateDecoration(context()->get_decoration_mgr(), var_id, + spv::Decoration::Location, *location); + CreateDecoration(context()->get_decoration_mgr(), var_id, + spv::Decoration::Component, component); + ++(*location); + return; + } + for (const auto& var : vars.GetComponents()) { + AddLocationAndComponentDecorations(var, location, component); + } +} + +bool InterfaceVariableScalarReplacement::ReplaceComponentsOfInterfaceVarWith( + Instruction* interface_var, + const std::vector& interface_var_users, + const NestedCompositeComponents& scalar_interface_vars, + std::vector& interface_var_component_indices, + const uint32_t* extra_array_index, + std::unordered_map* loads_to_composites, + std::unordered_map* + loads_for_access_chain_to_composites) { + if (!scalar_interface_vars.HasMultipleComponents()) { + for (Instruction* interface_var_user : interface_var_users) { + if (!ReplaceComponentOfInterfaceVarWith( + interface_var, interface_var_user, + scalar_interface_vars.GetComponentVariable(), + interface_var_component_indices, extra_array_index, + loads_to_composites, loads_for_access_chain_to_composites)) { + return false; + } + } + return true; + } + return ReplaceMultipleComponentsOfInterfaceVarWith( + interface_var, interface_var_users, scalar_interface_vars.GetComponents(), + interface_var_component_indices, extra_array_index, loads_to_composites, + loads_for_access_chain_to_composites); +} + +bool InterfaceVariableScalarReplacement:: + ReplaceMultipleComponentsOfInterfaceVarWith( + Instruction* interface_var, + const std::vector& interface_var_users, + const std::vector& components, + std::vector& interface_var_component_indices, + const uint32_t* extra_array_index, + std::unordered_map* loads_to_composites, + std::unordered_map* + loads_for_access_chain_to_composites) { + for (uint32_t i = 0; i < components.size(); ++i) { + interface_var_component_indices.push_back(i); + std::unordered_map loads_to_component_values; + std::unordered_map + loads_for_access_chain_to_component_values; + if (!ReplaceComponentsOfInterfaceVarWith( + interface_var, interface_var_users, components[i], + interface_var_component_indices, extra_array_index, + &loads_to_component_values, + &loads_for_access_chain_to_component_values)) { + return false; + } + interface_var_component_indices.pop_back(); + + uint32_t depth_to_component = + static_cast(interface_var_component_indices.size()); + AddComponentsToCompositesForLoads( + loads_for_access_chain_to_component_values, + loads_for_access_chain_to_composites, depth_to_component); + if (extra_array_index) ++depth_to_component; + AddComponentsToCompositesForLoads(loads_to_component_values, + loads_to_composites, depth_to_component); + } + return true; +} + +bool InterfaceVariableScalarReplacement::ReplaceComponentOfInterfaceVarWith( + Instruction* interface_var, Instruction* interface_var_user, + Instruction* scalar_var, + const std::vector& interface_var_component_indices, + const uint32_t* extra_array_index, + std::unordered_map* loads_to_component_values, + std::unordered_map* + loads_for_access_chain_to_component_values) { + spv::Op opcode = interface_var_user->opcode(); + if (opcode == spv::Op::OpStore) { + uint32_t value_id = interface_var_user->GetSingleWordInOperand(1); + StoreComponentOfValueToScalarVar(value_id, interface_var_component_indices, + scalar_var, extra_array_index, + interface_var_user); + return true; + } + if (opcode == spv::Op::OpLoad) { + Instruction* scalar_load = + LoadScalarVar(scalar_var, extra_array_index, interface_var_user); + loads_to_component_values->insert({interface_var_user, scalar_load}); + return true; + } + + // Copy OpName and annotation instructions only once. Therefore, we create + // them only for the first element of the extra array. + if (extra_array_index && *extra_array_index != 0) return true; + + if (opcode == spv::Op::OpDecorateId || opcode == spv::Op::OpDecorateString || + opcode == spv::Op::OpDecorate) { + CloneAnnotationForVariable(interface_var_user, scalar_var->result_id()); + return true; + } + + if (opcode == spv::Op::OpName) { + std::unique_ptr new_inst(interface_var_user->Clone(context())); + new_inst->SetInOperand(0, {scalar_var->result_id()}); + context()->AddDebug2Inst(std::move(new_inst)); + return true; + } + + if (opcode == spv::Op::OpEntryPoint) { + return ReplaceInterfaceVarInEntryPoint(interface_var, interface_var_user, + scalar_var->result_id()); + } + + if (opcode == spv::Op::OpAccessChain) { + ReplaceAccessChainWith(interface_var_user, interface_var_component_indices, + scalar_var, + loads_for_access_chain_to_component_values); + return true; + } + + std::string message("Unhandled instruction"); + message += "\n " + interface_var_user->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + message += + "\nfor interface variable scalar replacement\n " + + interface_var->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + context()->consumer()(SPV_MSG_ERROR, "", {0, 0, 0}, message.c_str()); + return false; +} + +void InterfaceVariableScalarReplacement::UseBaseAccessChainForAccessChain( + Instruction* access_chain, Instruction* base_access_chain) { + assert(base_access_chain->opcode() == spv::Op::OpAccessChain && + access_chain->opcode() == spv::Op::OpAccessChain && + access_chain->GetSingleWordInOperand(0) == + base_access_chain->result_id()); + Instruction::OperandList new_operands; + for (uint32_t i = 0; i < base_access_chain->NumInOperands(); ++i) { + new_operands.emplace_back(base_access_chain->GetInOperand(i)); + } + for (uint32_t i = 1; i < access_chain->NumInOperands(); ++i) { + new_operands.emplace_back(access_chain->GetInOperand(i)); + } + access_chain->SetInOperands(std::move(new_operands)); +} + +Instruction* InterfaceVariableScalarReplacement::CreateAccessChainToVar( + uint32_t var_type_id, Instruction* var, + const std::vector& index_ids, Instruction* insert_before, + uint32_t* component_type_id) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + *component_type_id = GetComponentTypeOfArrayMatrix( + def_use_mgr, var_type_id, static_cast(index_ids.size())); + + uint32_t ptr_type_id = + GetPointerType(*component_type_id, GetStorageClass(var)); + + std::unique_ptr new_access_chain(new Instruction( + context(), spv::Op::OpAccessChain, ptr_type_id, TakeNextId(), + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); + for (uint32_t index_id : index_ids) { + new_access_chain->AddOperand({SPV_OPERAND_TYPE_ID, {index_id}}); + } + + Instruction* inst = new_access_chain.get(); + def_use_mgr->AnalyzeInstDefUse(inst); + insert_before->InsertBefore(std::move(new_access_chain)); + return inst; +} + +Instruction* InterfaceVariableScalarReplacement::CreateAccessChainWithIndex( + uint32_t component_type_id, Instruction* var, uint32_t index, + Instruction* insert_before) { + uint32_t ptr_type_id = + GetPointerType(component_type_id, GetStorageClass(var)); + uint32_t index_id = context()->get_constant_mgr()->GetUIntConstId(index); + std::unique_ptr new_access_chain(new Instruction( + context(), spv::Op::OpAccessChain, ptr_type_id, TakeNextId(), + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}, + {SPV_OPERAND_TYPE_ID, {index_id}}, + })); + Instruction* inst = new_access_chain.get(); + context()->get_def_use_mgr()->AnalyzeInstDefUse(inst); + insert_before->InsertBefore(std::move(new_access_chain)); + return inst; +} + +void InterfaceVariableScalarReplacement::ReplaceAccessChainWith( + Instruction* access_chain, + const std::vector& interface_var_component_indices, + Instruction* scalar_var, + std::unordered_map* loads_to_component_values) { + std::vector indexes; + for (uint32_t i = 1; i < access_chain->NumInOperands(); ++i) { + indexes.push_back(access_chain->GetSingleWordInOperand(i)); + } + + // Note that we have a strong assumption that |access_chain| has only a single + // index that is for the extra arrayness. + context()->get_def_use_mgr()->ForEachUser( + access_chain, + [this, access_chain, &indexes, &interface_var_component_indices, + scalar_var, loads_to_component_values](Instruction* user) { + switch (user->opcode()) { + case spv::Op::OpAccessChain: { + UseBaseAccessChainForAccessChain(user, access_chain); + ReplaceAccessChainWith(user, interface_var_component_indices, + scalar_var, loads_to_component_values); + return; + } + case spv::Op::OpStore: { + uint32_t value_id = user->GetSingleWordInOperand(1); + StoreComponentOfValueToAccessChainToScalarVar( + value_id, interface_var_component_indices, scalar_var, indexes, + user); + return; + } + case spv::Op::OpLoad: { + Instruction* value = + LoadAccessChainToVar(scalar_var, indexes, user); + loads_to_component_values->insert({user, value}); + return; + } + default: + break; + } + }); +} + +void InterfaceVariableScalarReplacement::CloneAnnotationForVariable( + Instruction* annotation_inst, uint32_t var_id) { + assert(annotation_inst->opcode() == spv::Op::OpDecorate || + annotation_inst->opcode() == spv::Op::OpDecorateId || + annotation_inst->opcode() == spv::Op::OpDecorateString); + std::unique_ptr new_inst(annotation_inst->Clone(context())); + new_inst->SetInOperand(0, {var_id}); + context()->AddAnnotationInst(std::move(new_inst)); +} + +bool InterfaceVariableScalarReplacement::ReplaceInterfaceVarInEntryPoint( + Instruction* interface_var, Instruction* entry_point, + uint32_t scalar_var_id) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + uint32_t interface_var_id = interface_var->result_id(); + if (interface_vars_removed_from_entry_point_operands_.find( + interface_var_id) != + interface_vars_removed_from_entry_point_operands_.end()) { + entry_point->AddOperand({SPV_OPERAND_TYPE_ID, {scalar_var_id}}); + def_use_mgr->AnalyzeInstUse(entry_point); + return true; + } + + bool success = !entry_point->WhileEachInId( + [&interface_var_id, &scalar_var_id](uint32_t* id) { + if (*id == interface_var_id) { + *id = scalar_var_id; + return false; + } + return true; + }); + if (!success) { + std::string message( + "interface variable is not an operand of the entry point"); + message += "\n " + interface_var->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + message += "\n " + entry_point->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + context()->consumer()(SPV_MSG_ERROR, "", {0, 0, 0}, message.c_str()); + return false; + } + + def_use_mgr->AnalyzeInstUse(entry_point); + interface_vars_removed_from_entry_point_operands_.insert(interface_var_id); + return true; +} + +uint32_t InterfaceVariableScalarReplacement::GetPointeeTypeIdOfVar( + Instruction* var) { + assert(var->opcode() == spv::Op::OpVariable); + + uint32_t ptr_type_id = var->type_id(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + Instruction* ptr_type_inst = def_use_mgr->GetDef(ptr_type_id); + + assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && + "Variable must have a pointer type."); + return ptr_type_inst->GetSingleWordInOperand(kOpTypePtrTypeInOperandIndex); +} + +void InterfaceVariableScalarReplacement::StoreComponentOfValueToScalarVar( + uint32_t value_id, const std::vector& component_indices, + Instruction* scalar_var, const uint32_t* extra_array_index, + Instruction* insert_before) { + uint32_t component_type_id = GetPointeeTypeIdOfVar(scalar_var); + Instruction* ptr = scalar_var; + if (extra_array_index) { + auto* ty_mgr = context()->get_type_mgr(); + analysis::Array* array_type = ty_mgr->GetType(component_type_id)->AsArray(); + assert(array_type != nullptr); + component_type_id = ty_mgr->GetTypeInstruction(array_type->element_type()); + ptr = CreateAccessChainWithIndex(component_type_id, scalar_var, + *extra_array_index, insert_before); + } + + StoreComponentOfValueTo(component_type_id, value_id, component_indices, ptr, + extra_array_index, insert_before); +} + +Instruction* InterfaceVariableScalarReplacement::LoadScalarVar( + Instruction* scalar_var, const uint32_t* extra_array_index, + Instruction* insert_before) { + uint32_t component_type_id = GetPointeeTypeIdOfVar(scalar_var); + Instruction* ptr = scalar_var; + if (extra_array_index) { + auto* ty_mgr = context()->get_type_mgr(); + analysis::Array* array_type = ty_mgr->GetType(component_type_id)->AsArray(); + assert(array_type != nullptr); + component_type_id = ty_mgr->GetTypeInstruction(array_type->element_type()); + ptr = CreateAccessChainWithIndex(component_type_id, scalar_var, + *extra_array_index, insert_before); + } + + return CreateLoad(component_type_id, ptr, insert_before); +} + +Instruction* InterfaceVariableScalarReplacement::CreateLoad( + uint32_t type_id, Instruction* ptr, Instruction* insert_before) { + std::unique_ptr load( + new Instruction(context(), spv::Op::OpLoad, type_id, TakeNextId(), + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {ptr->result_id()}}})); + Instruction* load_inst = load.get(); + context()->get_def_use_mgr()->AnalyzeInstDefUse(load_inst); + insert_before->InsertBefore(std::move(load)); + return load_inst; +} + +void InterfaceVariableScalarReplacement::StoreComponentOfValueTo( + uint32_t component_type_id, uint32_t value_id, + const std::vector& component_indices, Instruction* ptr, + const uint32_t* extra_array_index, Instruction* insert_before) { + std::unique_ptr composite_extract(CreateCompositeExtract( + component_type_id, value_id, component_indices, extra_array_index)); + + std::unique_ptr new_store( + new Instruction(context(), spv::Op::OpStore)); + new_store->AddOperand({SPV_OPERAND_TYPE_ID, {ptr->result_id()}}); + new_store->AddOperand( + {SPV_OPERAND_TYPE_ID, {composite_extract->result_id()}}); + + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + def_use_mgr->AnalyzeInstDefUse(composite_extract.get()); + def_use_mgr->AnalyzeInstDefUse(new_store.get()); + + insert_before->InsertBefore(std::move(composite_extract)); + insert_before->InsertBefore(std::move(new_store)); +} + +Instruction* InterfaceVariableScalarReplacement::CreateCompositeExtract( + uint32_t type_id, uint32_t composite_id, + const std::vector& indexes, const uint32_t* extra_first_index) { + uint32_t component_id = TakeNextId(); + Instruction* composite_extract = new Instruction( + context(), spv::Op::OpCompositeExtract, type_id, component_id, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {composite_id}}}); + if (extra_first_index) { + composite_extract->AddOperand( + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {*extra_first_index}}); + } + for (uint32_t index : indexes) { + composite_extract->AddOperand({SPV_OPERAND_TYPE_LITERAL_INTEGER, {index}}); + } + return composite_extract; +} + +void InterfaceVariableScalarReplacement:: + StoreComponentOfValueToAccessChainToScalarVar( + uint32_t value_id, const std::vector& component_indices, + Instruction* scalar_var, + const std::vector& access_chain_indices, + Instruction* insert_before) { + uint32_t component_type_id = GetPointeeTypeIdOfVar(scalar_var); + Instruction* ptr = scalar_var; + if (!access_chain_indices.empty()) { + ptr = CreateAccessChainToVar(component_type_id, scalar_var, + access_chain_indices, insert_before, + &component_type_id); + } + + StoreComponentOfValueTo(component_type_id, value_id, component_indices, ptr, + nullptr, insert_before); +} + +Instruction* InterfaceVariableScalarReplacement::LoadAccessChainToVar( + Instruction* var, const std::vector& indexes, + Instruction* insert_before) { + uint32_t component_type_id = GetPointeeTypeIdOfVar(var); + Instruction* ptr = var; + if (!indexes.empty()) { + ptr = CreateAccessChainToVar(component_type_id, var, indexes, insert_before, + &component_type_id); + } + + return CreateLoad(component_type_id, ptr, insert_before); +} + +Instruction* +InterfaceVariableScalarReplacement::CreateCompositeConstructForComponentOfLoad( + Instruction* load, uint32_t depth_to_component) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + uint32_t type_id = load->type_id(); + if (depth_to_component != 0) { + type_id = GetComponentTypeOfArrayMatrix(def_use_mgr, load->type_id(), + depth_to_component); + } + uint32_t new_id = context()->TakeNextId(); + std::unique_ptr new_composite_construct(new Instruction( + context(), spv::Op::OpCompositeConstruct, type_id, new_id, {})); + Instruction* composite_construct = new_composite_construct.get(); + def_use_mgr->AnalyzeInstDefUse(composite_construct); + + // Insert |new_composite_construct| after |load|. When there are multiple + // recursive composite construct instructions for a load, we have to place the + // composite construct with a lower depth later because it constructs the + // composite that contains other composites with lower depths. + auto* insert_before = load->NextNode(); + while (true) { + auto itr = + composite_ids_to_component_depths.find(insert_before->result_id()); + if (itr == composite_ids_to_component_depths.end()) break; + if (itr->second <= depth_to_component) break; + insert_before = insert_before->NextNode(); + } + insert_before->InsertBefore(std::move(new_composite_construct)); + composite_ids_to_component_depths.insert({new_id, depth_to_component}); + return composite_construct; +} + +void InterfaceVariableScalarReplacement::AddComponentsToCompositesForLoads( + const std::unordered_map& + loads_to_component_values, + std::unordered_map* loads_to_composites, + uint32_t depth_to_component) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + for (auto& load_and_component_vale : loads_to_component_values) { + Instruction* load = load_and_component_vale.first; + Instruction* component_value = load_and_component_vale.second; + Instruction* composite_construct = nullptr; + auto itr = loads_to_composites->find(load); + if (itr == loads_to_composites->end()) { + composite_construct = + CreateCompositeConstructForComponentOfLoad(load, depth_to_component); + loads_to_composites->insert({load, composite_construct}); + } else { + composite_construct = itr->second; + } + composite_construct->AddOperand( + {SPV_OPERAND_TYPE_ID, {component_value->result_id()}}); + def_use_mgr->AnalyzeInstDefUse(composite_construct); + } +} + +uint32_t InterfaceVariableScalarReplacement::GetArrayType( + uint32_t elem_type_id, uint32_t array_length) { + analysis::Type* elem_type = context()->get_type_mgr()->GetType(elem_type_id); + uint32_t array_length_id = + context()->get_constant_mgr()->GetUIntConstId(array_length); + analysis::Array array_type( + elem_type, + analysis::Array::LengthInfo{array_length_id, {0, array_length}}); + return context()->get_type_mgr()->GetTypeInstruction(&array_type); +} + +uint32_t InterfaceVariableScalarReplacement::GetPointerType( + uint32_t type_id, spv::StorageClass storage_class) { + analysis::Type* type = context()->get_type_mgr()->GetType(type_id); + analysis::Pointer ptr_type(type, storage_class); + return context()->get_type_mgr()->GetTypeInstruction(&ptr_type); +} + +InterfaceVariableScalarReplacement::NestedCompositeComponents +InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForArray( + Instruction* interface_var_type, spv::StorageClass storage_class, + uint32_t extra_array_length) { + assert(interface_var_type->opcode() == spv::Op::OpTypeArray); + + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + uint32_t array_length = GetArrayLength(def_use_mgr, interface_var_type); + Instruction* elem_type = GetArrayElementType(def_use_mgr, interface_var_type); + + NestedCompositeComponents scalar_vars; + while (array_length > 0) { + NestedCompositeComponents scalar_vars_for_element = + CreateScalarInterfaceVarsForReplacement(elem_type, storage_class, + extra_array_length); + scalar_vars.AddComponent(scalar_vars_for_element); + --array_length; + } + return scalar_vars; +} + +InterfaceVariableScalarReplacement::NestedCompositeComponents +InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForMatrix( + Instruction* interface_var_type, spv::StorageClass storage_class, + uint32_t extra_array_length) { + assert(interface_var_type->opcode() == spv::Op::OpTypeMatrix); + + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + uint32_t column_count = interface_var_type->GetSingleWordInOperand( + kOpTypeMatrixColCountInOperandIndex); + Instruction* column_type = + GetMatrixColumnType(def_use_mgr, interface_var_type); + + NestedCompositeComponents scalar_vars; + while (column_count > 0) { + NestedCompositeComponents scalar_vars_for_column = + CreateScalarInterfaceVarsForReplacement(column_type, storage_class, + extra_array_length); + scalar_vars.AddComponent(scalar_vars_for_column); + --column_count; + } + return scalar_vars; +} + +InterfaceVariableScalarReplacement::NestedCompositeComponents +InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForReplacement( + Instruction* interface_var_type, spv::StorageClass storage_class, + uint32_t extra_array_length) { + // Handle array case. + if (interface_var_type->opcode() == spv::Op::OpTypeArray) { + return CreateScalarInterfaceVarsForArray(interface_var_type, storage_class, + extra_array_length); + } + + // Handle matrix case. + if (interface_var_type->opcode() == spv::Op::OpTypeMatrix) { + return CreateScalarInterfaceVarsForMatrix(interface_var_type, storage_class, + extra_array_length); + } + + // Handle scalar or vector case. + NestedCompositeComponents scalar_var; + uint32_t type_id = interface_var_type->result_id(); + if (extra_array_length != 0) { + type_id = GetArrayType(type_id, extra_array_length); + } + uint32_t ptr_type_id = + context()->get_type_mgr()->FindPointerToType(type_id, storage_class); + uint32_t id = TakeNextId(); + std::unique_ptr variable( + new Instruction(context(), spv::Op::OpVariable, ptr_type_id, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, + {static_cast(storage_class)}}})); + scalar_var.SetSingleComponentVariable(variable.get()); + context()->AddGlobalValue(std::move(variable)); + return scalar_var; +} + +Instruction* InterfaceVariableScalarReplacement::GetTypeOfVariable( + Instruction* var) { + uint32_t pointee_type_id = GetPointeeTypeIdOfVar(var); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + return def_use_mgr->GetDef(pointee_type_id); +} + +Pass::Status InterfaceVariableScalarReplacement::Process() { + Pass::Status status = Status::SuccessWithoutChange; + for (Instruction& entry_point : get_module()->entry_points()) { + status = + CombineStatus(status, ReplaceInterfaceVarsWithScalars(entry_point)); + } + return status; +} + +bool InterfaceVariableScalarReplacement:: + ReportErrorIfHasExtraArraynessForOtherEntry(Instruction* var) { + if (vars_with_extra_arrayness.find(var) == vars_with_extra_arrayness.end()) + return false; + + std::string message( + "A variable is arrayed for an entry point but it is not " + "arrayed for another entry point"); + message += + "\n " + var->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + context()->consumer()(SPV_MSG_ERROR, "", {0, 0, 0}, message.c_str()); + return true; +} + +bool InterfaceVariableScalarReplacement:: + ReportErrorIfHasNoExtraArraynessForOtherEntry(Instruction* var) { + if (vars_without_extra_arrayness.find(var) == + vars_without_extra_arrayness.end()) + return false; + + std::string message( + "A variable is not arrayed for an entry point but it is " + "arrayed for another entry point"); + message += + "\n " + var->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + context()->consumer()(SPV_MSG_ERROR, "", {0, 0, 0}, message.c_str()); + return true; +} + +Pass::Status +InterfaceVariableScalarReplacement::ReplaceInterfaceVarsWithScalars( + Instruction& entry_point) { + std::vector interface_vars = + CollectInterfaceVariables(entry_point); + + Pass::Status status = Status::SuccessWithoutChange; + for (Instruction* interface_var : interface_vars) { + uint32_t location, component; + if (!GetVariableLocation(interface_var, &location)) continue; + if (!GetVariableComponent(interface_var, &component)) component = 0; + + Instruction* interface_var_type = GetTypeOfVariable(interface_var); + uint32_t extra_array_length = 0; + if (HasExtraArrayness(entry_point, interface_var)) { + extra_array_length = + GetArrayLength(context()->get_def_use_mgr(), interface_var_type); + interface_var_type = + GetArrayElementType(context()->get_def_use_mgr(), interface_var_type); + vars_with_extra_arrayness.insert(interface_var); + } else { + vars_without_extra_arrayness.insert(interface_var); + } + + if (!CheckExtraArraynessConflictBetweenEntries(interface_var, + extra_array_length != 0)) { + return Pass::Status::Failure; + } + + if (interface_var_type->opcode() != spv::Op::OpTypeArray && + interface_var_type->opcode() != spv::Op::OpTypeMatrix) { + continue; + } + + if (!ReplaceInterfaceVariableWithScalars(interface_var, interface_var_type, + location, component, + extra_array_length)) { + return Pass::Status::Failure; + } + status = Pass::Status::SuccessWithChange; + } + + return status; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/interface_var_sroa.h b/thirdparty/glslang/External/spirv-tools/source/opt/interface_var_sroa.h new file mode 100644 index 000000000000..45ed3717ad8d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/interface_var_sroa.h @@ -0,0 +1,397 @@ +// Copyright (c) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_INTERFACE_VAR_SROA_H_ +#define SOURCE_OPT_INTERFACE_VAR_SROA_H_ + +#include + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +// +// Note that the current implementation of this pass covers only store, load, +// access chain instructions for the interface variables. Supporting other types +// of instructions is a future work. +class InterfaceVariableScalarReplacement : public Pass { + public: + InterfaceVariableScalarReplacement() {} + + const char* name() const override { + return "interface-variable-scalar-replacement"; + } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDecorations | IRContext::kAnalysisDefUse | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // A struct containing components of a composite variable. If the composite + // consists of multiple or recursive components, |component_variable| is + // nullptr and |nested_composite_components| keeps the components. If it has a + // single component, |nested_composite_components| is empty and + // |component_variable| is the component. Note that each element of + // |nested_composite_components| has the NestedCompositeComponents struct as + // its type that can recursively keep the components. + struct NestedCompositeComponents { + NestedCompositeComponents() : component_variable(nullptr) {} + + bool HasMultipleComponents() const { + return !nested_composite_components.empty(); + } + + const std::vector& GetComponents() const { + return nested_composite_components; + } + + void AddComponent(const NestedCompositeComponents& component) { + nested_composite_components.push_back(component); + } + + Instruction* GetComponentVariable() const { return component_variable; } + + void SetSingleComponentVariable(Instruction* var) { + component_variable = var; + } + + private: + std::vector nested_composite_components; + Instruction* component_variable; + }; + + // Collects all interface variables used by the |entry_point|. + std::vector CollectInterfaceVariables(Instruction& entry_point); + + // Returns whether |var| has the extra arrayness for the entry point + // |entry_point| or not. + bool HasExtraArrayness(Instruction& entry_point, Instruction* var); + + // Finds a Location BuiltIn decoration of |var| and returns it via + // |location|. Returns true whether the location exists or not. + bool GetVariableLocation(Instruction* var, uint32_t* location); + + // Finds a Component BuiltIn decoration of |var| and returns it via + // |component|. Returns true whether the component exists or not. + bool GetVariableComponent(Instruction* var, uint32_t* component); + + // Returns the type of |var| as an instruction. + Instruction* GetTypeOfVariable(Instruction* var); + + // Replaces an interface variable |interface_var| whose type is + // |interface_var_type| with scalars and returns whether it succeeds or not. + // |location| is the value of Location Decoration for |interface_var|. + // |component| is the value of Component Decoration for |interface_var|. + // If |extra_array_length| is 0, it means |interface_var| has a Patch + // decoration. Otherwise, |extra_array_length| denotes the length of the extra + // array of |interface_var|. + bool ReplaceInterfaceVariableWithScalars(Instruction* interface_var, + Instruction* interface_var_type, + uint32_t location, + uint32_t component, + uint32_t extra_array_length); + + // Creates scalar variables with the storage classe |storage_class| to replace + // an interface variable whose type is |interface_var_type|. If + // |extra_array_length| is not zero, adds the extra arrayness to the created + // scalar variables. + NestedCompositeComponents CreateScalarInterfaceVarsForReplacement( + Instruction* interface_var_type, spv::StorageClass storage_class, + uint32_t extra_array_length); + + // Creates scalar variables with the storage classe |storage_class| to replace + // the interface variable whose type is OpTypeArray |interface_var_type| with. + // If |extra_array_length| is not zero, adds the extra arrayness to all the + // scalar variables. + NestedCompositeComponents CreateScalarInterfaceVarsForArray( + Instruction* interface_var_type, spv::StorageClass storage_class, + uint32_t extra_array_length); + + // Creates scalar variables with the storage classe |storage_class| to replace + // the interface variable whose type is OpTypeMatrix |interface_var_type| + // with. If |extra_array_length| is not zero, adds the extra arrayness to all + // the scalar variables. + NestedCompositeComponents CreateScalarInterfaceVarsForMatrix( + Instruction* interface_var_type, spv::StorageClass storage_class, + uint32_t extra_array_length); + + // Recursively adds Location and Component decorations to variables in + // |vars| with |location| and |component|. Increases |location| by one after + // it actually adds Location and Component decorations for a variable. + void AddLocationAndComponentDecorations(const NestedCompositeComponents& vars, + uint32_t* location, + uint32_t component); + + // Replaces the interface variable |interface_var| with + // |scalar_interface_vars| and returns whether it succeeds or not. + // |extra_arrayness| is the extra arrayness of the interface variable. + // |scalar_interface_vars| contains the nested variables to replace the + // interface variable with. + bool ReplaceInterfaceVarWith( + Instruction* interface_var, uint32_t extra_arrayness, + const NestedCompositeComponents& scalar_interface_vars); + + // Replaces |interface_var| in the operands of instructions + // |interface_var_users| with |scalar_interface_vars|. This is a recursive + // method and |interface_var_component_indices| is used to specify which + // recursive component of |interface_var| is replaced. Returns composite + // construct instructions to be replaced with load instructions of + // |interface_var_users| via |loads_to_composites|. Returns composite + // construct instructions to be replaced with load instructions of access + // chain instructions in |interface_var_users| via + // |loads_for_access_chain_to_composites|. + bool ReplaceComponentsOfInterfaceVarWith( + Instruction* interface_var, + const std::vector& interface_var_users, + const NestedCompositeComponents& scalar_interface_vars, + std::vector& interface_var_component_indices, + const uint32_t* extra_array_index, + std::unordered_map* loads_to_composites, + std::unordered_map* + loads_for_access_chain_to_composites); + + // Replaces |interface_var| in the operands of instructions + // |interface_var_users| with |components| that is a vector of components for + // the interface variable |interface_var|. This is a recursive method and + // |interface_var_component_indices| is used to specify which recursive + // component of |interface_var| is replaced. Returns composite construct + // instructions to be replaced with load instructions of |interface_var_users| + // via |loads_to_composites|. Returns composite construct instructions to be + // replaced with load instructions of access chain instructions in + // |interface_var_users| via |loads_for_access_chain_to_composites|. + bool ReplaceMultipleComponentsOfInterfaceVarWith( + Instruction* interface_var, + const std::vector& interface_var_users, + const std::vector& components, + std::vector& interface_var_component_indices, + const uint32_t* extra_array_index, + std::unordered_map* loads_to_composites, + std::unordered_map* + loads_for_access_chain_to_composites); + + // Replaces a component of |interface_var| that is used as an operand of + // instruction |interface_var_user| with |scalar_var|. + // |interface_var_component_indices| is a vector of recursive indices for + // which recursive component of |interface_var| is replaced. If + // |interface_var_user| is a load, returns the component value via + // |loads_to_component_values|. If |interface_var_user| is an access chain, + // returns the component value for loads of |interface_var_user| via + // |loads_for_access_chain_to_component_values|. + bool ReplaceComponentOfInterfaceVarWith( + Instruction* interface_var, Instruction* interface_var_user, + Instruction* scalar_var, + const std::vector& interface_var_component_indices, + const uint32_t* extra_array_index, + std::unordered_map* loads_to_component_values, + std::unordered_map* + loads_for_access_chain_to_component_values); + + // Creates instructions to load |scalar_var| and inserts them before + // |insert_before|. If |extra_array_index| is not null, they load + // |extra_array_index| th component of |scalar_var| instead of |scalar_var| + // itself. + Instruction* LoadScalarVar(Instruction* scalar_var, + const uint32_t* extra_array_index, + Instruction* insert_before); + + // Creates instructions to load an access chain to |var| and inserts them + // before |insert_before|. |Indexes| will be Indexes operand of the access + // chain. + Instruction* LoadAccessChainToVar(Instruction* var, + const std::vector& indexes, + Instruction* insert_before); + + // Creates instructions to store a component of an aggregate whose id is + // |value_id| to an access chain to |scalar_var| and inserts the created + // instructions before |insert_before|. To get the component, recursively + // traverses the aggregate with |component_indices| as indexes. + // Numbers in |access_chain_indices| are the Indexes operand of the access + // chain to |scalar_var| + void StoreComponentOfValueToAccessChainToScalarVar( + uint32_t value_id, const std::vector& component_indices, + Instruction* scalar_var, + const std::vector& access_chain_indices, + Instruction* insert_before); + + // Creates instructions to store a component of an aggregate whose id is + // |value_id| to |scalar_var| and inserts the created instructions before + // |insert_before|. To get the component, recursively traverses the aggregate + // using |extra_array_index| and |component_indices| as indexes. + void StoreComponentOfValueToScalarVar( + uint32_t value_id, const std::vector& component_indices, + Instruction* scalar_var, const uint32_t* extra_array_index, + Instruction* insert_before); + + // Creates instructions to store a component of an aggregate whose id is + // |value_id| to |ptr| and inserts the created instructions before + // |insert_before|. To get the component, recursively traverses the aggregate + // using |extra_array_index| and |component_indices| as indexes. + // |component_type_id| is the id of the type instruction of the component. + void StoreComponentOfValueTo(uint32_t component_type_id, uint32_t value_id, + const std::vector& component_indices, + Instruction* ptr, + const uint32_t* extra_array_index, + Instruction* insert_before); + + // Creates new OpCompositeExtract with |type_id| for Result Type, + // |composite_id| for Composite operand, and |indexes| for Indexes operands. + // If |extra_first_index| is not nullptr, uses it as the first Indexes + // operand. + Instruction* CreateCompositeExtract(uint32_t type_id, uint32_t composite_id, + const std::vector& indexes, + const uint32_t* extra_first_index); + + // Creates a new OpLoad whose Result Type is |type_id| and Pointer operand is + // |ptr|. Inserts the new instruction before |insert_before|. + Instruction* CreateLoad(uint32_t type_id, Instruction* ptr, + Instruction* insert_before); + + // Clones an annotation instruction |annotation_inst| and sets the target + // operand of the new annotation instruction as |var_id|. + void CloneAnnotationForVariable(Instruction* annotation_inst, + uint32_t var_id); + + // Replaces the interface variable |interface_var| in the operands of the + // entry point |entry_point| with |scalar_var_id|. If it cannot find + // |interface_var| from the operands of the entry point |entry_point|, adds + // |scalar_var_id| as an operand of the entry point |entry_point|. + bool ReplaceInterfaceVarInEntryPoint(Instruction* interface_var, + Instruction* entry_point, + uint32_t scalar_var_id); + + // Creates an access chain instruction whose Base operand is |var| and Indexes + // operand is |index|. |component_type_id| is the id of the type instruction + // that is the type of component. Inserts the new access chain before + // |insert_before|. + Instruction* CreateAccessChainWithIndex(uint32_t component_type_id, + Instruction* var, uint32_t index, + Instruction* insert_before); + + // Returns the pointee type of the type of variable |var|. + uint32_t GetPointeeTypeIdOfVar(Instruction* var); + + // Replaces the access chain |access_chain| and its users with a new access + // chain that points |scalar_var| as the Base operand having + // |interface_var_component_indices| as Indexes operands and users of the new + // access chain. When some of the users are load instructions, returns the + // original load instruction to the new instruction that loads a component of + // the original load value via |loads_to_component_values|. + void ReplaceAccessChainWith( + Instruction* access_chain, + const std::vector& interface_var_component_indices, + Instruction* scalar_var, + std::unordered_map* + loads_to_component_values); + + // Assuming that |access_chain| is an access chain instruction whose Base + // operand is |base_access_chain|, replaces the operands of |access_chain| + // with operands of |base_access_chain| and Indexes operands of + // |access_chain|. + void UseBaseAccessChainForAccessChain(Instruction* access_chain, + Instruction* base_access_chain); + + // Creates composite construct instructions for load instructions that are the + // keys of |loads_to_component_values| if no such composite construct + // instructions exist. Adds a component of the composite as an operand of the + // created composite construct instruction. Each value of + // |loads_to_component_values| is the component. Returns the created composite + // construct instructions using |loads_to_composites|. |depth_to_component| is + // the number of recursive access steps to get the component from the + // composite. + void AddComponentsToCompositesForLoads( + const std::unordered_map& + loads_to_component_values, + std::unordered_map* loads_to_composites, + uint32_t depth_to_component); + + // Creates a composite construct instruction for a component of the value of + // instruction |load| in |depth_to_component| th recursive depth and inserts + // it after |load|. + Instruction* CreateCompositeConstructForComponentOfLoad( + Instruction* load, uint32_t depth_to_component); + + // Creates a new access chain instruction that points to variable |var| whose + // type is the instruction with |var_type_id| and inserts it before + // |insert_before|. The new access chain will have |index_ids| for Indexes + // operands. Returns the type id of the component that is pointed by the new + // access chain via |component_type_id|. + Instruction* CreateAccessChainToVar(uint32_t var_type_id, Instruction* var, + const std::vector& index_ids, + Instruction* insert_before, + uint32_t* component_type_id); + + // Returns the result id of OpTypeArray instrunction whose Element Type + // operand is |elem_type_id| and Length operand is |array_length|. + uint32_t GetArrayType(uint32_t elem_type_id, uint32_t array_length); + + // Returns the result id of OpTypePointer instrunction whose Type + // operand is |type_id| and Storage Class operand is |storage_class|. + uint32_t GetPointerType(uint32_t type_id, spv::StorageClass storage_class); + + // Kills an instrunction |inst| and its users. + void KillInstructionAndUsers(Instruction* inst); + + // Kills a vector of instrunctions |insts| and their users. + void KillInstructionsAndUsers(const std::vector& insts); + + // Kills all OpDecorate instructions for Location and Component of the + // variable whose id is |var_id|. + void KillLocationAndComponentDecorations(uint32_t var_id); + + // If |var| has the extra arrayness for an entry point, reports an error and + // returns true. Otherwise, returns false. + bool ReportErrorIfHasExtraArraynessForOtherEntry(Instruction* var); + + // If |var| does not have the extra arrayness for an entry point, reports an + // error and returns true. Otherwise, returns false. + bool ReportErrorIfHasNoExtraArraynessForOtherEntry(Instruction* var); + + // If |interface_var| has the extra arrayness for an entry point but it does + // not have one for another entry point, reports an error and returns false. + // Otherwise, returns true. |has_extra_arrayness| denotes whether it has an + // extra arrayness for an entry point or not. + bool CheckExtraArraynessConflictBetweenEntries(Instruction* interface_var, + bool has_extra_arrayness); + + // Conducts the scalar replacement for the interface variables used by the + // |entry_point|. + Pass::Status ReplaceInterfaceVarsWithScalars(Instruction& entry_point); + + // A set of interface variable ids that were already removed from operands of + // the entry point. + std::unordered_set + interface_vars_removed_from_entry_point_operands_; + + // A mapping from ids of new composite construct instructions that load + // instructions are replaced with to the recursive depth of the component of + // load that the new component construct instruction is used for. + std::unordered_map composite_ids_to_component_depths; + + // A set of interface variables with the extra arrayness for any of the entry + // points. + std::unordered_set vars_with_extra_arrayness; + + // A set of interface variables without the extra arrayness for any of the + // entry points. + std::unordered_set vars_without_extra_arrayness; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_INTERFACE_VAR_SROA_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/interp_fixup_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/interp_fixup_pass.cpp new file mode 100644 index 000000000000..2ec2147d6064 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/interp_fixup_pass.cpp @@ -0,0 +1,122 @@ +// Copyright (c) 2021 The Khronos Group Inc. +// Copyright (c) 2021 Valve Corporation +// Copyright (c) 2021 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/interp_fixup_pass.h" + +#include +#include + +#include "source/opt/ir_context.h" +#include "type_manager.h" + +namespace spvtools { +namespace opt { +namespace { + +// Input Operand Indices +constexpr int kSpvVariableStorageClassInIdx = 0; + +// Folding rule function which attempts to replace |op(OpLoad(a),...)| +// by |op(a,...)|, where |op| is one of the GLSLstd450 InterpolateAt* +// instructions. Returns true if replaced, false otherwise. +bool ReplaceInternalInterpolate(IRContext* ctx, Instruction* inst, + const std::vector&) { + uint32_t glsl450_ext_inst_id = + ctx->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + assert(glsl450_ext_inst_id != 0); + + uint32_t ext_opcode = inst->GetSingleWordInOperand(1); + + uint32_t op1_id = inst->GetSingleWordInOperand(2); + + Instruction* load_inst = ctx->get_def_use_mgr()->GetDef(op1_id); + if (load_inst->opcode() != spv::Op::OpLoad) return false; + + Instruction* base_inst = load_inst->GetBaseAddress(); + USE_ASSERT(base_inst->opcode() == spv::Op::OpVariable && + spv::StorageClass(base_inst->GetSingleWordInOperand( + kSpvVariableStorageClassInIdx)) == spv::StorageClass::Input && + "unexpected interpolant in InterpolateAt*"); + + uint32_t ptr_id = load_inst->GetSingleWordInOperand(0); + uint32_t op2_id = (ext_opcode != GLSLstd450InterpolateAtCentroid) + ? inst->GetSingleWordInOperand(3) + : 0; + + Instruction::OperandList new_operands; + new_operands.push_back({SPV_OPERAND_TYPE_ID, {glsl450_ext_inst_id}}); + new_operands.push_back( + {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, {ext_opcode}}); + new_operands.push_back({SPV_OPERAND_TYPE_ID, {ptr_id}}); + if (op2_id != 0) new_operands.push_back({SPV_OPERAND_TYPE_ID, {op2_id}}); + + inst->SetInOperands(std::move(new_operands)); + ctx->UpdateDefUse(inst); + return true; +} + +class InterpFoldingRules : public FoldingRules { + public: + explicit InterpFoldingRules(IRContext* ctx) : FoldingRules(ctx) {} + + protected: + virtual void AddFoldingRules() override { + uint32_t extension_id = + context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); + + if (extension_id != 0) { + ext_rules_[{extension_id, GLSLstd450InterpolateAtCentroid}].push_back( + ReplaceInternalInterpolate); + ext_rules_[{extension_id, GLSLstd450InterpolateAtSample}].push_back( + ReplaceInternalInterpolate); + ext_rules_[{extension_id, GLSLstd450InterpolateAtOffset}].push_back( + ReplaceInternalInterpolate); + } + } +}; + +class InterpConstFoldingRules : public ConstantFoldingRules { + public: + InterpConstFoldingRules(IRContext* ctx) : ConstantFoldingRules(ctx) {} + + protected: + virtual void AddFoldingRules() override {} +}; + +} // namespace + +Pass::Status InterpFixupPass::Process() { + bool changed = false; + + // Traverse the body of the functions to replace instructions that require + // the extensions. + InstructionFolder folder( + context(), + std::unique_ptr(new InterpFoldingRules(context())), + MakeUnique(context())); + for (Function& func : *get_module()) { + func.ForEachInst([&changed, &folder](Instruction* inst) { + if (folder.FoldInstruction(inst)) { + changed = true; + } + }); + } + + return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/interp_fixup_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/interp_fixup_pass.h new file mode 100644 index 000000000000..e112b651579b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/interp_fixup_pass.h @@ -0,0 +1,54 @@ +// Copyright (c) 2021 The Khronos Group Inc. +// Copyright (c) 2021 Valve Corporation +// Copyright (c) 2021 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_INTERP_FIXUP_H +#define SOURCE_OPT_INTERP_FIXUP_H + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// Replaces overloaded internal form for GLSLstd450Interpolate* instructions +// with external form. Specifically, removes OpLoad from the first argument +// and replaces it with the pointer for the OpLoad. glslang generates the +// internal form. This pass is called as part of glslang HLSL legalization. +class InterpFixupPass : public Pass { + public: + const char* name() const override { return "interp-fixup"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisScalarEvolution | + IRContext::kAnalysisRegisterPressure | + IRContext::kAnalysisValueNumberTable | + IRContext::kAnalysisStructuredCFG | + IRContext::kAnalysisBuiltinVarId | + IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | + IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; + } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_INTERP_FIXUP_H diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/invocation_interlock_placement_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/invocation_interlock_placement_pass.cpp new file mode 100644 index 000000000000..642e2d23a529 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/invocation_interlock_placement_pass.cpp @@ -0,0 +1,493 @@ +// Copyright (c) 2023 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/invocation_interlock_placement_pass.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/enum_set.h" +#include "source/enum_string_mapping.h" +#include "source/opt/ir_context.h" +#include "source/opt/reflect.h" +#include "source/spirv_target_env.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { + +namespace { +constexpr uint32_t kEntryPointExecutionModelInIdx = 0; +constexpr uint32_t kEntryPointFunctionIdInIdx = 1; +constexpr uint32_t kFunctionCallFunctionIdInIdx = 0; +} // namespace + +bool InvocationInterlockPlacementPass::hasSingleNextBlock(uint32_t block_id, + bool reverse_cfg) { + if (reverse_cfg) { + // We are traversing forward, so check whether there is a single successor. + BasicBlock* block = cfg()->block(block_id); + + switch (block->tail()->opcode()) { + case spv::Op::OpBranchConditional: + return false; + case spv::Op::OpSwitch: + return block->tail()->NumInOperandWords() == 1; + default: + return !block->tail()->IsReturnOrAbort(); + } + } else { + // We are traversing backward, so check whether there is a single + // predecessor. + return cfg()->preds(block_id).size() == 1; + } +} + +void InvocationInterlockPlacementPass::forEachNext( + uint32_t block_id, bool reverse_cfg, std::function f) { + if (reverse_cfg) { + BasicBlock* block = cfg()->block(block_id); + + block->ForEachSuccessorLabel([f](uint32_t succ_id) { f(succ_id); }); + } else { + for (uint32_t pred_id : cfg()->preds(block_id)) { + f(pred_id); + } + } +} + +void InvocationInterlockPlacementPass::addInstructionAtBlockBoundary( + BasicBlock* block, spv::Op opcode, bool at_end) { + if (at_end) { + assert(block->begin()->opcode() != spv::Op::OpPhi && + "addInstructionAtBlockBoundary expects to be called with at_end == " + "true only if there is a single successor to block"); + // Insert a begin instruction at the end of the block. + Instruction* begin_inst = new Instruction(context(), opcode); + begin_inst->InsertAfter(&*--block->tail()); + } else { + assert(block->begin()->opcode() != spv::Op::OpPhi && + "addInstructionAtBlockBoundary expects to be called with at_end == " + "false only if there is a single predecessor to block"); + // Insert an end instruction at the beginning of the block. + Instruction* end_inst = new Instruction(context(), opcode); + end_inst->InsertBefore(&*block->begin()); + } +} + +bool InvocationInterlockPlacementPass::killDuplicateBegin(BasicBlock* block) { + bool found = false; + + return context()->KillInstructionIf( + block->begin(), block->end(), [&found](Instruction* inst) { + if (inst->opcode() == spv::Op::OpBeginInvocationInterlockEXT) { + if (found) { + return true; + } + found = true; + } + return false; + }); +} + +bool InvocationInterlockPlacementPass::killDuplicateEnd(BasicBlock* block) { + std::vector to_kill; + block->ForEachInst([&to_kill](Instruction* inst) { + if (inst->opcode() == spv::Op::OpEndInvocationInterlockEXT) { + to_kill.push_back(inst); + } + }); + + if (to_kill.size() <= 1) { + return false; + } + + to_kill.pop_back(); + + for (Instruction* inst : to_kill) { + context()->KillInst(inst); + } + + return true; +} + +void InvocationInterlockPlacementPass::recordBeginOrEndInFunction( + Function* func) { + if (extracted_functions_.count(func)) { + return; + } + + bool had_begin = false; + bool had_end = false; + + func->ForEachInst([this, &had_begin, &had_end](Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpBeginInvocationInterlockEXT: + had_begin = true; + break; + case spv::Op::OpEndInvocationInterlockEXT: + had_end = true; + break; + case spv::Op::OpFunctionCall: { + uint32_t function_id = + inst->GetSingleWordInOperand(kFunctionCallFunctionIdInIdx); + Function* inner_func = context()->GetFunction(function_id); + recordBeginOrEndInFunction(inner_func); + ExtractionResult result = extracted_functions_[inner_func]; + had_begin = had_begin || result.had_begin; + had_end = had_end || result.had_end; + break; + } + default: + break; + } + }); + + ExtractionResult result = {had_begin, had_end}; + extracted_functions_[func] = result; +} + +bool InvocationInterlockPlacementPass:: + removeBeginAndEndInstructionsFromFunction(Function* func) { + bool modified = false; + func->ForEachInst([this, &modified](Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpBeginInvocationInterlockEXT: + context()->KillInst(inst); + modified = true; + break; + case spv::Op::OpEndInvocationInterlockEXT: + context()->KillInst(inst); + modified = true; + break; + default: + break; + } + }); + return modified; +} + +bool InvocationInterlockPlacementPass::extractInstructionsFromCalls( + std::vector blocks) { + bool modified = false; + + for (BasicBlock* block : blocks) { + block->ForEachInst([this, &modified](Instruction* inst) { + if (inst->opcode() == spv::Op::OpFunctionCall) { + uint32_t function_id = + inst->GetSingleWordInOperand(kFunctionCallFunctionIdInIdx); + Function* func = context()->GetFunction(function_id); + ExtractionResult result = extracted_functions_[func]; + + if (result.had_begin) { + Instruction* new_inst = new Instruction( + context(), spv::Op::OpBeginInvocationInterlockEXT); + new_inst->InsertBefore(inst); + modified = true; + } + if (result.had_end) { + Instruction* new_inst = + new Instruction(context(), spv::Op::OpEndInvocationInterlockEXT); + new_inst->InsertAfter(inst); + modified = true; + } + } + }); + } + return modified; +} + +void InvocationInterlockPlacementPass::recordExistingBeginAndEndBlock( + std::vector blocks) { + for (BasicBlock* block : blocks) { + block->ForEachInst([this, block](Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpBeginInvocationInterlockEXT: + begin_.insert(block->id()); + break; + case spv::Op::OpEndInvocationInterlockEXT: + end_.insert(block->id()); + break; + default: + break; + } + }); + } +} + +InvocationInterlockPlacementPass::BlockSet +InvocationInterlockPlacementPass::computeReachableBlocks( + BlockSet& previous_inside, const BlockSet& starting_nodes, + bool reverse_cfg) { + BlockSet inside = starting_nodes; + + std::deque worklist; + worklist.insert(worklist.begin(), starting_nodes.begin(), + starting_nodes.end()); + + while (!worklist.empty()) { + uint32_t block_id = worklist.front(); + worklist.pop_front(); + + forEachNext(block_id, reverse_cfg, + [&inside, &previous_inside, &worklist](uint32_t next_id) { + previous_inside.insert(next_id); + if (inside.insert(next_id).second) { + worklist.push_back(next_id); + } + }); + } + + return inside; +} + +bool InvocationInterlockPlacementPass::removeUnneededInstructions( + BasicBlock* block) { + bool modified = false; + if (!predecessors_after_begin_.count(block->id()) && + after_begin_.count(block->id())) { + // None of the previous blocks are in the critical section, but this block + // is. This can only happen if this block already has at least one begin + // instruction. Leave the first begin instruction, and remove any others. + modified |= killDuplicateBegin(block); + } else if (predecessors_after_begin_.count(block->id())) { + // At least one previous block is in the critical section; remove all + // begin instructions in this block. + modified |= context()->KillInstructionIf( + block->begin(), block->end(), [](Instruction* inst) { + return inst->opcode() == spv::Op::OpBeginInvocationInterlockEXT; + }); + } + + if (!successors_before_end_.count(block->id()) && + before_end_.count(block->id())) { + // Same as above + modified |= killDuplicateEnd(block); + } else if (successors_before_end_.count(block->id())) { + modified |= context()->KillInstructionIf( + block->begin(), block->end(), [](Instruction* inst) { + return inst->opcode() == spv::Op::OpEndInvocationInterlockEXT; + }); + } + return modified; +} + +BasicBlock* InvocationInterlockPlacementPass::splitEdge(BasicBlock* block, + uint32_t succ_id) { + // Create a new block to replace the critical edge. + auto new_succ_temp = MakeUnique( + MakeUnique(context(), spv::Op::OpLabel, 0, TakeNextId(), + std::initializer_list{})); + auto* new_succ = new_succ_temp.get(); + + // Insert the new block into the function. + block->GetParent()->InsertBasicBlockAfter(std::move(new_succ_temp), block); + + new_succ->AddInstruction(MakeUnique( + context(), spv::Op::OpBranch, 0, 0, + std::initializer_list{ + Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {succ_id})})); + + assert(block->tail()->opcode() == spv::Op::OpBranchConditional || + block->tail()->opcode() == spv::Op::OpSwitch); + + // Update the first branch to successor to instead branch to + // the new successor. If there are multiple edges, we arbitrarily choose the + // first time it appears in the list. The other edges to `succ_id` will have + // to be split by another call to `splitEdge`. + block->tail()->WhileEachInId([new_succ, succ_id](uint32_t* branch_id) { + if (*branch_id == succ_id) { + *branch_id = new_succ->id(); + return false; + } + return true; + }); + + return new_succ; +} + +bool InvocationInterlockPlacementPass::placeInstructionsForEdge( + BasicBlock* block, uint32_t next_id, BlockSet& inside, + BlockSet& previous_inside, spv::Op opcode, bool reverse_cfg) { + bool modified = false; + + if (previous_inside.count(next_id) && !inside.count(block->id())) { + // This block is not in the critical section but the next has at least one + // other previous block that is, so this block should be enter it as well. + // We need to add begin or end instructions to the edge. + + modified = true; + + if (hasSingleNextBlock(block->id(), reverse_cfg)) { + // This is the only next block. + + // Additionally, because `next_id` is in `previous_inside`, we know that + // `next_id` has at least one previous block in `inside`. And because + // 'block` is not in `inside`, that means the `next_id` has to have at + // least one other previous block in `inside`. + + // This is solely for a debug assertion. It is essentially recomputing the + // value of `previous_inside` to verify that it was computed correctly + // such that the above statement is true. + bool next_has_previous_inside = false; + // By passing !reverse_cfg to forEachNext, we are actually iterating over + // the previous blocks. + forEachNext(next_id, !reverse_cfg, + [&next_has_previous_inside, inside](uint32_t previous_id) { + if (inside.count(previous_id)) { + next_has_previous_inside = true; + } + }); + assert(next_has_previous_inside && + "`previous_inside` must be the set of blocks with at least one " + "previous block in `inside`"); + + addInstructionAtBlockBoundary(block, opcode, reverse_cfg); + } else { + // This block has multiple next blocks. Split the edge and insert the + // instruction in the new next block. + BasicBlock* new_branch; + if (reverse_cfg) { + new_branch = splitEdge(block, next_id); + } else { + new_branch = splitEdge(cfg()->block(next_id), block->id()); + } + + auto inst = new Instruction(context(), opcode); + inst->InsertBefore(&*new_branch->tail()); + } + } + + return modified; +} + +bool InvocationInterlockPlacementPass::placeInstructions(BasicBlock* block) { + bool modified = false; + + block->ForEachSuccessorLabel([this, block, &modified](uint32_t succ_id) { + modified |= placeInstructionsForEdge( + block, succ_id, after_begin_, predecessors_after_begin_, + spv::Op::OpBeginInvocationInterlockEXT, /* reverse_cfg= */ true); + modified |= placeInstructionsForEdge(cfg()->block(succ_id), block->id(), + before_end_, successors_before_end_, + spv::Op::OpEndInvocationInterlockEXT, + /* reverse_cfg= */ false); + }); + + return modified; +} + +bool InvocationInterlockPlacementPass::processFragmentShaderEntry( + Function* entry_func) { + bool modified = false; + + // Save the original order of blocks in the function, so we don't iterate over + // newly-added blocks. + std::vector original_blocks; + for (auto bi = entry_func->begin(); bi != entry_func->end(); ++bi) { + original_blocks.push_back(&*bi); + } + + modified |= extractInstructionsFromCalls(original_blocks); + recordExistingBeginAndEndBlock(original_blocks); + + after_begin_ = computeReachableBlocks(predecessors_after_begin_, begin_, + /* reverse_cfg= */ true); + before_end_ = computeReachableBlocks(successors_before_end_, end_, + /* reverse_cfg= */ false); + + for (BasicBlock* block : original_blocks) { + modified |= removeUnneededInstructions(block); + modified |= placeInstructions(block); + } + return modified; +} + +bool InvocationInterlockPlacementPass::isFragmentShaderInterlockEnabled() { + if (!context()->get_feature_mgr()->HasExtension( + kSPV_EXT_fragment_shader_interlock)) { + return false; + } + + if (context()->get_feature_mgr()->HasCapability( + spv::Capability::FragmentShaderSampleInterlockEXT)) { + return true; + } + + if (context()->get_feature_mgr()->HasCapability( + spv::Capability::FragmentShaderPixelInterlockEXT)) { + return true; + } + + if (context()->get_feature_mgr()->HasCapability( + spv::Capability::FragmentShaderShadingRateInterlockEXT)) { + return true; + } + + return false; +} + +Pass::Status InvocationInterlockPlacementPass::Process() { + // Skip this pass if the necessary extension or capability is missing + if (!isFragmentShaderInterlockEnabled()) { + return Status::SuccessWithoutChange; + } + + bool modified = false; + + std::unordered_set entry_points; + for (Instruction& entry_inst : context()->module()->entry_points()) { + uint32_t entry_id = + entry_inst.GetSingleWordInOperand(kEntryPointFunctionIdInIdx); + entry_points.insert(context()->GetFunction(entry_id)); + } + + for (auto fi = context()->module()->begin(); fi != context()->module()->end(); + ++fi) { + Function* func = &*fi; + recordBeginOrEndInFunction(func); + if (!entry_points.count(func) && extracted_functions_.count(func)) { + modified |= removeBeginAndEndInstructionsFromFunction(func); + } + } + + for (Instruction& entry_inst : context()->module()->entry_points()) { + uint32_t entry_id = + entry_inst.GetSingleWordInOperand(kEntryPointFunctionIdInIdx); + Function* entry_func = context()->GetFunction(entry_id); + + auto execution_model = spv::ExecutionModel( + entry_inst.GetSingleWordInOperand(kEntryPointExecutionModelInIdx)); + + if (execution_model != spv::ExecutionModel::Fragment) { + continue; + } + + modified |= processFragmentShaderEntry(entry_func); + } + + return modified ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/invocation_interlock_placement_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/invocation_interlock_placement_pass.h new file mode 100644 index 000000000000..4e85be858670 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/invocation_interlock_placement_pass.h @@ -0,0 +1,158 @@ +// Copyright (c) 2023 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_ +#define SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/enum_set.h" +#include "source/extensions.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" +#include "source/spirv_target_env.h" + +namespace spvtools { +namespace opt { + +// This pass will ensure that an entry point will only have at most one +// OpBeginInterlockInvocationEXT and one OpEndInterlockInvocationEXT, in that +// order +class InvocationInterlockPlacementPass : public Pass { + public: + InvocationInterlockPlacementPass() {} + InvocationInterlockPlacementPass(const InvocationInterlockPlacementPass&) = + delete; + InvocationInterlockPlacementPass(InvocationInterlockPlacementPass&&) = delete; + + const char* name() const override { return "dedupe-interlock-invocation"; } + Status Process() override; + + private: + using BlockSet = std::unordered_set; + + // Specifies whether a function originally had a begin or end instruction. + struct ExtractionResult { + bool had_begin : 1; + bool had_end : 2; + }; + + // Check if a block has only a single next block, depending on the directing + // that we are traversing the CFG. If reverse_cfg is true, we are walking + // forward through the CFG, and will return if the block has only one + // successor. Otherwise, we are walking backward through the CFG, and will + // return if the block has only one predecessor. + bool hasSingleNextBlock(uint32_t block_id, bool reverse_cfg); + + // Iterate over each of a block's predecessors or successors, depending on + // direction. If reverse_cfg is true, we are walking forward through the CFG, + // and need to iterate over the successors. Otherwise, we are walking backward + // through the CFG, and need to iterate over the predecessors. + void forEachNext(uint32_t block_id, bool reverse_cfg, + std::function f); + + // Add either a begin or end instruction to the edge of the basic block. If + // at_end is true, add the instruction to the end of the block; otherwise add + // the instruction to the beginning of the basic block. + void addInstructionAtBlockBoundary(BasicBlock* block, spv::Op opcode, + bool at_end); + + // Remove every OpBeginInvocationInterlockEXT instruction in block after the + // first. Returns whether any instructions were removed. + bool killDuplicateBegin(BasicBlock* block); + // Remove every OpBeginInvocationInterlockEXT instruction in block before the + // last. Returns whether any instructions were removed. + bool killDuplicateEnd(BasicBlock* block); + + // Records whether a function will potentially execute a begin or end + // instruction. + void recordBeginOrEndInFunction(Function* func); + + // Recursively removes any begin or end instructions from func and any + // function func calls. Returns whether any instructions were removed. + bool removeBeginAndEndInstructionsFromFunction(Function* func); + + // For every function call in any of the passed blocks, move any begin or end + // instructions outside of the function call. Returns whether any extractions + // occurred. + bool extractInstructionsFromCalls(std::vector blocks); + + // Finds the sets of blocks that contain OpBeginInvocationInterlockEXT and + // OpEndInvocationInterlockEXT, storing them in the member variables begin_ + // and end_ respectively. + void recordExistingBeginAndEndBlock(std::vector blocks); + + // Compute the set of blocks including or after the barrier instruction, and + // the set of blocks with any previous blocks inside the barrier instruction. + // If reverse_cfg is true, move forward through the CFG, computing + // after_begin_ and predecessors_after_begin_computing after_begin_ and + // predecessors_after_begin_, otherwise, move backward through the CFG, + // computing before_end_ and successors_before_end_. + BlockSet computeReachableBlocks(BlockSet& in_set, + const BlockSet& starting_nodes, + bool reverse_cfg); + + // Remove unneeded begin and end instructions in block. + bool removeUnneededInstructions(BasicBlock* block); + + // Given a block which branches to multiple successors, and a specific + // successor, creates a new empty block, and update the branch instruction to + // branch to the new block instead. + BasicBlock* splitEdge(BasicBlock* block, uint32_t succ_id); + + // For the edge from block to next_id, places a begin or end instruction on + // the edge, based on the direction we are walking the CFG, specified in + // reverse_cfg. + bool placeInstructionsForEdge(BasicBlock* block, uint32_t next_id, + BlockSet& inside, BlockSet& previous_inside, + spv::Op opcode, bool reverse_cfg); + // Calls placeInstructionsForEdge for each edge in block. + bool placeInstructions(BasicBlock* block); + + // Processes a single fragment shader entry function. + bool processFragmentShaderEntry(Function* entry_func); + + // Returns whether the module has the SPV_EXT_fragment_shader_interlock + // extension and one of the FragmentShader*InterlockEXT capabilities. + bool isFragmentShaderInterlockEnabled(); + + // Maps a function to whether that function originally held a begin or end + // instruction. + std::unordered_map extracted_functions_; + + // The set of blocks which have an OpBeginInvocationInterlockEXT instruction. + BlockSet begin_; + // The set of blocks which have an OpEndInvocationInterlockEXT instruction. + BlockSet end_; + // The set of blocks which either have a begin instruction, or have a + // predecessor which has a begin instruction. + BlockSet after_begin_; + // The set of blocks which either have an end instruction, or have a successor + // which have an end instruction. + BlockSet before_end_; + // The set of blocks which have a predecessor in after_begin_. + BlockSet predecessors_after_begin_; + // The set of blocks which have a successor in before_end_. + BlockSet successors_before_end_; +}; + +} // namespace opt +} // namespace spvtools +#endif // SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ir_builder.h b/thirdparty/glslang/External/spirv-tools/source/opt/ir_builder.h new file mode 100644 index 000000000000..f3e0afceaed3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ir_builder.h @@ -0,0 +1,674 @@ +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_IR_BUILDER_H_ +#define SOURCE_OPT_IR_BUILDER_H_ + +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/constants.h" +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +// In SPIR-V, ids are encoded as uint16_t, this id is guaranteed to be always +// invalid. +constexpr uint32_t kInvalidId = std::numeric_limits::max(); + +// Helper class to abstract instruction construction and insertion. +// The instruction builder can preserve the following analyses (specified via +// the constructors): +// - Def-use analysis +// - Instruction to block analysis +class InstructionBuilder { + public: + using InsertionPointTy = BasicBlock::iterator; + + // Creates an InstructionBuilder, all new instructions will be inserted before + // the instruction |insert_before|. + InstructionBuilder( + IRContext* context, Instruction* insert_before, + IRContext::Analysis preserved_analyses = IRContext::kAnalysisNone) + : InstructionBuilder(context, context->get_instr_block(insert_before), + InsertionPointTy(insert_before), + preserved_analyses) {} + + // Creates an InstructionBuilder, all new instructions will be inserted at the + // end of the basic block |parent_block|. + InstructionBuilder( + IRContext* context, BasicBlock* parent_block, + IRContext::Analysis preserved_analyses = IRContext::kAnalysisNone) + : InstructionBuilder(context, parent_block, parent_block->end(), + preserved_analyses) {} + + Instruction* AddNullaryOp(uint32_t type_id, spv::Op opcode) { + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } + std::unique_ptr new_inst( + new Instruction(GetContext(), opcode, type_id, result_id, {})); + return AddInstruction(std::move(new_inst)); + } + + Instruction* AddUnaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1) { + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } + std::unique_ptr newUnOp(new Instruction( + GetContext(), opcode, type_id, result_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}})); + return AddInstruction(std::move(newUnOp)); + } + + Instruction* AddBinaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, + uint32_t operand2) { + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } + std::unique_ptr newBinOp(new Instruction( + GetContext(), opcode, type_id, + opcode == spv::Op::OpStore ? 0 : result_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand2}}})); + return AddInstruction(std::move(newBinOp)); + } + + Instruction* AddTernaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, + uint32_t operand2, uint32_t operand3) { + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } + std::unique_ptr newTernOp(new Instruction( + GetContext(), opcode, type_id, result_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand2}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand3}}})); + return AddInstruction(std::move(newTernOp)); + } + + Instruction* AddQuadOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, + uint32_t operand2, uint32_t operand3, + uint32_t operand4) { + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } + std::unique_ptr newQuadOp(new Instruction( + GetContext(), opcode, type_id, result_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand2}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand3}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand4}}})); + return AddInstruction(std::move(newQuadOp)); + } + + Instruction* AddIdLiteralOp(uint32_t type_id, spv::Op opcode, uint32_t id, + uint32_t uliteral) { + uint32_t result_id = 0; + if (type_id != 0) { + result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + } + std::unique_ptr newBinOp(new Instruction( + GetContext(), opcode, type_id, result_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {uliteral}}})); + return AddInstruction(std::move(newBinOp)); + } + + // Creates an N-ary instruction of |opcode|. + // |typid| must be the id of the instruction's type. + // |operands| must be a sequence of operand ids. + // Use |result| for the result id if non-zero. + Instruction* AddNaryOp(uint32_t type_id, spv::Op opcode, + const std::vector& operands, + uint32_t result = 0) { + std::vector ops; + for (size_t i = 0; i < operands.size(); i++) { + ops.push_back({SPV_OPERAND_TYPE_ID, {operands[i]}}); + } + // TODO(1841): Handle id overflow. + std::unique_ptr new_inst(new Instruction( + GetContext(), opcode, type_id, + result != 0 ? result : GetContext()->TakeNextId(), ops)); + return AddInstruction(std::move(new_inst)); + } + + // Creates a new selection merge instruction. + // The id |merge_id| is the merge basic block id. + Instruction* AddSelectionMerge( + uint32_t merge_id, uint32_t selection_control = static_cast( + spv::SelectionControlMask::MaskNone)) { + std::unique_ptr new_branch_merge(new Instruction( + GetContext(), spv::Op::OpSelectionMerge, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_SELECTION_CONTROL, + {selection_control}}})); + return AddInstruction(std::move(new_branch_merge)); + } + + // Creates a new loop merge instruction. + // The id |merge_id| is the basic block id of the merge block. + // |continue_id| is the id of the continue block. + // |loop_control| are the loop control flags to be added to the instruction. + Instruction* AddLoopMerge(uint32_t merge_id, uint32_t continue_id, + uint32_t loop_control = static_cast( + spv::LoopControlMask::MaskNone)) { + std::unique_ptr new_branch_merge(new Instruction( + GetContext(), spv::Op::OpLoopMerge, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {continue_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LOOP_CONTROL, {loop_control}}})); + return AddInstruction(std::move(new_branch_merge)); + } + + // Creates a new branch instruction to |label_id|. + // Note that the user must make sure the final basic block is + // well formed. + Instruction* AddBranch(uint32_t label_id) { + std::unique_ptr new_branch(new Instruction( + GetContext(), spv::Op::OpBranch, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}})); + return AddInstruction(std::move(new_branch)); + } + + // Creates a new conditional instruction and the associated selection merge + // instruction if requested. + // The id |cond_id| is the id of the condition instruction, must be of + // type bool. + // The id |true_id| is the id of the basic block to branch to if the condition + // is true. + // The id |false_id| is the id of the basic block to branch to if the + // condition is false. + // The id |merge_id| is the id of the merge basic block for the selection + // merge instruction. If |merge_id| equals kInvalidId then no selection merge + // instruction will be created. + // The value |selection_control| is the selection control flag for the + // selection merge instruction. + // Note that the user must make sure the final basic block is + // well formed. + Instruction* AddConditionalBranch( + uint32_t cond_id, uint32_t true_id, uint32_t false_id, + uint32_t merge_id = kInvalidId, + uint32_t selection_control = + static_cast(spv::SelectionControlMask::MaskNone)) { + if (merge_id != kInvalidId) { + AddSelectionMerge(merge_id, selection_control); + } + std::unique_ptr new_branch(new Instruction( + GetContext(), spv::Op::OpBranchConditional, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {false_id}}})); + return AddInstruction(std::move(new_branch)); + } + + // Creates a new switch instruction and the associated selection merge + // instruction if requested. + // The id |selector_id| is the id of the selector instruction, must be of + // type int. + // The id |default_id| is the id of the default basic block to branch to. + // The vector |targets| is the pair of literal/branch id. + // The id |merge_id| is the id of the merge basic block for the selection + // merge instruction. If |merge_id| equals kInvalidId then no selection merge + // instruction will be created. + // The value |selection_control| is the selection control flag for the + // selection merge instruction. + // Note that the user must make sure the final basic block is + // well formed. + Instruction* AddSwitch( + uint32_t selector_id, uint32_t default_id, + const std::vector>& targets, + uint32_t merge_id = kInvalidId, + uint32_t selection_control = + static_cast(spv::SelectionControlMask::MaskNone)) { + if (merge_id != kInvalidId) { + AddSelectionMerge(merge_id, selection_control); + } + std::vector operands; + operands.emplace_back( + Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {selector_id}}); + operands.emplace_back( + Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {default_id}}); + for (auto& target : targets) { + operands.emplace_back( + Operand{spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, + target.first}); + operands.emplace_back( + Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {target.second}}); + } + std::unique_ptr new_switch( + new Instruction(GetContext(), spv::Op::OpSwitch, 0, 0, operands)); + return AddInstruction(std::move(new_switch)); + } + + // Creates a phi instruction. + // The id |type| must be the id of the phi instruction's type. + // The vector |incomings| must be a sequence of pairs of . + Instruction* AddPhi(uint32_t type, const std::vector& incomings, + uint32_t result = 0) { + assert(incomings.size() % 2 == 0 && "A sequence of pairs is expected"); + return AddNaryOp(type, spv::Op::OpPhi, incomings, result); + } + + // Creates an addition instruction. + // The id |type| must be the id of the instruction's type, must be the same as + // |op1| and |op2| types. + // The id |op1| is the left hand side of the operation. + // The id |op2| is the right hand side of the operation. + Instruction* AddIAdd(uint32_t type, uint32_t op1, uint32_t op2) { + // TODO(1841): Handle id overflow. + std::unique_ptr inst(new Instruction( + GetContext(), spv::Op::OpIAdd, type, GetContext()->TakeNextId(), + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); + return AddInstruction(std::move(inst)); + } + + // Creates a less than instruction for unsigned integer. + // The id |op1| is the left hand side of the operation. + // The id |op2| is the right hand side of the operation. + // It is assumed that |op1| and |op2| have the same underlying type. + Instruction* AddULessThan(uint32_t op1, uint32_t op2) { + analysis::Bool bool_type; + uint32_t type = GetContext()->get_type_mgr()->GetId(&bool_type); + // TODO(1841): Handle id overflow. + std::unique_ptr inst(new Instruction( + GetContext(), spv::Op::OpULessThan, type, GetContext()->TakeNextId(), + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); + return AddInstruction(std::move(inst)); + } + + // Creates a less than instruction for signed integer. + // The id |op1| is the left hand side of the operation. + // The id |op2| is the right hand side of the operation. + // It is assumed that |op1| and |op2| have the same underlying type. + Instruction* AddSLessThan(uint32_t op1, uint32_t op2) { + analysis::Bool bool_type; + uint32_t type = GetContext()->get_type_mgr()->GetId(&bool_type); + // TODO(1841): Handle id overflow. + std::unique_ptr inst(new Instruction( + GetContext(), spv::Op::OpSLessThan, type, GetContext()->TakeNextId(), + {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); + return AddInstruction(std::move(inst)); + } + + // Creates an OpILessThan or OpULessThen instruction depending on the sign of + // |op1|. The id |op1| is the left hand side of the operation. The id |op2| is + // the right hand side of the operation. It is assumed that |op1| and |op2| + // have the same underlying type. + Instruction* AddLessThan(uint32_t op1, uint32_t op2) { + Instruction* op1_insn = context_->get_def_use_mgr()->GetDef(op1); + analysis::Type* type = + GetContext()->get_type_mgr()->GetType(op1_insn->type_id()); + analysis::Integer* int_type = type->AsInteger(); + assert(int_type && "Operand is not of int type"); + + if (int_type->IsSigned()) + return AddSLessThan(op1, op2); + else + return AddULessThan(op1, op2); + } + + // Creates a select instruction. + // |type| must match the types of |true_value| and |false_value|. It is up to + // the caller to ensure that |cond| is a correct type (bool or vector of + // bool) for |type|. + Instruction* AddSelect(uint32_t type, uint32_t cond, uint32_t true_value, + uint32_t false_value) { + // TODO(1841): Handle id overflow. + std::unique_ptr select(new Instruction( + GetContext(), spv::Op::OpSelect, type, GetContext()->TakeNextId(), + std::initializer_list{{SPV_OPERAND_TYPE_ID, {cond}}, + {SPV_OPERAND_TYPE_ID, {true_value}}, + {SPV_OPERAND_TYPE_ID, {false_value}}})); + return AddInstruction(std::move(select)); + } + + // Returns a pointer to the definition of a signed 32-bit integer constant + // with the given value. Returns |nullptr| if the constant does not exist and + // cannot be created. + Instruction* GetSintConstant(int32_t value) { + return GetIntConstant(value, true); + } + + // Create a composite construct. + // |type| should be a composite type and the number of elements it has should + // match the size od |ids|. + Instruction* AddCompositeConstruct(uint32_t type, + const std::vector& ids) { + std::vector ops; + for (auto id : ids) { + ops.emplace_back(SPV_OPERAND_TYPE_ID, + std::initializer_list{id}); + } + // TODO(1841): Handle id overflow. + std::unique_ptr construct( + new Instruction(GetContext(), spv::Op::OpCompositeConstruct, type, + GetContext()->TakeNextId(), ops)); + return AddInstruction(std::move(construct)); + } + + // Returns a pointer to the definition of an unsigned 32-bit integer constant + // with the given value. Returns |nullptr| if the constant does not exist and + // cannot be created. + Instruction* GetUintConstant(uint32_t value) { + return GetIntConstant(value, false); + } + + uint32_t GetUintConstantId(uint32_t value) { + Instruction* uint_inst = GetUintConstant(value); + return (uint_inst != nullptr ? uint_inst->result_id() : 0); + } + + // Adds either a signed or unsigned 32 bit integer constant to the binary + // depending on the |sign|. If |sign| is true then the value is added as a + // signed constant otherwise as an unsigned constant. If |sign| is false the + // value must not be a negative number. Returns false if the constant does + // not exists and could be be created. + template + Instruction* GetIntConstant(T value, bool sign) { + // Assert that we are not trying to store a negative number in an unsigned + // type. + if (!sign) + assert(value >= 0 && + "Trying to add a signed integer with an unsigned type!"); + + analysis::Integer int_type{32, sign}; + + // Get or create the integer type. This rebuilds the type and manages the + // memory for the rebuilt type. + uint32_t type_id = + GetContext()->get_type_mgr()->GetTypeInstruction(&int_type); + + if (type_id == 0) { + return nullptr; + } + + // Get the memory managed type so that it is safe to be stored by + // GetConstant. + analysis::Type* rebuilt_type = + GetContext()->get_type_mgr()->GetType(type_id); + + // Even if the value is negative we need to pass the bit pattern as a + // uint32_t to GetConstant. + uint32_t word = value; + + // Create the constant value. + const analysis::Constant* constant = + GetContext()->get_constant_mgr()->GetConstant(rebuilt_type, {word}); + + // Create the OpConstant instruction using the type and the value. + return GetContext()->get_constant_mgr()->GetDefiningInstruction(constant); + } + + Instruction* GetBoolConstant(bool value) { + analysis::Bool type; + uint32_t type_id = GetContext()->get_type_mgr()->GetTypeInstruction(&type); + analysis::Type* rebuilt_type = + GetContext()->get_type_mgr()->GetType(type_id); + uint32_t word = value; + const analysis::Constant* constant = + GetContext()->get_constant_mgr()->GetConstant(rebuilt_type, {word}); + return GetContext()->get_constant_mgr()->GetDefiningInstruction(constant); + } + + uint32_t GetBoolConstantId(bool value) { + Instruction* inst = GetBoolConstant(value); + return (inst != nullptr ? inst->result_id() : 0); + } + + Instruction* AddCompositeExtract(uint32_t type, uint32_t id_of_composite, + const std::vector& index_list) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {id_of_composite}}); + + for (uint32_t index : index_list) { + operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {index}}); + } + + // TODO(1841): Handle id overflow. + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpCompositeExtract, type, + GetContext()->TakeNextId(), operands)); + return AddInstruction(std::move(new_inst)); + } + + // Creates an unreachable instruction. + Instruction* AddUnreachable() { + std::unique_ptr select( + new Instruction(GetContext(), spv::Op::OpUnreachable, 0, 0, + std::initializer_list{})); + return AddInstruction(std::move(select)); + } + + Instruction* AddAccessChain(uint32_t type_id, uint32_t base_ptr_id, + std::vector ids) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {base_ptr_id}}); + + for (uint32_t index_id : ids) { + operands.push_back({SPV_OPERAND_TYPE_ID, {index_id}}); + } + + // TODO(1841): Handle id overflow. + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpAccessChain, type_id, + GetContext()->TakeNextId(), operands)); + return AddInstruction(std::move(new_inst)); + } + + Instruction* AddLoad(uint32_t type_id, uint32_t base_ptr_id, + uint32_t alignment = 0) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {base_ptr_id}}); + if (alignment != 0) { + operands.push_back( + {SPV_OPERAND_TYPE_MEMORY_ACCESS, + {static_cast(spv::MemoryAccessMask::Aligned)}}); + operands.push_back({SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, {alignment}}); + } + + // TODO(1841): Handle id overflow. + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpLoad, type_id, + GetContext()->TakeNextId(), operands)); + return AddInstruction(std::move(new_inst)); + } + + Instruction* AddVariable(uint32_t type_id, uint32_t storage_class) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {storage_class}}); + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpVariable, type_id, + GetContext()->TakeNextId(), operands)); + return AddInstruction(std::move(new_inst)); + } + + Instruction* AddStore(uint32_t ptr_id, uint32_t obj_id) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {ptr_id}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {obj_id}}); + + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpStore, 0, 0, operands)); + return AddInstruction(std::move(new_inst)); + } + + Instruction* AddFunctionCall(uint32_t result_type, uint32_t function, + const std::vector& parameters) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {function}}); + for (uint32_t id : parameters) { + operands.push_back({SPV_OPERAND_TYPE_ID, {id}}); + } + + uint32_t result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpFunctionCall, result_type, + result_id, operands)); + return AddInstruction(std::move(new_inst)); + } + + Instruction* AddVectorShuffle(uint32_t result_type, uint32_t vec1, + uint32_t vec2, + const std::vector& components) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {vec1}}); + operands.push_back({SPV_OPERAND_TYPE_ID, {vec2}}); + for (uint32_t id : components) { + operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {id}}); + } + + uint32_t result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + + std::unique_ptr new_inst( + new Instruction(GetContext(), spv::Op::OpVectorShuffle, result_type, + result_id, operands)); + return AddInstruction(std::move(new_inst)); + } + + Instruction* AddNaryExtendedInstruction( + uint32_t result_type, uint32_t set, uint32_t instruction, + const std::vector& ext_operands) { + std::vector operands; + operands.push_back({SPV_OPERAND_TYPE_ID, {set}}); + operands.push_back( + {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, {instruction}}); + for (uint32_t id : ext_operands) { + operands.push_back({SPV_OPERAND_TYPE_ID, {id}}); + } + + uint32_t result_id = GetContext()->TakeNextId(); + if (result_id == 0) { + return nullptr; + } + + std::unique_ptr new_inst(new Instruction( + GetContext(), spv::Op::OpExtInst, result_type, result_id, operands)); + return AddInstruction(std::move(new_inst)); + } + + // Inserts the new instruction before the insertion point. + Instruction* AddInstruction(std::unique_ptr&& insn) { + Instruction* insn_ptr = &*insert_before_.InsertBefore(std::move(insn)); + UpdateInstrToBlockMapping(insn_ptr); + UpdateDefUseMgr(insn_ptr); + return insn_ptr; + } + + // Returns the insertion point iterator. + InsertionPointTy GetInsertPoint() { return insert_before_; } + + // Change the insertion point to insert before the instruction + // |insert_before|. + void SetInsertPoint(Instruction* insert_before) { + parent_ = context_->get_instr_block(insert_before); + insert_before_ = InsertionPointTy(insert_before); + } + + // Change the insertion point to insert at the end of the basic block + // |parent_block|. + void SetInsertPoint(BasicBlock* parent_block) { + parent_ = parent_block; + insert_before_ = parent_block->end(); + } + + // Returns the context which instructions are constructed for. + IRContext* GetContext() const { return context_; } + + // Returns the set of preserved analyses. + inline IRContext::Analysis GetPreservedAnalysis() const { + return preserved_analyses_; + } + + private: + InstructionBuilder(IRContext* context, BasicBlock* parent, + InsertionPointTy insert_before, + IRContext::Analysis preserved_analyses) + : context_(context), + parent_(parent), + insert_before_(insert_before), + preserved_analyses_(preserved_analyses) { + assert(!(preserved_analyses_ & ~(IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping))); + } + + // Returns true if the users requested to update |analysis|. + inline bool IsAnalysisUpdateRequested(IRContext::Analysis analysis) const { + if (!GetContext()->AreAnalysesValid(analysis)) { + // Do not try to update something that is not built. + return false; + } + return preserved_analyses_ & analysis; + } + + // Updates the def/use manager if the user requested it. If an update was not + // requested, this function does nothing. + inline void UpdateDefUseMgr(Instruction* insn) { + if (IsAnalysisUpdateRequested(IRContext::kAnalysisDefUse)) + GetContext()->get_def_use_mgr()->AnalyzeInstDefUse(insn); + } + + // Updates the instruction to block analysis if the user requested it. If + // an update was not requested, this function does nothing. + inline void UpdateInstrToBlockMapping(Instruction* insn) { + if (IsAnalysisUpdateRequested(IRContext::kAnalysisInstrToBlockMapping) && + parent_) + GetContext()->set_instr_block(insn, parent_); + } + + IRContext* context_; + BasicBlock* parent_; + InsertionPointTy insert_before_; + const IRContext::Analysis preserved_analyses_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_IR_BUILDER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ir_context.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/ir_context.cpp new file mode 100644 index 000000000000..239d316ca8b3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ir_context.cpp @@ -0,0 +1,1143 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/ir_context.h" + +#include + +#include "OpenCLDebugInfo100.h" +#include "source/latest_version_glsl_std_450_header.h" +#include "source/opt/log.h" +#include "source/opt/reflect.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr int kSpvDecorateTargetIdInIdx = 0; +constexpr int kSpvDecorateDecorationInIdx = 1; +constexpr int kSpvDecorateBuiltinInIdx = 2; +constexpr int kEntryPointInterfaceInIdx = 3; +constexpr int kEntryPointFunctionIdInIdx = 1; +constexpr int kEntryPointExecutionModelInIdx = 0; + +// Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100 +// extension instructions. +constexpr uint32_t kDebugFunctionOperandFunctionIndex = 13; +constexpr uint32_t kDebugGlobalVariableOperandVariableIndex = 11; +} // namespace + +void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) { + set = Analysis(set & ~valid_analyses_); + + if (set & kAnalysisDefUse) { + BuildDefUseManager(); + } + if (set & kAnalysisInstrToBlockMapping) { + BuildInstrToBlockMapping(); + } + if (set & kAnalysisDecorations) { + BuildDecorationManager(); + } + if (set & kAnalysisCFG) { + BuildCFG(); + } + if (set & kAnalysisDominatorAnalysis) { + ResetDominatorAnalysis(); + } + if (set & kAnalysisLoopAnalysis) { + ResetLoopAnalysis(); + } + if (set & kAnalysisBuiltinVarId) { + ResetBuiltinAnalysis(); + } + if (set & kAnalysisNameMap) { + BuildIdToNameMap(); + } + if (set & kAnalysisScalarEvolution) { + BuildScalarEvolutionAnalysis(); + } + if (set & kAnalysisRegisterPressure) { + BuildRegPressureAnalysis(); + } + if (set & kAnalysisValueNumberTable) { + BuildValueNumberTable(); + } + if (set & kAnalysisStructuredCFG) { + BuildStructuredCFGAnalysis(); + } + if (set & kAnalysisIdToFuncMapping) { + BuildIdToFuncMapping(); + } + if (set & kAnalysisConstants) { + BuildConstantManager(); + } + if (set & kAnalysisTypes) { + BuildTypeManager(); + } + if (set & kAnalysisDebugInfo) { + BuildDebugInfoManager(); + } +} + +void IRContext::InvalidateAnalysesExceptFor( + IRContext::Analysis preserved_analyses) { + uint32_t analyses_to_invalidate = valid_analyses_ & (~preserved_analyses); + InvalidateAnalyses(static_cast(analyses_to_invalidate)); +} + +void IRContext::InvalidateAnalyses(IRContext::Analysis analyses_to_invalidate) { + // The ConstantManager and DebugInfoManager contain Type pointers. If the + // TypeManager goes away, the ConstantManager and DebugInfoManager have to + // go away. + if (analyses_to_invalidate & kAnalysisTypes) { + analyses_to_invalidate |= kAnalysisConstants; + analyses_to_invalidate |= kAnalysisDebugInfo; + } + + // The dominator analysis hold the pseudo entry and exit nodes from the CFG. + // Also if the CFG change the dominators many changed as well, so the + // dominator analysis should be invalidated as well. + if (analyses_to_invalidate & kAnalysisCFG) { + analyses_to_invalidate |= kAnalysisDominatorAnalysis; + } + + if (analyses_to_invalidate & kAnalysisDefUse) { + def_use_mgr_.reset(nullptr); + } + if (analyses_to_invalidate & kAnalysisInstrToBlockMapping) { + instr_to_block_.clear(); + } + if (analyses_to_invalidate & kAnalysisDecorations) { + decoration_mgr_.reset(nullptr); + } + if (analyses_to_invalidate & kAnalysisCombinators) { + combinator_ops_.clear(); + } + if (analyses_to_invalidate & kAnalysisBuiltinVarId) { + builtin_var_id_map_.clear(); + } + if (analyses_to_invalidate & kAnalysisCFG) { + cfg_.reset(nullptr); + } + if (analyses_to_invalidate & kAnalysisDominatorAnalysis) { + dominator_trees_.clear(); + post_dominator_trees_.clear(); + } + if (analyses_to_invalidate & kAnalysisNameMap) { + id_to_name_.reset(nullptr); + } + if (analyses_to_invalidate & kAnalysisValueNumberTable) { + vn_table_.reset(nullptr); + } + if (analyses_to_invalidate & kAnalysisStructuredCFG) { + struct_cfg_analysis_.reset(nullptr); + } + if (analyses_to_invalidate & kAnalysisIdToFuncMapping) { + id_to_func_.clear(); + } + if (analyses_to_invalidate & kAnalysisConstants) { + constant_mgr_.reset(nullptr); + } + if (analyses_to_invalidate & kAnalysisLiveness) { + liveness_mgr_.reset(nullptr); + } + if (analyses_to_invalidate & kAnalysisTypes) { + type_mgr_.reset(nullptr); + } + + if (analyses_to_invalidate & kAnalysisDebugInfo) { + debug_info_mgr_.reset(nullptr); + } + + valid_analyses_ = Analysis(valid_analyses_ & ~analyses_to_invalidate); +} + +Instruction* IRContext::KillInst(Instruction* inst) { + if (!inst) { + return nullptr; + } + + KillNamesAndDecorates(inst); + + KillOperandFromDebugInstructions(inst); + + if (AreAnalysesValid(kAnalysisDefUse)) { + analysis::DefUseManager* def_use_mgr = get_def_use_mgr(); + def_use_mgr->ClearInst(inst); + for (auto& l_inst : inst->dbg_line_insts()) def_use_mgr->ClearInst(&l_inst); + } + if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) { + instr_to_block_.erase(inst); + } + if (AreAnalysesValid(kAnalysisDecorations)) { + if (inst->IsDecoration()) { + decoration_mgr_->RemoveDecoration(inst); + } + } + if (AreAnalysesValid(kAnalysisDebugInfo)) { + get_debug_info_mgr()->ClearDebugScopeAndInlinedAtUses(inst); + get_debug_info_mgr()->ClearDebugInfo(inst); + } + if (type_mgr_ && IsTypeInst(inst->opcode())) { + type_mgr_->RemoveId(inst->result_id()); + } + if (constant_mgr_ && IsConstantInst(inst->opcode())) { + constant_mgr_->RemoveId(inst->result_id()); + } + if (inst->opcode() == spv::Op::OpCapability || + inst->opcode() == spv::Op::OpExtension) { + // We reset the feature manager, instead of updating it, because it is just + // as much work. We would have to remove all capabilities implied by this + // capability that are not also implied by the remaining OpCapability + // instructions. We could update extensions, but we will see if it is + // needed. + ResetFeatureManager(); + } + + RemoveFromIdToName(inst); + + Instruction* next_instruction = nullptr; + if (inst->IsInAList()) { + next_instruction = inst->NextNode(); + inst->RemoveFromList(); + delete inst; + } else { + // Needed for instructions that are not part of a list like OpLabels, + // OpFunction, OpFunctionEnd, etc.. + inst->ToNop(); + } + return next_instruction; +} + +bool IRContext::KillInstructionIf(Module::inst_iterator begin, + Module::inst_iterator end, + std::function condition) { + bool removed = false; + for (auto it = begin; it != end;) { + if (!condition(&*it)) { + ++it; + continue; + } + + removed = true; + // `it` is an iterator on an intrusive list. Next is invalidated on the + // current node when an instruction is killed. The iterator must be moved + // forward before deleting the node. + auto instruction = &*it; + ++it; + KillInst(instruction); + } + + return removed; +} + +void IRContext::CollectNonSemanticTree( + Instruction* inst, std::unordered_set* to_kill) { + if (!inst->HasResultId()) return; + // Debug[No]Line result id is not used, so we are done + if (inst->IsDebugLineInst()) return; + std::vector work_list; + std::unordered_set seen; + work_list.push_back(inst); + + while (!work_list.empty()) { + auto* i = work_list.back(); + work_list.pop_back(); + get_def_use_mgr()->ForEachUser( + i, [&work_list, to_kill, &seen](Instruction* user) { + if (user->IsNonSemanticInstruction() && seen.insert(user).second) { + work_list.push_back(user); + to_kill->insert(user); + } + }); + } +} + +bool IRContext::KillDef(uint32_t id) { + Instruction* def = get_def_use_mgr()->GetDef(id); + if (def != nullptr) { + KillInst(def); + return true; + } + return false; +} + +bool IRContext::RemoveCapability(spv::Capability capability) { + const bool removed = KillInstructionIf( + module()->capability_begin(), module()->capability_end(), + [capability](Instruction* inst) { + return static_cast(inst->GetSingleWordOperand(0)) == + capability; + }); + + if (removed && feature_mgr_ != nullptr) { + feature_mgr_->RemoveCapability(capability); + } + + return removed; +} + +bool IRContext::RemoveExtension(Extension extension) { + const std::string_view extensionName = ExtensionToString(extension); + const bool removed = KillInstructionIf( + module()->extension_begin(), module()->extension_end(), + [&extensionName](Instruction* inst) { + return inst->GetOperand(0).AsString() == extensionName; + }); + + if (removed && feature_mgr_ != nullptr) { + feature_mgr_->RemoveExtension(extension); + } + + return removed; +} + +bool IRContext::ReplaceAllUsesWith(uint32_t before, uint32_t after) { + return ReplaceAllUsesWithPredicate(before, after, + [](Instruction*) { return true; }); +} + +bool IRContext::ReplaceAllUsesWithPredicate( + uint32_t before, uint32_t after, + const std::function& predicate) { + if (before == after) return false; + + if (AreAnalysesValid(kAnalysisDebugInfo)) { + get_debug_info_mgr()->ReplaceAllUsesInDebugScopeWithPredicate(before, after, + predicate); + } + + // Ensure that |after| has been registered as def. + assert(get_def_use_mgr()->GetDef(after) && + "'after' is not a registered def."); + + std::vector> uses_to_update; + get_def_use_mgr()->ForEachUse( + before, [&predicate, &uses_to_update](Instruction* user, uint32_t index) { + if (predicate(user)) { + uses_to_update.emplace_back(user, index); + } + }); + + Instruction* prev = nullptr; + for (auto p : uses_to_update) { + Instruction* user = p.first; + uint32_t index = p.second; + if (prev == nullptr || prev != user) { + ForgetUses(user); + prev = user; + } + const uint32_t type_result_id_count = + (user->result_id() != 0) + (user->type_id() != 0); + + if (index < type_result_id_count) { + // Update the type_id. Note that result id is immutable so it should + // never be updated. + if (user->type_id() != 0 && index == 0) { + user->SetResultType(after); + } else if (user->type_id() == 0) { + SPIRV_ASSERT(consumer_, false, + "Result type id considered as use while the instruction " + "doesn't have a result type id."); + (void)consumer_; // Makes the compiler happy for release build. + } else { + SPIRV_ASSERT(consumer_, false, + "Trying setting the immutable result id."); + } + } else { + // Update an in-operand. + uint32_t in_operand_pos = index - type_result_id_count; + // Make the modification in the instruction. + user->SetInOperand(in_operand_pos, {after}); + } + AnalyzeUses(user); + } + return true; +} + +bool IRContext::IsConsistent() { +#ifndef SPIRV_CHECK_CONTEXT + return true; +#else + if (AreAnalysesValid(kAnalysisDefUse)) { + analysis::DefUseManager new_def_use(module()); + if (!CompareAndPrintDifferences(*get_def_use_mgr(), new_def_use)) { + return false; + } + } + + if (AreAnalysesValid(kAnalysisIdToFuncMapping)) { + for (auto& fn : *module_) { + if (id_to_func_[fn.result_id()] != &fn) { + return false; + } + } + } + + if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) { + for (auto& func : *module()) { + for (auto& block : func) { + if (!block.WhileEachInst([this, &block](Instruction* inst) { + if (get_instr_block(inst) != &block) { + return false; + } + return true; + })) + return false; + } + } + } + + if (!CheckCFG()) { + return false; + } + + if (AreAnalysesValid(kAnalysisDecorations)) { + analysis::DecorationManager* dec_mgr = get_decoration_mgr(); + analysis::DecorationManager current(module()); + + if (*dec_mgr != current) { + return false; + } + } + + if (feature_mgr_ != nullptr) { + FeatureManager current(grammar_); + current.Analyze(module()); + + if (current != *feature_mgr_) { + return false; + } + } + return true; +#endif +} + +void IRContext::ForgetUses(Instruction* inst) { + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->EraseUseRecordsOfOperandIds(inst); + } + if (AreAnalysesValid(kAnalysisDecorations)) { + if (inst->IsDecoration()) { + get_decoration_mgr()->RemoveDecoration(inst); + } + } + if (AreAnalysesValid(kAnalysisDebugInfo)) { + get_debug_info_mgr()->ClearDebugInfo(inst); + } + RemoveFromIdToName(inst); +} + +void IRContext::AnalyzeUses(Instruction* inst) { + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstUse(inst); + } + if (AreAnalysesValid(kAnalysisDecorations)) { + if (inst->IsDecoration()) { + get_decoration_mgr()->AddDecoration(inst); + } + } + if (AreAnalysesValid(kAnalysisDebugInfo)) { + get_debug_info_mgr()->AnalyzeDebugInst(inst); + } + if (id_to_name_ && (inst->opcode() == spv::Op::OpName || + inst->opcode() == spv::Op::OpMemberName)) { + id_to_name_->insert({inst->GetSingleWordInOperand(0), inst}); + } +} + +void IRContext::KillNamesAndDecorates(uint32_t id) { + analysis::DecorationManager* dec_mgr = get_decoration_mgr(); + dec_mgr->RemoveDecorationsFrom(id); + + std::vector name_to_kill; + for (auto name : GetNames(id)) { + name_to_kill.push_back(name.second); + } + for (Instruction* name_inst : name_to_kill) { + KillInst(name_inst); + } +} + +void IRContext::KillNamesAndDecorates(Instruction* inst) { + const uint32_t rId = inst->result_id(); + if (rId == 0) return; + KillNamesAndDecorates(rId); +} + +void IRContext::KillOperandFromDebugInstructions(Instruction* inst) { + const auto opcode = inst->opcode(); + const uint32_t id = inst->result_id(); + // Kill id of OpFunction from DebugFunction. + if (opcode == spv::Op::OpFunction) { + for (auto it = module()->ext_inst_debuginfo_begin(); + it != module()->ext_inst_debuginfo_end(); ++it) { + if (it->GetOpenCL100DebugOpcode() != OpenCLDebugInfo100DebugFunction) + continue; + auto& operand = it->GetOperand(kDebugFunctionOperandFunctionIndex); + if (operand.words[0] == id) { + operand.words[0] = + get_debug_info_mgr()->GetDebugInfoNone()->result_id(); + get_def_use_mgr()->AnalyzeInstUse(&*it); + } + } + } + // Kill id of OpVariable for global variable from DebugGlobalVariable. + if (opcode == spv::Op::OpVariable || IsConstantInst(opcode)) { + for (auto it = module()->ext_inst_debuginfo_begin(); + it != module()->ext_inst_debuginfo_end(); ++it) { + if (it->GetCommonDebugOpcode() != CommonDebugInfoDebugGlobalVariable) + continue; + auto& operand = it->GetOperand(kDebugGlobalVariableOperandVariableIndex); + if (operand.words[0] == id) { + operand.words[0] = + get_debug_info_mgr()->GetDebugInfoNone()->result_id(); + get_def_use_mgr()->AnalyzeInstUse(&*it); + } + } + } +} + +void IRContext::AddCombinatorsForCapability(uint32_t capability) { + spv::Capability cap = spv::Capability(capability); + if (cap == spv::Capability::Shader) { + combinator_ops_[0].insert( + {(uint32_t)spv::Op::OpNop, + (uint32_t)spv::Op::OpUndef, + (uint32_t)spv::Op::OpConstant, + (uint32_t)spv::Op::OpConstantTrue, + (uint32_t)spv::Op::OpConstantFalse, + (uint32_t)spv::Op::OpConstantComposite, + (uint32_t)spv::Op::OpConstantSampler, + (uint32_t)spv::Op::OpConstantNull, + (uint32_t)spv::Op::OpTypeVoid, + (uint32_t)spv::Op::OpTypeBool, + (uint32_t)spv::Op::OpTypeInt, + (uint32_t)spv::Op::OpTypeFloat, + (uint32_t)spv::Op::OpTypeVector, + (uint32_t)spv::Op::OpTypeMatrix, + (uint32_t)spv::Op::OpTypeImage, + (uint32_t)spv::Op::OpTypeSampler, + (uint32_t)spv::Op::OpTypeSampledImage, + (uint32_t)spv::Op::OpTypeAccelerationStructureNV, + (uint32_t)spv::Op::OpTypeAccelerationStructureKHR, + (uint32_t)spv::Op::OpTypeRayQueryKHR, + (uint32_t)spv::Op::OpTypeHitObjectNV, + (uint32_t)spv::Op::OpTypeArray, + (uint32_t)spv::Op::OpTypeRuntimeArray, + (uint32_t)spv::Op::OpTypeStruct, + (uint32_t)spv::Op::OpTypeOpaque, + (uint32_t)spv::Op::OpTypePointer, + (uint32_t)spv::Op::OpTypeFunction, + (uint32_t)spv::Op::OpTypeEvent, + (uint32_t)spv::Op::OpTypeDeviceEvent, + (uint32_t)spv::Op::OpTypeReserveId, + (uint32_t)spv::Op::OpTypeQueue, + (uint32_t)spv::Op::OpTypePipe, + (uint32_t)spv::Op::OpTypeForwardPointer, + (uint32_t)spv::Op::OpVariable, + (uint32_t)spv::Op::OpImageTexelPointer, + (uint32_t)spv::Op::OpLoad, + (uint32_t)spv::Op::OpAccessChain, + (uint32_t)spv::Op::OpInBoundsAccessChain, + (uint32_t)spv::Op::OpArrayLength, + (uint32_t)spv::Op::OpVectorExtractDynamic, + (uint32_t)spv::Op::OpVectorInsertDynamic, + (uint32_t)spv::Op::OpVectorShuffle, + (uint32_t)spv::Op::OpCompositeConstruct, + (uint32_t)spv::Op::OpCompositeExtract, + (uint32_t)spv::Op::OpCompositeInsert, + (uint32_t)spv::Op::OpCopyObject, + (uint32_t)spv::Op::OpTranspose, + (uint32_t)spv::Op::OpSampledImage, + (uint32_t)spv::Op::OpImageSampleImplicitLod, + (uint32_t)spv::Op::OpImageSampleExplicitLod, + (uint32_t)spv::Op::OpImageSampleDrefImplicitLod, + (uint32_t)spv::Op::OpImageSampleDrefExplicitLod, + (uint32_t)spv::Op::OpImageSampleProjImplicitLod, + (uint32_t)spv::Op::OpImageSampleProjExplicitLod, + (uint32_t)spv::Op::OpImageSampleProjDrefImplicitLod, + (uint32_t)spv::Op::OpImageSampleProjDrefExplicitLod, + (uint32_t)spv::Op::OpImageFetch, + (uint32_t)spv::Op::OpImageGather, + (uint32_t)spv::Op::OpImageDrefGather, + (uint32_t)spv::Op::OpImageRead, + (uint32_t)spv::Op::OpImage, + (uint32_t)spv::Op::OpImageQueryFormat, + (uint32_t)spv::Op::OpImageQueryOrder, + (uint32_t)spv::Op::OpImageQuerySizeLod, + (uint32_t)spv::Op::OpImageQuerySize, + (uint32_t)spv::Op::OpImageQueryLevels, + (uint32_t)spv::Op::OpImageQuerySamples, + (uint32_t)spv::Op::OpConvertFToU, + (uint32_t)spv::Op::OpConvertFToS, + (uint32_t)spv::Op::OpConvertSToF, + (uint32_t)spv::Op::OpConvertUToF, + (uint32_t)spv::Op::OpUConvert, + (uint32_t)spv::Op::OpSConvert, + (uint32_t)spv::Op::OpFConvert, + (uint32_t)spv::Op::OpQuantizeToF16, + (uint32_t)spv::Op::OpBitcast, + (uint32_t)spv::Op::OpSNegate, + (uint32_t)spv::Op::OpFNegate, + (uint32_t)spv::Op::OpIAdd, + (uint32_t)spv::Op::OpFAdd, + (uint32_t)spv::Op::OpISub, + (uint32_t)spv::Op::OpFSub, + (uint32_t)spv::Op::OpIMul, + (uint32_t)spv::Op::OpFMul, + (uint32_t)spv::Op::OpUDiv, + (uint32_t)spv::Op::OpSDiv, + (uint32_t)spv::Op::OpFDiv, + (uint32_t)spv::Op::OpUMod, + (uint32_t)spv::Op::OpSRem, + (uint32_t)spv::Op::OpSMod, + (uint32_t)spv::Op::OpFRem, + (uint32_t)spv::Op::OpFMod, + (uint32_t)spv::Op::OpVectorTimesScalar, + (uint32_t)spv::Op::OpMatrixTimesScalar, + (uint32_t)spv::Op::OpVectorTimesMatrix, + (uint32_t)spv::Op::OpMatrixTimesVector, + (uint32_t)spv::Op::OpMatrixTimesMatrix, + (uint32_t)spv::Op::OpOuterProduct, + (uint32_t)spv::Op::OpDot, + (uint32_t)spv::Op::OpIAddCarry, + (uint32_t)spv::Op::OpISubBorrow, + (uint32_t)spv::Op::OpUMulExtended, + (uint32_t)spv::Op::OpSMulExtended, + (uint32_t)spv::Op::OpAny, + (uint32_t)spv::Op::OpAll, + (uint32_t)spv::Op::OpIsNan, + (uint32_t)spv::Op::OpIsInf, + (uint32_t)spv::Op::OpLogicalEqual, + (uint32_t)spv::Op::OpLogicalNotEqual, + (uint32_t)spv::Op::OpLogicalOr, + (uint32_t)spv::Op::OpLogicalAnd, + (uint32_t)spv::Op::OpLogicalNot, + (uint32_t)spv::Op::OpSelect, + (uint32_t)spv::Op::OpIEqual, + (uint32_t)spv::Op::OpINotEqual, + (uint32_t)spv::Op::OpUGreaterThan, + (uint32_t)spv::Op::OpSGreaterThan, + (uint32_t)spv::Op::OpUGreaterThanEqual, + (uint32_t)spv::Op::OpSGreaterThanEqual, + (uint32_t)spv::Op::OpULessThan, + (uint32_t)spv::Op::OpSLessThan, + (uint32_t)spv::Op::OpULessThanEqual, + (uint32_t)spv::Op::OpSLessThanEqual, + (uint32_t)spv::Op::OpFOrdEqual, + (uint32_t)spv::Op::OpFUnordEqual, + (uint32_t)spv::Op::OpFOrdNotEqual, + (uint32_t)spv::Op::OpFUnordNotEqual, + (uint32_t)spv::Op::OpFOrdLessThan, + (uint32_t)spv::Op::OpFUnordLessThan, + (uint32_t)spv::Op::OpFOrdGreaterThan, + (uint32_t)spv::Op::OpFUnordGreaterThan, + (uint32_t)spv::Op::OpFOrdLessThanEqual, + (uint32_t)spv::Op::OpFUnordLessThanEqual, + (uint32_t)spv::Op::OpFOrdGreaterThanEqual, + (uint32_t)spv::Op::OpFUnordGreaterThanEqual, + (uint32_t)spv::Op::OpShiftRightLogical, + (uint32_t)spv::Op::OpShiftRightArithmetic, + (uint32_t)spv::Op::OpShiftLeftLogical, + (uint32_t)spv::Op::OpBitwiseOr, + (uint32_t)spv::Op::OpBitwiseXor, + (uint32_t)spv::Op::OpBitwiseAnd, + (uint32_t)spv::Op::OpNot, + (uint32_t)spv::Op::OpBitFieldInsert, + (uint32_t)spv::Op::OpBitFieldSExtract, + (uint32_t)spv::Op::OpBitFieldUExtract, + (uint32_t)spv::Op::OpBitReverse, + (uint32_t)spv::Op::OpBitCount, + (uint32_t)spv::Op::OpPhi, + (uint32_t)spv::Op::OpImageSparseSampleImplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleExplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleDrefImplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleDrefExplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleProjImplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleProjExplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleProjDrefImplicitLod, + (uint32_t)spv::Op::OpImageSparseSampleProjDrefExplicitLod, + (uint32_t)spv::Op::OpImageSparseFetch, + (uint32_t)spv::Op::OpImageSparseGather, + (uint32_t)spv::Op::OpImageSparseDrefGather, + (uint32_t)spv::Op::OpImageSparseTexelsResident, + (uint32_t)spv::Op::OpImageSparseRead, + (uint32_t)spv::Op::OpSizeOf}); + } +} + +void IRContext::AddCombinatorsForExtension(Instruction* extension) { + assert(extension->opcode() == spv::Op::OpExtInstImport && + "Expecting an import of an extension's instruction set."); + const std::string extension_name = extension->GetInOperand(0).AsString(); + if (extension_name == "GLSL.std.450") { + combinator_ops_[extension->result_id()] = { + (uint32_t)GLSLstd450Round, + (uint32_t)GLSLstd450RoundEven, + (uint32_t)GLSLstd450Trunc, + (uint32_t)GLSLstd450FAbs, + (uint32_t)GLSLstd450SAbs, + (uint32_t)GLSLstd450FSign, + (uint32_t)GLSLstd450SSign, + (uint32_t)GLSLstd450Floor, + (uint32_t)GLSLstd450Ceil, + (uint32_t)GLSLstd450Fract, + (uint32_t)GLSLstd450Radians, + (uint32_t)GLSLstd450Degrees, + (uint32_t)GLSLstd450Sin, + (uint32_t)GLSLstd450Cos, + (uint32_t)GLSLstd450Tan, + (uint32_t)GLSLstd450Asin, + (uint32_t)GLSLstd450Acos, + (uint32_t)GLSLstd450Atan, + (uint32_t)GLSLstd450Sinh, + (uint32_t)GLSLstd450Cosh, + (uint32_t)GLSLstd450Tanh, + (uint32_t)GLSLstd450Asinh, + (uint32_t)GLSLstd450Acosh, + (uint32_t)GLSLstd450Atanh, + (uint32_t)GLSLstd450Atan2, + (uint32_t)GLSLstd450Pow, + (uint32_t)GLSLstd450Exp, + (uint32_t)GLSLstd450Log, + (uint32_t)GLSLstd450Exp2, + (uint32_t)GLSLstd450Log2, + (uint32_t)GLSLstd450Sqrt, + (uint32_t)GLSLstd450InverseSqrt, + (uint32_t)GLSLstd450Determinant, + (uint32_t)GLSLstd450MatrixInverse, + (uint32_t)GLSLstd450ModfStruct, + (uint32_t)GLSLstd450FMin, + (uint32_t)GLSLstd450UMin, + (uint32_t)GLSLstd450SMin, + (uint32_t)GLSLstd450FMax, + (uint32_t)GLSLstd450UMax, + (uint32_t)GLSLstd450SMax, + (uint32_t)GLSLstd450FClamp, + (uint32_t)GLSLstd450UClamp, + (uint32_t)GLSLstd450SClamp, + (uint32_t)GLSLstd450FMix, + (uint32_t)GLSLstd450IMix, + (uint32_t)GLSLstd450Step, + (uint32_t)GLSLstd450SmoothStep, + (uint32_t)GLSLstd450Fma, + (uint32_t)GLSLstd450FrexpStruct, + (uint32_t)GLSLstd450Ldexp, + (uint32_t)GLSLstd450PackSnorm4x8, + (uint32_t)GLSLstd450PackUnorm4x8, + (uint32_t)GLSLstd450PackSnorm2x16, + (uint32_t)GLSLstd450PackUnorm2x16, + (uint32_t)GLSLstd450PackHalf2x16, + (uint32_t)GLSLstd450PackDouble2x32, + (uint32_t)GLSLstd450UnpackSnorm2x16, + (uint32_t)GLSLstd450UnpackUnorm2x16, + (uint32_t)GLSLstd450UnpackHalf2x16, + (uint32_t)GLSLstd450UnpackSnorm4x8, + (uint32_t)GLSLstd450UnpackUnorm4x8, + (uint32_t)GLSLstd450UnpackDouble2x32, + (uint32_t)GLSLstd450Length, + (uint32_t)GLSLstd450Distance, + (uint32_t)GLSLstd450Cross, + (uint32_t)GLSLstd450Normalize, + (uint32_t)GLSLstd450FaceForward, + (uint32_t)GLSLstd450Reflect, + (uint32_t)GLSLstd450Refract, + (uint32_t)GLSLstd450FindILsb, + (uint32_t)GLSLstd450FindSMsb, + (uint32_t)GLSLstd450FindUMsb, + (uint32_t)GLSLstd450InterpolateAtCentroid, + (uint32_t)GLSLstd450InterpolateAtSample, + (uint32_t)GLSLstd450InterpolateAtOffset, + (uint32_t)GLSLstd450NMin, + (uint32_t)GLSLstd450NMax, + (uint32_t)GLSLstd450NClamp}; + } else { + // Map the result id to the empty set. + combinator_ops_[extension->result_id()]; + } +} + +void IRContext::InitializeCombinators() { + for (auto capability : get_feature_mgr()->GetCapabilities()) { + AddCombinatorsForCapability(uint32_t(capability)); + } + + for (auto& extension : module()->ext_inst_imports()) { + AddCombinatorsForExtension(&extension); + } + + valid_analyses_ |= kAnalysisCombinators; +} + +void IRContext::RemoveFromIdToName(const Instruction* inst) { + if (id_to_name_ && (inst->opcode() == spv::Op::OpName || + inst->opcode() == spv::Op::OpMemberName)) { + auto range = id_to_name_->equal_range(inst->GetSingleWordInOperand(0)); + for (auto it = range.first; it != range.second; ++it) { + if (it->second == inst) { + id_to_name_->erase(it); + break; + } + } + } +} + +LoopDescriptor* IRContext::GetLoopDescriptor(const Function* f) { + if (!AreAnalysesValid(kAnalysisLoopAnalysis)) { + ResetLoopAnalysis(); + } + + std::unordered_map::iterator it = + loop_descriptors_.find(f); + if (it == loop_descriptors_.end()) { + return &loop_descriptors_ + .emplace(std::make_pair(f, LoopDescriptor(this, f))) + .first->second; + } + + return &it->second; +} + +uint32_t IRContext::FindBuiltinInputVar(uint32_t builtin) { + for (auto& a : module_->annotations()) { + if (spv::Op(a.opcode()) != spv::Op::OpDecorate) continue; + if (spv::Decoration(a.GetSingleWordInOperand( + kSpvDecorateDecorationInIdx)) != spv::Decoration::BuiltIn) + continue; + if (a.GetSingleWordInOperand(kSpvDecorateBuiltinInIdx) != builtin) continue; + uint32_t target_id = a.GetSingleWordInOperand(kSpvDecorateTargetIdInIdx); + Instruction* b_var = get_def_use_mgr()->GetDef(target_id); + if (b_var->opcode() != spv::Op::OpVariable) continue; + if (spv::StorageClass(b_var->GetSingleWordInOperand(0)) != + spv::StorageClass::Input) + continue; + return target_id; + } + return 0; +} + +void IRContext::AddVarToEntryPoints(uint32_t var_id) { + uint32_t ocnt = 0; + for (auto& e : module()->entry_points()) { + bool found = false; + e.ForEachInOperand([&ocnt, &found, &var_id](const uint32_t* idp) { + if (ocnt >= kEntryPointInterfaceInIdx) { + if (*idp == var_id) found = true; + } + ++ocnt; + }); + if (!found) { + e.AddOperand({SPV_OPERAND_TYPE_ID, {var_id}}); + get_def_use_mgr()->AnalyzeInstDefUse(&e); + } + } +} + +uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { + if (!AreAnalysesValid(kAnalysisBuiltinVarId)) ResetBuiltinAnalysis(); + // If cached, return it. + std::unordered_map::iterator it = + builtin_var_id_map_.find(builtin); + if (it != builtin_var_id_map_.end()) return it->second; + // Look for one in shader + uint32_t var_id = FindBuiltinInputVar(builtin); + if (var_id == 0) { + // If not found, create it + // TODO(greg-lunarg): Add support for all builtins + analysis::TypeManager* type_mgr = get_type_mgr(); + analysis::Type* reg_type; + switch (spv::BuiltIn(builtin)) { + case spv::BuiltIn::FragCoord: { + analysis::Float float_ty(32); + analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty); + analysis::Vector v4float_ty(reg_float_ty, 4); + reg_type = type_mgr->GetRegisteredType(&v4float_ty); + break; + } + case spv::BuiltIn::VertexIndex: + case spv::BuiltIn::InstanceIndex: + case spv::BuiltIn::PrimitiveId: + case spv::BuiltIn::InvocationId: + case spv::BuiltIn::SubgroupLocalInvocationId: { + analysis::Integer uint_ty(32, false); + reg_type = type_mgr->GetRegisteredType(&uint_ty); + break; + } + case spv::BuiltIn::GlobalInvocationId: + case spv::BuiltIn::LaunchIdNV: { + analysis::Integer uint_ty(32, false); + analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); + analysis::Vector v3uint_ty(reg_uint_ty, 3); + reg_type = type_mgr->GetRegisteredType(&v3uint_ty); + break; + } + case spv::BuiltIn::TessCoord: { + analysis::Float float_ty(32); + analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty); + analysis::Vector v3float_ty(reg_float_ty, 3); + reg_type = type_mgr->GetRegisteredType(&v3float_ty); + break; + } + case spv::BuiltIn::SubgroupLtMask: { + analysis::Integer uint_ty(32, false); + analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); + analysis::Vector v4uint_ty(reg_uint_ty, 4); + reg_type = type_mgr->GetRegisteredType(&v4uint_ty); + break; + } + default: { + assert(false && "unhandled builtin"); + return 0; + } + } + uint32_t type_id = type_mgr->GetTypeInstruction(reg_type); + uint32_t varTyPtrId = + type_mgr->FindPointerToType(type_id, spv::StorageClass::Input); + // TODO(1841): Handle id overflow. + var_id = TakeNextId(); + std::unique_ptr newVarOp( + new Instruction(this, spv::Op::OpVariable, varTyPtrId, var_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {uint32_t(spv::StorageClass::Input)}}})); + get_def_use_mgr()->AnalyzeInstDefUse(&*newVarOp); + module()->AddGlobalValue(std::move(newVarOp)); + get_decoration_mgr()->AddDecorationVal( + var_id, uint32_t(spv::Decoration::BuiltIn), builtin); + AddVarToEntryPoints(var_id); + } + builtin_var_id_map_[builtin] = var_id; + return var_id; +} + +void IRContext::AddCalls(const Function* func, std::queue* todo) { + for (auto bi = func->begin(); bi != func->end(); ++bi) + for (auto ii = bi->begin(); ii != bi->end(); ++ii) + if (ii->opcode() == spv::Op::OpFunctionCall) + todo->push(ii->GetSingleWordInOperand(0)); +} + +bool IRContext::ProcessEntryPointCallTree(ProcessFunction& pfn) { + // Collect all of the entry points as the roots. + std::queue roots; + for (auto& e : module()->entry_points()) { + roots.push(e.GetSingleWordInOperand(kEntryPointFunctionIdInIdx)); + } + return ProcessCallTreeFromRoots(pfn, &roots); +} + +bool IRContext::ProcessReachableCallTree(ProcessFunction& pfn) { + std::queue roots; + + // Add all entry points since they can be reached from outside the module. + for (auto& e : module()->entry_points()) + roots.push(e.GetSingleWordInOperand(kEntryPointFunctionIdInIdx)); + + // Add all exported functions since they can be reached from outside the + // module. + for (auto& a : annotations()) { + // TODO: Handle group decorations as well. Currently not generate by any + // front-end, but could be coming. + if (a.opcode() == spv::Op::OpDecorate) { + if (spv::Decoration(a.GetSingleWordOperand(1)) == + spv::Decoration::LinkageAttributes) { + uint32_t lastOperand = a.NumOperands() - 1; + if (spv::LinkageType(a.GetSingleWordOperand(lastOperand)) == + spv::LinkageType::Export) { + uint32_t id = a.GetSingleWordOperand(0); + if (GetFunction(id)) { + roots.push(id); + } + } + } + } + } + + return ProcessCallTreeFromRoots(pfn, &roots); +} + +bool IRContext::ProcessCallTreeFromRoots(ProcessFunction& pfn, + std::queue* roots) { + // Process call tree + bool modified = false; + std::unordered_set done; + + while (!roots->empty()) { + const uint32_t fi = roots->front(); + roots->pop(); + if (done.insert(fi).second) { + Function* fn = GetFunction(fi); + assert(fn && "Trying to process a function that does not exist."); + modified = pfn(fn) || modified; + AddCalls(fn, roots); + } + } + return modified; +} + +void IRContext::CollectCallTreeFromRoots(unsigned entryId, + std::unordered_set* funcs) { + std::queue roots; + roots.push(entryId); + while (!roots.empty()) { + const uint32_t fi = roots.front(); + roots.pop(); + funcs->insert(fi); + Function* fn = GetFunction(fi); + AddCalls(fn, &roots); + } +} + +void IRContext::EmitErrorMessage(std::string message, Instruction* inst) { + if (!consumer()) { + return; + } + + Instruction* line_inst = inst; + while (line_inst != nullptr) { // Stop at the beginning of the basic block. + if (!line_inst->dbg_line_insts().empty()) { + line_inst = &line_inst->dbg_line_insts().back(); + if (line_inst->IsNoLine()) { + line_inst = nullptr; + } + break; + } + line_inst = line_inst->PreviousNode(); + } + + uint32_t line_number = 0; + uint32_t col_number = 0; + std::string source; + if (line_inst != nullptr) { + Instruction* file_name = + get_def_use_mgr()->GetDef(line_inst->GetSingleWordInOperand(0)); + source = file_name->GetInOperand(0).AsString(); + + // Get the line number and column number. + line_number = line_inst->GetSingleWordInOperand(1); + col_number = line_inst->GetSingleWordInOperand(2); + } + + message += + "\n " + inst->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES); + consumer()(SPV_MSG_ERROR, source.c_str(), {line_number, col_number, 0}, + message.c_str()); +} + +// Gets the dominator analysis for function |f|. +DominatorAnalysis* IRContext::GetDominatorAnalysis(const Function* f) { + if (!AreAnalysesValid(kAnalysisDominatorAnalysis)) { + ResetDominatorAnalysis(); + } + + if (dominator_trees_.find(f) == dominator_trees_.end()) { + dominator_trees_[f].InitializeTree(*cfg(), f); + } + + return &dominator_trees_[f]; +} + +// Gets the postdominator analysis for function |f|. +PostDominatorAnalysis* IRContext::GetPostDominatorAnalysis(const Function* f) { + if (!AreAnalysesValid(kAnalysisDominatorAnalysis)) { + ResetDominatorAnalysis(); + } + + if (post_dominator_trees_.find(f) == post_dominator_trees_.end()) { + post_dominator_trees_[f].InitializeTree(*cfg(), f); + } + + return &post_dominator_trees_[f]; +} + +bool IRContext::CheckCFG() { + std::unordered_map> real_preds; + if (!AreAnalysesValid(kAnalysisCFG)) { + return true; + } + + for (Function& function : *module()) { + for (const auto& bb : function) { + bb.ForEachSuccessorLabel([&bb, &real_preds](const uint32_t lab_id) { + real_preds[lab_id].push_back(bb.id()); + }); + } + + for (auto& bb : function) { + std::vector preds = cfg()->preds(bb.id()); + std::vector real = real_preds[bb.id()]; + std::sort(preds.begin(), preds.end()); + std::sort(real.begin(), real.end()); + + bool same = true; + if (preds.size() != real.size()) { + same = false; + } + + for (size_t i = 0; i < real.size() && same; i++) { + if (preds[i] != real[i]) { + same = false; + } + } + + if (!same) { + std::cerr << "Predecessors for " << bb.id() << " are different:\n"; + + std::cerr << "Real:"; + for (uint32_t i : real) { + std::cerr << ' ' << i; + } + std::cerr << std::endl; + + std::cerr << "Recorded:"; + for (uint32_t i : preds) { + std::cerr << ' ' << i; + } + std::cerr << std::endl; + } + if (!same) return false; + } + } + + return true; +} + +bool IRContext::IsReachable(const opt::BasicBlock& bb) { + auto enclosing_function = bb.GetParent(); + return GetDominatorAnalysis(enclosing_function) + ->Dominates(enclosing_function->entry().get(), &bb); +} + +spv::ExecutionModel IRContext::GetStage() { + const auto& entry_points = module()->entry_points(); + if (entry_points.empty()) { + return spv::ExecutionModel::Max; + } + + uint32_t stage = entry_points.begin()->GetSingleWordInOperand( + kEntryPointExecutionModelInIdx); + auto it = std::find_if( + entry_points.begin(), entry_points.end(), [stage](const Instruction& x) { + return x.GetSingleWordInOperand(kEntryPointExecutionModelInIdx) != + stage; + }); + if (it != entry_points.end()) { + EmitErrorMessage("Mixed stage shader module not supported", &(*it)); + } + + return static_cast(stage); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ir_context.h b/thirdparty/glslang/External/spirv-tools/source/opt/ir_context.h new file mode 100644 index 000000000000..5685db809d0b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ir_context.h @@ -0,0 +1,1301 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_IR_CONTEXT_H_ +#define SOURCE_OPT_IR_CONTEXT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/assembly_grammar.h" +#include "source/enum_string_mapping.h" +#include "source/opt/cfg.h" +#include "source/opt/constants.h" +#include "source/opt/debug_info_manager.h" +#include "source/opt/decoration_manager.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/dominator_analysis.h" +#include "source/opt/feature_manager.h" +#include "source/opt/fold.h" +#include "source/opt/liveness.h" +#include "source/opt/loop_descriptor.h" +#include "source/opt/module.h" +#include "source/opt/register_pressure.h" +#include "source/opt/scalar_analysis.h" +#include "source/opt/struct_cfg_analysis.h" +#include "source/opt/type_manager.h" +#include "source/opt/value_number_table.h" +#include "source/util/make_unique.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { + +class IRContext { + public: + // Available analyses. + // + // When adding a new analysis: + // + // 1. Enum values should be powers of 2. These are cast into uint32_t + // bitmasks, so we can have at most 31 analyses represented. + // + // 2. Make sure it gets invalidated or preserved by IRContext methods that add + // or remove IR elements (e.g., KillDef, KillInst, ReplaceAllUsesWith). + // + // 3. Add handling code in BuildInvalidAnalyses and InvalidateAnalyses + enum Analysis { + kAnalysisNone = 0 << 0, + kAnalysisBegin = 1 << 0, + kAnalysisDefUse = kAnalysisBegin, + kAnalysisInstrToBlockMapping = 1 << 1, + kAnalysisDecorations = 1 << 2, + kAnalysisCombinators = 1 << 3, + kAnalysisCFG = 1 << 4, + kAnalysisDominatorAnalysis = 1 << 5, + kAnalysisLoopAnalysis = 1 << 6, + kAnalysisNameMap = 1 << 7, + kAnalysisScalarEvolution = 1 << 8, + kAnalysisRegisterPressure = 1 << 9, + kAnalysisValueNumberTable = 1 << 10, + kAnalysisStructuredCFG = 1 << 11, + kAnalysisBuiltinVarId = 1 << 12, + kAnalysisIdToFuncMapping = 1 << 13, + kAnalysisConstants = 1 << 14, + kAnalysisTypes = 1 << 15, + kAnalysisDebugInfo = 1 << 16, + kAnalysisLiveness = 1 << 17, + kAnalysisEnd = 1 << 17 + }; + + using ProcessFunction = std::function; + + friend inline Analysis operator|(Analysis lhs, Analysis rhs); + friend inline Analysis& operator|=(Analysis& lhs, Analysis rhs); + friend inline Analysis operator<<(Analysis a, int shift); + friend inline Analysis& operator<<=(Analysis& a, int shift); + + // Creates an |IRContext| that contains an owned |Module| + IRContext(spv_target_env env, MessageConsumer c) + : syntax_context_(spvContextCreate(env)), + grammar_(syntax_context_), + unique_id_(0), + module_(new Module()), + consumer_(std::move(c)), + def_use_mgr_(nullptr), + feature_mgr_(nullptr), + valid_analyses_(kAnalysisNone), + constant_mgr_(nullptr), + type_mgr_(nullptr), + id_to_name_(nullptr), + max_id_bound_(kDefaultMaxIdBound), + preserve_bindings_(false), + preserve_spec_constants_(false) { + SetContextMessageConsumer(syntax_context_, consumer_); + module_->SetContext(this); + } + + IRContext(spv_target_env env, std::unique_ptr&& m, MessageConsumer c) + : syntax_context_(spvContextCreate(env)), + grammar_(syntax_context_), + unique_id_(0), + module_(std::move(m)), + consumer_(std::move(c)), + def_use_mgr_(nullptr), + feature_mgr_(nullptr), + valid_analyses_(kAnalysisNone), + type_mgr_(nullptr), + id_to_name_(nullptr), + max_id_bound_(kDefaultMaxIdBound), + preserve_bindings_(false), + preserve_spec_constants_(false) { + SetContextMessageConsumer(syntax_context_, consumer_); + module_->SetContext(this); + InitializeCombinators(); + } + + ~IRContext() { spvContextDestroy(syntax_context_); } + + Module* module() const { return module_.get(); } + + // Returns a vector of pointers to constant-creation instructions in this + // context. + inline std::vector GetConstants(); + inline std::vector GetConstants() const; + + // Iterators for annotation instructions contained in this context. + inline Module::inst_iterator annotation_begin(); + inline Module::inst_iterator annotation_end(); + inline IteratorRange annotations(); + inline IteratorRange annotations() const; + + // Iterators for capabilities instructions contained in this module. + inline Module::inst_iterator capability_begin(); + inline Module::inst_iterator capability_end(); + inline IteratorRange capabilities(); + inline IteratorRange capabilities() const; + + // Iterators for extensions instructions contained in this module. + inline Module::inst_iterator extension_begin(); + inline Module::inst_iterator extension_end(); + inline IteratorRange extensions(); + inline IteratorRange extensions() const; + + // Iterators for types, constants and global variables instructions. + inline Module::inst_iterator types_values_begin(); + inline Module::inst_iterator types_values_end(); + inline IteratorRange types_values(); + inline IteratorRange types_values() const; + + // Iterators for ext_inst import instructions contained in this module. + inline Module::inst_iterator ext_inst_import_begin(); + inline Module::inst_iterator ext_inst_import_end(); + inline IteratorRange ext_inst_imports(); + inline IteratorRange ext_inst_imports() const; + + // There are several kinds of debug instructions, according to where they can + // appear in the logical layout of a module: + // - Section 7a: OpString, OpSourceExtension, OpSource, OpSourceContinued + // - Section 7b: OpName, OpMemberName + // - Section 7c: OpModuleProcessed + // - Mostly anywhere: OpLine and OpNoLine + // + + // Iterators for debug 1 instructions (excluding OpLine & OpNoLine) contained + // in this module. These are for layout section 7a. + inline Module::inst_iterator debug1_begin(); + inline Module::inst_iterator debug1_end(); + inline IteratorRange debugs1(); + inline IteratorRange debugs1() const; + + // Iterators for debug 2 instructions (excluding OpLine & OpNoLine) contained + // in this module. These are for layout section 7b. + inline Module::inst_iterator debug2_begin(); + inline Module::inst_iterator debug2_end(); + inline IteratorRange debugs2(); + inline IteratorRange debugs2() const; + + // Iterators for debug 3 instructions (excluding OpLine & OpNoLine) contained + // in this module. These are for layout section 7c. + inline Module::inst_iterator debug3_begin(); + inline Module::inst_iterator debug3_end(); + inline IteratorRange debugs3(); + inline IteratorRange debugs3() const; + + // Iterators for debug info instructions (excluding OpLine & OpNoLine) + // contained in this module. These are OpExtInst for DebugInfo extension + // placed between section 9 and 10. + inline Module::inst_iterator ext_inst_debuginfo_begin(); + inline Module::inst_iterator ext_inst_debuginfo_end(); + inline IteratorRange ext_inst_debuginfo(); + inline IteratorRange ext_inst_debuginfo() const; + + // Add |capability| to the module, if it is not already enabled. + inline void AddCapability(spv::Capability capability); + // Appends a capability instruction to this module. + inline void AddCapability(std::unique_ptr&& c); + // Removes instruction declaring `capability` from this module. + // Returns true if the capability was removed, false otherwise. + bool RemoveCapability(spv::Capability capability); + + // Appends an extension instruction to this module. + inline void AddExtension(const std::string& ext_name); + inline void AddExtension(std::unique_ptr&& e); + // Removes instruction declaring `extension` from this module. + // Returns true if the extension was removed, false otherwise. + bool RemoveExtension(Extension extension); + + // Appends an extended instruction set instruction to this module. + inline void AddExtInstImport(const std::string& name); + inline void AddExtInstImport(std::unique_ptr&& e); + // Set the memory model for this module. + inline void SetMemoryModel(std::unique_ptr&& m); + // Get the memory model for this module. + inline const Instruction* GetMemoryModel() const; + // Appends an entry point instruction to this module. + inline void AddEntryPoint(std::unique_ptr&& e); + // Appends an execution mode instruction to this module. + inline void AddExecutionMode(std::unique_ptr&& e); + // Appends a debug 1 instruction (excluding OpLine & OpNoLine) to this module. + // "debug 1" instructions are the ones in layout section 7.a), see section + // 2.4 Logical Layout of a Module from the SPIR-V specification. + inline void AddDebug1Inst(std::unique_ptr&& d); + // Appends a debug 2 instruction (excluding OpLine & OpNoLine) to this module. + // "debug 2" instructions are the ones in layout section 7.b), see section + // 2.4 Logical Layout of a Module from the SPIR-V specification. + inline void AddDebug2Inst(std::unique_ptr&& d); + // Appends a debug 3 instruction (OpModuleProcessed) to this module. + // This is due to decision by the SPIR Working Group, pending publication. + inline void AddDebug3Inst(std::unique_ptr&& d); + // Appends a OpExtInst for DebugInfo to this module. + inline void AddExtInstDebugInfo(std::unique_ptr&& d); + // Appends an annotation instruction to this module. + inline void AddAnnotationInst(std::unique_ptr&& a); + // Appends a type-declaration instruction to this module. + inline void AddType(std::unique_ptr&& t); + // Appends a constant, global variable, or OpUndef instruction to this module. + inline void AddGlobalValue(std::unique_ptr&& v); + // Prepends a function declaration to this module. + inline void AddFunctionDeclaration(std::unique_ptr&& f); + // Appends a function to this module. + inline void AddFunction(std::unique_ptr&& f); + + // Returns a pointer to a def-use manager. If the def-use manager is + // invalid, it is rebuilt first. + analysis::DefUseManager* get_def_use_mgr() { + if (!AreAnalysesValid(kAnalysisDefUse)) { + BuildDefUseManager(); + } + return def_use_mgr_.get(); + } + + // Returns a pointer to a liveness manager. If the liveness manager is + // invalid, it is rebuilt first. + analysis::LivenessManager* get_liveness_mgr() { + if (!AreAnalysesValid(kAnalysisLiveness)) { + BuildLivenessManager(); + } + return liveness_mgr_.get(); + } + + // Returns a pointer to a value number table. If the liveness analysis is + // invalid, it is rebuilt first. + ValueNumberTable* GetValueNumberTable() { + if (!AreAnalysesValid(kAnalysisValueNumberTable)) { + BuildValueNumberTable(); + } + return vn_table_.get(); + } + + // Returns a pointer to a StructuredCFGAnalysis. If the analysis is invalid, + // it is rebuilt first. + StructuredCFGAnalysis* GetStructuredCFGAnalysis() { + if (!AreAnalysesValid(kAnalysisStructuredCFG)) { + BuildStructuredCFGAnalysis(); + } + return struct_cfg_analysis_.get(); + } + + // Returns a pointer to a liveness analysis. If the liveness analysis is + // invalid, it is rebuilt first. + LivenessAnalysis* GetLivenessAnalysis() { + if (!AreAnalysesValid(kAnalysisRegisterPressure)) { + BuildRegPressureAnalysis(); + } + return reg_pressure_.get(); + } + + // Returns the basic block for instruction |instr|. Re-builds the instruction + // block map, if needed. + BasicBlock* get_instr_block(Instruction* instr) { + if (!AreAnalysesValid(kAnalysisInstrToBlockMapping)) { + BuildInstrToBlockMapping(); + } + auto entry = instr_to_block_.find(instr); + return (entry != instr_to_block_.end()) ? entry->second : nullptr; + } + + // Returns the basic block for |id|. Re-builds the instruction block map, if + // needed. + // + // |id| must be a registered definition. + BasicBlock* get_instr_block(uint32_t id) { + Instruction* def = get_def_use_mgr()->GetDef(id); + return get_instr_block(def); + } + + // Sets the basic block for |inst|. Re-builds the mapping if it has become + // invalid. + void set_instr_block(Instruction* inst, BasicBlock* block) { + if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) { + instr_to_block_[inst] = block; + } + } + + // Returns a pointer the decoration manager. If the decoration manager is + // invalid, it is rebuilt first. + analysis::DecorationManager* get_decoration_mgr() { + if (!AreAnalysesValid(kAnalysisDecorations)) { + BuildDecorationManager(); + } + return decoration_mgr_.get(); + } + + // Returns a pointer to the constant manager. If no constant manager has been + // created yet, it creates one. NOTE: Once created, the constant manager + // remains active and it is never re-built. + analysis::ConstantManager* get_constant_mgr() { + if (!AreAnalysesValid(kAnalysisConstants)) { + BuildConstantManager(); + } + return constant_mgr_.get(); + } + + // Returns a pointer to the type manager. If no type manager has been created + // yet, it creates one. NOTE: Once created, the type manager remains active it + // is never re-built. + analysis::TypeManager* get_type_mgr() { + if (!AreAnalysesValid(kAnalysisTypes)) { + BuildTypeManager(); + } + return type_mgr_.get(); + } + + // Returns a pointer to the debug information manager. If no debug + // information manager has been created yet, it creates one. + // NOTE: Once created, the debug information manager remains active + // it is never re-built. + analysis::DebugInfoManager* get_debug_info_mgr() { + if (!AreAnalysesValid(kAnalysisDebugInfo)) { + BuildDebugInfoManager(); + } + return debug_info_mgr_.get(); + } + + // Returns a pointer to the scalar evolution analysis. If it is invalid it + // will be rebuilt first. + ScalarEvolutionAnalysis* GetScalarEvolutionAnalysis() { + if (!AreAnalysesValid(kAnalysisScalarEvolution)) { + BuildScalarEvolutionAnalysis(); + } + return scalar_evolution_analysis_.get(); + } + + // Build the map from the ids to the OpName and OpMemberName instruction + // associated with it. + inline void BuildIdToNameMap(); + + // Returns a range of instrucions that contain all of the OpName and + // OpMemberNames associated with the given id. + inline IteratorRange::iterator> + GetNames(uint32_t id); + + // Returns an OpMemberName instruction that targets |struct_type_id| at + // index |index|. Returns nullptr if no such instruction exists. + // While the SPIR-V spec does not prohibit having multiple OpMemberName + // instructions for the same structure member, it is hard to imagine a member + // having more than one name. This method returns the first one it finds. + inline Instruction* GetMemberName(uint32_t struct_type_id, uint32_t index); + + // Copy names from |old_id| to |new_id|. Only copy member name if index is + // less than |max_member_index|. + inline void CloneNames(const uint32_t old_id, const uint32_t new_id, + const uint32_t max_member_index = UINT32_MAX); + + // Sets the message consumer to the given |consumer|. |consumer| which will be + // invoked every time there is a message to be communicated to the outside. + void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); } + + // Returns the reference to the message consumer for this pass. + const MessageConsumer& consumer() const { return consumer_; } + + // Rebuilds the analyses in |set| that are invalid. + void BuildInvalidAnalyses(Analysis set); + + // Invalidates all of the analyses except for those in |preserved_analyses|. + void InvalidateAnalysesExceptFor(Analysis preserved_analyses); + + // Invalidates the analyses marked in |analyses_to_invalidate|. + void InvalidateAnalyses(Analysis analyses_to_invalidate); + + // Deletes the instruction defining the given |id|. Returns true on + // success, false if the given |id| is not defined at all. This method also + // erases the name, decorations, and definition of |id|. + // + // Pointers and iterators pointing to the deleted instructions become invalid. + // However other pointers and iterators are still valid. + bool KillDef(uint32_t id); + + // Deletes the given instruction |inst|. This method erases the + // information of the given instruction's uses of its operands. If |inst| + // defines a result id, its name and decorations will also be deleted. + // + // Pointer and iterator pointing to the deleted instructions become invalid. + // However other pointers and iterators are still valid. + // + // Note that if an instruction is not in an instruction list, the memory may + // not be safe to delete, so the instruction is turned into a OpNop instead. + // This can happen with OpLabel. + // + // Returns a pointer to the instruction after |inst| or |nullptr| if no such + // instruction exists. + Instruction* KillInst(Instruction* inst); + + // Deletes all the instruction in the range [`begin`; `end`[, for which the + // unary predicate `condition` returned true. + // Returns true if at least one instruction was removed, false otherwise. + // + // Pointer and iterator pointing to the deleted instructions become invalid. + // However other pointers and iterators are still valid. + bool KillInstructionIf(Module::inst_iterator begin, Module::inst_iterator end, + std::function condition); + + // Collects the non-semantic instruction tree that uses |inst|'s result id + // to be killed later. + void CollectNonSemanticTree(Instruction* inst, + std::unordered_set* to_kill); + + // Collect function reachable from |entryId|, returns |funcs| + void CollectCallTreeFromRoots(unsigned entryId, + std::unordered_set* funcs); + + // Returns true if all of the given analyses are valid. + bool AreAnalysesValid(Analysis set) { return (set & valid_analyses_) == set; } + + // Replaces all uses of |before| id with |after| id. Returns true if any + // replacement happens. This method does not kill the definition of the + // |before| id. If |after| is the same as |before|, does nothing and returns + // false. + // + // |before| and |after| must be registered definitions in the DefUseManager. + bool ReplaceAllUsesWith(uint32_t before, uint32_t after); + + // Replace all uses of |before| id with |after| id if those uses + // (instruction) return true for |predicate|. Returns true if + // any replacement happens. This method does not kill the definition of the + // |before| id. If |after| is the same as |before|, does nothing and return + // false. + bool ReplaceAllUsesWithPredicate( + uint32_t before, uint32_t after, + const std::function& predicate); + + // Returns true if all of the analyses that are suppose to be valid are + // actually valid. + bool IsConsistent(); + + // The IRContext will look at the def and uses of |inst| and update any valid + // analyses will be updated accordingly. + inline void AnalyzeDefUse(Instruction* inst); + + // Informs the IRContext that the uses of |inst| are going to change, and that + // is should forget everything it know about the current uses. Any valid + // analyses will be updated accordingly. + void ForgetUses(Instruction* inst); + + // The IRContext will look at the uses of |inst| and update any valid analyses + // will be updated accordingly. + void AnalyzeUses(Instruction* inst); + + // Kill all name and decorate ops targeting |id|. + void KillNamesAndDecorates(uint32_t id); + + // Kill all name and decorate ops targeting the result id of |inst|. + void KillNamesAndDecorates(Instruction* inst); + + // Change operands of debug instruction to DebugInfoNone. + void KillOperandFromDebugInstructions(Instruction* inst); + + // Returns the next unique id for use by an instruction. + inline uint32_t TakeNextUniqueId() { + assert(unique_id_ != std::numeric_limits::max()); + + // Skip zero. + return ++unique_id_; + } + + // Returns true if |inst| is a combinator in the current context. + // |combinator_ops_| is built if it has not been already. + inline bool IsCombinatorInstruction(const Instruction* inst) { + if (!AreAnalysesValid(kAnalysisCombinators)) { + InitializeCombinators(); + } + constexpr uint32_t kExtInstSetIdInIndx = 0; + constexpr uint32_t kExtInstInstructionInIndx = 1; + + if (inst->opcode() != spv::Op::OpExtInst) { + return combinator_ops_[0].count(uint32_t(inst->opcode())) != 0; + } else { + uint32_t set = inst->GetSingleWordInOperand(kExtInstSetIdInIndx); + auto op = inst->GetSingleWordInOperand(kExtInstInstructionInIndx); + return combinator_ops_[set].count(op) != 0; + } + } + + // Returns a pointer to the CFG for all the functions in |module_|. + CFG* cfg() { + if (!AreAnalysesValid(kAnalysisCFG)) { + BuildCFG(); + } + return cfg_.get(); + } + + // Gets the loop descriptor for function |f|. + LoopDescriptor* GetLoopDescriptor(const Function* f); + + // Gets the dominator analysis for function |f|. + DominatorAnalysis* GetDominatorAnalysis(const Function* f); + + // Gets the postdominator analysis for function |f|. + PostDominatorAnalysis* GetPostDominatorAnalysis(const Function* f); + + // Remove the dominator tree of |f| from the cache. + inline void RemoveDominatorAnalysis(const Function* f) { + dominator_trees_.erase(f); + } + + // Remove the postdominator tree of |f| from the cache. + inline void RemovePostDominatorAnalysis(const Function* f) { + post_dominator_trees_.erase(f); + } + + // Return the next available SSA id and increment it. Returns 0 if the + // maximum SSA id has been reached. + inline uint32_t TakeNextId() { + uint32_t next_id = module()->TakeNextIdBound(); + if (next_id == 0) { + if (consumer()) { + std::string message = "ID overflow. Try running compact-ids."; + consumer()(SPV_MSG_ERROR, "", {0, 0, 0}, message.c_str()); + } +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + // If TakeNextId returns 0, it is very likely that execution will + // subsequently fail. Such failures are false alarms from a fuzzing point + // of view: they are due to the fact that too many ids were used, rather + // than being due to an actual bug. Thus, during a fuzzing build, it is + // preferable to bail out when ID overflow occurs. + // + // A zero exit code is returned here because a non-zero code would cause + // ClusterFuzz/OSS-Fuzz to regard the termination as a crash, and spurious + // crash reports is what this guard aims to avoid. + exit(0); +#endif + } + return next_id; + } + + FeatureManager* get_feature_mgr() { + if (!feature_mgr_.get()) { + AnalyzeFeatures(); + } + return feature_mgr_.get(); + } + + void ResetFeatureManager() { feature_mgr_.reset(nullptr); } + + // Returns the grammar for this context. + const AssemblyGrammar& grammar() const { return grammar_; } + + // If |inst| has not yet been analysed by the def-use manager, then analyse + // its definitions and uses. + inline void UpdateDefUse(Instruction* inst); + + const InstructionFolder& get_instruction_folder() { + if (!inst_folder_) { + inst_folder_ = MakeUnique(this); + } + return *inst_folder_; + } + + uint32_t max_id_bound() const { return max_id_bound_; } + void set_max_id_bound(uint32_t new_bound) { max_id_bound_ = new_bound; } + + bool preserve_bindings() const { return preserve_bindings_; } + void set_preserve_bindings(bool should_preserve_bindings) { + preserve_bindings_ = should_preserve_bindings; + } + + bool preserve_spec_constants() const { return preserve_spec_constants_; } + void set_preserve_spec_constants(bool should_preserve_spec_constants) { + preserve_spec_constants_ = should_preserve_spec_constants; + } + + // Return id of input variable only decorated with |builtin|, if in module. + // Create variable and return its id otherwise. If builtin not currently + // supported, return 0. + uint32_t GetBuiltinInputVarId(uint32_t builtin); + + // Returns the function whose id is |id|, if one exists. Returns |nullptr| + // otherwise. + Function* GetFunction(uint32_t id) { + if (!AreAnalysesValid(kAnalysisIdToFuncMapping)) { + BuildIdToFuncMapping(); + } + auto entry = id_to_func_.find(id); + return (entry != id_to_func_.end()) ? entry->second : nullptr; + } + + Function* GetFunction(Instruction* inst) { + if (inst->opcode() != spv::Op::OpFunction) { + return nullptr; + } + return GetFunction(inst->result_id()); + } + + // Add to |todo| all ids of functions called directly from |func|. + void AddCalls(const Function* func, std::queue* todo); + + // Applies |pfn| to every function in the call trees that are rooted at the + // entry points. Returns true if any call |pfn| returns true. By convention + // |pfn| should return true if it modified the module. + bool ProcessEntryPointCallTree(ProcessFunction& pfn); + + // Applies |pfn| to every function in the call trees rooted at the entry + // points and exported functions. Returns true if any call |pfn| returns + // true. By convention |pfn| should return true if it modified the module. + bool ProcessReachableCallTree(ProcessFunction& pfn); + + // Applies |pfn| to every function in the call trees rooted at the elements of + // |roots|. Returns true if any call to |pfn| returns true. By convention + // |pfn| should return true if it modified the module. After returning + // |roots| will be empty. + bool ProcessCallTreeFromRoots(ProcessFunction& pfn, + std::queue* roots); + + // Emits a error message to the message consumer indicating the error + // described by |message| occurred in |inst|. + void EmitErrorMessage(std::string message, Instruction* inst); + + // Returns true if and only if there is a path to |bb| from the entry block of + // the function that contains |bb|. + bool IsReachable(const opt::BasicBlock& bb); + + // Return the stage of the module. Will generate error if entry points don't + // all have the same stage. + spv::ExecutionModel GetStage(); + + // Returns true of the current target environment is at least that of the + // given environment. + bool IsTargetEnvAtLeast(spv_target_env env) { + // A bit of a hack. We assume that the target environments are appended to + // the enum, so that there is an appropriate order. + return syntax_context_->target_env >= env; + } + + // Return the target environment for the current context. + spv_target_env GetTargetEnv() const { return syntax_context_->target_env; } + + private: + // Builds the def-use manager from scratch, even if it was already valid. + void BuildDefUseManager() { + def_use_mgr_ = MakeUnique(module()); + valid_analyses_ = valid_analyses_ | kAnalysisDefUse; + } + + // Builds the liveness manager from scratch, even if it was already valid. + void BuildLivenessManager() { + liveness_mgr_ = MakeUnique(this); + valid_analyses_ = valid_analyses_ | kAnalysisLiveness; + } + + // Builds the instruction-block map for the whole module. + void BuildInstrToBlockMapping() { + instr_to_block_.clear(); + for (auto& fn : *module_) { + for (auto& block : fn) { + block.ForEachInst([this, &block](Instruction* inst) { + instr_to_block_[inst] = █ + }); + } + } + valid_analyses_ = valid_analyses_ | kAnalysisInstrToBlockMapping; + } + + // Builds the instruction-function map for the whole module. + void BuildIdToFuncMapping() { + id_to_func_.clear(); + for (auto& fn : *module_) { + id_to_func_[fn.result_id()] = &fn; + } + valid_analyses_ = valid_analyses_ | kAnalysisIdToFuncMapping; + } + + void BuildDecorationManager() { + decoration_mgr_ = MakeUnique(module()); + valid_analyses_ = valid_analyses_ | kAnalysisDecorations; + } + + void BuildCFG() { + cfg_ = MakeUnique(module()); + valid_analyses_ = valid_analyses_ | kAnalysisCFG; + } + + void BuildScalarEvolutionAnalysis() { + scalar_evolution_analysis_ = MakeUnique(this); + valid_analyses_ = valid_analyses_ | kAnalysisScalarEvolution; + } + + // Builds the liveness analysis from scratch, even if it was already valid. + void BuildRegPressureAnalysis() { + reg_pressure_ = MakeUnique(this); + valid_analyses_ = valid_analyses_ | kAnalysisRegisterPressure; + } + + // Builds the value number table analysis from scratch, even if it was already + // valid. + void BuildValueNumberTable() { + vn_table_ = MakeUnique(this); + valid_analyses_ = valid_analyses_ | kAnalysisValueNumberTable; + } + + // Builds the structured CFG analysis from scratch, even if it was already + // valid. + void BuildStructuredCFGAnalysis() { + struct_cfg_analysis_ = MakeUnique(this); + valid_analyses_ = valid_analyses_ | kAnalysisStructuredCFG; + } + + // Builds the constant manager from scratch, even if it was already + // valid. + void BuildConstantManager() { + constant_mgr_ = MakeUnique(this); + valid_analyses_ = valid_analyses_ | kAnalysisConstants; + } + + // Builds the type manager from scratch, even if it was already + // valid. + void BuildTypeManager() { + type_mgr_ = MakeUnique(consumer(), this); + valid_analyses_ = valid_analyses_ | kAnalysisTypes; + } + + // Builds the debug information manager from scratch, even if it was + // already valid. + void BuildDebugInfoManager() { + debug_info_mgr_ = MakeUnique(this); + valid_analyses_ = valid_analyses_ | kAnalysisDebugInfo; + } + + // Removes all computed dominator and post-dominator trees. This will force + // the context to rebuild the trees on demand. + void ResetDominatorAnalysis() { + // Clear the cache. + dominator_trees_.clear(); + post_dominator_trees_.clear(); + valid_analyses_ = valid_analyses_ | kAnalysisDominatorAnalysis; + } + + // Removes all computed loop descriptors. + void ResetLoopAnalysis() { + // Clear the cache. + loop_descriptors_.clear(); + valid_analyses_ = valid_analyses_ | kAnalysisLoopAnalysis; + } + + // Removes all computed loop descriptors. + void ResetBuiltinAnalysis() { + // Clear the cache. + builtin_var_id_map_.clear(); + valid_analyses_ = valid_analyses_ | kAnalysisBuiltinVarId; + } + + // Analyzes the features in the owned module. Builds the manager if required. + void AnalyzeFeatures() { + feature_mgr_ = + std::unique_ptr(new FeatureManager(grammar_)); + feature_mgr_->Analyze(module()); + } + + // Scans a module looking for it capabilities, and initializes combinator_ops_ + // accordingly. + void InitializeCombinators(); + + // Add the combinator opcode for the given capability to combinator_ops_. + void AddCombinatorsForCapability(uint32_t capability); + + // Add the combinator opcode for the given extension to combinator_ops_. + void AddCombinatorsForExtension(Instruction* extension); + + // Remove |inst| from |id_to_name_| if it is in map. + void RemoveFromIdToName(const Instruction* inst); + + // Returns true if it is suppose to be valid but it is incorrect. Returns + // true if the cfg is invalidated. + bool CheckCFG(); + + // Return id of input variable only decorated with |builtin|, if in module. + // Return 0 otherwise. + uint32_t FindBuiltinInputVar(uint32_t builtin); + + // Add |var_id| to all entry points in module. + void AddVarToEntryPoints(uint32_t var_id); + + // The SPIR-V syntax context containing grammar tables for opcodes and + // operands. + spv_context syntax_context_; + + // Auxiliary object for querying SPIR-V grammar facts. + AssemblyGrammar grammar_; + + // An unique identifier for instructions in |module_|. Can be used to order + // instructions in a container. + // + // This member is initialized to 0, but always issues this value plus one. + // Therefore, 0 is not a valid unique id for an instruction. + uint32_t unique_id_; + + // The module being processed within this IR context. + std::unique_ptr module_; + + // A message consumer for diagnostics. + MessageConsumer consumer_; + + // The def-use manager for |module_|. + std::unique_ptr def_use_mgr_; + + // The instruction decoration manager for |module_|. + std::unique_ptr decoration_mgr_; + + // The feature manager for |module_|. + std::unique_ptr feature_mgr_; + + // A map from instructions to the basic block they belong to. This mapping is + // built on-demand when get_instr_block() is called. + // + // NOTE: Do not traverse this map. Ever. Use the function and basic block + // iterators to traverse instructions. + std::unordered_map instr_to_block_; + + // A map from ids to the function they define. This mapping is + // built on-demand when GetFunction() is called. + // + // NOTE: Do not traverse this map. Ever. Use the function and basic block + // iterators to traverse instructions. + std::unordered_map id_to_func_; + + // A bitset indicating which analyzes are currently valid. + Analysis valid_analyses_; + + // Opcodes of shader capability core executable instructions + // without side-effect. + std::unordered_map> combinator_ops_; + + // Opcodes of shader capability core executable instructions + // without side-effect. + std::unordered_map builtin_var_id_map_; + + // The CFG for all the functions in |module_|. + std::unique_ptr cfg_; + + // Each function in the module will create its own dominator tree. We cache + // the result so it doesn't need to be rebuilt each time. + std::map dominator_trees_; + std::map post_dominator_trees_; + + // Cache of loop descriptors for each function. + std::unordered_map loop_descriptors_; + + // Constant manager for |module_|. + std::unique_ptr constant_mgr_; + + // Type manager for |module_|. + std::unique_ptr type_mgr_; + + // Debug information manager for |module_|. + std::unique_ptr debug_info_mgr_; + + // A map from an id to its corresponding OpName and OpMemberName instructions. + std::unique_ptr> id_to_name_; + + // The cache scalar evolution analysis node. + std::unique_ptr scalar_evolution_analysis_; + + // The liveness analysis |module_|. + std::unique_ptr reg_pressure_; + + std::unique_ptr vn_table_; + + std::unique_ptr inst_folder_; + + std::unique_ptr struct_cfg_analysis_; + + // The liveness manager for |module_|. + std::unique_ptr liveness_mgr_; + + // The maximum legal value for the id bound. + uint32_t max_id_bound_; + + // Whether all bindings within |module_| should be preserved. + bool preserve_bindings_; + + // Whether all specialization constants within |module_| + // should be preserved. + bool preserve_spec_constants_; +}; + +inline IRContext::Analysis operator|(IRContext::Analysis lhs, + IRContext::Analysis rhs) { + return static_cast(static_cast(lhs) | + static_cast(rhs)); +} + +inline IRContext::Analysis& operator|=(IRContext::Analysis& lhs, + IRContext::Analysis rhs) { + lhs = lhs | rhs; + return lhs; +} + +inline IRContext::Analysis operator<<(IRContext::Analysis a, int shift) { + return static_cast(static_cast(a) << shift); +} + +inline IRContext::Analysis& operator<<=(IRContext::Analysis& a, int shift) { + a = static_cast(static_cast(a) << shift); + return a; +} + +std::vector IRContext::GetConstants() { + return module()->GetConstants(); +} + +std::vector IRContext::GetConstants() const { + return ((const Module*)module())->GetConstants(); +} + +Module::inst_iterator IRContext::annotation_begin() { + return module()->annotation_begin(); +} + +Module::inst_iterator IRContext::annotation_end() { + return module()->annotation_end(); +} + +IteratorRange IRContext::annotations() { + return module_->annotations(); +} + +IteratorRange IRContext::annotations() const { + return ((const Module*)module_.get())->annotations(); +} + +Module::inst_iterator IRContext::capability_begin() { + return module()->capability_begin(); +} + +Module::inst_iterator IRContext::capability_end() { + return module()->capability_end(); +} + +IteratorRange IRContext::capabilities() { + return module()->capabilities(); +} + +IteratorRange IRContext::capabilities() const { + return ((const Module*)module())->capabilities(); +} + +Module::inst_iterator IRContext::extension_begin() { + return module()->extension_begin(); +} + +Module::inst_iterator IRContext::extension_end() { + return module()->extension_end(); +} + +IteratorRange IRContext::extensions() { + return module()->extensions(); +} + +IteratorRange IRContext::extensions() const { + return ((const Module*)module())->extensions(); +} + +Module::inst_iterator IRContext::types_values_begin() { + return module()->types_values_begin(); +} + +Module::inst_iterator IRContext::types_values_end() { + return module()->types_values_end(); +} + +IteratorRange IRContext::types_values() { + return module()->types_values(); +} + +IteratorRange IRContext::types_values() const { + return ((const Module*)module_.get())->types_values(); +} + +Module::inst_iterator IRContext::ext_inst_import_begin() { + return module()->ext_inst_import_begin(); +} + +Module::inst_iterator IRContext::ext_inst_import_end() { + return module()->ext_inst_import_end(); +} + +IteratorRange IRContext::ext_inst_imports() { + return module()->ext_inst_imports(); +} + +IteratorRange IRContext::ext_inst_imports() const { + return ((const Module*)module_.get())->ext_inst_imports(); +} + +Module::inst_iterator IRContext::debug1_begin() { + return module()->debug1_begin(); +} + +Module::inst_iterator IRContext::debug1_end() { return module()->debug1_end(); } + +IteratorRange IRContext::debugs1() { + return module()->debugs1(); +} + +IteratorRange IRContext::debugs1() const { + return ((const Module*)module_.get())->debugs1(); +} + +Module::inst_iterator IRContext::debug2_begin() { + return module()->debug2_begin(); +} +Module::inst_iterator IRContext::debug2_end() { return module()->debug2_end(); } + +IteratorRange IRContext::debugs2() { + return module()->debugs2(); +} + +IteratorRange IRContext::debugs2() const { + return ((const Module*)module_.get())->debugs2(); +} + +Module::inst_iterator IRContext::debug3_begin() { + return module()->debug3_begin(); +} + +Module::inst_iterator IRContext::debug3_end() { return module()->debug3_end(); } + +IteratorRange IRContext::debugs3() { + return module()->debugs3(); +} + +IteratorRange IRContext::debugs3() const { + return ((const Module*)module_.get())->debugs3(); +} + +Module::inst_iterator IRContext::ext_inst_debuginfo_begin() { + return module()->ext_inst_debuginfo_begin(); +} + +Module::inst_iterator IRContext::ext_inst_debuginfo_end() { + return module()->ext_inst_debuginfo_end(); +} + +IteratorRange IRContext::ext_inst_debuginfo() { + return module()->ext_inst_debuginfo(); +} + +IteratorRange IRContext::ext_inst_debuginfo() + const { + return ((const Module*)module_.get())->ext_inst_debuginfo(); +} + +void IRContext::AddCapability(spv::Capability capability) { + if (!get_feature_mgr()->HasCapability(capability)) { + std::unique_ptr capability_inst(new Instruction( + this, spv::Op::OpCapability, 0, 0, + {{SPV_OPERAND_TYPE_CAPABILITY, {static_cast(capability)}}})); + AddCapability(std::move(capability_inst)); + } +} + +void IRContext::AddCapability(std::unique_ptr&& c) { + AddCombinatorsForCapability(c->GetSingleWordInOperand(0)); + if (feature_mgr_ != nullptr) { + feature_mgr_->AddCapability( + static_cast(c->GetSingleWordInOperand(0))); + } + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstDefUse(c.get()); + } + module()->AddCapability(std::move(c)); +} + +void IRContext::AddExtension(const std::string& ext_name) { + std::vector ext_words = spvtools::utils::MakeVector(ext_name); + AddExtension(std::unique_ptr( + new Instruction(this, spv::Op::OpExtension, 0u, 0u, + {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}}))); +} + +void IRContext::AddExtension(std::unique_ptr&& e) { + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstDefUse(e.get()); + } + if (feature_mgr_ != nullptr) { + feature_mgr_->AddExtension(&*e); + } + module()->AddExtension(std::move(e)); +} + +void IRContext::AddExtInstImport(const std::string& name) { + std::vector ext_words = spvtools::utils::MakeVector(name); + AddExtInstImport(std::unique_ptr( + new Instruction(this, spv::Op::OpExtInstImport, 0u, TakeNextId(), + {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}}))); +} + +void IRContext::AddExtInstImport(std::unique_ptr&& e) { + AddCombinatorsForExtension(e.get()); + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstDefUse(e.get()); + } + module()->AddExtInstImport(std::move(e)); + if (feature_mgr_ != nullptr) { + feature_mgr_->AddExtInstImportIds(module()); + } +} + +void IRContext::SetMemoryModel(std::unique_ptr&& m) { + module()->SetMemoryModel(std::move(m)); +} + +const Instruction* IRContext::GetMemoryModel() const { + return module()->GetMemoryModel(); +} + +void IRContext::AddEntryPoint(std::unique_ptr&& e) { + module()->AddEntryPoint(std::move(e)); +} + +void IRContext::AddExecutionMode(std::unique_ptr&& e) { + module()->AddExecutionMode(std::move(e)); +} + +void IRContext::AddDebug1Inst(std::unique_ptr&& d) { + module()->AddDebug1Inst(std::move(d)); +} + +void IRContext::AddDebug2Inst(std::unique_ptr&& d) { + if (AreAnalysesValid(kAnalysisNameMap)) { + if (d->opcode() == spv::Op::OpName || + d->opcode() == spv::Op::OpMemberName) { + // OpName and OpMemberName do not have result-ids. The target of the + // instruction is at InOperand index 0. + id_to_name_->insert({d->GetSingleWordInOperand(0), d.get()}); + } + } + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstDefUse(d.get()); + } + module()->AddDebug2Inst(std::move(d)); +} + +void IRContext::AddDebug3Inst(std::unique_ptr&& d) { + module()->AddDebug3Inst(std::move(d)); +} + +void IRContext::AddExtInstDebugInfo(std::unique_ptr&& d) { + module()->AddExtInstDebugInfo(std::move(d)); +} + +void IRContext::AddAnnotationInst(std::unique_ptr&& a) { + if (AreAnalysesValid(kAnalysisDecorations)) { + get_decoration_mgr()->AddDecoration(a.get()); + } + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstDefUse(a.get()); + } + module()->AddAnnotationInst(std::move(a)); +} + +void IRContext::AddType(std::unique_ptr&& t) { + module()->AddType(std::move(t)); + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstDefUse(&*(--types_values_end())); + } +} + +void IRContext::AddGlobalValue(std::unique_ptr&& v) { + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstDefUse(&*v); + } + module()->AddGlobalValue(std::move(v)); +} + +void IRContext::AddFunctionDeclaration(std::unique_ptr&& f) { + module()->AddFunctionDeclaration(std::move(f)); +} + +void IRContext::AddFunction(std::unique_ptr&& f) { + module()->AddFunction(std::move(f)); +} + +void IRContext::AnalyzeDefUse(Instruction* inst) { + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->AnalyzeInstDefUse(inst); + } +} + +void IRContext::UpdateDefUse(Instruction* inst) { + if (AreAnalysesValid(kAnalysisDefUse)) { + get_def_use_mgr()->UpdateDefUse(inst); + } +} + +void IRContext::BuildIdToNameMap() { + id_to_name_ = MakeUnique>(); + for (Instruction& debug_inst : debugs2()) { + if (debug_inst.opcode() == spv::Op::OpMemberName || + debug_inst.opcode() == spv::Op::OpName) { + id_to_name_->insert({debug_inst.GetSingleWordInOperand(0), &debug_inst}); + } + } + valid_analyses_ = valid_analyses_ | kAnalysisNameMap; +} + +IteratorRange::iterator> +IRContext::GetNames(uint32_t id) { + if (!AreAnalysesValid(kAnalysisNameMap)) { + BuildIdToNameMap(); + } + auto result = id_to_name_->equal_range(id); + return make_range(std::move(result.first), std::move(result.second)); +} + +Instruction* IRContext::GetMemberName(uint32_t struct_type_id, uint32_t index) { + if (!AreAnalysesValid(kAnalysisNameMap)) { + BuildIdToNameMap(); + } + auto result = id_to_name_->equal_range(struct_type_id); + for (auto i = result.first; i != result.second; ++i) { + auto* name_instr = i->second; + if (name_instr->opcode() == spv::Op::OpMemberName && + name_instr->GetSingleWordInOperand(1) == index) { + return name_instr; + } + } + return nullptr; +} + +void IRContext::CloneNames(const uint32_t old_id, const uint32_t new_id, + const uint32_t max_member_index) { + std::vector> names_to_add; + auto names = GetNames(old_id); + for (auto n : names) { + Instruction* old_name_inst = n.second; + if (old_name_inst->opcode() == spv::Op::OpMemberName) { + auto midx = old_name_inst->GetSingleWordInOperand(1); + if (midx >= max_member_index) continue; + } + std::unique_ptr new_name_inst(old_name_inst->Clone(this)); + new_name_inst->SetInOperand(0, {new_id}); + names_to_add.push_back(std::move(new_name_inst)); + } + // We can't add the new names when we are iterating over name range above. + // We can add all the new names now. + for (auto& new_name : names_to_add) AddDebug2Inst(std::move(new_name)); +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_IR_CONTEXT_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ir_loader.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/ir_loader.cpp new file mode 100644 index 000000000000..e9b7bbfc2b1e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ir_loader.cpp @@ -0,0 +1,370 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/ir_loader.h" + +#include + +#include "DebugInfo.h" +#include "OpenCLDebugInfo100.h" +#include "source/ext_inst.h" +#include "source/opt/ir_context.h" +#include "source/opt/log.h" +#include "source/opt/reflect.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kExtInstSetIndex = 4; +constexpr uint32_t kLexicalScopeIndex = 5; +constexpr uint32_t kInlinedAtIndex = 6; +} // namespace + +IrLoader::IrLoader(const MessageConsumer& consumer, Module* m) + : consumer_(consumer), + module_(m), + source_(""), + inst_index_(0), + last_dbg_scope_(kNoDebugScope, kNoInlinedAt) {} + +bool IsLineInst(const spv_parsed_instruction_t* inst) { + const auto opcode = static_cast(inst->opcode); + if (IsOpLineInst(opcode)) return true; + if (opcode != spv::Op::OpExtInst) return false; + if (inst->ext_inst_type != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) + return false; + const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; + const NonSemanticShaderDebugInfo100Instructions ext_inst_key = + NonSemanticShaderDebugInfo100Instructions(ext_inst_index); + return ext_inst_key == NonSemanticShaderDebugInfo100DebugLine || + ext_inst_key == NonSemanticShaderDebugInfo100DebugNoLine; +} + +bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { + ++inst_index_; + if (IsLineInst(inst)) { + module()->SetContainsDebugInfo(); + last_line_inst_.reset(); + dbg_line_info_.emplace_back(module()->context(), *inst, last_dbg_scope_); + return true; + } + + // If it is a DebugScope or DebugNoScope of debug extension, we do not + // create a new instruction, but simply keep the information in + // struct DebugScope. + const auto opcode = static_cast(inst->opcode); + if (opcode == spv::Op::OpExtInst && + spvExtInstIsDebugInfo(inst->ext_inst_type)) { + const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; + if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 || + inst->ext_inst_type == + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { + const CommonDebugInfoInstructions ext_inst_key = + CommonDebugInfoInstructions(ext_inst_index); + if (ext_inst_key == CommonDebugInfoDebugScope) { + uint32_t inlined_at = 0; + if (inst->num_words > kInlinedAtIndex) + inlined_at = inst->words[kInlinedAtIndex]; + last_dbg_scope_ = + DebugScope(inst->words[kLexicalScopeIndex], inlined_at); + module()->SetContainsDebugInfo(); + return true; + } + if (ext_inst_key == CommonDebugInfoDebugNoScope) { + last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt); + module()->SetContainsDebugInfo(); + return true; + } + } else { + const DebugInfoInstructions ext_inst_key = + DebugInfoInstructions(ext_inst_index); + if (ext_inst_key == DebugInfoDebugScope) { + uint32_t inlined_at = 0; + if (inst->num_words > kInlinedAtIndex) + inlined_at = inst->words[kInlinedAtIndex]; + last_dbg_scope_ = + DebugScope(inst->words[kLexicalScopeIndex], inlined_at); + module()->SetContainsDebugInfo(); + return true; + } + if (ext_inst_key == DebugInfoDebugNoScope) { + last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt); + module()->SetContainsDebugInfo(); + return true; + } + } + } + + std::unique_ptr spv_inst( + new Instruction(module()->context(), *inst, std::move(dbg_line_info_))); + if (!spv_inst->dbg_line_insts().empty()) { + if (extra_line_tracking_ && + (!spv_inst->dbg_line_insts().back().IsNoLine())) { + last_line_inst_ = std::unique_ptr( + spv_inst->dbg_line_insts().back().Clone(module()->context())); + if (last_line_inst_->IsDebugLineInst()) + last_line_inst_->SetResultId(module()->context()->TakeNextId()); + } + dbg_line_info_.clear(); + } else if (last_line_inst_ != nullptr) { + last_line_inst_->SetDebugScope(last_dbg_scope_); + spv_inst->dbg_line_insts().push_back(*last_line_inst_); + last_line_inst_ = std::unique_ptr( + spv_inst->dbg_line_insts().back().Clone(module()->context())); + if (last_line_inst_->IsDebugLineInst()) + last_line_inst_->SetResultId(module()->context()->TakeNextId()); + } + + const char* src = source_.c_str(); + spv_position_t loc = {inst_index_, 0, 0}; + + // Handle function and basic block boundaries first, then normal + // instructions. + if (opcode == spv::Op::OpFunction) { + if (function_ != nullptr) { + Error(consumer_, src, loc, "function inside function"); + return false; + } + function_ = MakeUnique(std::move(spv_inst)); + } else if (opcode == spv::Op::OpFunctionEnd) { + if (function_ == nullptr) { + Error(consumer_, src, loc, + "OpFunctionEnd without corresponding OpFunction"); + return false; + } + if (block_ != nullptr) { + Error(consumer_, src, loc, "OpFunctionEnd inside basic block"); + return false; + } + function_->SetFunctionEnd(std::move(spv_inst)); + module_->AddFunction(std::move(function_)); + function_ = nullptr; + } else if (opcode == spv::Op::OpLabel) { + if (function_ == nullptr) { + Error(consumer_, src, loc, "OpLabel outside function"); + return false; + } + if (block_ != nullptr) { + Error(consumer_, src, loc, "OpLabel inside basic block"); + return false; + } + block_ = MakeUnique(std::move(spv_inst)); + } else if (spvOpcodeIsBlockTerminator(opcode)) { + if (function_ == nullptr) { + Error(consumer_, src, loc, "terminator instruction outside function"); + return false; + } + if (block_ == nullptr) { + Error(consumer_, src, loc, "terminator instruction outside basic block"); + return false; + } + if (last_dbg_scope_.GetLexicalScope() != kNoDebugScope) + spv_inst->SetDebugScope(last_dbg_scope_); + block_->AddInstruction(std::move(spv_inst)); + function_->AddBasicBlock(std::move(block_)); + block_ = nullptr; + last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt); + last_line_inst_.reset(); + dbg_line_info_.clear(); + } else { + if (function_ == nullptr) { // Outside function definition + SPIRV_ASSERT(consumer_, block_ == nullptr); + if (opcode == spv::Op::OpCapability) { + module_->AddCapability(std::move(spv_inst)); + } else if (opcode == spv::Op::OpExtension) { + module_->AddExtension(std::move(spv_inst)); + } else if (opcode == spv::Op::OpExtInstImport) { + module_->AddExtInstImport(std::move(spv_inst)); + } else if (opcode == spv::Op::OpMemoryModel) { + module_->SetMemoryModel(std::move(spv_inst)); + } else if (opcode == spv::Op::OpSamplerImageAddressingModeNV) { + module_->SetSampledImageAddressMode(std::move(spv_inst)); + } else if (opcode == spv::Op::OpEntryPoint) { + module_->AddEntryPoint(std::move(spv_inst)); + } else if (opcode == spv::Op::OpExecutionMode || + opcode == spv::Op::OpExecutionModeId) { + module_->AddExecutionMode(std::move(spv_inst)); + } else if (IsDebug1Inst(opcode)) { + module_->AddDebug1Inst(std::move(spv_inst)); + } else if (IsDebug2Inst(opcode)) { + module_->AddDebug2Inst(std::move(spv_inst)); + } else if (IsDebug3Inst(opcode)) { + module_->AddDebug3Inst(std::move(spv_inst)); + } else if (IsAnnotationInst(opcode)) { + module_->AddAnnotationInst(std::move(spv_inst)); + } else if (IsTypeInst(opcode)) { + module_->AddType(std::move(spv_inst)); + } else if (IsConstantInst(opcode) || opcode == spv::Op::OpVariable || + opcode == spv::Op::OpUndef) { + module_->AddGlobalValue(std::move(spv_inst)); + } else if (opcode == spv::Op::OpExtInst && + spvExtInstIsDebugInfo(inst->ext_inst_type)) { + module_->AddExtInstDebugInfo(std::move(spv_inst)); + } else if (opcode == spv::Op::OpExtInst && + spvExtInstIsNonSemantic(inst->ext_inst_type)) { + // If there are no functions, add the non-semantic instructions to the + // global values. Otherwise append it to the list of the last function. + auto func_begin = module_->begin(); + auto func_end = module_->end(); + if (func_begin == func_end) { + module_->AddGlobalValue(std::move(spv_inst)); + } else { + (--func_end)->AddNonSemanticInstruction(std::move(spv_inst)); + } + } else { + Errorf(consumer_, src, loc, + "Unhandled inst type (opcode: %d) found outside function " + "definition.", + opcode); + return false; + } + } else { + if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) + last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt); + if (last_dbg_scope_.GetLexicalScope() != kNoDebugScope) + spv_inst->SetDebugScope(last_dbg_scope_); + if (opcode == spv::Op::OpExtInst && + spvExtInstIsDebugInfo(inst->ext_inst_type)) { + const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; + if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) { + const OpenCLDebugInfo100Instructions ext_inst_key = + OpenCLDebugInfo100Instructions(ext_inst_index); + switch (ext_inst_key) { + case OpenCLDebugInfo100DebugDeclare: { + if (block_ == nullptr) // Inside function but outside blocks + function_->AddDebugInstructionInHeader(std::move(spv_inst)); + else + block_->AddInstruction(std::move(spv_inst)); + break; + } + case OpenCLDebugInfo100DebugValue: { + if (block_ == nullptr) // Inside function but outside blocks + function_->AddDebugInstructionInHeader(std::move(spv_inst)); + else + block_->AddInstruction(std::move(spv_inst)); + break; + } + default: { + Errorf(consumer_, src, loc, + "Debug info extension instruction other than DebugScope, " + "DebugNoScope, DebugFunctionDefinition, DebugDeclare, and " + "DebugValue found inside function", + opcode); + return false; + } + } + } else if (inst->ext_inst_type == + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { + const NonSemanticShaderDebugInfo100Instructions ext_inst_key = + NonSemanticShaderDebugInfo100Instructions(ext_inst_index); + switch (ext_inst_key) { + case NonSemanticShaderDebugInfo100DebugDeclare: + case NonSemanticShaderDebugInfo100DebugValue: + case NonSemanticShaderDebugInfo100DebugScope: + case NonSemanticShaderDebugInfo100DebugNoScope: + case NonSemanticShaderDebugInfo100DebugFunctionDefinition: { + if (block_ == nullptr) { // Inside function but outside blocks + Errorf(consumer_, src, loc, + "Debug info extension instruction found inside function " + "but outside block", + opcode); + } else { + block_->AddInstruction(std::move(spv_inst)); + } + break; + } + default: { + Errorf(consumer_, src, loc, + "Debug info extension instruction other than DebugScope, " + "DebugNoScope, DebugDeclare, and DebugValue found inside " + "function", + opcode); + return false; + } + } + } else { + const DebugInfoInstructions ext_inst_key = + DebugInfoInstructions(ext_inst_index); + switch (ext_inst_key) { + case DebugInfoDebugDeclare: { + if (block_ == nullptr) // Inside function but outside blocks + function_->AddDebugInstructionInHeader(std::move(spv_inst)); + else + block_->AddInstruction(std::move(spv_inst)); + break; + } + case DebugInfoDebugValue: { + if (block_ == nullptr) // Inside function but outside blocks + function_->AddDebugInstructionInHeader(std::move(spv_inst)); + else + block_->AddInstruction(std::move(spv_inst)); + break; + } + default: { + Errorf(consumer_, src, loc, + "Debug info extension instruction other than DebugScope, " + "DebugNoScope, DebugDeclare, and DebugValue found inside " + "function", + opcode); + return false; + } + } + } + } else { + if (block_ == nullptr) { // Inside function but outside blocks + if (opcode != spv::Op::OpFunctionParameter) { + Errorf(consumer_, src, loc, + "Non-OpFunctionParameter (opcode: %d) found inside " + "function but outside basic block", + opcode); + return false; + } + function_->AddParameter(std::move(spv_inst)); + } else { + block_->AddInstruction(std::move(spv_inst)); + } + } + } + } + return true; +} + +// Resolves internal references among the module, functions, basic blocks, etc. +// This function should be called after adding all instructions. +void IrLoader::EndModule() { + if (block_ && function_) { + // We're in the middle of a basic block, but the terminator is missing. + // Register the block anyway. This lets us write tests with less + // boilerplate. + function_->AddBasicBlock(std::move(block_)); + block_ = nullptr; + } + if (function_) { + // We're in the middle of a function, but the OpFunctionEnd is missing. + // Register the function anyway. This lets us write tests with less + // boilerplate. + module_->AddFunction(std::move(function_)); + function_ = nullptr; + } + for (auto& function : *module_) { + for (auto& bb : function) bb.SetParent(&function); + } + + // Copy any trailing Op*Line instruction into the module + module_->SetTrailingDbgLineInfo(std::move(dbg_line_info_)); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ir_loader.h b/thirdparty/glslang/External/spirv-tools/source/opt/ir_loader.h new file mode 100644 index 000000000000..16bc2c7c84bd --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ir_loader.h @@ -0,0 +1,101 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_IR_LOADER_H_ +#define SOURCE_OPT_IR_LOADER_H_ + +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/instruction.h" +#include "source/opt/module.h" +#include "spirv-tools/libspirv.hpp" + +namespace spvtools { +namespace opt { + +// Loader class for constructing SPIR-V in-memory IR representation. Methods in +// this class are designed to work with the interface for spvBinaryParse() in +// libspirv.h so that we can leverage the syntax checks implemented behind it. +// +// The user is expected to call SetModuleHeader() to fill in the module's +// header, and then AddInstruction() for each decoded instruction, and finally +// EndModule() to finalize the module. The instructions processed in sequence +// by AddInstruction() should comprise a valid SPIR-V module. +class IrLoader { + public: + // Instantiates a builder to construct the given |module| gradually. + // All internal messages will be communicated to the outside via the given + // message |consumer|. This instance only keeps a reference to the |consumer|, + // so the |consumer| should outlive this instance. + IrLoader(const MessageConsumer& consumer, Module* m); + + // Sets the source name of the module. + void SetSource(const std::string& src) { source_ = src; } + + Module* module() const { return module_; } + + // Sets the fields in the module's header to the given parameters. + void SetModuleHeader(uint32_t magic, uint32_t version, uint32_t generator, + uint32_t bound, uint32_t reserved) { + module_->SetHeader({magic, version, generator, bound, reserved}); + } + // Adds an instruction to the module. Returns true if no error occurs. This + // method will properly capture and store the data provided in |inst| so that + // |inst| is no longer needed after returning. + bool AddInstruction(const spv_parsed_instruction_t* inst); + // Finalizes the module construction. This must be called after the module + // header has been set and all instructions have been added. This is + // forgiving in the case of a missing terminator instruction on a basic block, + // or a missing OpFunctionEnd. Resolves internal bookkeeping. + void EndModule(); + + // Sets whether extra OpLine instructions should be injected to better + // track line information. + void SetExtraLineTracking(bool flag) { extra_line_tracking_ = flag; } + + private: + // Consumer for communicating messages to outside. + const MessageConsumer& consumer_; + // The module to be built. + Module* module_; + // The source name of the module. + std::string source_; + // The last used instruction index. + uint32_t inst_index_; + // The current Function under construction. + std::unique_ptr function_; + // The current BasicBlock under construction. + std::unique_ptr block_; + // Line related debug instructions accumulated thus far. + std::vector dbg_line_info_; + // If doing extra line tracking, this is the line instruction that should be + // applied to the next instruction. Otherwise it always contains null. + std::unique_ptr last_line_inst_; + + // The last DebugScope information that IrLoader::AddInstruction() handled. + DebugScope last_dbg_scope_; + + // When true, do extra line information tracking: Additional OpLine + // instructions will be injected to help track line info more robustly during + // transformations. + bool extra_line_tracking_ = true; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_IR_LOADER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/iterator.h b/thirdparty/glslang/External/spirv-tools/source/opt/iterator.h new file mode 100644 index 000000000000..847e1bbd52a4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/iterator.h @@ -0,0 +1,350 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_ITERATOR_H_ +#define SOURCE_OPT_ITERATOR_H_ + +#include // for ptrdiff_t +#include +#include +#include +#include +#include + +namespace spvtools { +namespace opt { + +// An ad hoc iterator class for std::vector>. The +// purpose of this iterator class is to provide transparent access to those +// std::unique_ptr managed elements in the vector, behaving like we are using +// std::vector<|ValueType|>. +template +class UptrVectorIterator { + public: + using iterator_category = std::random_access_iterator_tag; + using value_type = ValueType; + + using pointer = value_type*; + using reference = value_type&; + using difference_type = std::ptrdiff_t; + + // Type aliases. We need to apply constness properly if |IsConst| is true. + using Uptr = std::unique_ptr; + using UptrVector = typename std::conditional, + std::vector>::type; + using UnderlyingIterator = + typename std::conditional::type; + + // Creates a new iterator from the given |container| and its raw iterator + // |it|. + UptrVectorIterator(UptrVector* container, const UnderlyingIterator& it) + : container_(container), iterator_(it) {} + UptrVectorIterator(const UptrVectorIterator&) = default; + UptrVectorIterator& operator=(const UptrVectorIterator&) = default; + + inline UptrVectorIterator& operator++(); + inline UptrVectorIterator operator++(int); + inline UptrVectorIterator& operator--(); + inline UptrVectorIterator operator--(int); + + reference operator*() const { return **iterator_; } + pointer operator->() { return (*iterator_).get(); } + reference operator[](ptrdiff_t index) { return **(iterator_ + index); } + + inline bool operator==(const UptrVectorIterator& that) const; + inline bool operator!=(const UptrVectorIterator& that) const; + + inline ptrdiff_t operator-(const UptrVectorIterator& that) const; + inline bool operator<(const UptrVectorIterator& that) const; + + // Inserts the given |value| to the position pointed to by this iterator + // and returns an iterator to the newly iserted |value|. + // If the underlying vector changes capacity, all previous iterators will be + // invalidated. Otherwise, those previous iterators pointing to after the + // insertion point will be invalidated. + template + inline typename std::enable_if::type + InsertBefore(Uptr value); + + // Inserts the given |valueVector| to the position pointed to by this iterator + // and returns an iterator to the first newly inserted value. + // If the underlying vector changes capacity, all previous iterators will be + // invalidated. Otherwise, those previous iterators pointing to after the + // insertion point will be invalidated. + template + inline typename std::enable_if::type + InsertBefore(UptrVector* valueVector); + + // Erases the value at the position pointed to by this iterator + // and returns an iterator to the following value. + // If the underlying vector changes capacity, all previous iterators will be + // invalidated. Otherwise, those previous iterators pointing to after the + // erasure point will be invalidated. + template + inline typename std::enable_if::type + Erase(); + + // Returns the underlying iterator. + UnderlyingIterator Get() const { return iterator_; } + + // Returns a valid end iterator for the underlying container. + UptrVectorIterator End() const { + return UptrVectorIterator(container_, container_->end()); + } + + private: + UptrVector* container_; // The container we are manipulating. + UnderlyingIterator iterator_; // The raw iterator from the container. +}; + +// Handy class for a (begin, end) iterator pair. +template +class IteratorRange { + public: + IteratorRange(const IteratorType& b, const IteratorType& e) + : begin_(b), end_(e) {} + IteratorRange(IteratorType&& b, IteratorType&& e) + : begin_(std::move(b)), end_(std::move(e)) {} + + IteratorType begin() const { return begin_; } + IteratorType end() const { return end_; } + + bool empty() const { return begin_ == end_; } + size_t size() const { return end_ - begin_; } + + private: + IteratorType begin_; + IteratorType end_; +}; + +// Returns a (begin, end) iterator pair for the given iterators. +// The iterators must belong to the same container. +template +inline IteratorRange make_range(const IteratorType& begin, + const IteratorType& end) { + return {begin, end}; +} + +// Returns a (begin, end) iterator pair for the given iterators. +// The iterators must belong to the same container. +template +inline IteratorRange make_range(IteratorType&& begin, + IteratorType&& end) { + return {std::forward(begin), std::forward(end)}; +} + +// Returns a (begin, end) iterator pair for the given container. +template > +inline IteratorRange make_range( + std::vector>& container) { + return {IteratorType(&container, container.begin()), + IteratorType(&container, container.end())}; +} + +// Returns a const (begin, end) iterator pair for the given container. +template > +inline IteratorRange make_const_range( + const std::vector>& container) { + return {IteratorType(&container, container.cbegin()), + IteratorType(&container, container.cend())}; +} + +// Wrapping iterator class that only consider elements that satisfy the given +// predicate |Predicate|. When moving to the next element of the iterator, the +// FilterIterator will iterate over the range until it finds an element that +// satisfies |Predicate| or reaches the end of the iterator. +// +// Currently this iterator is always an input iterator. +template +class FilterIterator { + public: + // Iterator interface. + using iterator_category = typename SubIterator::iterator_category; + using value_type = typename SubIterator::value_type; + using pointer = typename SubIterator::pointer; + using reference = typename SubIterator::reference; + using difference_type = typename SubIterator::difference_type; + + using Range = IteratorRange; + + FilterIterator(const IteratorRange& iteration_range, + Predicate predicate) + : cur_(iteration_range.begin()), + end_(iteration_range.end()), + predicate_(predicate) { + if (!IsPredicateSatisfied()) { + MoveToNextPosition(); + } + } + + FilterIterator(const SubIterator& end, Predicate predicate) + : FilterIterator({end, end}, predicate) {} + + inline FilterIterator& operator++() { + MoveToNextPosition(); + return *this; + } + inline FilterIterator operator++(int) { + FilterIterator old = *this; + MoveToNextPosition(); + return old; + } + + reference operator*() const { return *cur_; } + pointer operator->() { return &*cur_; } + + inline bool operator==(const FilterIterator& rhs) const { + return cur_ == rhs.cur_ && end_ == rhs.end_; + } + inline bool operator!=(const FilterIterator& rhs) const { + return !(*this == rhs); + } + + // Returns the underlying iterator. + SubIterator Get() const { return cur_; } + + // Returns the sentinel iterator. + FilterIterator GetEnd() const { return FilterIterator(end_, predicate_); } + + private: + // Returns true if the predicate is satisfied or the current iterator reached + // the end. + bool IsPredicateSatisfied() { return cur_ == end_ || predicate_(*cur_); } + + void MoveToNextPosition() { + if (cur_ == end_) return; + + do { + ++cur_; + } while (!IsPredicateSatisfied()); + } + + SubIterator cur_; + SubIterator end_; + Predicate predicate_; +}; + +template +FilterIterator MakeFilterIterator( + const IteratorRange& sub_iterator_range, Predicate predicate) { + return FilterIterator(sub_iterator_range, predicate); +} + +template +FilterIterator MakeFilterIterator( + const SubIterator& begin, const SubIterator& end, Predicate predicate) { + return MakeFilterIterator(make_range(begin, end), predicate); +} + +template +typename FilterIterator::Range MakeFilterIteratorRange( + const SubIterator& begin, const SubIterator& end, Predicate predicate) { + return typename FilterIterator::Range( + MakeFilterIterator(begin, end, predicate), + MakeFilterIterator(end, end, predicate)); +} + +template +inline UptrVectorIterator& UptrVectorIterator::operator++() { + ++iterator_; + return *this; +} + +template +inline UptrVectorIterator UptrVectorIterator::operator++(int) { + auto it = *this; + ++(*this); + return it; +} + +template +inline UptrVectorIterator& UptrVectorIterator::operator--() { + --iterator_; + return *this; +} + +template +inline UptrVectorIterator UptrVectorIterator::operator--(int) { + auto it = *this; + --(*this); + return it; +} + +template +inline bool UptrVectorIterator::operator==( + const UptrVectorIterator& that) const { + return container_ == that.container_ && iterator_ == that.iterator_; +} + +template +inline bool UptrVectorIterator::operator!=( + const UptrVectorIterator& that) const { + return !(*this == that); +} + +template +inline ptrdiff_t UptrVectorIterator::operator-( + const UptrVectorIterator& that) const { + assert(container_ == that.container_); + return iterator_ - that.iterator_; +} + +template +inline bool UptrVectorIterator::operator<( + const UptrVectorIterator& that) const { + assert(container_ == that.container_); + return iterator_ < that.iterator_; +} + +template +template +inline + typename std::enable_if>::type + UptrVectorIterator::InsertBefore(Uptr value) { + auto index = iterator_ - container_->begin(); + container_->insert(iterator_, std::move(value)); + return UptrVectorIterator(container_, container_->begin() + index); +} + +template +template +inline + typename std::enable_if>::type + UptrVectorIterator::InsertBefore(UptrVector* values) { + const auto pos = iterator_ - container_->begin(); + const auto origsz = container_->size(); + container_->resize(origsz + values->size()); + std::move_backward(container_->begin() + pos, container_->begin() + origsz, + container_->end()); + std::move(values->begin(), values->end(), container_->begin() + pos); + return UptrVectorIterator(container_, container_->begin() + pos); +} + +template +template +inline + typename std::enable_if>::type + UptrVectorIterator::Erase() { + auto index = iterator_ - container_->begin(); + (void)container_->erase(iterator_); + return UptrVectorIterator(container_, container_->begin() + index); +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_ITERATOR_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/licm_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/licm_pass.cpp new file mode 100644 index 000000000000..f2a6e4df5654 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/licm_pass.cpp @@ -0,0 +1,139 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/licm_pass.h" + +#include + +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +Pass::Status LICMPass::Process() { return ProcessIRContext(); } + +Pass::Status LICMPass::ProcessIRContext() { + Status status = Status::SuccessWithoutChange; + Module* module = get_module(); + + // Process each function in the module + for (auto func = module->begin(); + func != module->end() && status != Status::Failure; ++func) { + status = CombineStatus(status, ProcessFunction(&*func)); + } + return status; +} + +Pass::Status LICMPass::ProcessFunction(Function* f) { + Status status = Status::SuccessWithoutChange; + LoopDescriptor* loop_descriptor = context()->GetLoopDescriptor(f); + + // Process each loop in the function + for (auto it = loop_descriptor->begin(); + it != loop_descriptor->end() && status != Status::Failure; ++it) { + Loop& loop = *it; + // Ignore nested loops, as we will process them in order in ProcessLoop + if (loop.IsNested()) { + continue; + } + status = CombineStatus(status, ProcessLoop(&loop, f)); + } + return status; +} + +Pass::Status LICMPass::ProcessLoop(Loop* loop, Function* f) { + Status status = Status::SuccessWithoutChange; + + // Process all nested loops first + for (auto nl = loop->begin(); nl != loop->end() && status != Status::Failure; + ++nl) { + Loop* nested_loop = *nl; + status = CombineStatus(status, ProcessLoop(nested_loop, f)); + } + + std::vector loop_bbs{}; + status = CombineStatus( + status, + AnalyseAndHoistFromBB(loop, f, loop->GetHeaderBlock(), &loop_bbs)); + + for (size_t i = 0; i < loop_bbs.size() && status != Status::Failure; ++i) { + BasicBlock* bb = loop_bbs[i]; + // do not delete the element + status = + CombineStatus(status, AnalyseAndHoistFromBB(loop, f, bb, &loop_bbs)); + } + + return status; +} + +Pass::Status LICMPass::AnalyseAndHoistFromBB( + Loop* loop, Function* f, BasicBlock* bb, + std::vector* loop_bbs) { + bool modified = false; + std::function hoist_inst = + [this, &loop, &modified](Instruction* inst) { + if (loop->ShouldHoistInstruction(*inst)) { + if (!HoistInstruction(loop, inst)) { + return false; + } + modified = true; + } + return true; + }; + + if (IsImmediatelyContainedInLoop(loop, f, bb)) { + if (!bb->WhileEachInst(hoist_inst, false)) { + return Status::Failure; + } + } + + DominatorAnalysis* dom_analysis = context()->GetDominatorAnalysis(f); + DominatorTree& dom_tree = dom_analysis->GetDomTree(); + + for (DominatorTreeNode* child_dom_tree_node : *dom_tree.GetTreeNode(bb)) { + if (loop->IsInsideLoop(child_dom_tree_node->bb_)) { + loop_bbs->push_back(child_dom_tree_node->bb_); + } + } + + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool LICMPass::IsImmediatelyContainedInLoop(Loop* loop, Function* f, + BasicBlock* bb) { + LoopDescriptor* loop_descriptor = context()->GetLoopDescriptor(f); + return loop == (*loop_descriptor)[bb->id()]; +} + +bool LICMPass::HoistInstruction(Loop* loop, Instruction* inst) { + // TODO(1841): Handle failure to create pre-header. + BasicBlock* pre_header_bb = loop->GetOrCreatePreHeaderBlock(); + if (!pre_header_bb) { + return false; + } + Instruction* insertion_point = &*pre_header_bb->tail(); + Instruction* previous_node = insertion_point->PreviousNode(); + if (previous_node && (previous_node->opcode() == spv::Op::OpLoopMerge || + previous_node->opcode() == spv::Op::OpSelectionMerge)) { + insertion_point = previous_node; + } + + inst->InsertBefore(insertion_point); + context()->set_instr_block(inst, pre_header_bb); + return true; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/licm_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/licm_pass.h new file mode 100644 index 000000000000..597fe920a466 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/licm_pass.h @@ -0,0 +1,72 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LICM_PASS_H_ +#define SOURCE_OPT_LICM_PASS_H_ + +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/instruction.h" +#include "source/opt/loop_descriptor.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +class LICMPass : public Pass { + public: + LICMPass() {} + + const char* name() const override { return "loop-invariant-code-motion"; } + Status Process() override; + + private: + // Searches the IRContext for functions and processes each, moving invariants + // outside loops within the function where possible. + // Returns the status depending on whether or not there was a failure or + // change. + Pass::Status ProcessIRContext(); + + // Checks the function for loops, calling ProcessLoop on each one found. + // Returns the status depending on whether or not there was a failure or + // change. + Pass::Status ProcessFunction(Function* f); + + // Checks for invariants in the loop and attempts to move them to the loops + // preheader. Works from inner loop to outer when nested loops are found. + // Returns the status depending on whether or not there was a failure or + // change. + Pass::Status ProcessLoop(Loop* loop, Function* f); + + // Analyses each instruction in |bb|, hoisting invariants to |pre_header_bb|. + // Each child of |bb| wrt to |dom_tree| is pushed to |loop_bbs| + // Returns the status depending on whether or not there was a failure or + // change. + Pass::Status AnalyseAndHoistFromBB(Loop* loop, Function* f, BasicBlock* bb, + std::vector* loop_bbs); + + // Returns true if |bb| is immediately contained in |loop| + bool IsImmediatelyContainedInLoop(Loop* loop, Function* f, BasicBlock* bb); + + // Move the instruction to the preheader of |loop|. + // This method will update the instruction to block mapping for the context + bool HoistInstruction(Loop* loop, Instruction* inst); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LICM_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/liveness.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/liveness.cpp new file mode 100644 index 000000000000..336f3ae526c9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/liveness.cpp @@ -0,0 +1,332 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/liveness.h" + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace analysis { +namespace { +constexpr uint32_t kDecorationLocationInIdx = 2; +constexpr uint32_t kOpDecorateMemberMemberInIdx = 1; +constexpr uint32_t kOpDecorateMemberLocationInIdx = 3; +constexpr uint32_t kOpDecorateBuiltInLiteralInIdx = 2; +constexpr uint32_t kOpDecorateMemberBuiltInLiteralInIdx = 3; +} // namespace + +LivenessManager::LivenessManager(IRContext* ctx) : ctx_(ctx), computed_(false) { + // Liveness sets computed when queried +} + +void LivenessManager::InitializeAnalysis() { + live_locs_.clear(); + live_builtins_.clear(); + // Mark all builtins live for frag shader. + if (context()->GetStage() == spv::ExecutionModel::Fragment) { + live_builtins_.insert(uint32_t(spv::BuiltIn::PointSize)); + live_builtins_.insert(uint32_t(spv::BuiltIn::ClipDistance)); + live_builtins_.insert(uint32_t(spv::BuiltIn::CullDistance)); + } +} + +bool LivenessManager::IsAnalyzedBuiltin(uint32_t bi) { + // There are only three builtins that can be analyzed and removed between + // two stages: PointSize, ClipDistance and CullDistance. All others are + // always consumed implicitly by the downstream stage. + const auto builtin = spv::BuiltIn(bi); + return builtin == spv::BuiltIn::PointSize || + builtin == spv::BuiltIn::ClipDistance || + builtin == spv::BuiltIn::CullDistance; +} + +bool LivenessManager::AnalyzeBuiltIn(uint32_t id) { + auto deco_mgr = context()->get_decoration_mgr(); + bool saw_builtin = false; + // Analyze all builtin decorations of |id|. + (void)deco_mgr->ForEachDecoration( + id, uint32_t(spv::Decoration::BuiltIn), + [this, &saw_builtin](const Instruction& deco_inst) { + saw_builtin = true; + // No need to process builtins in frag shader. All assumed used. + if (context()->GetStage() == spv::ExecutionModel::Fragment) return; + uint32_t builtin = uint32_t(spv::BuiltIn::Max); + if (deco_inst.opcode() == spv::Op::OpDecorate) + builtin = + deco_inst.GetSingleWordInOperand(kOpDecorateBuiltInLiteralInIdx); + else if (deco_inst.opcode() == spv::Op::OpMemberDecorate) + builtin = deco_inst.GetSingleWordInOperand( + kOpDecorateMemberBuiltInLiteralInIdx); + else + assert(false && "unexpected decoration"); + if (IsAnalyzedBuiltin(builtin)) live_builtins_.insert(builtin); + }); + return saw_builtin; +} + +void LivenessManager::MarkLocsLive(uint32_t start, uint32_t count) { + auto finish = start + count; + for (uint32_t u = start; u < finish; ++u) { + live_locs_.insert(u); + } +} + +uint32_t LivenessManager::GetLocSize(const analysis::Type* type) const { + auto arr_type = type->AsArray(); + if (arr_type) { + auto comp_type = arr_type->element_type(); + auto len_info = arr_type->length_info(); + assert(len_info.words[0] == analysis::Array::LengthInfo::kConstant && + "unexpected array length"); + auto comp_len = len_info.words[1]; + return comp_len * GetLocSize(comp_type); + } + auto struct_type = type->AsStruct(); + if (struct_type) { + uint32_t size = 0u; + for (auto& el_type : struct_type->element_types()) + size += GetLocSize(el_type); + return size; + } + auto mat_type = type->AsMatrix(); + if (mat_type) { + auto cnt = mat_type->element_count(); + auto comp_type = mat_type->element_type(); + return cnt * GetLocSize(comp_type); + } + auto vec_type = type->AsVector(); + if (vec_type) { + auto comp_type = vec_type->element_type(); + if (comp_type->AsInteger()) return 1; + auto float_type = comp_type->AsFloat(); + assert(float_type && "unexpected vector component type"); + auto width = float_type->width(); + if (width == 32 || width == 16) return 1; + assert(width == 64 && "unexpected float type width"); + auto comp_cnt = vec_type->element_count(); + return (comp_cnt > 2) ? 2 : 1; + } + assert((type->AsInteger() || type->AsFloat()) && "unexpected input type"); + return 1; +} + +const analysis::Type* LivenessManager::GetComponentType( + uint32_t index, const analysis::Type* agg_type) const { + auto arr_type = agg_type->AsArray(); + if (arr_type) return arr_type->element_type(); + auto struct_type = agg_type->AsStruct(); + if (struct_type) return struct_type->element_types()[index]; + auto mat_type = agg_type->AsMatrix(); + if (mat_type) return mat_type->element_type(); + auto vec_type = agg_type->AsVector(); + assert(vec_type && "unexpected non-aggregate type"); + return vec_type->element_type(); +} + +uint32_t LivenessManager::GetLocOffset(uint32_t index, + const analysis::Type* agg_type) const { + auto arr_type = agg_type->AsArray(); + if (arr_type) return index * GetLocSize(arr_type->element_type()); + auto struct_type = agg_type->AsStruct(); + if (struct_type) { + uint32_t offset = 0u; + uint32_t cnt = 0u; + for (auto& el_type : struct_type->element_types()) { + if (cnt == index) break; + offset += GetLocSize(el_type); + ++cnt; + } + return offset; + } + auto mat_type = agg_type->AsMatrix(); + if (mat_type) return index * GetLocSize(mat_type->element_type()); + auto vec_type = agg_type->AsVector(); + assert(vec_type && "unexpected non-aggregate type"); + auto comp_type = vec_type->element_type(); + auto flt_type = comp_type->AsFloat(); + if (flt_type && flt_type->width() == 64u && index >= 2u) return 1; + return 0; +} + +void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac, + const analysis::Type** curr_type, + uint32_t* offset, bool* no_loc, + bool is_patch, bool input) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + // For tesc, tese and geom input variables, and tesc output variables, + // first array index does not contribute to offset. + auto stage = context()->GetStage(); + bool skip_first_index = false; + if ((input && (stage == spv::ExecutionModel::TessellationControl || + stage == spv::ExecutionModel::TessellationEvaluation || + stage == spv::ExecutionModel::Geometry)) || + (!input && stage == spv::ExecutionModel::TessellationControl)) + skip_first_index = !is_patch; + uint32_t ocnt = 0; + ac->WhileEachInOperand([this, &ocnt, def_use_mgr, type_mgr, deco_mgr, + curr_type, offset, no_loc, + skip_first_index](const uint32_t* opnd) { + if (ocnt >= 1) { + // Skip first index's contribution to offset if indicated + if (ocnt == 1 && skip_first_index) { + auto arr_type = (*curr_type)->AsArray(); + assert(arr_type && "unexpected wrapper type"); + *curr_type = arr_type->element_type(); + ocnt++; + return true; + } + // If any non-constant index, mark the entire current object and return. + auto idx_inst = def_use_mgr->GetDef(*opnd); + if (idx_inst->opcode() != spv::Op::OpConstant) return false; + // If current type is struct, look for location decoration on member and + // reset offset if found. + auto index = idx_inst->GetSingleWordInOperand(0); + auto str_type = (*curr_type)->AsStruct(); + if (str_type) { + uint32_t loc = 0; + auto str_type_id = type_mgr->GetId(str_type); + bool no_mem_loc = deco_mgr->WhileEachDecoration( + str_type_id, uint32_t(spv::Decoration::Location), + [&loc, index, no_loc](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpMemberDecorate && + "unexpected decoration"); + if (deco.GetSingleWordInOperand(kOpDecorateMemberMemberInIdx) == + index) { + loc = + deco.GetSingleWordInOperand(kOpDecorateMemberLocationInIdx); + *no_loc = false; + return false; + } + return true; + }); + if (!no_mem_loc) { + *offset = loc; + *curr_type = GetComponentType(index, *curr_type); + ocnt++; + return true; + } + } + + // Update offset and current type based on constant index. + *offset += GetLocOffset(index, *curr_type); + *curr_type = GetComponentType(index, *curr_type); + } + ocnt++; + return true; + }); +} + +void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + // Find variable location if present. + uint32_t loc = 0; + auto var_id = var->result_id(); + bool no_loc = deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::Location), + [&loc](const Instruction& deco) { + assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); + loc = deco.GetSingleWordInOperand(kDecorationLocationInIdx); + return false; + }); + // Find patch decoration if present + bool is_patch = !deco_mgr->WhileEachDecoration( + var_id, uint32_t(spv::Decoration::Patch), [](const Instruction& deco) { + if (deco.opcode() != spv::Op::OpDecorate) + assert(false && "unexpected decoration"); + return false; + }); + // If use is a load, mark all locations of var + auto ptr_type = type_mgr->GetType(var->type_id())->AsPointer(); + assert(ptr_type && "unexpected var type"); + auto var_type = ptr_type->pointee_type(); + if (ref->opcode() == spv::Op::OpLoad) { + assert(!no_loc && "missing input variable location"); + MarkLocsLive(loc, GetLocSize(var_type)); + return; + } + // Mark just those locations indicated by access chain + assert((ref->opcode() == spv::Op::OpAccessChain || + ref->opcode() == spv::Op::OpInBoundsAccessChain) && + "unexpected use of input variable"); + // Traverse access chain, compute location offset and type of reference + // through constant indices and mark those locs live. Assert if no location + // found. + uint32_t offset = loc; + auto curr_type = var_type; + AnalyzeAccessChainLoc(ref, &curr_type, &offset, &no_loc, is_patch); + assert(!no_loc && "missing input variable location"); + MarkLocsLive(offset, GetLocSize(curr_type)); +} + +void LivenessManager::ComputeLiveness() { + InitializeAnalysis(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + // Process all input variables + for (auto& var : context()->types_values()) { + if (var.opcode() != spv::Op::OpVariable) { + continue; + } + analysis::Type* var_type = type_mgr->GetType(var.type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + if (ptr_type->storage_class() != spv::StorageClass::Input) { + continue; + } + // If var is builtin, mark live if analyzed and continue to next variable + auto var_id = var.result_id(); + if (AnalyzeBuiltIn(var_id)) continue; + // If interface block with builtin members, mark live if analyzed and + // continue to next variable. Input interface blocks will only appear + // in tesc, tese and geom shaders. Will need to strip off one level of + // arrayness to get to block type. + auto pte_type = ptr_type->pointee_type(); + auto arr_type = pte_type->AsArray(); + if (arr_type) { + auto elt_type = arr_type->element_type(); + auto str_type = elt_type->AsStruct(); + if (str_type) { + auto str_type_id = type_mgr->GetId(str_type); + if (AnalyzeBuiltIn(str_type_id)) continue; + } + } + // Mark all used locations of var live + def_use_mgr->ForEachUser(var_id, [this, &var](Instruction* user) { + auto op = user->opcode(); + if (op == spv::Op::OpEntryPoint || op == spv::Op::OpName || + op == spv::Op::OpDecorate || user->IsNonSemanticInstruction()) { + return; + } + MarkRefLive(user, &var); + }); + } +} + +void LivenessManager::GetLiveness(std::unordered_set* live_locs, + std::unordered_set* live_builtins) { + if (!computed_) { + ComputeLiveness(); + computed_ = true; + } + *live_locs = live_locs_; + *live_builtins = live_builtins_; +} + +} // namespace analysis +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/liveness.h b/thirdparty/glslang/External/spirv-tools/source/opt/liveness.h new file mode 100644 index 000000000000..7d8a9fb408d6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/liveness.h @@ -0,0 +1,99 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LIVENESS_H_ +#define SOURCE_OPT_LIVENESS_H_ + +#include +#include + +namespace spvtools { +namespace opt { + +class IRContext; +class Instruction; + +namespace analysis { + +class Type; + +// This class represents the liveness of the input variables of a module +class LivenessManager { + public: + LivenessManager(IRContext* ctx); + + // Copy liveness info into |live_locs| and |builtin_locs|. + void GetLiveness(std::unordered_set* live_locs, + std::unordered_set* live_builtins); + + // Return true if builtin |bi| is being analyzed. + bool IsAnalyzedBuiltin(uint32_t bi); + + // Determine starting loc |offset| and the type |cur_type| of + // access chain |ac|. Set |no_loc| to true if no loc found. + // |is_patch| indicates if patch variable. |input| is true + // if input variable, otherwise output variable. + void AnalyzeAccessChainLoc(const Instruction* ac, + const analysis::Type** curr_type, uint32_t* offset, + bool* no_loc, bool is_patch, bool input = true); + + // Return size of |type_id| in units of locations + uint32_t GetLocSize(const analysis::Type* type) const; + + private: + IRContext* context() const { return ctx_; } + + // Initialize analysis + void InitializeAnalysis(); + + // Analyze |id| for builtin var and struct members. Return true if builtins + // found. + bool AnalyzeBuiltIn(uint32_t id); + + // Mark all live locations resulting from |user| of |var| at |loc|. + void MarkRefLive(const Instruction* user, Instruction* var); + + // Mark |count| locations starting at location |start|. + void MarkLocsLive(uint32_t start, uint32_t count); + + // Return type of component of aggregate type |agg_type| at |index| + const analysis::Type* GetComponentType(uint32_t index, + const analysis::Type* agg_type) const; + + // Return offset of |index| into aggregate type |agg_type| in units of + // input locations + uint32_t GetLocOffset(uint32_t index, const analysis::Type* agg_type) const; + + // Populate live_locs_ and live_builtins_ + void ComputeLiveness(); + + // IR context that owns this liveness manager. + IRContext* ctx_; + + // True if live_locs_ and live_builtins_ are computed + bool computed_; + + // Live locations + std::unordered_set live_locs_; + + // Live builtins + std::unordered_set live_builtins_; +}; + +} // namespace analysis +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LIVENESS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/local_access_chain_convert_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/local_access_chain_convert_pass.cpp new file mode 100644 index 000000000000..7ba75cb7a423 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/local_access_chain_convert_pass.cpp @@ -0,0 +1,473 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/local_access_chain_convert_pass.h" + +#include "ir_context.h" +#include "iterator.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kStoreValIdInIdx = 1; +constexpr uint32_t kAccessChainPtrIdInIdx = 0; +} // namespace + +void LocalAccessChainConvertPass::BuildAndAppendInst( + spv::Op opcode, uint32_t typeId, uint32_t resultId, + const std::vector& in_opnds, + std::vector>* newInsts) { + std::unique_ptr newInst( + new Instruction(context(), opcode, typeId, resultId, in_opnds)); + get_def_use_mgr()->AnalyzeInstDefUse(&*newInst); + newInsts->emplace_back(std::move(newInst)); +} + +uint32_t LocalAccessChainConvertPass::BuildAndAppendVarLoad( + const Instruction* ptrInst, uint32_t* varId, uint32_t* varPteTypeId, + std::vector>* newInsts) { + const uint32_t ldResultId = TakeNextId(); + if (ldResultId == 0) { + return 0; + } + + *varId = ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx); + const Instruction* varInst = get_def_use_mgr()->GetDef(*varId); + assert(varInst->opcode() == spv::Op::OpVariable); + *varPteTypeId = GetPointeeTypeId(varInst); + BuildAndAppendInst(spv::Op::OpLoad, *varPteTypeId, ldResultId, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*varId}}}, + newInsts); + return ldResultId; +} + +void LocalAccessChainConvertPass::AppendConstantOperands( + const Instruction* ptrInst, std::vector* in_opnds) { + uint32_t iidIdx = 0; + ptrInst->ForEachInId([&iidIdx, &in_opnds, this](const uint32_t* iid) { + if (iidIdx > 0) { + const Instruction* cInst = get_def_use_mgr()->GetDef(*iid); + const auto* constant_value = + context()->get_constant_mgr()->GetConstantFromInst(cInst); + assert(constant_value != nullptr && + "Expecting the index to be a constant."); + + // We take the sign extended value because OpAccessChain interprets the + // index as signed. + int64_t long_value = constant_value->GetSignExtendedValue(); + assert(long_value <= UINT32_MAX && long_value >= 0 && + "The index value is too large for a composite insert or extract " + "instruction."); + + uint32_t val = static_cast(long_value); + in_opnds->push_back( + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {val}}); + } + ++iidIdx; + }); +} + +bool LocalAccessChainConvertPass::ReplaceAccessChainLoad( + const Instruction* address_inst, Instruction* original_load) { + // Build and append load of variable in ptrInst + if (address_inst->NumInOperands() == 1) { + // An access chain with no indices is essentially a copy. All that is + // needed is to propagate the address. + context()->ReplaceAllUsesWith( + address_inst->result_id(), + address_inst->GetSingleWordInOperand(kAccessChainPtrIdInIdx)); + return true; + } + + std::vector> new_inst; + uint32_t varId; + uint32_t varPteTypeId; + const uint32_t ldResultId = + BuildAndAppendVarLoad(address_inst, &varId, &varPteTypeId, &new_inst); + if (ldResultId == 0) { + return false; + } + + new_inst[0]->UpdateDebugInfoFrom(original_load); + context()->get_decoration_mgr()->CloneDecorations( + original_load->result_id(), ldResultId, + {spv::Decoration::RelaxedPrecision}); + original_load->InsertBefore(std::move(new_inst)); + context()->get_debug_info_mgr()->AnalyzeDebugInst( + original_load->PreviousNode()); + + // Rewrite |original_load| into an extract. + Instruction::OperandList new_operands; + + // copy the result id and the type id to the new operand list. + new_operands.emplace_back(original_load->GetOperand(0)); + new_operands.emplace_back(original_load->GetOperand(1)); + + new_operands.emplace_back( + Operand({spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}})); + AppendConstantOperands(address_inst, &new_operands); + original_load->SetOpcode(spv::Op::OpCompositeExtract); + original_load->ReplaceOperands(new_operands); + context()->UpdateDefUse(original_load); + return true; +} + +bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement( + const Instruction* ptrInst, uint32_t valId, + std::vector>* newInsts) { + if (ptrInst->NumInOperands() == 1) { + // An access chain with no indices is essentially a copy. However, we still + // have to create a new store because the old ones will be deleted. + BuildAndAppendInst( + spv::Op::OpStore, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}}, + newInsts); + return true; + } + + // Build and append load of variable in ptrInst + uint32_t varId; + uint32_t varPteTypeId; + const uint32_t ldResultId = + BuildAndAppendVarLoad(ptrInst, &varId, &varPteTypeId, newInsts); + if (ldResultId == 0) { + return false; + } + + context()->get_decoration_mgr()->CloneDecorations( + varId, ldResultId, {spv::Decoration::RelaxedPrecision}); + + // Build and append Insert + const uint32_t insResultId = TakeNextId(); + if (insResultId == 0) { + return false; + } + std::vector ins_in_opnds = { + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}}; + AppendConstantOperands(ptrInst, &ins_in_opnds); + BuildAndAppendInst(spv::Op::OpCompositeInsert, varPteTypeId, insResultId, + ins_in_opnds, newInsts); + + context()->get_decoration_mgr()->CloneDecorations( + varId, insResultId, {spv::Decoration::RelaxedPrecision}); + + // Build and append Store + BuildAndAppendInst(spv::Op::OpStore, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {varId}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {insResultId}}}, + newInsts); + return true; +} + +bool LocalAccessChainConvertPass::Is32BitConstantIndexAccessChain( + const Instruction* acp) const { + uint32_t inIdx = 0; + return acp->WhileEachInId([&inIdx, this](const uint32_t* tid) { + if (inIdx > 0) { + Instruction* opInst = get_def_use_mgr()->GetDef(*tid); + if (opInst->opcode() != spv::Op::OpConstant) return false; + const auto* index = + context()->get_constant_mgr()->GetConstantFromInst(opInst); + int64_t index_value = index->GetSignExtendedValue(); + if (index_value > UINT32_MAX) return false; + if (index_value < 0) return false; + } + ++inIdx; + return true; + }); +} + +bool LocalAccessChainConvertPass::HasOnlySupportedRefs(uint32_t ptrId) { + if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true; + if (get_def_use_mgr()->WhileEachUser(ptrId, [this](Instruction* user) { + if (user->GetCommonDebugOpcode() == CommonDebugInfoDebugValue || + user->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { + return true; + } + spv::Op op = user->opcode(); + if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { + if (!HasOnlySupportedRefs(user->result_id())) { + return false; + } + } else if (op != spv::Op::OpStore && op != spv::Op::OpLoad && + op != spv::Op::OpName && !IsNonTypeDecorate(op)) { + return false; + } + return true; + })) { + supported_ref_ptrs_.insert(ptrId); + return true; + } + return false; +} + +void LocalAccessChainConvertPass::FindTargetVars(Function* func) { + for (auto bi = func->begin(); bi != func->end(); ++bi) { + for (auto ii = bi->begin(); ii != bi->end(); ++ii) { + switch (ii->opcode()) { + case spv::Op::OpStore: + case spv::Op::OpLoad: { + uint32_t varId; + Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsTargetVar(varId)) break; + const spv::Op op = ptrInst->opcode(); + // Rule out variables with non-supported refs eg function calls + if (!HasOnlySupportedRefs(varId)) { + seen_non_target_vars_.insert(varId); + seen_target_vars_.erase(varId); + break; + } + // Rule out variables with nested access chains + // TODO(): Convert nested access chains + bool is_non_ptr_access_chain = IsNonPtrAccessChain(op); + if (is_non_ptr_access_chain && ptrInst->GetSingleWordInOperand( + kAccessChainPtrIdInIdx) != varId) { + seen_non_target_vars_.insert(varId); + seen_target_vars_.erase(varId); + break; + } + // Rule out variables accessed with non-constant indices + if (!Is32BitConstantIndexAccessChain(ptrInst)) { + seen_non_target_vars_.insert(varId); + seen_target_vars_.erase(varId); + break; + } + + if (is_non_ptr_access_chain && AnyIndexIsOutOfBounds(ptrInst)) { + seen_non_target_vars_.insert(varId); + seen_target_vars_.erase(varId); + break; + } + } break; + default: + break; + } + } + } +} + +Pass::Status LocalAccessChainConvertPass::ConvertLocalAccessChains( + Function* func) { + FindTargetVars(func); + // Replace access chains of all targeted variables with equivalent + // extract and insert sequences + bool modified = false; + for (auto bi = func->begin(); bi != func->end(); ++bi) { + std::vector dead_instructions; + for (auto ii = bi->begin(); ii != bi->end(); ++ii) { + switch (ii->opcode()) { + case spv::Op::OpLoad: { + uint32_t varId; + Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsNonPtrAccessChain(ptrInst->opcode())) break; + if (!IsTargetVar(varId)) break; + if (!ReplaceAccessChainLoad(ptrInst, &*ii)) { + return Status::Failure; + } + modified = true; + } break; + case spv::Op::OpStore: { + uint32_t varId; + Instruction* store = &*ii; + Instruction* ptrInst = GetPtr(store, &varId); + if (!IsNonPtrAccessChain(ptrInst->opcode())) break; + if (!IsTargetVar(varId)) break; + std::vector> newInsts; + uint32_t valId = store->GetSingleWordInOperand(kStoreValIdInIdx); + if (!GenAccessChainStoreReplacement(ptrInst, valId, &newInsts)) { + return Status::Failure; + } + size_t num_of_instructions_to_skip = newInsts.size() - 1; + dead_instructions.push_back(store); + ++ii; + ii = ii.InsertBefore(std::move(newInsts)); + for (size_t i = 0; i < num_of_instructions_to_skip; ++i) { + ii->UpdateDebugInfoFrom(store); + context()->get_debug_info_mgr()->AnalyzeDebugInst(&*ii); + ++ii; + } + ii->UpdateDebugInfoFrom(store); + context()->get_debug_info_mgr()->AnalyzeDebugInst(&*ii); + modified = true; + } break; + default: + break; + } + } + + while (!dead_instructions.empty()) { + Instruction* inst = dead_instructions.back(); + dead_instructions.pop_back(); + DCEInst(inst, [&dead_instructions](Instruction* other_inst) { + auto i = std::find(dead_instructions.begin(), dead_instructions.end(), + other_inst); + if (i != dead_instructions.end()) { + dead_instructions.erase(i); + } + }); + } + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +void LocalAccessChainConvertPass::Initialize() { + // Initialize Target Variable Caches + seen_target_vars_.clear(); + seen_non_target_vars_.clear(); + + // Initialize collections + supported_ref_ptrs_.clear(); + + // Initialize extension allowlist + InitExtensions(); +} + +bool LocalAccessChainConvertPass::AllExtensionsSupported() const { + // This capability can now exist without the extension, so we have to check + // for the capability. This pass is only looking at function scope symbols, + // so we do not care if there are variable pointers on storage buffers. + if (context()->get_feature_mgr()->HasCapability( + spv::Capability::VariablePointers)) + return false; + // If any extension not in allowlist, return false + for (auto& ei : get_module()->extensions()) { + const std::string extName = ei.GetInOperand(0).AsString(); + if (extensions_allowlist_.find(extName) == extensions_allowlist_.end()) + return false; + } + // only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise + // around unknown extended + // instruction sets even if they are non-semantic + for (auto& inst : context()->module()->ext_inst_imports()) { + assert(inst.opcode() == spv::Op::OpExtInstImport && + "Expecting an import of an extension's instruction set."); + const std::string extension_name = inst.GetInOperand(0).AsString(); + if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && + extension_name != "NonSemantic.Shader.DebugInfo.100") { + return false; + } + } + return true; +} + +Pass::Status LocalAccessChainConvertPass::ProcessImpl() { + // Do not process if module contains OpGroupDecorate. Additional + // support required in KillNamesAndDecorates(). + // TODO(greg-lunarg): Add support for OpGroupDecorate + for (auto& ai : get_module()->annotations()) + if (ai.opcode() == spv::Op::OpGroupDecorate) + return Status::SuccessWithoutChange; + // Do not process if any disallowed extensions are enabled + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; + + // Process all functions in the module. + Status status = Status::SuccessWithoutChange; + for (Function& func : *get_module()) { + status = CombineStatus(status, ConvertLocalAccessChains(&func)); + if (status == Status::Failure) { + break; + } + } + return status; +} + +LocalAccessChainConvertPass::LocalAccessChainConvertPass() {} + +Pass::Status LocalAccessChainConvertPass::Process() { + Initialize(); + return ProcessImpl(); +} + +void LocalAccessChainConvertPass::InitExtensions() { + extensions_allowlist_.clear(); + extensions_allowlist_.insert( + {"SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", "SPV_KHR_8bit_storage", "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + // SPV_KHR_variable_pointers + // Currently do not support extended pointer expressions + "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", "SPV_EXT_shader_stencil_export", + "SPV_EXT_shader_viewport_index_layer", + "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_fragment_mask", + "SPV_EXT_fragment_fully_covered", "SPV_AMD_gpu_shader_half_float_fetch", + "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", + "SPV_GOOGLE_user_type", "SPV_NV_shader_subgroup_partitioned", + "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", + "SPV_NV_fragment_shader_barycentric", + "SPV_NV_compute_shader_derivatives", "SPV_NV_shader_image_footprint", + "SPV_NV_shading_rate", "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader", + "SPV_NV_ray_tracing", "SPV_KHR_ray_tracing", "SPV_KHR_ray_query", + "SPV_EXT_fragment_invocation_density", "SPV_KHR_terminate_invocation", + "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_integer_dot_product", + "SPV_EXT_shader_image_int64", "SPV_KHR_non_semantic_info", + "SPV_KHR_uniform_group_instructions", + "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_vulkan_memory_model", + "SPV_NV_bindless_texture", "SPV_EXT_shader_atomic_float_add", + "SPV_EXT_fragment_shader_interlock", + "SPV_NV_compute_shader_derivatives"}); +} + +bool LocalAccessChainConvertPass::AnyIndexIsOutOfBounds( + const Instruction* access_chain_inst) { + assert(IsNonPtrAccessChain(access_chain_inst->opcode())); + + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + auto constants = const_mgr->GetOperandConstants(access_chain_inst); + uint32_t base_pointer_id = access_chain_inst->GetSingleWordInOperand(0); + Instruction* base_pointer = get_def_use_mgr()->GetDef(base_pointer_id); + const analysis::Pointer* base_pointer_type = + type_mgr->GetType(base_pointer->type_id())->AsPointer(); + assert(base_pointer_type != nullptr && + "The base of the access chain is not a pointer."); + const analysis::Type* current_type = base_pointer_type->pointee_type(); + for (uint32_t i = 1; i < access_chain_inst->NumInOperands(); ++i) { + if (IsIndexOutOfBounds(constants[i], current_type)) { + return true; + } + + uint32_t index = + (constants[i] + ? static_cast(constants[i]->GetZeroExtendedValue()) + : 0); + current_type = type_mgr->GetMemberType(current_type, {index}); + } + + return false; +} + +bool LocalAccessChainConvertPass::IsIndexOutOfBounds( + const analysis::Constant* index, const analysis::Type* type) const { + if (index == nullptr) { + return false; + } + return index->GetZeroExtendedValue() >= type->NumberOfComponents(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/local_access_chain_convert_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/local_access_chain_convert_pass.h new file mode 100644 index 000000000000..0cda196f65d1 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/local_access_chain_convert_pass.h @@ -0,0 +1,145 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOCAL_ACCESS_CHAIN_CONVERT_PASS_H_ +#define SOURCE_OPT_LOCAL_ACCESS_CHAIN_CONVERT_PASS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class LocalAccessChainConvertPass : public MemPass { + public: + LocalAccessChainConvertPass(); + + const char* name() const override { return "convert-local-access-chains"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + using ProcessFunction = std::function; + + private: + // Return true if all refs through |ptrId| are only loads or stores and + // cache ptrId in supported_ref_ptrs_. TODO(dnovillo): This function is + // replicated in other passes and it's slightly different in every pass. Is it + // possible to make one common implementation? + bool HasOnlySupportedRefs(uint32_t ptrId); + + // Search |func| and cache function scope variables of target type that are + // not accessed with non-constant-index access chains. Also cache non-target + // variables. + void FindTargetVars(Function* func); + + // Build instruction from |opcode|, |typeId|, |resultId|, and |in_opnds|. + // Append to |newInsts|. + void BuildAndAppendInst(spv::Op opcode, uint32_t typeId, uint32_t resultId, + const std::vector& in_opnds, + std::vector>* newInsts); + + // Build load of variable in |ptrInst| and append to |newInsts|. + // Return var in |varId| and its pointee type in |varPteTypeId|. + uint32_t BuildAndAppendVarLoad( + const Instruction* ptrInst, uint32_t* varId, uint32_t* varPteTypeId, + std::vector>* newInsts); + + // Append literal integer operands to |in_opnds| corresponding to constant + // integer operands from access chain |ptrInst|. Assumes all indices in + // access chains are OpConstant. + void AppendConstantOperands(const Instruction* ptrInst, + std::vector* in_opnds); + + // Create a load/insert/store equivalent to a store of + // |valId| through (constant index) access chain |ptrInst|. + // Append to |newInsts|. Returns true if successful. + bool GenAccessChainStoreReplacement( + const Instruction* ptrInst, uint32_t valId, + std::vector>* newInsts); + + // For the (constant index) access chain |address_inst|, create an + // equivalent load and extract that replaces |original_load|. The result id + // of the extract will be the same as the original result id of + // |original_load|. Returns true if successful. + bool ReplaceAccessChainLoad(const Instruction* address_inst, + Instruction* original_load); + + // Return true if all indices of the access chain |acp| are OpConstant + // integers whose signed values can be represented as unsigned 32-bit values. + bool Is32BitConstantIndexAccessChain(const Instruction* acp) const; + + // Identify all function scope variables of target type which are + // accessed only with loads, stores and access chains with constant + // indices. Convert all loads and stores of such variables into equivalent + // loads, stores, extracts and inserts. This unifies access to these + // variables to a single mode and simplifies analysis and optimization. + // See IsTargetType() for targeted types. + // + // Nested access chains and pointer access chains are not currently + // converted. + // + // Returns a status to indicate success or failure, and change or no change. + Status ConvertLocalAccessChains(Function* func); + + // Returns true one of the indexes in the |access_chain_inst| is definitly out + // of bounds. If the size of the type or the value of the index is unknown, + // then it will be considered in-bounds. + bool AnyIndexIsOutOfBounds(const Instruction* access_chain_inst); + + // Returns true if getting element |index| from |type| would be out-of-bounds. + // If |index| is nullptr or the size of the type are unknown, then it will be + // considered in-bounds. + bool IsIndexOutOfBounds(const analysis::Constant* index, + const analysis::Type* type) const; + + // Initialize extensions allowlist + void InitExtensions(); + + // Return true if all extensions in this module are allowed by this pass. + bool AllExtensionsSupported() const; + + void Initialize(); + Pass::Status ProcessImpl(); + + // Variables with only supported references, ie. loads and stores using + // variable directly or through non-ptr access chains. + std::unordered_set supported_ref_ptrs_; + + // Extensions supported by this pass. + std::unordered_set extensions_allowlist_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOCAL_ACCESS_CHAIN_CONVERT_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/local_redundancy_elimination.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/local_redundancy_elimination.cpp new file mode 100644 index 000000000000..9539e6556610 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/local_redundancy_elimination.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/local_redundancy_elimination.h" + +#include "source/opt/value_number_table.h" + +namespace spvtools { +namespace opt { + +Pass::Status LocalRedundancyEliminationPass::Process() { + bool modified = false; + ValueNumberTable vnTable(context()); + + for (auto& func : *get_module()) { + for (auto& bb : func) { + // Keeps track of all ids that contain a given value number. We keep + // track of multiple values because they could have the same value, but + // different decorations. + std::map value_to_ids; + if (EliminateRedundanciesInBB(&bb, vnTable, &value_to_ids)) + modified = true; + } + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool LocalRedundancyEliminationPass::EliminateRedundanciesInBB( + BasicBlock* block, const ValueNumberTable& vnTable, + std::map* value_to_ids) { + bool modified = false; + + auto func = [this, &vnTable, &modified, value_to_ids](Instruction* inst) { + if (inst->result_id() == 0) { + return; + } + + uint32_t value = vnTable.GetValueNumber(inst); + + if (value == 0) { + return; + } + + auto candidate = value_to_ids->insert({value, inst->result_id()}); + if (!candidate.second) { + context()->KillNamesAndDecorates(inst); + context()->ReplaceAllUsesWith(inst->result_id(), candidate.first->second); + context()->KillInst(inst); + modified = true; + } + }; + block->ForEachInst(func); + return modified; +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/local_redundancy_elimination.h b/thirdparty/glslang/External/spirv-tools/source/opt/local_redundancy_elimination.h new file mode 100644 index 000000000000..770457a32fbf --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/local_redundancy_elimination.h @@ -0,0 +1,68 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOCAL_REDUNDANCY_ELIMINATION_H_ +#define SOURCE_OPT_LOCAL_REDUNDANCY_ELIMINATION_H_ + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/pass.h" +#include "source/opt/value_number_table.h" + +namespace spvtools { +namespace opt { + +// This pass implements local redundancy elimination. Its goal is to reduce the +// number of times the same value is computed. It works on each basic block +// independently, ie local. For each instruction in a basic block, it gets the +// value number for the result id, |id|, of the instruction. If that value +// number has already been computed in the basic block, it tries to replace the +// uses of |id| by the id that already contains the same value. Then the +// current instruction is deleted. +class LocalRedundancyEliminationPass : public Pass { + public: + const char* name() const override { return "local-redundancy-elimination"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + protected: + // Deletes instructions in |block| whose value is in |value_to_ids| or is + // computed earlier in |block|. + // + // |vnTable| must have computed a value number for every result id defined + // in |bb|. + // + // |value_to_ids| is a map from value number to ids. If {vn, id} is in + // |value_to_ids| then vn is the value number of id, and the definition of id + // dominates |bb|. + // + // Returns true if the module is changed. + bool EliminateRedundanciesInBB(BasicBlock* block, + const ValueNumberTable& vnTable, + std::map* value_to_ids); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOCAL_REDUNDANCY_ELIMINATION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/local_single_block_elim_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/local_single_block_elim_pass.cpp new file mode 100644 index 000000000000..d7a9295e8460 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/local_single_block_elim_pass.cpp @@ -0,0 +1,298 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/local_single_block_elim_pass.h" + +#include + +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kStoreValIdInIdx = 1; +} // namespace + +bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) { + if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true; + if (get_def_use_mgr()->WhileEachUser(ptrId, [this](Instruction* user) { + auto dbg_op = user->GetCommonDebugOpcode(); + if (dbg_op == CommonDebugInfoDebugDeclare || + dbg_op == CommonDebugInfoDebugValue) { + return true; + } + spv::Op op = user->opcode(); + if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { + if (!HasOnlySupportedRefs(user->result_id())) { + return false; + } + } else if (op != spv::Op::OpStore && op != spv::Op::OpLoad && + op != spv::Op::OpName && !IsNonTypeDecorate(op)) { + return false; + } + return true; + })) { + supported_ref_ptrs_.insert(ptrId); + return true; + } + return false; +} + +bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( + Function* func) { + // Perform local store/load, load/load and store/store elimination + // on each block + bool modified = false; + std::vector instructions_to_kill; + std::unordered_set instructions_to_save; + for (auto bi = func->begin(); bi != func->end(); ++bi) { + var2store_.clear(); + var2load_.clear(); + auto next = bi->begin(); + for (auto ii = next; ii != bi->end(); ii = next) { + ++next; + switch (ii->opcode()) { + case spv::Op::OpStore: { + // Verify store variable is target type + uint32_t varId; + Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsTargetVar(varId)) continue; + if (!HasOnlySupportedRefs(varId)) continue; + // If a store to the whole variable, remember it for succeeding + // loads and stores. Otherwise forget any previous store to that + // variable. + if (ptrInst->opcode() == spv::Op::OpVariable) { + // If a previous store to same variable, mark the store + // for deletion if not still used. Don't delete store + // if debugging; let ssa-rewrite and DCE handle it + auto prev_store = var2store_.find(varId); + if (prev_store != var2store_.end() && + instructions_to_save.count(prev_store->second) == 0 && + !context()->get_debug_info_mgr()->IsVariableDebugDeclared( + varId)) { + instructions_to_kill.push_back(prev_store->second); + modified = true; + } + + bool kill_store = false; + auto li = var2load_.find(varId); + if (li != var2load_.end()) { + if (ii->GetSingleWordInOperand(kStoreValIdInIdx) == + li->second->result_id()) { + // We are storing the same value that already exists in the + // memory location. The store does nothing. + kill_store = true; + } + } + + if (!kill_store) { + var2store_[varId] = &*ii; + var2load_.erase(varId); + } else { + instructions_to_kill.push_back(&*ii); + modified = true; + } + } else { + assert(IsNonPtrAccessChain(ptrInst->opcode())); + var2store_.erase(varId); + var2load_.erase(varId); + } + } break; + case spv::Op::OpLoad: { + // Verify store variable is target type + uint32_t varId; + Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsTargetVar(varId)) continue; + if (!HasOnlySupportedRefs(varId)) continue; + uint32_t replId = 0; + if (ptrInst->opcode() == spv::Op::OpVariable) { + // If a load from a variable, look for a previous store or + // load from that variable and use its value. + auto si = var2store_.find(varId); + if (si != var2store_.end()) { + replId = si->second->GetSingleWordInOperand(kStoreValIdInIdx); + } else { + auto li = var2load_.find(varId); + if (li != var2load_.end()) { + replId = li->second->result_id(); + } + } + } else { + // If a partial load of a previously seen store, remember + // not to delete the store. + auto si = var2store_.find(varId); + if (si != var2store_.end()) instructions_to_save.insert(si->second); + } + if (replId != 0) { + // replace load's result id and delete load + context()->KillNamesAndDecorates(&*ii); + context()->ReplaceAllUsesWith(ii->result_id(), replId); + instructions_to_kill.push_back(&*ii); + modified = true; + } else { + if (ptrInst->opcode() == spv::Op::OpVariable) + var2load_[varId] = &*ii; // register load + } + } break; + case spv::Op::OpFunctionCall: { + // Conservatively assume all locals are redefined for now. + // TODO(): Handle more optimally + var2store_.clear(); + var2load_.clear(); + } break; + default: + break; + } + } + } + + for (Instruction* inst : instructions_to_kill) { + context()->KillInst(inst); + } + + return modified; +} + +void LocalSingleBlockLoadStoreElimPass::Initialize() { + // Initialize Target Type Caches + seen_target_vars_.clear(); + seen_non_target_vars_.clear(); + + // Clear collections + supported_ref_ptrs_.clear(); + + // Initialize extensions allowlist + InitExtensions(); +} + +bool LocalSingleBlockLoadStoreElimPass::AllExtensionsSupported() const { + // If any extension not in allowlist, return false + for (auto& ei : get_module()->extensions()) { + const std::string extName = ei.GetInOperand(0).AsString(); + if (extensions_allowlist_.find(extName) == extensions_allowlist_.end()) + return false; + } + // only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise + // around unknown extended + // instruction sets even if they are non-semantic + for (auto& inst : context()->module()->ext_inst_imports()) { + assert(inst.opcode() == spv::Op::OpExtInstImport && + "Expecting an import of an extension's instruction set."); + const std::string extension_name = inst.GetInOperand(0).AsString(); + if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && + extension_name != "NonSemantic.Shader.DebugInfo.100") { + return false; + } + } + return true; +} + +Pass::Status LocalSingleBlockLoadStoreElimPass::ProcessImpl() { + // Assumes relaxed logical addressing only (see instruction.h). + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) + return Status::SuccessWithoutChange; + + // Do not process if module contains OpGroupDecorate. Additional + // support required in KillNamesAndDecorates(). + // TODO(greg-lunarg): Add support for OpGroupDecorate + for (auto& ai : get_module()->annotations()) + if (ai.opcode() == spv::Op::OpGroupDecorate) + return Status::SuccessWithoutChange; + // If any extensions in the module are not explicitly supported, + // return unmodified. + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; + // Process all entry point functions + ProcessFunction pfn = [this](Function* fp) { + return LocalSingleBlockLoadStoreElim(fp); + }; + + bool modified = context()->ProcessReachableCallTree(pfn); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElimPass() = + default; + +Pass::Status LocalSingleBlockLoadStoreElimPass::Process() { + Initialize(); + return ProcessImpl(); +} + +void LocalSingleBlockLoadStoreElimPass::InitExtensions() { + extensions_allowlist_.clear(); + extensions_allowlist_.insert({"SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_8bit_storage", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers", + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", + "SPV_EXT_shader_stencil_export", + "SPV_EXT_shader_viewport_index_layer", + "SPV_AMD_shader_image_load_store_lod", + "SPV_AMD_shader_fragment_mask", + "SPV_EXT_fragment_fully_covered", + "SPV_AMD_gpu_shader_half_float_fetch", + "SPV_GOOGLE_decorate_string", + "SPV_GOOGLE_hlsl_functionality1", + "SPV_GOOGLE_user_type", + "SPV_NV_shader_subgroup_partitioned", + "SPV_EXT_demote_to_helper_invocation", + "SPV_EXT_descriptor_indexing", + "SPV_NV_fragment_shader_barycentric", + "SPV_NV_compute_shader_derivatives", + "SPV_NV_shader_image_footprint", + "SPV_NV_shading_rate", + "SPV_NV_mesh_shader", + "SPV_EXT_mesh_shader", + "SPV_NV_ray_tracing", + "SPV_KHR_ray_tracing", + "SPV_KHR_ray_query", + "SPV_EXT_fragment_invocation_density", + "SPV_EXT_physical_storage_buffer", + "SPV_KHR_physical_storage_buffer", + "SPV_KHR_terminate_invocation", + "SPV_KHR_subgroup_uniform_control_flow", + "SPV_KHR_integer_dot_product", + "SPV_EXT_shader_image_int64", + "SPV_KHR_non_semantic_info", + "SPV_KHR_uniform_group_instructions", + "SPV_KHR_fragment_shader_barycentric", + "SPV_KHR_vulkan_memory_model", + "SPV_NV_bindless_texture", + "SPV_EXT_shader_atomic_float_add", + "SPV_EXT_fragment_shader_interlock", + "SPV_NV_compute_shader_derivatives"}); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/local_single_block_elim_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/local_single_block_elim_pass.h new file mode 100644 index 000000000000..ea72816a8e6b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/local_single_block_elim_pass.h @@ -0,0 +1,107 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOCAL_SINGLE_BLOCK_ELIM_PASS_H_ +#define SOURCE_OPT_LOCAL_SINGLE_BLOCK_ELIM_PASS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class LocalSingleBlockLoadStoreElimPass : public MemPass { + public: + LocalSingleBlockLoadStoreElimPass(); + + const char* name() const override { return "eliminate-local-single-block"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Return true if all uses of |varId| are only through supported reference + // operations ie. loads and store. Also cache in supported_ref_ptrs_. + // TODO(dnovillo): This function is replicated in other passes and it's + // slightly different in every pass. Is it possible to make one common + // implementation? + bool HasOnlySupportedRefs(uint32_t varId); + + // On all entry point functions, within each basic block, eliminate + // loads and stores to function variables where possible. For + // loads, if previous load or store to same variable, replace + // load id with previous id and delete load. Finally, check if + // remaining stores are useless, and delete store and variable + // where possible. Assumes logical addressing. + bool LocalSingleBlockLoadStoreElim(Function* func); + + // Initialize extensions allowlist + void InitExtensions(); + + // Return true if all extensions in this module are supported by this pass. + bool AllExtensionsSupported() const; + + void Initialize(); + Pass::Status ProcessImpl(); + + // Map from function scope variable to a store of that variable in the + // current block whose value is currently valid. This map is cleared + // at the start of each block and incrementally updated as the block + // is scanned. The stores are candidates for elimination. The map is + // conservatively cleared when a function call is encountered. + std::unordered_map var2store_; + + // Map from function scope variable to a load of that variable in the + // current block whose value is currently valid. This map is cleared + // at the start of each block and incrementally updated as the block + // is scanned. The stores are candidates for elimination. The map is + // conservatively cleared when a function call is encountered. + std::unordered_map var2load_; + + // Set of variables whose most recent store in the current block cannot be + // deleted, for example, if there is a load of the variable which is + // dependent on the store and is not replaced and deleted by this pass, + // for example, a load through an access chain. A variable is removed + // from this set each time a new store of that variable is encountered. + std::unordered_set pinned_vars_; + + // Extensions supported by this pass. + std::unordered_set extensions_allowlist_; + + // Variables that are only referenced by supported operations for this + // pass ie. loads and stores. + std::unordered_set supported_ref_ptrs_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOCAL_SINGLE_BLOCK_ELIM_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/local_single_store_elim_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/local_single_store_elim_pass.cpp new file mode 100644 index 000000000000..7cd6b0eb476c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/local_single_store_elim_pass.cpp @@ -0,0 +1,310 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/local_single_store_elim_pass.h" + +#include "source/cfa.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kStoreValIdInIdx = 1; +constexpr uint32_t kVariableInitIdInIdx = 1; +} // namespace + +bool LocalSingleStoreElimPass::LocalSingleStoreElim(Function* func) { + bool modified = false; + + // Check all function scope variables in |func|. + BasicBlock* entry_block = &*func->begin(); + for (Instruction& inst : *entry_block) { + if (inst.opcode() != spv::Op::OpVariable) { + break; + } + + modified |= ProcessVariable(&inst); + } + return modified; +} + +bool LocalSingleStoreElimPass::AllExtensionsSupported() const { + // If any extension not in allowlist, return false + for (auto& ei : get_module()->extensions()) { + const std::string extName = ei.GetInOperand(0).AsString(); + if (extensions_allowlist_.find(extName) == extensions_allowlist_.end()) + return false; + } + // only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise + // around unknown extended + // instruction sets even if they are non-semantic + for (auto& inst : context()->module()->ext_inst_imports()) { + assert(inst.opcode() == spv::Op::OpExtInstImport && + "Expecting an import of an extension's instruction set."); + const std::string extension_name = inst.GetInOperand(0).AsString(); + if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && + extension_name != "NonSemantic.Shader.DebugInfo.100") { + return false; + } + } + return true; +} + +Pass::Status LocalSingleStoreElimPass::ProcessImpl() { + // Assumes relaxed logical addressing only (see instruction.h) + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) + return Status::SuccessWithoutChange; + + // Do not process if any disallowed extensions are enabled + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; + // Process all entry point functions + ProcessFunction pfn = [this](Function* fp) { + return LocalSingleStoreElim(fp); + }; + bool modified = context()->ProcessReachableCallTree(pfn); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +LocalSingleStoreElimPass::LocalSingleStoreElimPass() = default; + +Pass::Status LocalSingleStoreElimPass::Process() { + InitExtensionAllowList(); + return ProcessImpl(); +} + +void LocalSingleStoreElimPass::InitExtensionAllowList() { + extensions_allowlist_.insert({"SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_8bit_storage", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers", + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", + "SPV_EXT_shader_stencil_export", + "SPV_EXT_shader_viewport_index_layer", + "SPV_AMD_shader_image_load_store_lod", + "SPV_AMD_shader_fragment_mask", + "SPV_EXT_fragment_fully_covered", + "SPV_AMD_gpu_shader_half_float_fetch", + "SPV_GOOGLE_decorate_string", + "SPV_GOOGLE_hlsl_functionality1", + "SPV_NV_shader_subgroup_partitioned", + "SPV_EXT_descriptor_indexing", + "SPV_NV_fragment_shader_barycentric", + "SPV_NV_compute_shader_derivatives", + "SPV_NV_shader_image_footprint", + "SPV_NV_shading_rate", + "SPV_NV_mesh_shader", + "SPV_EXT_mesh_shader", + "SPV_NV_ray_tracing", + "SPV_KHR_ray_query", + "SPV_EXT_fragment_invocation_density", + "SPV_EXT_physical_storage_buffer", + "SPV_KHR_physical_storage_buffer", + "SPV_KHR_terminate_invocation", + "SPV_KHR_subgroup_uniform_control_flow", + "SPV_KHR_integer_dot_product", + "SPV_EXT_shader_image_int64", + "SPV_KHR_non_semantic_info", + "SPV_KHR_uniform_group_instructions", + "SPV_KHR_fragment_shader_barycentric", + "SPV_KHR_vulkan_memory_model", + "SPV_NV_bindless_texture", + "SPV_EXT_shader_atomic_float_add", + "SPV_EXT_fragment_shader_interlock", + "SPV_NV_compute_shader_derivatives"}); +} +bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) { + std::vector users; + FindUses(var_inst, &users); + + Instruction* store_inst = FindSingleStoreAndCheckUses(var_inst, users); + + if (store_inst == nullptr) { + return false; + } + + bool all_rewritten; + bool modified = RewriteLoads(store_inst, users, &all_rewritten); + + // If all uses are rewritten and the variable has a DebugDeclare and the + // variable is not an aggregate, add a DebugValue after the store and remove + // the DebugDeclare. + uint32_t var_id = var_inst->result_id(); + if (all_rewritten && + context()->get_debug_info_mgr()->IsVariableDebugDeclared(var_id)) { + const analysis::Type* var_type = + context()->get_type_mgr()->GetType(var_inst->type_id()); + const analysis::Type* store_type = var_type->AsPointer()->pointee_type(); + if (!(store_type->AsStruct() || store_type->AsArray())) { + modified |= RewriteDebugDeclares(store_inst, var_id); + } + } + + return modified; +} + +bool LocalSingleStoreElimPass::RewriteDebugDeclares(Instruction* store_inst, + uint32_t var_id) { + uint32_t value_id = store_inst->GetSingleWordInOperand(1); + bool modified = context()->get_debug_info_mgr()->AddDebugValueForVariable( + store_inst, var_id, value_id, store_inst); + modified |= context()->get_debug_info_mgr()->KillDebugDeclares(var_id); + return modified; +} + +Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses( + Instruction* var_inst, const std::vector& users) const { + // Make sure there is exactly 1 store. + Instruction* store_inst = nullptr; + + // If |var_inst| has an initializer, then that will count as a store. + if (var_inst->NumInOperands() > 1) { + store_inst = var_inst; + } + + for (Instruction* user : users) { + switch (user->opcode()) { + case spv::Op::OpStore: + // Since we are in the relaxed addressing mode, the use has to be the + // base address of the store, and not the value being store. Otherwise, + // we would have a pointer to a pointer to function scope memory, which + // is not allowed. + if (store_inst == nullptr) { + store_inst = user; + } else { + // More than 1 store. + return nullptr; + } + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + if (FeedsAStore(user)) { + // Has a partial store. Cannot propagate that. + return nullptr; + } + break; + case spv::Op::OpLoad: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpName: + case spv::Op::OpCopyObject: + break; + case spv::Op::OpExtInst: { + auto dbg_op = user->GetCommonDebugOpcode(); + if (dbg_op == CommonDebugInfoDebugDeclare || + dbg_op == CommonDebugInfoDebugValue) { + break; + } + return nullptr; + } + default: + if (!user->IsDecoration()) { + // Don't know if this instruction modifies the variable. + // Conservatively assume it is a store. + return nullptr; + } + break; + } + } + return store_inst; +} + +void LocalSingleStoreElimPass::FindUses( + const Instruction* var_inst, std::vector* users) const { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + def_use_mgr->ForEachUser(var_inst, [users, this](Instruction* user) { + users->push_back(user); + if (user->opcode() == spv::Op::OpCopyObject) { + FindUses(user, users); + } + }); +} + +bool LocalSingleStoreElimPass::FeedsAStore(Instruction* inst) const { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + return !def_use_mgr->WhileEachUser(inst, [this](Instruction* user) { + switch (user->opcode()) { + case spv::Op::OpStore: + return false; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpCopyObject: + return !FeedsAStore(user); + case spv::Op::OpLoad: + case spv::Op::OpImageTexelPointer: + case spv::Op::OpName: + return true; + default: + // Don't know if this instruction modifies the variable. + // Conservatively assume it is a store. + return user->IsDecoration(); + } + }); +} + +bool LocalSingleStoreElimPass::RewriteLoads( + Instruction* store_inst, const std::vector& uses, + bool* all_rewritten) { + BasicBlock* store_block = context()->get_instr_block(store_inst); + DominatorAnalysis* dominator_analysis = + context()->GetDominatorAnalysis(store_block->GetParent()); + + uint32_t stored_id; + if (store_inst->opcode() == spv::Op::OpStore) + stored_id = store_inst->GetSingleWordInOperand(kStoreValIdInIdx); + else + stored_id = store_inst->GetSingleWordInOperand(kVariableInitIdInIdx); + + *all_rewritten = true; + bool modified = false; + for (Instruction* use : uses) { + if (use->opcode() == spv::Op::OpStore) continue; + auto dbg_op = use->GetCommonDebugOpcode(); + if (dbg_op == CommonDebugInfoDebugDeclare || + dbg_op == CommonDebugInfoDebugValue) + continue; + if (use->opcode() == spv::Op::OpLoad && + dominator_analysis->Dominates(store_inst, use)) { + modified = true; + context()->KillNamesAndDecorates(use->result_id()); + context()->ReplaceAllUsesWith(use->result_id(), stored_id); + context()->KillInst(use); + } else { + *all_rewritten = false; + } + } + + return modified; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/local_single_store_elim_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/local_single_store_elim_pass.h new file mode 100644 index 000000000000..3aa0f02aa2fe --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/local_single_store_elim_pass.h @@ -0,0 +1,108 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOCAL_SINGLE_STORE_ELIM_PASS_H_ +#define SOURCE_OPT_LOCAL_SINGLE_STORE_ELIM_PASS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class LocalSingleStoreElimPass : public Pass { + using cbb_ptr = const BasicBlock*; + + public: + LocalSingleStoreElimPass(); + + const char* name() const override { return "eliminate-local-single-store"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Do "single-store" optimization of function variables defined only + // with a single non-access-chain store in |func|. Replace all their + // non-access-chain loads with the value that is stored and eliminate + // any resulting dead code. + bool LocalSingleStoreElim(Function* func); + + // Initialize extensions allowlist + void InitExtensionAllowList(); + + // Return true if all extensions in this module are allowed by this pass. + bool AllExtensionsSupported() const; + + Pass::Status ProcessImpl(); + + // If there is a single store to |var_inst|, and it covers the entire + // variable, then replace all of the loads of the entire variable that are + // dominated by the store by the value that was stored. Returns true if the + // module was changed. + bool ProcessVariable(Instruction* var_inst); + + // Collects all of the uses of |var_inst| into |uses|. This looks through + // OpObjectCopy's that copy the address of the variable, and collects those + // uses as well. + void FindUses(const Instruction* var_inst, + std::vector* uses) const; + + // Returns a store to |var_inst| if + // - it is a store to the entire variable, + // - and there are no other instructions that may modify |var_inst|. + Instruction* FindSingleStoreAndCheckUses( + Instruction* var_inst, const std::vector& users) const; + + // Returns true if the address that results from |inst| may be used as a base + // address in a store instruction or may be used to compute the base address + // of a store instruction. + bool FeedsAStore(Instruction* inst) const; + + // Replaces all of the loads in |uses| by the value stored in |store_inst|. + // The load instructions are then killed. |all_rewritten| is true iff all + // uses have been rewritten. + bool RewriteLoads(Instruction* store_inst, + const std::vector& uses, bool* all_rewritten); + + // Replaces DebugDeclares of |var_id| with DebugValues using the value + // assignment of |store_inst|. + bool RewriteDebugDeclares(Instruction* store_inst, uint32_t var_id); + + // Extensions supported by this pass. + std::unordered_set extensions_allowlist_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOCAL_SINGLE_STORE_ELIM_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/log.h b/thirdparty/glslang/External/spirv-tools/source/opt/log.h new file mode 100644 index 000000000000..4fb66fd45547 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/log.h @@ -0,0 +1,222 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOG_H_ +#define SOURCE_OPT_LOG_H_ + +#include +#include +#include +#include + +#include "spirv-tools/libspirv.hpp" + +// Asserts the given condition is true. Otherwise, sends a message to the +// consumer and exits the program with failure code. Accepts the following +// formats: +// +// SPIRV_ASSERT(, ); +// SPIRV_ASSERT(, , ); +// SPIRV_ASSERT(, , +// , ); +// +// In the third format, the number of cannot exceed (5 - +// 2). If more arguments are wanted, grow PP_ARG_N and PP_NARGS in the below. +#if !defined(NDEBUG) +#define SPIRV_ASSERT(consumer, ...) SPIRV_ASSERT_IMPL(consumer, __VA_ARGS__) +#else +// Adding a use to avoid errors in the release build related to unused +// consumers. +#define SPIRV_ASSERT(consumer, ...) (void)(consumer) +#endif + +// Logs a debug message to the consumer. Accepts the following formats: +// +// SPIRV_DEBUG(, ); +// SPIRV_DEBUG(, , ); +// +// In the second format, the number of cannot exceed (5 - +// 1). If more arguments are wanted, grow PP_ARG_N and PP_NARGS in the below. +#if !defined(NDEBUG) && defined(SPIRV_LOG_DEBUG) +#define SPIRV_DEBUG(consumer, ...) SPIRV_DEBUG_IMPL(consumer, __VA_ARGS__) +#else +// Adding a use to avoid errors in the release build related to unused +// consumers. +#define SPIRV_DEBUG(consumer, ...) (void)(consumer) +#endif + +// Helper macros for concatenating arguments. +#define SPIRV_CONCATENATE(a, b) SPIRV_CONCATENATE_(a, b) +#define SPIRV_CONCATENATE_(a, b) a##b + +// Helper macro to force expanding __VA_ARGS__ to satisfy MSVC compiler. +#define PP_EXPAND(x) x + +namespace spvtools { + +// Calls the given |consumer| by supplying the |message|. The |message| is from +// the given |source| and |location| and of the given severity |level|. +inline void Log(const MessageConsumer& consumer, spv_message_level_t level, + const char* source, const spv_position_t& position, + const char* message) { + if (consumer != nullptr) consumer(level, source, position, message); +} + +// Calls the given |consumer| by supplying the message composed according to the +// given |format|. The |message| is from the given |source| and |location| and +// of the given severity |level|. +template +void Logf(const MessageConsumer& consumer, spv_message_level_t level, + const char* source, const spv_position_t& position, + const char* format, Args&&... args) { +#if defined(_MSC_VER) && _MSC_VER < 1900 +// Sadly, snprintf() is not supported until Visual Studio 2015! +#define snprintf _snprintf +#endif + + enum { kInitBufferSize = 256 }; + + char message[kInitBufferSize]; + const int size = + snprintf(message, kInitBufferSize, format, std::forward(args)...); + + if (size >= 0 && size < kInitBufferSize) { + Log(consumer, level, source, position, message); + return; + } + + if (size >= 0) { + // The initial buffer is insufficient. Allocate a buffer of a larger size, + // and write to it instead. Force the size to be unsigned to avoid a + // warning in GCC 7.1. + std::vector longer_message(size + 1u); + snprintf(longer_message.data(), longer_message.size(), format, + std::forward(args)...); + Log(consumer, level, source, position, longer_message.data()); + return; + } + + Log(consumer, level, source, position, "cannot compose log message"); + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#undef snprintf +#endif +} + +// Calls the given |consumer| by supplying the given error |message|. The +// |message| is from the given |source| and |location|. +inline void Error(const MessageConsumer& consumer, const char* source, + const spv_position_t& position, const char* message) { + Log(consumer, SPV_MSG_ERROR, source, position, message); +} + +// Calls the given |consumer| by supplying the error message composed according +// to the given |format|. The |message| is from the given |source| and +// |location|. +template +inline void Errorf(const MessageConsumer& consumer, const char* source, + const spv_position_t& position, const char* format, + Args&&... args) { + Logf(consumer, SPV_MSG_ERROR, source, position, format, + std::forward(args)...); +} + +} // namespace spvtools + +#define SPIRV_ASSERT_IMPL(consumer, ...) \ + PP_EXPAND(SPIRV_CONCATENATE(SPIRV_ASSERT_, PP_NARGS(__VA_ARGS__))( \ + consumer, __VA_ARGS__)) + +#define SPIRV_DEBUG_IMPL(consumer, ...) \ + PP_EXPAND(SPIRV_CONCATENATE(SPIRV_DEBUG_, PP_NARGS(__VA_ARGS__))( \ + consumer, __VA_ARGS__)) + +#define SPIRV_ASSERT_1(consumer, condition) \ + do { \ + if (!(condition)) { \ + spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \ + {static_cast(__LINE__), 0, 0}, \ + "assertion failed: " #condition); \ + std::exit(EXIT_FAILURE); \ + } \ + } while (0) + +#define SPIRV_ASSERT_2(consumer, condition, message) \ + do { \ + if (!(condition)) { \ + spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \ + {static_cast(__LINE__), 0, 0}, \ + "assertion failed: " message); \ + std::exit(EXIT_FAILURE); \ + } \ + } while (0) + +#define SPIRV_ASSERT_more(consumer, condition, format, ...) \ + do { \ + if (!(condition)) { \ + spvtools::Logf(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \ + {static_cast(__LINE__), 0, 0}, \ + "assertion failed: " format, __VA_ARGS__); \ + std::exit(EXIT_FAILURE); \ + } \ + } while (0) + +#define SPIRV_ASSERT_3(consumer, condition, format, ...) \ + SPIRV_ASSERT_more(consumer, condition, format, __VA_ARGS__) + +#define SPIRV_ASSERT_4(consumer, condition, format, ...) \ + SPIRV_ASSERT_more(consumer, condition, format, __VA_ARGS__) + +#define SPIRV_ASSERT_5(consumer, condition, format, ...) \ + SPIRV_ASSERT_more(consumer, condition, format, __VA_ARGS__) + +#define SPIRV_DEBUG_1(consumer, message) \ + do { \ + spvtools::Log(consumer, SPV_MSG_DEBUG, __FILE__, \ + {static_cast(__LINE__), 0, 0}, message); \ + } while (0) + +#define SPIRV_DEBUG_more(consumer, format, ...) \ + do { \ + spvtools::Logf(consumer, SPV_MSG_DEBUG, __FILE__, \ + {static_cast(__LINE__), 0, 0}, format, \ + __VA_ARGS__); \ + } while (0) + +#define SPIRV_DEBUG_2(consumer, format, ...) \ + SPIRV_DEBUG_more(consumer, format, __VA_ARGS__) + +#define SPIRV_DEBUG_3(consumer, format, ...) \ + SPIRV_DEBUG_more(consumer, format, __VA_ARGS__) + +#define SPIRV_DEBUG_4(consumer, format, ...) \ + SPIRV_DEBUG_more(consumer, format, __VA_ARGS__) + +#define SPIRV_DEBUG_5(consumer, format, ...) \ + SPIRV_DEBUG_more(consumer, format, __VA_ARGS__) + +// Macros for counting the number of arguments passed in. +#define PP_NARGS(...) PP_EXPAND(PP_ARG_N(__VA_ARGS__, 5, 4, 3, 2, 1, 0)) +#define PP_ARG_N(_1, _2, _3, _4, _5, N, ...) N + +// Tests for making sure that PP_NARGS() behaves as expected. +static_assert(PP_NARGS(0) == 1, "PP_NARGS macro error"); +static_assert(PP_NARGS(0, 0) == 2, "PP_NARGS macro error"); +static_assert(PP_NARGS(0, 0, 0) == 3, "PP_NARGS macro error"); +static_assert(PP_NARGS(0, 0, 0, 0) == 4, "PP_NARGS macro error"); +static_assert(PP_NARGS(0, 0, 0, 0, 0) == 5, "PP_NARGS macro error"); +static_assert(PP_NARGS(1 + 1, 2, 3 / 3) == 3, "PP_NARGS macro error"); +static_assert(PP_NARGS((1, 1), 2, (3, 3)) == 3, "PP_NARGS macro error"); + +#endif // SOURCE_OPT_LOG_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence.cpp new file mode 100644 index 000000000000..e41c044afdc3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence.cpp @@ -0,0 +1,1674 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/loop_dependence.h" + +#include +#include +#include +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/scalar_analysis_nodes.h" + +namespace spvtools { +namespace opt { + +using SubscriptPair = std::pair; + +namespace { + +// Calculate the greatest common divisor of a & b using Stein's algorithm. +// https://en.wikipedia.org/wiki/Binary_GCD_algorithm +int64_t GreatestCommonDivisor(int64_t a, int64_t b) { + // Simple cases + if (a == b) { + return a; + } else if (a == 0) { + return b; + } else if (b == 0) { + return a; + } + + // Both even + if (a % 2 == 0 && b % 2 == 0) { + return 2 * GreatestCommonDivisor(a / 2, b / 2); + } + + // Even a, odd b + if (a % 2 == 0 && b % 2 == 1) { + return GreatestCommonDivisor(a / 2, b); + } + + // Odd a, even b + if (a % 2 == 1 && b % 2 == 0) { + return GreatestCommonDivisor(a, b / 2); + } + + // Both odd, reduce the larger argument + if (a > b) { + return GreatestCommonDivisor((a - b) / 2, b); + } else { + return GreatestCommonDivisor((b - a) / 2, a); + } +} + +// Check if node is affine, ie in the form: a0*i0 + a1*i1 + ... an*in + c +// and contains only the following types of nodes: SERecurrentNode, SEAddNode +// and SEConstantNode +bool IsInCorrectFormForGCDTest(SENode* node) { + bool children_ok = true; + + if (auto add_node = node->AsSEAddNode()) { + for (auto child : add_node->GetChildren()) { + children_ok &= IsInCorrectFormForGCDTest(child); + } + } + + bool this_ok = node->AsSERecurrentNode() || node->AsSEAddNode() || + node->AsSEConstantNode(); + + return children_ok && this_ok; +} + +// If |node| is an SERecurrentNode then returns |node| or if |node| is an +// SEAddNode returns a vector of SERecurrentNode that are its children. +std::vector GetAllTopLevelRecurrences(SENode* node) { + auto nodes = std::vector{}; + if (auto recurrent_node = node->AsSERecurrentNode()) { + nodes.push_back(recurrent_node); + } + + if (auto add_node = node->AsSEAddNode()) { + for (auto child : add_node->GetChildren()) { + auto child_nodes = GetAllTopLevelRecurrences(child); + nodes.insert(nodes.end(), child_nodes.begin(), child_nodes.end()); + } + } + + return nodes; +} + +// If |node| is an SEConstantNode then returns |node| or if |node| is an +// SEAddNode returns a vector of SEConstantNode that are its children. +std::vector GetAllTopLevelConstants(SENode* node) { + auto nodes = std::vector{}; + if (auto recurrent_node = node->AsSEConstantNode()) { + nodes.push_back(recurrent_node); + } + + if (auto add_node = node->AsSEAddNode()) { + for (auto child : add_node->GetChildren()) { + auto child_nodes = GetAllTopLevelConstants(child); + nodes.insert(nodes.end(), child_nodes.begin(), child_nodes.end()); + } + } + + return nodes; +} + +bool AreOffsetsAndCoefficientsConstant( + const std::vector& nodes) { + for (auto node : nodes) { + if (!node->GetOffset()->AsSEConstantNode() || + !node->GetOffset()->AsSEConstantNode()) { + return false; + } + } + return true; +} + +// Fold all SEConstantNode that appear in |recurrences| and |constants| into a +// single integer value. +int64_t CalculateConstantTerm(const std::vector& recurrences, + const std::vector& constants) { + int64_t constant_term = 0; + for (auto recurrence : recurrences) { + constant_term += + recurrence->GetOffset()->AsSEConstantNode()->FoldToSingleValue(); + } + + for (auto constant : constants) { + constant_term += constant->FoldToSingleValue(); + } + + return constant_term; +} + +int64_t CalculateGCDFromCoefficients( + const std::vector& recurrences, int64_t running_gcd) { + for (SERecurrentNode* recurrence : recurrences) { + auto coefficient = recurrence->GetCoefficient()->AsSEConstantNode(); + + running_gcd = GreatestCommonDivisor( + running_gcd, std::abs(coefficient->FoldToSingleValue())); + } + + return running_gcd; +} + +// Compare 2 fractions while first normalizing them, e.g. 2/4 and 4/8 will both +// be simplified to 1/2 and then determined to be equal. +bool NormalizeAndCompareFractions(int64_t numerator_0, int64_t denominator_0, + int64_t numerator_1, int64_t denominator_1) { + auto gcd_0 = + GreatestCommonDivisor(std::abs(numerator_0), std::abs(denominator_0)); + auto gcd_1 = + GreatestCommonDivisor(std::abs(numerator_1), std::abs(denominator_1)); + + auto normalized_numerator_0 = numerator_0 / gcd_0; + auto normalized_denominator_0 = denominator_0 / gcd_0; + auto normalized_numerator_1 = numerator_1 / gcd_1; + auto normalized_denominator_1 = denominator_1 / gcd_1; + + return normalized_numerator_0 == normalized_numerator_1 && + normalized_denominator_0 == normalized_denominator_1; +} + +} // namespace + +bool LoopDependenceAnalysis::GetDependence(const Instruction* source, + const Instruction* destination, + DistanceVector* distance_vector) { + // Start off by finding and marking all the loops in |loops_| that are + // irrelevant to the dependence analysis. + MarkUnsusedDistanceEntriesAsIrrelevant(source, destination, distance_vector); + + Instruction* source_access_chain = GetOperandDefinition(source, 0); + Instruction* destination_access_chain = GetOperandDefinition(destination, 0); + + auto num_access_chains = + (source_access_chain->opcode() == spv::Op::OpAccessChain) + + (destination_access_chain->opcode() == spv::Op::OpAccessChain); + + // If neither is an access chain, then they are load/store to a variable. + if (num_access_chains == 0) { + if (source_access_chain != destination_access_chain) { + // Not the same location, report independence + return true; + } else { + // Accessing the same variable + for (auto& entry : distance_vector->GetEntries()) { + entry = DistanceEntry(); + } + return false; + } + } + + // If only one is an access chain, it could be accessing a part of a struct + if (num_access_chains == 1) { + auto source_is_chain = + source_access_chain->opcode() == spv::Op::OpAccessChain; + auto access_chain = + source_is_chain ? source_access_chain : destination_access_chain; + auto variable = + source_is_chain ? destination_access_chain : source_access_chain; + + auto location_in_chain = GetOperandDefinition(access_chain, 0); + + if (variable != location_in_chain) { + // Not the same location, report independence + return true; + } else { + // Accessing the same variable + for (auto& entry : distance_vector->GetEntries()) { + entry = DistanceEntry(); + } + return false; + } + } + + // If the access chains aren't collecting from the same structure there is no + // dependence. + Instruction* source_array = GetOperandDefinition(source_access_chain, 0); + Instruction* destination_array = + GetOperandDefinition(destination_access_chain, 0); + + // Nested access chains are not supported yet, bail out. + if (source_array->opcode() == spv::Op::OpAccessChain || + destination_array->opcode() == spv::Op::OpAccessChain) { + for (auto& entry : distance_vector->GetEntries()) { + entry = DistanceEntry(); + } + return false; + } + + if (source_array != destination_array) { + PrintDebug("Proved independence through different arrays."); + return true; + } + + // To handle multiple subscripts we must get every operand in the access + // chains past the first. + std::vector source_subscripts = GetSubscripts(source); + std::vector destination_subscripts = GetSubscripts(destination); + + auto sets_of_subscripts = + PartitionSubscripts(source_subscripts, destination_subscripts); + + auto first_coupled = std::partition( + std::begin(sets_of_subscripts), std::end(sets_of_subscripts), + [](const std::set>& set) { + return set.size() == 1; + }); + + // Go through each subscript testing for independence. + // If any subscript results in independence, we prove independence between the + // load and store. + // If we can't prove independence we store what information we can gather in + // a DistanceVector. + for (auto it = std::begin(sets_of_subscripts); it < first_coupled; ++it) { + auto source_subscript = std::get<0>(*(*it).begin()); + auto destination_subscript = std::get<1>(*(*it).begin()); + + SENode* source_node = scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(source_subscript)); + SENode* destination_node = scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(destination_subscript)); + + // Check the loops are in a form we support. + auto subscript_pair = std::make_pair(source_node, destination_node); + + const Loop* loop = GetLoopForSubscriptPair(subscript_pair); + if (loop) { + if (!IsSupportedLoop(loop)) { + PrintDebug( + "GetDependence found an unsupported loop form. Assuming <=> for " + "loop."); + DistanceEntry* distance_entry = + GetDistanceEntryForSubscriptPair(subscript_pair, distance_vector); + if (distance_entry) { + distance_entry->direction = DistanceEntry::Directions::ALL; + } + continue; + } + } + + // If either node is simplified to a CanNotCompute we can't perform any + // analysis so must assume <=> dependence and return. + if (source_node->GetType() == SENode::CanNotCompute || + destination_node->GetType() == SENode::CanNotCompute) { + // Record the <=> dependence if we can get a DistanceEntry + PrintDebug( + "GetDependence found source_node || destination_node as " + "CanNotCompute. Abandoning evaluation for this subscript."); + DistanceEntry* distance_entry = + GetDistanceEntryForSubscriptPair(subscript_pair, distance_vector); + if (distance_entry) { + distance_entry->direction = DistanceEntry::Directions::ALL; + } + continue; + } + + // We have no induction variables so can apply a ZIV test. + if (IsZIV(subscript_pair)) { + PrintDebug("Found a ZIV subscript pair"); + if (ZIVTest(subscript_pair)) { + PrintDebug("Proved independence with ZIVTest."); + return true; + } + } + + // We have only one induction variable so should attempt an SIV test. + if (IsSIV(subscript_pair)) { + PrintDebug("Found a SIV subscript pair."); + if (SIVTest(subscript_pair, distance_vector)) { + PrintDebug("Proved independence with SIVTest."); + return true; + } + } + + // We have multiple induction variables so should attempt an MIV test. + if (IsMIV(subscript_pair)) { + PrintDebug("Found a MIV subscript pair."); + if (GCDMIVTest(subscript_pair)) { + PrintDebug("Proved independence with the GCD test."); + auto current_loops = CollectLoops(source_node, destination_node); + + for (auto current_loop : current_loops) { + auto distance_entry = + GetDistanceEntryForLoop(current_loop, distance_vector); + distance_entry->direction = DistanceEntry::Directions::NONE; + } + return true; + } + } + } + + for (auto it = first_coupled; it < std::end(sets_of_subscripts); ++it) { + auto coupled_instructions = *it; + std::vector coupled_subscripts{}; + + for (const auto& elem : coupled_instructions) { + auto source_subscript = std::get<0>(elem); + auto destination_subscript = std::get<1>(elem); + + SENode* source_node = scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(source_subscript)); + SENode* destination_node = scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(destination_subscript)); + + coupled_subscripts.push_back({source_node, destination_node}); + } + + auto supported = true; + + for (const auto& subscript : coupled_subscripts) { + auto loops = CollectLoops(std::get<0>(subscript), std::get<1>(subscript)); + + auto is_subscript_supported = + std::all_of(std::begin(loops), std::end(loops), + [this](const Loop* l) { return IsSupportedLoop(l); }); + + supported = supported && is_subscript_supported; + } + + if (DeltaTest(coupled_subscripts, distance_vector)) { + return true; + } + } + + // We were unable to prove independence so must gather all of the direction + // information we found. + PrintDebug( + "Couldn't prove independence.\n" + "All possible direction information has been collected in the input " + "DistanceVector."); + + return false; +} + +bool LoopDependenceAnalysis::ZIVTest( + const std::pair& subscript_pair) { + auto source = std::get<0>(subscript_pair); + auto destination = std::get<1>(subscript_pair); + + PrintDebug("Performing ZIVTest"); + // If source == destination, dependence with direction = and distance 0. + if (source == destination) { + PrintDebug("ZIVTest found EQ dependence."); + return false; + } else { + PrintDebug("ZIVTest found independence."); + // Otherwise we prove independence. + return true; + } +} + +bool LoopDependenceAnalysis::SIVTest( + const std::pair& subscript_pair, + DistanceVector* distance_vector) { + DistanceEntry* distance_entry = + GetDistanceEntryForSubscriptPair(subscript_pair, distance_vector); + if (!distance_entry) { + PrintDebug( + "SIVTest could not find a DistanceEntry for subscript_pair. Exiting"); + } + + SENode* source_node = std::get<0>(subscript_pair); + SENode* destination_node = std::get<1>(subscript_pair); + + int64_t source_induction_count = CountInductionVariables(source_node); + int64_t destination_induction_count = + CountInductionVariables(destination_node); + + // If the source node has no induction variables we can apply a + // WeakZeroSrcTest. + if (source_induction_count == 0) { + PrintDebug("Found source has no induction variable."); + if (WeakZeroSourceSIVTest( + source_node, destination_node->AsSERecurrentNode(), + destination_node->AsSERecurrentNode()->GetCoefficient(), + distance_entry)) { + PrintDebug("Proved independence with WeakZeroSourceSIVTest."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } + } + + // If the destination has no induction variables we can apply a + // WeakZeroDestTest. + if (destination_induction_count == 0) { + PrintDebug("Found destination has no induction variable."); + if (WeakZeroDestinationSIVTest( + source_node->AsSERecurrentNode(), destination_node, + source_node->AsSERecurrentNode()->GetCoefficient(), + distance_entry)) { + PrintDebug("Proved independence with WeakZeroDestinationSIVTest."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } + } + + // We now need to collect the SERecurrentExpr nodes from source and + // destination. We do not handle cases where source or destination have + // multiple SERecurrentExpr nodes. + std::vector source_recurrent_nodes = + source_node->CollectRecurrentNodes(); + std::vector destination_recurrent_nodes = + destination_node->CollectRecurrentNodes(); + + if (source_recurrent_nodes.size() == 1 && + destination_recurrent_nodes.size() == 1) { + PrintDebug("Found source and destination have 1 induction variable."); + SERecurrentNode* source_recurrent_expr = *source_recurrent_nodes.begin(); + SERecurrentNode* destination_recurrent_expr = + *destination_recurrent_nodes.begin(); + + // If the coefficients are identical we can apply a StrongSIVTest. + if (source_recurrent_expr->GetCoefficient() == + destination_recurrent_expr->GetCoefficient()) { + PrintDebug("Found source and destination share coefficient."); + if (StrongSIVTest(source_node, destination_node, + source_recurrent_expr->GetCoefficient(), + distance_entry)) { + PrintDebug("Proved independence with StrongSIVTest"); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } + } + + // If the coefficients are of equal magnitude and opposite sign we can + // apply a WeakCrossingSIVTest. + if (source_recurrent_expr->GetCoefficient() == + scalar_evolution_.CreateNegation( + destination_recurrent_expr->GetCoefficient())) { + PrintDebug("Found source coefficient = -destination coefficient."); + if (WeakCrossingSIVTest(source_node, destination_node, + source_recurrent_expr->GetCoefficient(), + distance_entry)) { + PrintDebug("Proved independence with WeakCrossingSIVTest"); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } + } + } + + return false; +} + +bool LoopDependenceAnalysis::StrongSIVTest(SENode* source, SENode* destination, + SENode* coefficient, + DistanceEntry* distance_entry) { + PrintDebug("Performing StrongSIVTest."); + // If both source and destination are SERecurrentNodes we can perform tests + // based on distance. + // If either source or destination contain value unknown nodes or if one or + // both are not SERecurrentNodes we must attempt a symbolic test. + std::vector source_value_unknown_nodes = + source->CollectValueUnknownNodes(); + std::vector destination_value_unknown_nodes = + destination->CollectValueUnknownNodes(); + if (source_value_unknown_nodes.size() > 0 || + destination_value_unknown_nodes.size() > 0) { + PrintDebug( + "StrongSIVTest found symbolics. Will attempt SymbolicStrongSIVTest."); + return SymbolicStrongSIVTest(source, destination, coefficient, + distance_entry); + } + + if (!source->AsSERecurrentNode() || !destination->AsSERecurrentNode()) { + PrintDebug( + "StrongSIVTest could not simplify source and destination to " + "SERecurrentNodes so will exit."); + distance_entry->direction = DistanceEntry::Directions::ALL; + return false; + } + + // Build an SENode for distance. + std::pair subscript_pair = + std::make_pair(source, destination); + const Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair); + SENode* source_constant_term = + GetConstantTerm(subscript_loop, source->AsSERecurrentNode()); + SENode* destination_constant_term = + GetConstantTerm(subscript_loop, destination->AsSERecurrentNode()); + if (!source_constant_term || !destination_constant_term) { + PrintDebug( + "StrongSIVTest could not collect the constant terms of either source " + "or destination so will exit."); + return false; + } + SENode* constant_term_delta = + scalar_evolution_.SimplifyExpression(scalar_evolution_.CreateSubtraction( + destination_constant_term, source_constant_term)); + + // Scalar evolution doesn't perform division, so we must fold to constants and + // do it manually. + // We must check the offset delta and coefficient are constants. + int64_t distance = 0; + SEConstantNode* delta_constant = constant_term_delta->AsSEConstantNode(); + SEConstantNode* coefficient_constant = coefficient->AsSEConstantNode(); + if (delta_constant && coefficient_constant) { + int64_t delta_value = delta_constant->FoldToSingleValue(); + int64_t coefficient_value = coefficient_constant->FoldToSingleValue(); + PrintDebug( + "StrongSIVTest found delta value and coefficient value as constants " + "with values:\n" + "\tdelta value: " + + ToString(delta_value) + + "\n\tcoefficient value: " + ToString(coefficient_value) + "\n"); + // Check if the distance is not integral to try to prove independence. + if (delta_value % coefficient_value != 0) { + PrintDebug( + "StrongSIVTest proved independence through distance not being an " + "integer."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } else { + distance = delta_value / coefficient_value; + PrintDebug("StrongSIV test found distance as " + ToString(distance)); + } + } else { + // If we can't fold delta and coefficient to single values we can't produce + // distance. + // As a result we can't perform the rest of the pass and must assume + // dependence in all directions. + PrintDebug("StrongSIVTest could not produce a distance. Must exit."); + distance_entry->distance = DistanceEntry::Directions::ALL; + return false; + } + + // Next we gather the upper and lower bounds as constants if possible. If + // distance > upper_bound - lower_bound we prove independence. + SENode* lower_bound = GetLowerBound(subscript_loop); + SENode* upper_bound = GetUpperBound(subscript_loop); + if (lower_bound && upper_bound) { + PrintDebug("StrongSIVTest found bounds."); + SENode* bounds = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction(upper_bound, lower_bound)); + + if (bounds->GetType() == SENode::SENodeType::Constant) { + int64_t bounds_value = bounds->AsSEConstantNode()->FoldToSingleValue(); + PrintDebug( + "StrongSIVTest found upper_bound - lower_bound as a constant with " + "value " + + ToString(bounds_value)); + + // If the absolute value of the distance is > upper bound - lower bound + // then we prove independence. + if (llabs(distance) > llabs(bounds_value)) { + PrintDebug( + "StrongSIVTest proved independence through distance escaping the " + "loop bounds."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DISTANCE; + distance_entry->direction = DistanceEntry::Directions::NONE; + distance_entry->distance = distance; + return true; + } + } + } else { + PrintDebug("StrongSIVTest was unable to gather lower and upper bounds."); + } + + // Otherwise we can get a direction as follows + // { < if distance > 0 + // direction = { = if distance == 0 + // { > if distance < 0 + PrintDebug( + "StrongSIVTest could not prove independence. Gathering direction " + "information."); + if (distance > 0) { + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DISTANCE; + distance_entry->direction = DistanceEntry::Directions::LT; + distance_entry->distance = distance; + return false; + } + if (distance == 0) { + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DISTANCE; + distance_entry->direction = DistanceEntry::Directions::EQ; + distance_entry->distance = 0; + return false; + } + if (distance < 0) { + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DISTANCE; + distance_entry->direction = DistanceEntry::Directions::GT; + distance_entry->distance = distance; + return false; + } + + // We were unable to prove independence or discern any additional information + // Must assume <=> direction. + PrintDebug( + "StrongSIVTest was unable to determine any dependence information."); + distance_entry->direction = DistanceEntry::Directions::ALL; + return false; +} + +bool LoopDependenceAnalysis::SymbolicStrongSIVTest( + SENode* source, SENode* destination, SENode* coefficient, + DistanceEntry* distance_entry) { + PrintDebug("Performing SymbolicStrongSIVTest."); + SENode* source_destination_delta = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction(source, destination)); + // By cancelling out the induction variables by subtracting the source and + // destination we can produce an expression of symbolics and constants. This + // expression can be compared to the loop bounds to find if the offset is + // outwith the bounds. + std::pair subscript_pair = + std::make_pair(source, destination); + const Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair); + if (IsProvablyOutsideOfLoopBounds(subscript_loop, source_destination_delta, + coefficient)) { + PrintDebug( + "SymbolicStrongSIVTest proved independence through loop bounds."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } + // We were unable to prove independence or discern any additional information. + // Must assume <=> direction. + PrintDebug( + "SymbolicStrongSIVTest was unable to determine any dependence " + "information."); + distance_entry->direction = DistanceEntry::Directions::ALL; + return false; +} + +bool LoopDependenceAnalysis::WeakZeroSourceSIVTest( + SENode* source, SERecurrentNode* destination, SENode* coefficient, + DistanceEntry* distance_entry) { + PrintDebug("Performing WeakZeroSourceSIVTest."); + std::pair subscript_pair = + std::make_pair(source, destination); + const Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair); + // Build an SENode for distance. + SENode* destination_constant_term = + GetConstantTerm(subscript_loop, destination); + SENode* delta = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction(source, destination_constant_term)); + + // Scalar evolution doesn't perform division, so we must fold to constants and + // do it manually. + int64_t distance = 0; + SEConstantNode* delta_constant = delta->AsSEConstantNode(); + SEConstantNode* coefficient_constant = coefficient->AsSEConstantNode(); + if (delta_constant && coefficient_constant) { + PrintDebug( + "WeakZeroSourceSIVTest folding delta and coefficient to constants."); + int64_t delta_value = delta_constant->FoldToSingleValue(); + int64_t coefficient_value = coefficient_constant->FoldToSingleValue(); + // Check if the distance is not integral. + if (delta_value % coefficient_value != 0) { + PrintDebug( + "WeakZeroSourceSIVTest proved independence through distance not " + "being an integer."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } else { + distance = delta_value / coefficient_value; + PrintDebug( + "WeakZeroSourceSIVTest calculated distance with the following " + "values\n" + "\tdelta value: " + + ToString(delta_value) + + "\n\tcoefficient value: " + ToString(coefficient_value) + + "\n\tdistance: " + ToString(distance) + "\n"); + } + } else { + PrintDebug( + "WeakZeroSourceSIVTest was unable to fold delta and coefficient to " + "constants."); + } + + // If we can prove the distance is outside the bounds we prove independence. + SEConstantNode* lower_bound = + GetLowerBound(subscript_loop)->AsSEConstantNode(); + SEConstantNode* upper_bound = + GetUpperBound(subscript_loop)->AsSEConstantNode(); + if (lower_bound && upper_bound) { + PrintDebug("WeakZeroSourceSIVTest found bounds as SEConstantNodes."); + int64_t lower_bound_value = lower_bound->FoldToSingleValue(); + int64_t upper_bound_value = upper_bound->FoldToSingleValue(); + if (!IsWithinBounds(llabs(distance), lower_bound_value, + upper_bound_value)) { + PrintDebug( + "WeakZeroSourceSIVTest proved independence through distance escaping " + "the loop bounds."); + PrintDebug( + "Bound values were as follow\n" + "\tlower bound value: " + + ToString(lower_bound_value) + + "\n\tupper bound value: " + ToString(upper_bound_value) + + "\n\tdistance value: " + ToString(distance) + "\n"); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DISTANCE; + distance_entry->direction = DistanceEntry::Directions::NONE; + distance_entry->distance = distance; + return true; + } + } else { + PrintDebug( + "WeakZeroSourceSIVTest was unable to find lower and upper bound as " + "SEConstantNodes."); + } + + // Now we want to see if we can detect to peel the first or last iterations. + + // We get the FirstTripValue as GetFirstTripInductionNode() + + // GetConstantTerm(destination) + SENode* first_trip_SENode = + scalar_evolution_.SimplifyExpression(scalar_evolution_.CreateAddNode( + GetFirstTripInductionNode(subscript_loop), + GetConstantTerm(subscript_loop, destination))); + + // If source == FirstTripValue, peel_first. + if (first_trip_SENode) { + PrintDebug("WeakZeroSourceSIVTest built first_trip_SENode."); + if (first_trip_SENode->AsSEConstantNode()) { + PrintDebug( + "WeakZeroSourceSIVTest has found first_trip_SENode as an " + "SEConstantNode with value: " + + ToString(first_trip_SENode->AsSEConstantNode()->FoldToSingleValue()) + + "\n"); + } + if (source == first_trip_SENode) { + // We have found that peeling the first iteration will break dependency. + PrintDebug( + "WeakZeroSourceSIVTest has found peeling first iteration will break " + "dependency"); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::PEEL; + distance_entry->peel_first = true; + return false; + } + } else { + PrintDebug("WeakZeroSourceSIVTest was unable to build first_trip_SENode"); + } + + // We get the LastTripValue as GetFinalTripInductionNode(coefficient) + + // GetConstantTerm(destination) + SENode* final_trip_SENode = + scalar_evolution_.SimplifyExpression(scalar_evolution_.CreateAddNode( + GetFinalTripInductionNode(subscript_loop, coefficient), + GetConstantTerm(subscript_loop, destination))); + + // If source == LastTripValue, peel_last. + if (final_trip_SENode) { + PrintDebug("WeakZeroSourceSIVTest built final_trip_SENode."); + if (first_trip_SENode->AsSEConstantNode()) { + PrintDebug( + "WeakZeroSourceSIVTest has found final_trip_SENode as an " + "SEConstantNode with value: " + + ToString(final_trip_SENode->AsSEConstantNode()->FoldToSingleValue()) + + "\n"); + } + if (source == final_trip_SENode) { + // We have found that peeling the last iteration will break dependency. + PrintDebug( + "WeakZeroSourceSIVTest has found peeling final iteration will break " + "dependency"); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::PEEL; + distance_entry->peel_last = true; + return false; + } + } else { + PrintDebug("WeakZeroSourceSIVTest was unable to build final_trip_SENode"); + } + + // We were unable to prove independence or discern any additional information. + // Must assume <=> direction. + PrintDebug( + "WeakZeroSourceSIVTest was unable to determine any dependence " + "information."); + distance_entry->direction = DistanceEntry::Directions::ALL; + return false; +} + +bool LoopDependenceAnalysis::WeakZeroDestinationSIVTest( + SERecurrentNode* source, SENode* destination, SENode* coefficient, + DistanceEntry* distance_entry) { + PrintDebug("Performing WeakZeroDestinationSIVTest."); + // Build an SENode for distance. + std::pair subscript_pair = + std::make_pair(source, destination); + const Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair); + SENode* source_constant_term = GetConstantTerm(subscript_loop, source); + SENode* delta = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction(destination, source_constant_term)); + + // Scalar evolution doesn't perform division, so we must fold to constants and + // do it manually. + int64_t distance = 0; + SEConstantNode* delta_constant = delta->AsSEConstantNode(); + SEConstantNode* coefficient_constant = coefficient->AsSEConstantNode(); + if (delta_constant && coefficient_constant) { + PrintDebug( + "WeakZeroDestinationSIVTest folding delta and coefficient to " + "constants."); + int64_t delta_value = delta_constant->FoldToSingleValue(); + int64_t coefficient_value = coefficient_constant->FoldToSingleValue(); + // Check if the distance is not integral. + if (delta_value % coefficient_value != 0) { + PrintDebug( + "WeakZeroDestinationSIVTest proved independence through distance not " + "being an integer."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } else { + distance = delta_value / coefficient_value; + PrintDebug( + "WeakZeroDestinationSIVTest calculated distance with the following " + "values\n" + "\tdelta value: " + + ToString(delta_value) + + "\n\tcoefficient value: " + ToString(coefficient_value) + + "\n\tdistance: " + ToString(distance) + "\n"); + } + } else { + PrintDebug( + "WeakZeroDestinationSIVTest was unable to fold delta and coefficient " + "to constants."); + } + + // If we can prove the distance is outside the bounds we prove independence. + SEConstantNode* lower_bound = + GetLowerBound(subscript_loop)->AsSEConstantNode(); + SEConstantNode* upper_bound = + GetUpperBound(subscript_loop)->AsSEConstantNode(); + if (lower_bound && upper_bound) { + PrintDebug("WeakZeroDestinationSIVTest found bounds as SEConstantNodes."); + int64_t lower_bound_value = lower_bound->FoldToSingleValue(); + int64_t upper_bound_value = upper_bound->FoldToSingleValue(); + if (!IsWithinBounds(llabs(distance), lower_bound_value, + upper_bound_value)) { + PrintDebug( + "WeakZeroDestinationSIVTest proved independence through distance " + "escaping the loop bounds."); + PrintDebug( + "Bound values were as follows\n" + "\tlower bound value: " + + ToString(lower_bound_value) + + "\n\tupper bound value: " + ToString(upper_bound_value) + + "\n\tdistance value: " + ToString(distance)); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DISTANCE; + distance_entry->direction = DistanceEntry::Directions::NONE; + distance_entry->distance = distance; + return true; + } + } else { + PrintDebug( + "WeakZeroDestinationSIVTest was unable to find lower and upper bound " + "as SEConstantNodes."); + } + + // Now we want to see if we can detect to peel the first or last iterations. + + // We get the FirstTripValue as GetFirstTripInductionNode() + + // GetConstantTerm(source) + SENode* first_trip_SENode = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateAddNode(GetFirstTripInductionNode(subscript_loop), + GetConstantTerm(subscript_loop, source))); + + // If destination == FirstTripValue, peel_first. + if (first_trip_SENode) { + PrintDebug("WeakZeroDestinationSIVTest built first_trip_SENode."); + if (first_trip_SENode->AsSEConstantNode()) { + PrintDebug( + "WeakZeroDestinationSIVTest has found first_trip_SENode as an " + "SEConstantNode with value: " + + ToString(first_trip_SENode->AsSEConstantNode()->FoldToSingleValue()) + + "\n"); + } + if (destination == first_trip_SENode) { + // We have found that peeling the first iteration will break dependency. + PrintDebug( + "WeakZeroDestinationSIVTest has found peeling first iteration will " + "break dependency"); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::PEEL; + distance_entry->peel_first = true; + return false; + } + } else { + PrintDebug( + "WeakZeroDestinationSIVTest was unable to build first_trip_SENode"); + } + + // We get the LastTripValue as GetFinalTripInductionNode(coefficient) + + // GetConstantTerm(source) + SENode* final_trip_SENode = + scalar_evolution_.SimplifyExpression(scalar_evolution_.CreateAddNode( + GetFinalTripInductionNode(subscript_loop, coefficient), + GetConstantTerm(subscript_loop, source))); + + // If destination == LastTripValue, peel_last. + if (final_trip_SENode) { + PrintDebug("WeakZeroDestinationSIVTest built final_trip_SENode."); + if (final_trip_SENode->AsSEConstantNode()) { + PrintDebug( + "WeakZeroDestinationSIVTest has found final_trip_SENode as an " + "SEConstantNode with value: " + + ToString(final_trip_SENode->AsSEConstantNode()->FoldToSingleValue()) + + "\n"); + } + if (destination == final_trip_SENode) { + // We have found that peeling the last iteration will break dependency. + PrintDebug( + "WeakZeroDestinationSIVTest has found peeling final iteration will " + "break dependency"); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::PEEL; + distance_entry->peel_last = true; + return false; + } + } else { + PrintDebug( + "WeakZeroDestinationSIVTest was unable to build final_trip_SENode"); + } + + // We were unable to prove independence or discern any additional information. + // Must assume <=> direction. + PrintDebug( + "WeakZeroDestinationSIVTest was unable to determine any dependence " + "information."); + distance_entry->direction = DistanceEntry::Directions::ALL; + return false; +} + +bool LoopDependenceAnalysis::WeakCrossingSIVTest( + SENode* source, SENode* destination, SENode* coefficient, + DistanceEntry* distance_entry) { + PrintDebug("Performing WeakCrossingSIVTest."); + // We currently can't handle symbolic WeakCrossingSIVTests. If either source + // or destination are not SERecurrentNodes we must exit. + if (!source->AsSERecurrentNode() || !destination->AsSERecurrentNode()) { + PrintDebug( + "WeakCrossingSIVTest found source or destination != SERecurrentNode. " + "Exiting"); + distance_entry->direction = DistanceEntry::Directions::ALL; + return false; + } + + // Build an SENode for distance. + SENode* offset_delta = + scalar_evolution_.SimplifyExpression(scalar_evolution_.CreateSubtraction( + destination->AsSERecurrentNode()->GetOffset(), + source->AsSERecurrentNode()->GetOffset())); + + // Scalar evolution doesn't perform division, so we must fold to constants and + // do it manually. + int64_t distance = 0; + SEConstantNode* delta_constant = offset_delta->AsSEConstantNode(); + SEConstantNode* coefficient_constant = coefficient->AsSEConstantNode(); + if (delta_constant && coefficient_constant) { + PrintDebug( + "WeakCrossingSIVTest folding offset_delta and coefficient to " + "constants."); + int64_t delta_value = delta_constant->FoldToSingleValue(); + int64_t coefficient_value = coefficient_constant->FoldToSingleValue(); + // Check if the distance is not integral or if it has a non-integral part + // equal to 1/2. + if (delta_value % (2 * coefficient_value) != 0 && + static_cast(delta_value % (2 * coefficient_value)) / + static_cast(2 * coefficient_value) != + 0.5) { + PrintDebug( + "WeakCrossingSIVTest proved independence through distance escaping " + "the loop bounds."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DIRECTION; + distance_entry->direction = DistanceEntry::Directions::NONE; + return true; + } else { + distance = delta_value / (2 * coefficient_value); + } + + if (distance == 0) { + PrintDebug("WeakCrossingSIVTest found EQ dependence."); + distance_entry->dependence_information = + DistanceEntry::DependenceInformation::DISTANCE; + distance_entry->direction = DistanceEntry::Directions::EQ; + distance_entry->distance = 0; + return false; + } + } else { + PrintDebug( + "WeakCrossingSIVTest was unable to fold offset_delta and coefficient " + "to constants."); + } + + // We were unable to prove independence or discern any additional information. + // Must assume <=> direction. + PrintDebug( + "WeakCrossingSIVTest was unable to determine any dependence " + "information."); + distance_entry->direction = DistanceEntry::Directions::ALL; + return false; +} + +// Perform the GCD test if both, the source and the destination nodes, are in +// the form a0*i0 + a1*i1 + ... an*in + c. +bool LoopDependenceAnalysis::GCDMIVTest( + const std::pair& subscript_pair) { + auto source = std::get<0>(subscript_pair); + auto destination = std::get<1>(subscript_pair); + + // Bail out if source/destination is in an unexpected form. + if (!IsInCorrectFormForGCDTest(source) || + !IsInCorrectFormForGCDTest(destination)) { + return false; + } + + auto source_recurrences = GetAllTopLevelRecurrences(source); + auto dest_recurrences = GetAllTopLevelRecurrences(destination); + + // Bail out if all offsets and coefficients aren't constant. + if (!AreOffsetsAndCoefficientsConstant(source_recurrences) || + !AreOffsetsAndCoefficientsConstant(dest_recurrences)) { + return false; + } + + // Calculate the GCD of all coefficients. + auto source_constants = GetAllTopLevelConstants(source); + int64_t source_constant = + CalculateConstantTerm(source_recurrences, source_constants); + + auto dest_constants = GetAllTopLevelConstants(destination); + int64_t destination_constant = + CalculateConstantTerm(dest_recurrences, dest_constants); + + int64_t delta = std::abs(source_constant - destination_constant); + + int64_t running_gcd = 0; + + running_gcd = CalculateGCDFromCoefficients(source_recurrences, running_gcd); + running_gcd = CalculateGCDFromCoefficients(dest_recurrences, running_gcd); + + return delta % running_gcd != 0; +} + +using PartitionedSubscripts = + std::vector>>; +PartitionedSubscripts LoopDependenceAnalysis::PartitionSubscripts( + const std::vector& source_subscripts, + const std::vector& destination_subscripts) { + PartitionedSubscripts partitions{}; + + auto num_subscripts = source_subscripts.size(); + + // Create initial partitions with one subscript pair per partition. + for (size_t i = 0; i < num_subscripts; ++i) { + partitions.push_back({{source_subscripts[i], destination_subscripts[i]}}); + } + + // Iterate over the loops to create all partitions + for (auto loop : loops_) { + int64_t k = -1; + + for (size_t j = 0; j < partitions.size(); ++j) { + auto& current_partition = partitions[j]; + + // Does |loop| appear in |current_partition| + auto it = std::find_if( + current_partition.begin(), current_partition.end(), + [loop, + this](const std::pair& elem) -> bool { + auto source_recurrences = + scalar_evolution_.AnalyzeInstruction(std::get<0>(elem)) + ->CollectRecurrentNodes(); + auto destination_recurrences = + scalar_evolution_.AnalyzeInstruction(std::get<1>(elem)) + ->CollectRecurrentNodes(); + + source_recurrences.insert(source_recurrences.end(), + destination_recurrences.begin(), + destination_recurrences.end()); + + auto loops_in_pair = CollectLoops(source_recurrences); + auto end_it = loops_in_pair.end(); + + return std::find(loops_in_pair.begin(), end_it, loop) != end_it; + }); + + auto has_loop = it != current_partition.end(); + + if (has_loop) { + if (k == -1) { + k = j; + } else { + // Add |partitions[j]| to |partitions[k]| and discard |partitions[j]| + partitions[static_cast(k)].insert(current_partition.begin(), + current_partition.end()); + current_partition.clear(); + } + } + } + } + + // Remove empty (discarded) partitions + partitions.erase( + std::remove_if( + partitions.begin(), partitions.end(), + [](const std::set>& partition) { + return partition.empty(); + }), + partitions.end()); + + return partitions; +} + +Constraint* LoopDependenceAnalysis::IntersectConstraints( + Constraint* constraint_0, Constraint* constraint_1, + const SENode* lower_bound, const SENode* upper_bound) { + if (constraint_0->AsDependenceNone()) { + return constraint_1; + } else if (constraint_1->AsDependenceNone()) { + return constraint_0; + } + + // Both constraints are distances. Either the same distance or independent. + if (constraint_0->AsDependenceDistance() && + constraint_1->AsDependenceDistance()) { + auto dist_0 = constraint_0->AsDependenceDistance(); + auto dist_1 = constraint_1->AsDependenceDistance(); + + if (*dist_0->GetDistance() == *dist_1->GetDistance()) { + return constraint_0; + } else { + return make_constraint(); + } + } + + // Both constraints are points. Either the same point or independent. + if (constraint_0->AsDependencePoint() && constraint_1->AsDependencePoint()) { + auto point_0 = constraint_0->AsDependencePoint(); + auto point_1 = constraint_1->AsDependencePoint(); + + if (*point_0->GetSource() == *point_1->GetSource() && + *point_0->GetDestination() == *point_1->GetDestination()) { + return constraint_0; + } else { + return make_constraint(); + } + } + + // Both constraints are lines/distances. + if ((constraint_0->AsDependenceDistance() || + constraint_0->AsDependenceLine()) && + (constraint_1->AsDependenceDistance() || + constraint_1->AsDependenceLine())) { + auto is_distance_0 = constraint_0->AsDependenceDistance() != nullptr; + auto is_distance_1 = constraint_1->AsDependenceDistance() != nullptr; + + auto a0 = is_distance_0 ? scalar_evolution_.CreateConstant(1) + : constraint_0->AsDependenceLine()->GetA(); + auto b0 = is_distance_0 ? scalar_evolution_.CreateConstant(-1) + : constraint_0->AsDependenceLine()->GetB(); + auto c0 = + is_distance_0 + ? scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateNegation( + constraint_0->AsDependenceDistance()->GetDistance())) + : constraint_0->AsDependenceLine()->GetC(); + + auto a1 = is_distance_1 ? scalar_evolution_.CreateConstant(1) + : constraint_1->AsDependenceLine()->GetA(); + auto b1 = is_distance_1 ? scalar_evolution_.CreateConstant(-1) + : constraint_1->AsDependenceLine()->GetB(); + auto c1 = + is_distance_1 + ? scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateNegation( + constraint_1->AsDependenceDistance()->GetDistance())) + : constraint_1->AsDependenceLine()->GetC(); + + if (a0->AsSEConstantNode() && b0->AsSEConstantNode() && + c0->AsSEConstantNode() && a1->AsSEConstantNode() && + b1->AsSEConstantNode() && c1->AsSEConstantNode()) { + auto constant_a0 = a0->AsSEConstantNode()->FoldToSingleValue(); + auto constant_b0 = b0->AsSEConstantNode()->FoldToSingleValue(); + auto constant_c0 = c0->AsSEConstantNode()->FoldToSingleValue(); + + auto constant_a1 = a1->AsSEConstantNode()->FoldToSingleValue(); + auto constant_b1 = b1->AsSEConstantNode()->FoldToSingleValue(); + auto constant_c1 = c1->AsSEConstantNode()->FoldToSingleValue(); + + // a & b can't both be zero, otherwise it wouldn't be line. + if (NormalizeAndCompareFractions(constant_a0, constant_b0, constant_a1, + constant_b1)) { + // Slopes are equal, either parallel lines or the same line. + + if (constant_b0 == 0 && constant_b1 == 0) { + if (NormalizeAndCompareFractions(constant_c0, constant_a0, + constant_c1, constant_a1)) { + return constraint_0; + } + + return make_constraint(); + } else if (NormalizeAndCompareFractions(constant_c0, constant_b0, + constant_c1, constant_b1)) { + // Same line. + return constraint_0; + } else { + // Parallel lines can't intersect, report independence. + return make_constraint(); + } + + } else { + // Lines are not parallel, therefore, they must intersect. + + // Calculate intersection. + if (upper_bound->AsSEConstantNode() && + lower_bound->AsSEConstantNode()) { + auto constant_lower_bound = + lower_bound->AsSEConstantNode()->FoldToSingleValue(); + auto constant_upper_bound = + upper_bound->AsSEConstantNode()->FoldToSingleValue(); + + auto up = constant_b1 * constant_c0 - constant_b0 * constant_c1; + // Both b or both a can't be 0, so down is never 0 + // otherwise would have entered the parallel line section. + auto down = constant_b1 * constant_a0 - constant_b0 * constant_a1; + + auto x_coord = up / down; + + int64_t y_coord = 0; + int64_t arg1 = 0; + int64_t const_b_to_use = 0; + + if (constant_b1 != 0) { + arg1 = constant_c1 - constant_a1 * x_coord; + y_coord = arg1 / constant_b1; + const_b_to_use = constant_b1; + } else if (constant_b0 != 0) { + arg1 = constant_c0 - constant_a0 * x_coord; + y_coord = arg1 / constant_b0; + const_b_to_use = constant_b0; + } + + if (up % down == 0 && + arg1 % const_b_to_use == 0 && // Coordinates are integers. + constant_lower_bound <= + x_coord && // x_coord is within loop bounds. + x_coord <= constant_upper_bound && + constant_lower_bound <= + y_coord && // y_coord is within loop bounds. + y_coord <= constant_upper_bound) { + // Lines intersect at integer coordinates. + return make_constraint( + scalar_evolution_.CreateConstant(x_coord), + scalar_evolution_.CreateConstant(y_coord), + constraint_0->GetLoop()); + + } else { + return make_constraint(); + } + + } else { + // Not constants, bail out. + return make_constraint(); + } + } + + } else { + // Not constants, bail out. + return make_constraint(); + } + } + + // One constraint is a line/distance and the other is a point. + if ((constraint_0->AsDependencePoint() && + (constraint_1->AsDependenceLine() || + constraint_1->AsDependenceDistance())) || + (constraint_1->AsDependencePoint() && + (constraint_0->AsDependenceLine() || + constraint_0->AsDependenceDistance()))) { + auto point_0 = constraint_0->AsDependencePoint() != nullptr; + + auto point = point_0 ? constraint_0->AsDependencePoint() + : constraint_1->AsDependencePoint(); + + auto line_or_distance = point_0 ? constraint_1 : constraint_0; + + auto is_distance = line_or_distance->AsDependenceDistance() != nullptr; + + auto a = is_distance ? scalar_evolution_.CreateConstant(1) + : line_or_distance->AsDependenceLine()->GetA(); + auto b = is_distance ? scalar_evolution_.CreateConstant(-1) + : line_or_distance->AsDependenceLine()->GetB(); + auto c = + is_distance + ? scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateNegation( + line_or_distance->AsDependenceDistance()->GetDistance())) + : line_or_distance->AsDependenceLine()->GetC(); + + auto x = point->GetSource(); + auto y = point->GetDestination(); + + if (a->AsSEConstantNode() && b->AsSEConstantNode() && + c->AsSEConstantNode() && x->AsSEConstantNode() && + y->AsSEConstantNode()) { + auto constant_a = a->AsSEConstantNode()->FoldToSingleValue(); + auto constant_b = b->AsSEConstantNode()->FoldToSingleValue(); + auto constant_c = c->AsSEConstantNode()->FoldToSingleValue(); + + auto constant_x = x->AsSEConstantNode()->FoldToSingleValue(); + auto constant_y = y->AsSEConstantNode()->FoldToSingleValue(); + + auto left_hand_side = constant_a * constant_x + constant_b * constant_y; + + if (left_hand_side == constant_c) { + // Point is on line, return point + return point_0 ? constraint_0 : constraint_1; + } else { + // Point not on line, report independence (empty constraint). + return make_constraint(); + } + + } else { + // Not constants, bail out. + return make_constraint(); + } + } + + return nullptr; +} + +// Propagate constraints function as described in section 5 of Practical +// Dependence Testing, Goff, Kennedy, Tseng, 1991. +SubscriptPair LoopDependenceAnalysis::PropagateConstraints( + const SubscriptPair& subscript_pair, + const std::vector& constraints) { + SENode* new_first = subscript_pair.first; + SENode* new_second = subscript_pair.second; + + for (auto& constraint : constraints) { + // In the paper this is a[k]. We're extracting the coefficient ('a') of a + // recurrent expression with respect to the loop 'k'. + SENode* coefficient_of_recurrent = + scalar_evolution_.GetCoefficientFromRecurrentTerm( + new_first, constraint->GetLoop()); + + // In the paper this is a'[k]. + SENode* coefficient_of_recurrent_prime = + scalar_evolution_.GetCoefficientFromRecurrentTerm( + new_second, constraint->GetLoop()); + + if (constraint->GetType() == Constraint::Distance) { + DependenceDistance* as_distance = constraint->AsDependenceDistance(); + + // In the paper this is a[k]*d + SENode* rhs = scalar_evolution_.CreateMultiplyNode( + coefficient_of_recurrent, as_distance->GetDistance()); + + // In the paper this is a[k] <- 0 + SENode* zeroed_coefficient = + scalar_evolution_.BuildGraphWithoutRecurrentTerm( + new_first, constraint->GetLoop()); + + // In the paper this is e <- e - a[k]*d. + new_first = scalar_evolution_.CreateSubtraction(zeroed_coefficient, rhs); + new_first = scalar_evolution_.SimplifyExpression(new_first); + + // In the paper this is a'[k] - a[k]. + SENode* new_child = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction(coefficient_of_recurrent_prime, + coefficient_of_recurrent)); + + // In the paper this is a'[k]'i[k]. + SERecurrentNode* prime_recurrent = + scalar_evolution_.GetRecurrentTerm(new_second, constraint->GetLoop()); + + if (!prime_recurrent) continue; + + // As we hash the nodes we need to create a new node when we update a + // child. + SENode* new_recurrent = scalar_evolution_.CreateRecurrentExpression( + constraint->GetLoop(), prime_recurrent->GetOffset(), new_child); + // In the paper this is a'[k] <- a'[k] - a[k]. + new_second = scalar_evolution_.UpdateChildNode( + new_second, prime_recurrent, new_recurrent); + } + } + + new_second = scalar_evolution_.SimplifyExpression(new_second); + return std::make_pair(new_first, new_second); +} + +bool LoopDependenceAnalysis::DeltaTest( + const std::vector& coupled_subscripts, + DistanceVector* dv_entry) { + std::vector constraints(loops_.size()); + + std::vector loop_appeared(loops_.size()); + + std::generate(std::begin(constraints), std::end(constraints), + [this]() { return make_constraint(); }); + + // Separate SIV and MIV subscripts + std::vector siv_subscripts{}; + std::vector miv_subscripts{}; + + for (const auto& subscript_pair : coupled_subscripts) { + if (IsSIV(subscript_pair)) { + siv_subscripts.push_back(subscript_pair); + } else { + miv_subscripts.push_back(subscript_pair); + } + } + + // Delta Test + while (!siv_subscripts.empty()) { + std::vector results(siv_subscripts.size()); + + std::vector current_distances( + siv_subscripts.size(), DistanceVector(loops_.size())); + + // Apply SIV test to all SIV subscripts, report independence if any of them + // is independent + std::transform( + std::begin(siv_subscripts), std::end(siv_subscripts), + std::begin(current_distances), std::begin(results), + [this](SubscriptPair& p, DistanceVector& d) { return SIVTest(p, &d); }); + + if (std::accumulate(std::begin(results), std::end(results), false, + std::logical_or{})) { + return true; + } + + // Derive new constraint vector. + std::vector> all_new_constrants{}; + + for (size_t i = 0; i < siv_subscripts.size(); ++i) { + auto loop = GetLoopForSubscriptPair(siv_subscripts[i]); + + auto loop_id = + std::distance(std::begin(loops_), + std::find(std::begin(loops_), std::end(loops_), loop)); + + loop_appeared[loop_id] = true; + auto distance_entry = current_distances[i].GetEntries()[loop_id]; + + if (distance_entry.dependence_information == + DistanceEntry::DependenceInformation::DISTANCE) { + // Construct a DependenceDistance. + auto node = scalar_evolution_.CreateConstant(distance_entry.distance); + + all_new_constrants.push_back( + {make_constraint(node, loop), loop_id}); + } else { + // Construct a DependenceLine. + const auto& subscript_pair = siv_subscripts[i]; + SENode* source_node = std::get<0>(subscript_pair); + SENode* destination_node = std::get<1>(subscript_pair); + + int64_t source_induction_count = CountInductionVariables(source_node); + int64_t destination_induction_count = + CountInductionVariables(destination_node); + + SENode* a = nullptr; + SENode* b = nullptr; + SENode* c = nullptr; + + if (destination_induction_count != 0) { + a = destination_node->AsSERecurrentNode()->GetCoefficient(); + c = scalar_evolution_.CreateNegation( + destination_node->AsSERecurrentNode()->GetOffset()); + } else { + a = scalar_evolution_.CreateConstant(0); + c = scalar_evolution_.CreateNegation(destination_node); + } + + if (source_induction_count != 0) { + b = scalar_evolution_.CreateNegation( + source_node->AsSERecurrentNode()->GetCoefficient()); + c = scalar_evolution_.CreateAddNode( + c, source_node->AsSERecurrentNode()->GetOffset()); + } else { + b = scalar_evolution_.CreateConstant(0); + c = scalar_evolution_.CreateAddNode(c, source_node); + } + + a = scalar_evolution_.SimplifyExpression(a); + b = scalar_evolution_.SimplifyExpression(b); + c = scalar_evolution_.SimplifyExpression(c); + + all_new_constrants.push_back( + {make_constraint(a, b, c, loop), loop_id}); + } + } + + // Calculate the intersection between the new and existing constraints. + std::vector intersection = constraints; + for (const auto& constraint_to_intersect : all_new_constrants) { + auto loop_id = std::get<1>(constraint_to_intersect); + auto loop = loops_[loop_id]; + intersection[loop_id] = IntersectConstraints( + intersection[loop_id], std::get<0>(constraint_to_intersect), + GetLowerBound(loop), GetUpperBound(loop)); + } + + // Report independence if an empty constraint (DependenceEmpty) is found. + auto first_empty = + std::find_if(std::begin(intersection), std::end(intersection), + [](Constraint* constraint) { + return constraint->AsDependenceEmpty() != nullptr; + }); + if (first_empty != std::end(intersection)) { + return true; + } + std::vector new_siv_subscripts{}; + std::vector new_miv_subscripts{}; + + auto equal = + std::equal(std::begin(constraints), std::end(constraints), + std::begin(intersection), + [](Constraint* a, Constraint* b) { return *a == *b; }); + + // If any constraints have changed, propagate them into the rest of the + // subscripts possibly creating new ZIV/SIV subscripts. + if (!equal) { + std::vector new_subscripts(miv_subscripts.size()); + + // Propagate constraints into MIV subscripts + std::transform(std::begin(miv_subscripts), std::end(miv_subscripts), + std::begin(new_subscripts), + [this, &intersection](SubscriptPair& subscript_pair) { + return PropagateConstraints(subscript_pair, + intersection); + }); + + // If a ZIV subscript is returned, apply test, otherwise, update untested + // subscripts. + for (auto& subscript : new_subscripts) { + if (IsZIV(subscript) && ZIVTest(subscript)) { + return true; + } else if (IsSIV(subscript)) { + new_siv_subscripts.push_back(subscript); + } else { + new_miv_subscripts.push_back(subscript); + } + } + } + + // Set new constraints and subscripts to test. + std::swap(siv_subscripts, new_siv_subscripts); + std::swap(miv_subscripts, new_miv_subscripts); + std::swap(constraints, intersection); + } + + // Create the dependence vector from the constraints. + for (size_t i = 0; i < loops_.size(); ++i) { + // Don't touch entries for loops that weren't tested. + if (loop_appeared[i]) { + auto current_constraint = constraints[i]; + auto& current_distance_entry = (*dv_entry).GetEntries()[i]; + + if (auto dependence_distance = + current_constraint->AsDependenceDistance()) { + if (auto constant_node = + dependence_distance->GetDistance()->AsSEConstantNode()) { + current_distance_entry.dependence_information = + DistanceEntry::DependenceInformation::DISTANCE; + + current_distance_entry.distance = constant_node->FoldToSingleValue(); + if (current_distance_entry.distance == 0) { + current_distance_entry.direction = DistanceEntry::Directions::EQ; + } else if (current_distance_entry.distance < 0) { + current_distance_entry.direction = DistanceEntry::Directions::GT; + } else { + current_distance_entry.direction = DistanceEntry::Directions::LT; + } + } + } else if (auto dependence_point = + current_constraint->AsDependencePoint()) { + auto source = dependence_point->GetSource(); + auto destination = dependence_point->GetDestination(); + + if (source->AsSEConstantNode() && destination->AsSEConstantNode()) { + current_distance_entry = DistanceEntry( + source->AsSEConstantNode()->FoldToSingleValue(), + destination->AsSEConstantNode()->FoldToSingleValue()); + } + } + } + } + + // Test any remaining MIV subscripts and report independence if found. + std::vector results(miv_subscripts.size()); + + std::transform(std::begin(miv_subscripts), std::end(miv_subscripts), + std::begin(results), + [this](const SubscriptPair& p) { return GCDMIVTest(p); }); + + return std::accumulate(std::begin(results), std::end(results), false, + std::logical_or{}); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence.h new file mode 100644 index 000000000000..03a9075fe012 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence.h @@ -0,0 +1,560 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_DEPENDENCE_H_ +#define SOURCE_OPT_LOOP_DEPENDENCE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" +#include "source/opt/loop_descriptor.h" +#include "source/opt/scalar_analysis.h" + +namespace spvtools { +namespace opt { + +// Stores information about dependence between a load and a store wrt a single +// loop in a loop nest. +// DependenceInformation +// * UNKNOWN if no dependence information can be gathered or is gathered +// for it. +// * DIRECTION if a dependence direction could be found, but not a +// distance. +// * DISTANCE if a dependence distance could be found. +// * PEEL if peeling either the first or last iteration will break +// dependence between the given load and store. +// * IRRELEVANT if it has no effect on the dependence between the given +// load and store. +// +// If peel_first == true, the analysis has found that peeling the first +// iteration of this loop will break dependence. +// +// If peel_last == true, the analysis has found that peeling the last iteration +// of this loop will break dependence. +class DistanceEntry { + public: + enum DependenceInformation { + UNKNOWN = 0, + DIRECTION = 1, + DISTANCE = 2, + PEEL = 3, + IRRELEVANT = 4, + POINT = 5 + }; + enum Directions { + NONE = 0, + LT = 1, + EQ = 2, + LE = 3, + GT = 4, + NE = 5, + GE = 6, + ALL = 7 + }; + DependenceInformation dependence_information; + Directions direction; + int64_t distance; + bool peel_first; + bool peel_last; + int64_t point_x; + int64_t point_y; + + DistanceEntry() + : dependence_information(DependenceInformation::UNKNOWN), + direction(Directions::ALL), + distance(0), + peel_first(false), + peel_last(false), + point_x(0), + point_y(0) {} + + explicit DistanceEntry(Directions direction_) + : dependence_information(DependenceInformation::DIRECTION), + direction(direction_), + distance(0), + peel_first(false), + peel_last(false), + point_x(0), + point_y(0) {} + + DistanceEntry(Directions direction_, int64_t distance_) + : dependence_information(DependenceInformation::DISTANCE), + direction(direction_), + distance(distance_), + peel_first(false), + peel_last(false), + point_x(0), + point_y(0) {} + + DistanceEntry(int64_t x, int64_t y) + : dependence_information(DependenceInformation::POINT), + direction(Directions::ALL), + distance(0), + peel_first(false), + peel_last(false), + point_x(x), + point_y(y) {} + + bool operator==(const DistanceEntry& rhs) const { + return direction == rhs.direction && peel_first == rhs.peel_first && + peel_last == rhs.peel_last && distance == rhs.distance && + point_x == rhs.point_x && point_y == rhs.point_y; + } + + bool operator!=(const DistanceEntry& rhs) const { return !(*this == rhs); } +}; + +// Stores a vector of DistanceEntrys, one per loop in the analysis. +// A DistanceVector holds all of the information gathered in a dependence +// analysis wrt the loops stored in the LoopDependenceAnalysis performing the +// analysis. +class DistanceVector { + public: + explicit DistanceVector(size_t size) : entries(size, DistanceEntry{}) {} + + explicit DistanceVector(std::vector entries_) + : entries(entries_) {} + + DistanceEntry& GetEntry(size_t index) { return entries[index]; } + const DistanceEntry& GetEntry(size_t index) const { return entries[index]; } + + std::vector& GetEntries() { return entries; } + const std::vector& GetEntries() const { return entries; } + + bool operator==(const DistanceVector& rhs) const { + if (entries.size() != rhs.entries.size()) { + return false; + } + for (size_t i = 0; i < entries.size(); ++i) { + if (entries[i] != rhs.entries[i]) { + return false; + } + } + return true; + } + bool operator!=(const DistanceVector& rhs) const { return !(*this == rhs); } + + private: + std::vector entries; +}; + +class DependenceLine; +class DependenceDistance; +class DependencePoint; +class DependenceNone; +class DependenceEmpty; + +class Constraint { + public: + explicit Constraint(const Loop* loop) : loop_(loop) {} + enum ConstraintType { Line, Distance, Point, None, Empty }; + + virtual ConstraintType GetType() const = 0; + + virtual ~Constraint() {} + + // Get the loop this constraint belongs to. + const Loop* GetLoop() const { return loop_; } + + bool operator==(const Constraint& other) const; + + bool operator!=(const Constraint& other) const; + +// clang-format off +#define DeclareCastMethod(target) \ + virtual target* As##target() { return nullptr; } \ + virtual const target* As##target() const { return nullptr; } + DeclareCastMethod(DependenceLine) + DeclareCastMethod(DependenceDistance) + DeclareCastMethod(DependencePoint) + DeclareCastMethod(DependenceNone) + DeclareCastMethod(DependenceEmpty) +#undef DeclareCastMethod + + protected: + const Loop* loop_; +}; +// clang-format on + +class DependenceLine : public Constraint { + public: + DependenceLine(SENode* a, SENode* b, SENode* c, const Loop* loop) + : Constraint(loop), a_(a), b_(b), c_(c) {} + + ConstraintType GetType() const final { return Line; } + + DependenceLine* AsDependenceLine() final { return this; } + const DependenceLine* AsDependenceLine() const final { return this; } + + SENode* GetA() const { return a_; } + SENode* GetB() const { return b_; } + SENode* GetC() const { return c_; } + + private: + SENode* a_; + SENode* b_; + SENode* c_; +}; + +class DependenceDistance : public Constraint { + public: + DependenceDistance(SENode* distance, const Loop* loop) + : Constraint(loop), distance_(distance) {} + + ConstraintType GetType() const final { return Distance; } + + DependenceDistance* AsDependenceDistance() final { return this; } + const DependenceDistance* AsDependenceDistance() const final { return this; } + + SENode* GetDistance() const { return distance_; } + + private: + SENode* distance_; +}; + +class DependencePoint : public Constraint { + public: + DependencePoint(SENode* source, SENode* destination, const Loop* loop) + : Constraint(loop), source_(source), destination_(destination) {} + + ConstraintType GetType() const final { return Point; } + + DependencePoint* AsDependencePoint() final { return this; } + const DependencePoint* AsDependencePoint() const final { return this; } + + SENode* GetSource() const { return source_; } + SENode* GetDestination() const { return destination_; } + + private: + SENode* source_; + SENode* destination_; +}; + +class DependenceNone : public Constraint { + public: + DependenceNone() : Constraint(nullptr) {} + ConstraintType GetType() const final { return None; } + + DependenceNone* AsDependenceNone() final { return this; } + const DependenceNone* AsDependenceNone() const final { return this; } +}; + +class DependenceEmpty : public Constraint { + public: + DependenceEmpty() : Constraint(nullptr) {} + ConstraintType GetType() const final { return Empty; } + + DependenceEmpty* AsDependenceEmpty() final { return this; } + const DependenceEmpty* AsDependenceEmpty() const final { return this; } +}; + +// Provides dependence information between a store instruction and a load +// instruction inside the same loop in a loop nest. +// +// The analysis can only check dependence between stores and loads with regard +// to the loop nest it is created with. +// +// The analysis can output debugging information to a stream. The output +// describes the control flow of the analysis and what information it can deduce +// at each step. +// SetDebugStream and ClearDebugStream are provided for this functionality. +// +// The dependency algorithm is based on the 1990 Paper +// Practical Dependence Testing +// Gina Goff, Ken Kennedy, Chau-Wen Tseng +// +// The algorithm first identifies subscript pairs between the load and store. +// Each pair is tested until all have been tested or independence is found. +// The number of induction variables in a pair determines which test to perform +// on it; +// Zero Index Variable (ZIV) is used when no induction variables are present +// in the pair. +// Single Index Variable (SIV) is used when only one induction variable is +// present, but may occur multiple times in the pair. +// Multiple Index Variable (MIV) is used when more than one induction variable +// is present in the pair. +class LoopDependenceAnalysis { + public: + LoopDependenceAnalysis(IRContext* context, std::vector loops) + : context_(context), + loops_(loops), + scalar_evolution_(context), + debug_stream_(nullptr), + constraints_{} {} + + // Finds the dependence between |source| and |destination|. + // |source| should be an OpLoad. + // |destination| should be an OpStore. + // Any direction and distance information found will be stored in + // |distance_vector|. + // Returns true if independence is found, false otherwise. + bool GetDependence(const Instruction* source, const Instruction* destination, + DistanceVector* distance_vector); + + // Returns true if |subscript_pair| represents a Zero Index Variable pair + // (ZIV) + bool IsZIV(const std::pair& subscript_pair); + + // Returns true if |subscript_pair| represents a Single Index Variable + // (SIV) pair + bool IsSIV(const std::pair& subscript_pair); + + // Returns true if |subscript_pair| represents a Multiple Index Variable + // (MIV) pair + bool IsMIV(const std::pair& subscript_pair); + + // Finds the lower bound of |loop| as an SENode* and returns the result. + // The lower bound is the starting value of the loops induction variable + SENode* GetLowerBound(const Loop* loop); + + // Finds the upper bound of |loop| as an SENode* and returns the result. + // The upper bound is the last value before the loop exit condition is met. + SENode* GetUpperBound(const Loop* loop); + + // Returns true if |value| is between |bound_one| and |bound_two| (inclusive). + bool IsWithinBounds(int64_t value, int64_t bound_one, int64_t bound_two); + + // Finds the bounds of |loop| as upper_bound - lower_bound and returns the + // resulting SENode. + // If the operations can not be completed a nullptr is returned. + SENode* GetTripCount(const Loop* loop); + + // Returns the SENode* produced by building an SENode from the result of + // calling GetInductionInitValue on |loop|. + // If the operation can not be completed a nullptr is returned. + SENode* GetFirstTripInductionNode(const Loop* loop); + + // Returns the SENode* produced by building an SENode from the result of + // GetFirstTripInductionNode + (GetTripCount - 1) * induction_coefficient. + // If the operation can not be completed a nullptr is returned. + SENode* GetFinalTripInductionNode(const Loop* loop, + SENode* induction_coefficient); + + // Returns all the distinct loops that appear in |nodes|. + std::set CollectLoops( + const std::vector& nodes); + + // Returns all the distinct loops that appear in |source| and |destination|. + std::set CollectLoops(SENode* source, SENode* destination); + + // Returns true if |distance| is provably outside the loop bounds. + // |coefficient| must be an SENode representing the coefficient of the + // induction variable of |loop|. + // This method is able to handle some symbolic cases which IsWithinBounds + // can't handle. + bool IsProvablyOutsideOfLoopBounds(const Loop* loop, SENode* distance, + SENode* coefficient); + + // Sets the ostream for debug information for the analysis. + void SetDebugStream(std::ostream& debug_stream) { + debug_stream_ = &debug_stream; + } + + // Clears the stored ostream to stop debug information printing. + void ClearDebugStream() { debug_stream_ = nullptr; } + + // Returns the ScalarEvolutionAnalysis used by this analysis. + ScalarEvolutionAnalysis* GetScalarEvolution() { return &scalar_evolution_; } + + // Creates a new constraint of type |T| and returns the pointer to it. + template + Constraint* make_constraint(Args&&... args) { + constraints_.push_back( + std::unique_ptr(new T(std::forward(args)...))); + + return constraints_.back().get(); + } + + // Subscript partitioning as described in Figure 1 of 'Practical Dependence + // Testing' by Gina Goff, Ken Kennedy, and Chau-Wen Tseng from PLDI '91. + // Partitions the subscripts into independent subscripts and minimally coupled + // sets of subscripts. + // Returns the partitioning of subscript pairs. Sets of size 1 indicates an + // independent subscript-pair and others indicate coupled sets. + using PartitionedSubscripts = + std::vector>>; + PartitionedSubscripts PartitionSubscripts( + const std::vector& source_subscripts, + const std::vector& destination_subscripts); + + // Returns the Loop* matching the loop for |subscript_pair|. + // |subscript_pair| must be an SIV pair. + const Loop* GetLoopForSubscriptPair( + const std::pair& subscript_pair); + + // Returns the DistanceEntry matching the loop for |subscript_pair|. + // |subscript_pair| must be an SIV pair. + DistanceEntry* GetDistanceEntryForSubscriptPair( + const std::pair& subscript_pair, + DistanceVector* distance_vector); + + // Returns the DistanceEntry matching |loop|. + DistanceEntry* GetDistanceEntryForLoop(const Loop* loop, + DistanceVector* distance_vector); + + // Returns a vector of Instruction* which form the subscripts of the array + // access defined by the access chain |instruction|. + std::vector GetSubscripts(const Instruction* instruction); + + // Delta test as described in Figure 3 of 'Practical Dependence + // Testing' by Gina Goff, Ken Kennedy, and Chau-Wen Tseng from PLDI '91. + bool DeltaTest( + const std::vector>& coupled_subscripts, + DistanceVector* dv_entry); + + // Constraint propagation as described in Figure 5 of 'Practical Dependence + // Testing' by Gina Goff, Ken Kennedy, and Chau-Wen Tseng from PLDI '91. + std::pair PropagateConstraints( + const std::pair& subscript_pair, + const std::vector& constraints); + + // Constraint intersection as described in Figure 4 of 'Practical Dependence + // Testing' by Gina Goff, Ken Kennedy, and Chau-Wen Tseng from PLDI '91. + Constraint* IntersectConstraints(Constraint* constraint_0, + Constraint* constraint_1, + const SENode* lower_bound, + const SENode* upper_bound); + + // Returns true if each loop in |loops| is in a form supported by this + // analysis. + // A loop is supported if it has a single induction variable and that + // induction variable has a step of +1 or -1 per loop iteration. + bool CheckSupportedLoops(std::vector loops); + + // Returns true if |loop| is in a form supported by this analysis. + // A loop is supported if it has a single induction variable and that + // induction variable has a step of +1 or -1 per loop iteration. + bool IsSupportedLoop(const Loop* loop); + + private: + IRContext* context_; + + // The loop nest we are analysing the dependence of. + std::vector loops_; + + // The ScalarEvolutionAnalysis used by this analysis to store and perform much + // of its logic. + ScalarEvolutionAnalysis scalar_evolution_; + + // The ostream debug information for the analysis to print to. + std::ostream* debug_stream_; + + // Stores all the constraints created by the analysis. + std::list> constraints_; + + // Returns true if independence can be proven and false if it can't be proven. + bool ZIVTest(const std::pair& subscript_pair); + + // Analyzes the subscript pair to find an applicable SIV test. + // Returns true if independence can be proven and false if it can't be proven. + bool SIVTest(const std::pair& subscript_pair, + DistanceVector* distance_vector); + + // Takes the form a*i + c1, a*i + c2 + // When c1 and c2 are loop invariant and a is constant + // distance = (c1 - c2)/a + // < if distance > 0 + // direction = = if distance = 0 + // > if distance < 0 + // Returns true if independence is proven and false if it can't be proven. + bool StrongSIVTest(SENode* source, SENode* destination, SENode* coeff, + DistanceEntry* distance_entry); + + // Takes for form a*i + c1, a*i + c2 + // where c1 and c2 are loop invariant and a is constant. + // c1 and/or c2 contain one or more SEValueUnknown nodes. + bool SymbolicStrongSIVTest(SENode* source, SENode* destination, + SENode* coefficient, + DistanceEntry* distance_entry); + + // Takes the form a1*i + c1, a2*i + c2 + // where a1 = 0 + // distance = (c1 - c2) / a2 + // Returns true if independence is proven and false if it can't be proven. + bool WeakZeroSourceSIVTest(SENode* source, SERecurrentNode* destination, + SENode* coefficient, + DistanceEntry* distance_entry); + + // Takes the form a1*i + c1, a2*i + c2 + // where a2 = 0 + // distance = (c2 - c1) / a1 + // Returns true if independence is proven and false if it can't be proven. + bool WeakZeroDestinationSIVTest(SERecurrentNode* source, SENode* destination, + SENode* coefficient, + DistanceEntry* distance_entry); + + // Takes the form a1*i + c1, a2*i + c2 + // where a1 = -a2 + // distance = (c2 - c1) / 2*a1 + // Returns true if independence is proven and false if it can't be proven. + bool WeakCrossingSIVTest(SENode* source, SENode* destination, + SENode* coefficient, DistanceEntry* distance_entry); + + // Uses the def_use_mgr to get the instruction referenced by + // SingleWordInOperand(|id|) when called on |instruction|. + Instruction* GetOperandDefinition(const Instruction* instruction, int id); + + // Perform the GCD test if both, the source and the destination nodes, are in + // the form a0*i0 + a1*i1 + ... an*in + c. + bool GCDMIVTest(const std::pair& subscript_pair); + + // Finds the number of induction variables in |node|. + // Returns -1 on failure. + int64_t CountInductionVariables(SENode* node); + + // Finds the number of induction variables shared between |source| and + // |destination|. + // Returns -1 on failure. + int64_t CountInductionVariables(SENode* source, SENode* destination); + + // Takes the offset from the induction variable and subtracts the lower bound + // from it to get the constant term added to the induction. + // Returns the resuting constant term, or nullptr if it could not be produced. + SENode* GetConstantTerm(const Loop* loop, SERecurrentNode* induction); + + // Marks all the distance entries in |distance_vector| that were relate to + // loops in |loops_| but were not used in any subscripts as irrelevant to the + // to the dependence test. + void MarkUnsusedDistanceEntriesAsIrrelevant(const Instruction* source, + const Instruction* destination, + DistanceVector* distance_vector); + + // Converts |value| to a std::string and returns the result. + // This is required because Android does not compile std::to_string. + template + std::string ToString(valueT value) { + std::ostringstream string_stream; + string_stream << value; + return string_stream.str(); + } + + // Prints |debug_msg| and "\n" to the ostream pointed to by |debug_stream_|. + // Won't print anything if |debug_stream_| is nullptr. + void PrintDebug(std::string debug_msg); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_DEPENDENCE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence_helpers.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence_helpers.cpp new file mode 100644 index 000000000000..5d7d994035e6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_dependence_helpers.cpp @@ -0,0 +1,539 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/instruction.h" +#include "source/opt/loop_dependence.h" +#include "source/opt/scalar_analysis_nodes.h" + +namespace spvtools { +namespace opt { + +bool LoopDependenceAnalysis::IsZIV( + const std::pair& subscript_pair) { + return CountInductionVariables(subscript_pair.first, subscript_pair.second) == + 0; +} + +bool LoopDependenceAnalysis::IsSIV( + const std::pair& subscript_pair) { + return CountInductionVariables(subscript_pair.first, subscript_pair.second) == + 1; +} + +bool LoopDependenceAnalysis::IsMIV( + const std::pair& subscript_pair) { + return CountInductionVariables(subscript_pair.first, subscript_pair.second) > + 1; +} + +SENode* LoopDependenceAnalysis::GetLowerBound(const Loop* loop) { + Instruction* cond_inst = loop->GetConditionInst(); + if (!cond_inst) { + return nullptr; + } + Instruction* lower_inst = GetOperandDefinition(cond_inst, 0); + switch (cond_inst->opcode()) { + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: { + // If we have a phi we are looking at the induction variable. We look + // through the phi to the initial value of the phi upon entering the loop. + if (lower_inst->opcode() == spv::Op::OpPhi) { + lower_inst = GetOperandDefinition(lower_inst, 0); + // We don't handle looking through multiple phis. + if (lower_inst->opcode() == spv::Op::OpPhi) { + return nullptr; + } + } + return scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(lower_inst)); + } + default: + return nullptr; + } +} + +SENode* LoopDependenceAnalysis::GetUpperBound(const Loop* loop) { + Instruction* cond_inst = loop->GetConditionInst(); + if (!cond_inst) { + return nullptr; + } + Instruction* upper_inst = GetOperandDefinition(cond_inst, 1); + switch (cond_inst->opcode()) { + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: { + // When we have a < condition we must subtract 1 from the analyzed upper + // instruction. + SENode* upper_bound = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction( + scalar_evolution_.AnalyzeInstruction(upper_inst), + scalar_evolution_.CreateConstant(1))); + return upper_bound; + } + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: { + // When we have a > condition we must add 1 to the analyzed upper + // instruction. + SENode* upper_bound = + scalar_evolution_.SimplifyExpression(scalar_evolution_.CreateAddNode( + scalar_evolution_.AnalyzeInstruction(upper_inst), + scalar_evolution_.CreateConstant(1))); + return upper_bound; + } + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: { + // We don't need to modify the results of analyzing when we have <= or >=. + SENode* upper_bound = scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(upper_inst)); + return upper_bound; + } + default: + return nullptr; + } +} + +bool LoopDependenceAnalysis::IsWithinBounds(int64_t value, int64_t bound_one, + int64_t bound_two) { + if (bound_one < bound_two) { + // If |bound_one| is the lower bound. + return (value >= bound_one && value <= bound_two); + } else if (bound_one > bound_two) { + // If |bound_two| is the lower bound. + return (value >= bound_two && value <= bound_one); + } else { + // Both bounds have the same value. + return value == bound_one; + } +} + +bool LoopDependenceAnalysis::IsProvablyOutsideOfLoopBounds( + const Loop* loop, SENode* distance, SENode* coefficient) { + // We test to see if we can reduce the coefficient to an integral constant. + SEConstantNode* coefficient_constant = coefficient->AsSEConstantNode(); + if (!coefficient_constant) { + PrintDebug( + "IsProvablyOutsideOfLoopBounds could not reduce coefficient to a " + "SEConstantNode so must exit."); + return false; + } + + SENode* lower_bound = GetLowerBound(loop); + SENode* upper_bound = GetUpperBound(loop); + if (!lower_bound || !upper_bound) { + PrintDebug( + "IsProvablyOutsideOfLoopBounds could not get both the lower and upper " + "bounds so must exit."); + return false; + } + // If the coefficient is positive we calculate bounds as upper - lower + // If the coefficient is negative we calculate bounds as lower - upper + SENode* bounds = nullptr; + if (coefficient_constant->FoldToSingleValue() >= 0) { + PrintDebug( + "IsProvablyOutsideOfLoopBounds found coefficient >= 0.\n" + "Using bounds as upper - lower."); + bounds = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction(upper_bound, lower_bound)); + } else { + PrintDebug( + "IsProvablyOutsideOfLoopBounds found coefficient < 0.\n" + "Using bounds as lower - upper."); + bounds = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction(lower_bound, upper_bound)); + } + + // We can attempt to deal with symbolic cases by subtracting |distance| and + // the bound nodes. If we can subtract, simplify and produce a SEConstantNode + // we can produce some information. + SEConstantNode* distance_minus_bounds = + scalar_evolution_ + .SimplifyExpression( + scalar_evolution_.CreateSubtraction(distance, bounds)) + ->AsSEConstantNode(); + if (distance_minus_bounds) { + PrintDebug( + "IsProvablyOutsideOfLoopBounds found distance - bounds as a " + "SEConstantNode with value " + + ToString(distance_minus_bounds->FoldToSingleValue())); + // If distance - bounds > 0 we prove the distance is outwith the loop + // bounds. + if (distance_minus_bounds->FoldToSingleValue() > 0) { + PrintDebug( + "IsProvablyOutsideOfLoopBounds found distance escaped the loop " + "bounds."); + return true; + } + } + + return false; +} + +const Loop* LoopDependenceAnalysis::GetLoopForSubscriptPair( + const std::pair& subscript_pair) { + // Collect all the SERecurrentNodes. + std::vector source_nodes = + std::get<0>(subscript_pair)->CollectRecurrentNodes(); + std::vector destination_nodes = + std::get<1>(subscript_pair)->CollectRecurrentNodes(); + + // Collect all the loops stored by the SERecurrentNodes. + std::unordered_set loops{}; + for (auto source_nodes_it = source_nodes.begin(); + source_nodes_it != source_nodes.end(); ++source_nodes_it) { + loops.insert((*source_nodes_it)->GetLoop()); + } + for (auto destination_nodes_it = destination_nodes.begin(); + destination_nodes_it != destination_nodes.end(); + ++destination_nodes_it) { + loops.insert((*destination_nodes_it)->GetLoop()); + } + + // If we didn't find 1 loop |subscript_pair| is a subscript over multiple or 0 + // loops. We don't handle this so return nullptr. + if (loops.size() != 1) { + PrintDebug("GetLoopForSubscriptPair found loops.size() != 1."); + return nullptr; + } + return *loops.begin(); +} + +DistanceEntry* LoopDependenceAnalysis::GetDistanceEntryForLoop( + const Loop* loop, DistanceVector* distance_vector) { + if (!loop) { + return nullptr; + } + + DistanceEntry* distance_entry = nullptr; + for (size_t loop_index = 0; loop_index < loops_.size(); ++loop_index) { + if (loop == loops_[loop_index]) { + distance_entry = &(distance_vector->GetEntries()[loop_index]); + break; + } + } + + return distance_entry; +} + +DistanceEntry* LoopDependenceAnalysis::GetDistanceEntryForSubscriptPair( + const std::pair& subscript_pair, + DistanceVector* distance_vector) { + const Loop* loop = GetLoopForSubscriptPair(subscript_pair); + + return GetDistanceEntryForLoop(loop, distance_vector); +} + +SENode* LoopDependenceAnalysis::GetTripCount(const Loop* loop) { + BasicBlock* condition_block = loop->FindConditionBlock(); + if (!condition_block) { + return nullptr; + } + Instruction* induction_instr = loop->FindConditionVariable(condition_block); + if (!induction_instr) { + return nullptr; + } + Instruction* cond_instr = loop->GetConditionInst(); + if (!cond_instr) { + return nullptr; + } + + size_t iteration_count = 0; + + // We have to check the instruction type here. If the condition instruction + // isn't a supported type we can't calculate the trip count. + if (loop->IsSupportedCondition(cond_instr->opcode())) { + if (loop->FindNumberOfIterations(induction_instr, &*condition_block->tail(), + &iteration_count)) { + return scalar_evolution_.CreateConstant( + static_cast(iteration_count)); + } + } + + return nullptr; +} + +SENode* LoopDependenceAnalysis::GetFirstTripInductionNode(const Loop* loop) { + BasicBlock* condition_block = loop->FindConditionBlock(); + if (!condition_block) { + return nullptr; + } + Instruction* induction_instr = loop->FindConditionVariable(condition_block); + if (!induction_instr) { + return nullptr; + } + int64_t induction_initial_value = 0; + if (!loop->GetInductionInitValue(induction_instr, &induction_initial_value)) { + return nullptr; + } + + SENode* induction_init_SENode = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateConstant(induction_initial_value)); + return induction_init_SENode; +} + +SENode* LoopDependenceAnalysis::GetFinalTripInductionNode( + const Loop* loop, SENode* induction_coefficient) { + SENode* first_trip_induction_node = GetFirstTripInductionNode(loop); + if (!first_trip_induction_node) { + return nullptr; + } + // Get trip_count as GetTripCount - 1 + // This is because the induction variable is not stepped on the first + // iteration of the loop + SENode* trip_count = + scalar_evolution_.SimplifyExpression(scalar_evolution_.CreateSubtraction( + GetTripCount(loop), scalar_evolution_.CreateConstant(1))); + // Return first_trip_induction_node + trip_count * induction_coefficient + return scalar_evolution_.SimplifyExpression(scalar_evolution_.CreateAddNode( + first_trip_induction_node, + scalar_evolution_.CreateMultiplyNode(trip_count, induction_coefficient))); +} + +std::set LoopDependenceAnalysis::CollectLoops( + const std::vector& recurrent_nodes) { + // We don't handle loops with more than one induction variable. Therefore we + // can identify the number of induction variables by collecting all of the + // loops the collected recurrent nodes belong to. + std::set loops{}; + for (auto recurrent_nodes_it = recurrent_nodes.begin(); + recurrent_nodes_it != recurrent_nodes.end(); ++recurrent_nodes_it) { + loops.insert((*recurrent_nodes_it)->GetLoop()); + } + + return loops; +} + +int64_t LoopDependenceAnalysis::CountInductionVariables(SENode* node) { + if (!node) { + return -1; + } + + std::vector recurrent_nodes = node->CollectRecurrentNodes(); + + // We don't handle loops with more than one induction variable. Therefore we + // can identify the number of induction variables by collecting all of the + // loops the collected recurrent nodes belong to. + std::set loops = CollectLoops(recurrent_nodes); + + return static_cast(loops.size()); +} + +std::set LoopDependenceAnalysis::CollectLoops( + SENode* source, SENode* destination) { + if (!source || !destination) { + return std::set{}; + } + + std::vector source_nodes = source->CollectRecurrentNodes(); + std::vector destination_nodes = + destination->CollectRecurrentNodes(); + + std::set loops = CollectLoops(source_nodes); + std::set destination_loops = CollectLoops(destination_nodes); + + loops.insert(std::begin(destination_loops), std::end(destination_loops)); + + return loops; +} + +int64_t LoopDependenceAnalysis::CountInductionVariables(SENode* source, + SENode* destination) { + if (!source || !destination) { + return -1; + } + + std::set loops = CollectLoops(source, destination); + + return static_cast(loops.size()); +} + +Instruction* LoopDependenceAnalysis::GetOperandDefinition( + const Instruction* instruction, int id) { + return context_->get_def_use_mgr()->GetDef( + instruction->GetSingleWordInOperand(id)); +} + +std::vector LoopDependenceAnalysis::GetSubscripts( + const Instruction* instruction) { + Instruction* access_chain = GetOperandDefinition(instruction, 0); + + std::vector subscripts; + + for (auto i = 1u; i < access_chain->NumInOperandWords(); ++i) { + subscripts.push_back(GetOperandDefinition(access_chain, i)); + } + + return subscripts; +} + +SENode* LoopDependenceAnalysis::GetConstantTerm(const Loop* loop, + SERecurrentNode* induction) { + SENode* offset = induction->GetOffset(); + SENode* lower_bound = GetLowerBound(loop); + if (!offset || !lower_bound) { + return nullptr; + } + SENode* constant_term = scalar_evolution_.SimplifyExpression( + scalar_evolution_.CreateSubtraction(offset, lower_bound)); + return constant_term; +} + +bool LoopDependenceAnalysis::CheckSupportedLoops( + std::vector loops) { + for (auto loop : loops) { + if (!IsSupportedLoop(loop)) { + return false; + } + } + return true; +} + +void LoopDependenceAnalysis::MarkUnsusedDistanceEntriesAsIrrelevant( + const Instruction* source, const Instruction* destination, + DistanceVector* distance_vector) { + std::vector source_subscripts = GetSubscripts(source); + std::vector destination_subscripts = GetSubscripts(destination); + + std::set used_loops{}; + + for (Instruction* source_inst : source_subscripts) { + SENode* source_node = scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(source_inst)); + std::vector recurrent_nodes = + source_node->CollectRecurrentNodes(); + for (SERecurrentNode* recurrent_node : recurrent_nodes) { + used_loops.insert(recurrent_node->GetLoop()); + } + } + + for (Instruction* destination_inst : destination_subscripts) { + SENode* destination_node = scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(destination_inst)); + std::vector recurrent_nodes = + destination_node->CollectRecurrentNodes(); + for (SERecurrentNode* recurrent_node : recurrent_nodes) { + used_loops.insert(recurrent_node->GetLoop()); + } + } + + for (size_t i = 0; i < loops_.size(); ++i) { + if (used_loops.find(loops_[i]) == used_loops.end()) { + distance_vector->GetEntries()[i].dependence_information = + DistanceEntry::DependenceInformation::IRRELEVANT; + } + } +} + +bool LoopDependenceAnalysis::IsSupportedLoop(const Loop* loop) { + std::vector inductions{}; + loop->GetInductionVariables(inductions); + if (inductions.size() != 1) { + return false; + } + Instruction* induction = inductions[0]; + SENode* induction_node = scalar_evolution_.SimplifyExpression( + scalar_evolution_.AnalyzeInstruction(induction)); + if (!induction_node->AsSERecurrentNode()) { + return false; + } + SENode* induction_step = + induction_node->AsSERecurrentNode()->GetCoefficient(); + if (!induction_step->AsSEConstantNode()) { + return false; + } + if (!(induction_step->AsSEConstantNode()->FoldToSingleValue() == 1 || + induction_step->AsSEConstantNode()->FoldToSingleValue() == -1)) { + return false; + } + return true; +} + +void LoopDependenceAnalysis::PrintDebug(std::string debug_msg) { + if (debug_stream_) { + (*debug_stream_) << debug_msg << "\n"; + } +} + +bool Constraint::operator==(const Constraint& other) const { + // A distance of |d| is equivalent to a line |x - y = -d| + if ((GetType() == ConstraintType::Distance && + other.GetType() == ConstraintType::Line) || + (GetType() == ConstraintType::Line && + other.GetType() == ConstraintType::Distance)) { + auto is_distance = AsDependenceLine() != nullptr; + + auto as_distance = + is_distance ? AsDependenceDistance() : other.AsDependenceDistance(); + auto distance = as_distance->GetDistance(); + + auto line = other.AsDependenceLine(); + + auto scalar_evolution = distance->GetParentAnalysis(); + + auto neg_distance = scalar_evolution->SimplifyExpression( + scalar_evolution->CreateNegation(distance)); + + return *scalar_evolution->CreateConstant(1) == *line->GetA() && + *scalar_evolution->CreateConstant(-1) == *line->GetB() && + *neg_distance == *line->GetC(); + } + + if (GetType() != other.GetType()) { + return false; + } + + if (AsDependenceDistance()) { + return *AsDependenceDistance()->GetDistance() == + *other.AsDependenceDistance()->GetDistance(); + } + + if (AsDependenceLine()) { + auto this_line = AsDependenceLine(); + auto other_line = other.AsDependenceLine(); + return *this_line->GetA() == *other_line->GetA() && + *this_line->GetB() == *other_line->GetB() && + *this_line->GetC() == *other_line->GetC(); + } + + if (AsDependencePoint()) { + auto this_point = AsDependencePoint(); + auto other_point = other.AsDependencePoint(); + + return *this_point->GetSource() == *other_point->GetSource() && + *this_point->GetDestination() == *other_point->GetDestination(); + } + + return true; +} + +bool Constraint::operator!=(const Constraint& other) const { + return !(*this == other); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_descriptor.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_descriptor.cpp new file mode 100644 index 000000000000..cbfc2e7599fc --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_descriptor.cpp @@ -0,0 +1,1024 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/loop_descriptor.h" + +#include +#include +#include +#include +#include + +#include "source/opt/cfg.h" +#include "source/opt/constants.h" +#include "source/opt/dominator_tree.h" +#include "source/opt/ir_context.h" +#include "source/opt/iterator.h" +#include "source/opt/tree_iterator.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { + +// Takes in a phi instruction |induction| and the loop |header| and returns the +// step operation of the loop. +Instruction* Loop::GetInductionStepOperation( + const Instruction* induction) const { + // Induction must be a phi instruction. + assert(induction->opcode() == spv::Op::OpPhi); + + Instruction* step = nullptr; + + analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr(); + + // Traverse the incoming operands of the phi instruction. + for (uint32_t operand_id = 1; operand_id < induction->NumInOperands(); + operand_id += 2) { + // Incoming edge. + BasicBlock* incoming_block = + context_->cfg()->block(induction->GetSingleWordInOperand(operand_id)); + + // Check if the block is dominated by header, and thus coming from within + // the loop. + if (IsInsideLoop(incoming_block)) { + step = def_use_manager->GetDef( + induction->GetSingleWordInOperand(operand_id - 1)); + break; + } + } + + if (!step || !IsSupportedStepOp(step->opcode())) { + return nullptr; + } + + // The induction variable which binds the loop must only be modified once. + uint32_t lhs = step->GetSingleWordInOperand(0); + uint32_t rhs = step->GetSingleWordInOperand(1); + + // One of the left hand side or right hand side of the step instruction must + // be the induction phi and the other must be an OpConstant. + if (lhs != induction->result_id() && rhs != induction->result_id()) { + return nullptr; + } + + if (def_use_manager->GetDef(lhs)->opcode() != spv::Op::OpConstant && + def_use_manager->GetDef(rhs)->opcode() != spv::Op::OpConstant) { + return nullptr; + } + + return step; +} + +// Returns true if the |step| operation is an induction variable step operation +// which is currently handled. +bool Loop::IsSupportedStepOp(spv::Op step) const { + switch (step) { + case spv::Op::OpISub: + case spv::Op::OpIAdd: + return true; + default: + return false; + } +} + +bool Loop::IsSupportedCondition(spv::Op condition) const { + switch (condition) { + // < + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + // > + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + + // >= + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpUGreaterThanEqual: + // <= + case spv::Op::OpSLessThanEqual: + case spv::Op::OpULessThanEqual: + + return true; + default: + return false; + } +} + +int64_t Loop::GetResidualConditionValue(spv::Op condition, + int64_t initial_value, + int64_t step_value, + size_t number_of_iterations, + size_t factor) { + int64_t remainder = + initial_value + (number_of_iterations % factor) * step_value; + + // We subtract or add one as the above formula calculates the remainder if the + // loop where just less than or greater than. Adding or subtracting one should + // give a functionally equivalent value. + switch (condition) { + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpUGreaterThanEqual: { + remainder -= 1; + break; + } + case spv::Op::OpSLessThanEqual: + case spv::Op::OpULessThanEqual: { + remainder += 1; + break; + } + + default: + break; + } + return remainder; +} + +Instruction* Loop::GetConditionInst() const { + BasicBlock* condition_block = FindConditionBlock(); + if (!condition_block) { + return nullptr; + } + Instruction* branch_conditional = &*condition_block->tail(); + if (!branch_conditional || + branch_conditional->opcode() != spv::Op::OpBranchConditional) { + return nullptr; + } + Instruction* condition_inst = context_->get_def_use_mgr()->GetDef( + branch_conditional->GetSingleWordInOperand(0)); + if (IsSupportedCondition(condition_inst->opcode())) { + return condition_inst; + } + + return nullptr; +} + +// Extract the initial value from the |induction| OpPhi instruction and store it +// in |value|. If the function couldn't find the initial value of |induction| +// return false. +bool Loop::GetInductionInitValue(const Instruction* induction, + int64_t* value) const { + Instruction* constant_instruction = nullptr; + analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr(); + + for (uint32_t operand_id = 0; operand_id < induction->NumInOperands(); + operand_id += 2) { + BasicBlock* bb = context_->cfg()->block( + induction->GetSingleWordInOperand(operand_id + 1)); + + if (!IsInsideLoop(bb)) { + constant_instruction = def_use_manager->GetDef( + induction->GetSingleWordInOperand(operand_id)); + } + } + + if (!constant_instruction) return false; + + const analysis::Constant* constant = + context_->get_constant_mgr()->FindDeclaredConstant( + constant_instruction->result_id()); + if (!constant) return false; + + if (value) { + const analysis::Integer* type = constant->type()->AsInteger(); + if (!type) { + return false; + } + + *value = type->IsSigned() ? constant->GetSignExtendedValue() + : constant->GetZeroExtendedValue(); + } + + return true; +} + +Loop::Loop(IRContext* context, DominatorAnalysis* dom_analysis, + BasicBlock* header, BasicBlock* continue_target, + BasicBlock* merge_target) + : context_(context), + loop_header_(header), + loop_continue_(continue_target), + loop_merge_(merge_target), + loop_preheader_(nullptr), + parent_(nullptr), + loop_is_marked_for_removal_(false) { + assert(context); + assert(dom_analysis); + loop_preheader_ = FindLoopPreheader(dom_analysis); + loop_latch_ = FindLatchBlock(); +} + +BasicBlock* Loop::FindLoopPreheader(DominatorAnalysis* dom_analysis) { + CFG* cfg = context_->cfg(); + DominatorTree& dom_tree = dom_analysis->GetDomTree(); + DominatorTreeNode* header_node = dom_tree.GetTreeNode(loop_header_); + + // The loop predecessor. + BasicBlock* loop_pred = nullptr; + + auto header_pred = cfg->preds(loop_header_->id()); + for (uint32_t p_id : header_pred) { + DominatorTreeNode* node = dom_tree.GetTreeNode(p_id); + if (node && !dom_tree.Dominates(header_node, node)) { + // The predecessor is not part of the loop, so potential loop preheader. + if (loop_pred && node->bb_ != loop_pred) { + // If we saw 2 distinct predecessors that are outside the loop, we don't + // have a loop preheader. + return nullptr; + } + loop_pred = node->bb_; + } + } + // Safe guard against invalid code, SPIR-V spec forbids loop with the entry + // node as header. + assert(loop_pred && "The header node is the entry block ?"); + + // So we have a unique basic block that can enter this loop. + // If this loop is the unique successor of this block, then it is a loop + // preheader. + bool is_preheader = true; + uint32_t loop_header_id = loop_header_->id(); + const auto* const_loop_pred = loop_pred; + const_loop_pred->ForEachSuccessorLabel( + [&is_preheader, loop_header_id](const uint32_t id) { + if (id != loop_header_id) is_preheader = false; + }); + if (is_preheader) return loop_pred; + return nullptr; +} + +bool Loop::IsInsideLoop(Instruction* inst) const { + const BasicBlock* parent_block = context_->get_instr_block(inst); + if (!parent_block) return false; + return IsInsideLoop(parent_block); +} + +bool Loop::IsBasicBlockInLoopSlow(const BasicBlock* bb) { + assert(bb->GetParent() && "The basic block does not belong to a function"); + DominatorAnalysis* dom_analysis = + context_->GetDominatorAnalysis(bb->GetParent()); + if (dom_analysis->IsReachable(bb) && + !dom_analysis->Dominates(GetHeaderBlock(), bb)) + return false; + + return true; +} + +BasicBlock* Loop::GetOrCreatePreHeaderBlock() { + if (loop_preheader_) return loop_preheader_; + + CFG* cfg = context_->cfg(); + loop_header_ = cfg->SplitLoopHeader(loop_header_); + return loop_preheader_; +} + +void Loop::SetContinueBlock(BasicBlock* continue_block) { + assert(IsInsideLoop(continue_block)); + loop_continue_ = continue_block; +} + +void Loop::SetLatchBlock(BasicBlock* latch) { +#ifndef NDEBUG + assert(latch->GetParent() && "The basic block does not belong to a function"); + + const auto* const_latch = latch; + const_latch->ForEachSuccessorLabel([this](uint32_t id) { + assert((!IsInsideLoop(id) || id == GetHeaderBlock()->id()) && + "A predecessor of the continue block does not belong to the loop"); + }); +#endif // NDEBUG + assert(IsInsideLoop(latch) && "The continue block is not in the loop"); + + SetLatchBlockImpl(latch); +} + +void Loop::SetMergeBlock(BasicBlock* merge) { +#ifndef NDEBUG + assert(merge->GetParent() && "The basic block does not belong to a function"); +#endif // NDEBUG + assert(!IsInsideLoop(merge) && "The merge block is in the loop"); + + SetMergeBlockImpl(merge); + if (GetHeaderBlock()->GetLoopMergeInst()) { + UpdateLoopMergeInst(); + } +} + +void Loop::SetPreHeaderBlock(BasicBlock* preheader) { + if (preheader) { + assert(!IsInsideLoop(preheader) && "The preheader block is in the loop"); + assert(preheader->tail()->opcode() == spv::Op::OpBranch && + "The preheader block does not unconditionally branch to the header " + "block"); + assert(preheader->tail()->GetSingleWordOperand(0) == + GetHeaderBlock()->id() && + "The preheader block does not unconditionally branch to the header " + "block"); + } + loop_preheader_ = preheader; +} + +BasicBlock* Loop::FindLatchBlock() { + CFG* cfg = context_->cfg(); + + DominatorAnalysis* dominator_analysis = + context_->GetDominatorAnalysis(loop_header_->GetParent()); + + // Look at the predecessors of the loop header to find a predecessor block + // which is dominated by the loop continue target. There should only be one + // block which meets this criteria and this is the latch block, as per the + // SPIR-V spec. + for (uint32_t block_id : cfg->preds(loop_header_->id())) { + if (dominator_analysis->Dominates(loop_continue_->id(), block_id)) { + return cfg->block(block_id); + } + } + + assert( + false && + "Every loop should have a latch block dominated by the continue target"); + return nullptr; +} + +void Loop::GetExitBlocks(std::unordered_set* exit_blocks) const { + CFG* cfg = context_->cfg(); + exit_blocks->clear(); + + for (uint32_t bb_id : GetBlocks()) { + const BasicBlock* bb = cfg->block(bb_id); + bb->ForEachSuccessorLabel([exit_blocks, this](uint32_t succ) { + if (!IsInsideLoop(succ)) { + exit_blocks->insert(succ); + } + }); + } +} + +void Loop::GetMergingBlocks( + std::unordered_set* merging_blocks) const { + assert(GetMergeBlock() && "This loop is not structured"); + CFG* cfg = context_->cfg(); + merging_blocks->clear(); + + std::stack to_visit; + to_visit.push(GetMergeBlock()); + while (!to_visit.empty()) { + const BasicBlock* bb = to_visit.top(); + to_visit.pop(); + merging_blocks->insert(bb->id()); + for (uint32_t pred_id : cfg->preds(bb->id())) { + if (!IsInsideLoop(pred_id) && !merging_blocks->count(pred_id)) { + to_visit.push(cfg->block(pred_id)); + } + } + } +} + +namespace { + +inline bool IsBasicBlockSafeToClone(IRContext* context, BasicBlock* bb) { + for (Instruction& inst : *bb) { + if (!inst.IsBranch() && !context->IsCombinatorInstruction(&inst)) + return false; + } + + return true; +} + +} // namespace + +bool Loop::IsSafeToClone() const { + CFG& cfg = *context_->cfg(); + + for (uint32_t bb_id : GetBlocks()) { + BasicBlock* bb = cfg.block(bb_id); + assert(bb); + if (!IsBasicBlockSafeToClone(context_, bb)) return false; + } + + // Look at the merge construct. + if (GetHeaderBlock()->GetLoopMergeInst()) { + std::unordered_set blocks; + GetMergingBlocks(&blocks); + blocks.erase(GetMergeBlock()->id()); + for (uint32_t bb_id : blocks) { + BasicBlock* bb = cfg.block(bb_id); + assert(bb); + if (!IsBasicBlockSafeToClone(context_, bb)) return false; + } + } + + return true; +} + +bool Loop::IsLCSSA() const { + CFG* cfg = context_->cfg(); + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + std::unordered_set exit_blocks; + GetExitBlocks(&exit_blocks); + + // Declare ir_context so we can capture context_ in the below lambda + IRContext* ir_context = context_; + + for (uint32_t bb_id : GetBlocks()) { + for (Instruction& insn : *cfg->block(bb_id)) { + // All uses must be either: + // - In the loop; + // - In an exit block and in a phi instruction. + if (!def_use_mgr->WhileEachUser( + &insn, + [&exit_blocks, ir_context, this](Instruction* use) -> bool { + BasicBlock* parent = ir_context->get_instr_block(use); + assert(parent && "Invalid analysis"); + if (IsInsideLoop(parent)) return true; + if (use->opcode() != spv::Op::OpPhi) return false; + return exit_blocks.count(parent->id()); + })) + return false; + } + } + return true; +} + +bool Loop::ShouldHoistInstruction(const Instruction& inst) const { + return inst.IsOpcodeCodeMotionSafe() && AreAllOperandsOutsideLoop(inst) && + (!inst.IsLoad() || inst.IsReadOnlyLoad()); +} + +bool Loop::AreAllOperandsOutsideLoop(const Instruction& inst) const { + analysis::DefUseManager* def_use_mgr = GetContext()->get_def_use_mgr(); + + const std::function operand_outside_loop = + [this, &def_use_mgr](const uint32_t* id) { + return !this->IsInsideLoop(def_use_mgr->GetDef(*id)); + }; + + return inst.WhileEachInId(operand_outside_loop); +} + +void Loop::ComputeLoopStructuredOrder( + std::vector* ordered_loop_blocks, bool include_pre_header, + bool include_merge) const { + CFG& cfg = *context_->cfg(); + + // Reserve the memory: all blocks in the loop + extra if needed. + ordered_loop_blocks->reserve(GetBlocks().size() + include_pre_header + + include_merge); + + if (include_pre_header && GetPreHeaderBlock()) + ordered_loop_blocks->push_back(loop_preheader_); + + bool is_shader = + context_->get_feature_mgr()->HasCapability(spv::Capability::Shader); + if (!is_shader) { + cfg.ForEachBlockInReversePostOrder( + loop_header_, [ordered_loop_blocks, this](BasicBlock* bb) { + if (IsInsideLoop(bb)) ordered_loop_blocks->push_back(bb); + }); + } else { + // If this is a shader, it is possible that there are unreachable merge and + // continue blocks that must be copied to retain the structured order. + // The structured order will include these. + std::list order; + cfg.ComputeStructuredOrder(loop_header_->GetParent(), loop_header_, + loop_merge_, &order); + for (BasicBlock* bb : order) { + if (bb == GetMergeBlock()) { + break; + } + ordered_loop_blocks->push_back(bb); + } + } + if (include_merge && GetMergeBlock()) + ordered_loop_blocks->push_back(loop_merge_); +} + +LoopDescriptor::LoopDescriptor(IRContext* context, const Function* f) + : loops_(), placeholder_top_loop_(nullptr) { + PopulateList(context, f); +} + +LoopDescriptor::~LoopDescriptor() { ClearLoops(); } + +void LoopDescriptor::PopulateList(IRContext* context, const Function* f) { + DominatorAnalysis* dom_analysis = context->GetDominatorAnalysis(f); + + ClearLoops(); + + // Post-order traversal of the dominator tree to find all the OpLoopMerge + // instructions. + DominatorTree& dom_tree = dom_analysis->GetDomTree(); + for (DominatorTreeNode& node : + make_range(dom_tree.post_begin(), dom_tree.post_end())) { + Instruction* merge_inst = node.bb_->GetLoopMergeInst(); + if (merge_inst) { + bool all_backedge_unreachable = true; + for (uint32_t pid : context->cfg()->preds(node.bb_->id())) { + if (dom_analysis->IsReachable(pid) && + dom_analysis->Dominates(node.bb_->id(), pid)) { + all_backedge_unreachable = false; + break; + } + } + if (all_backedge_unreachable) + continue; // ignore this one, we actually never branch back. + + // The id of the merge basic block of this loop. + uint32_t merge_bb_id = merge_inst->GetSingleWordOperand(0); + + // The id of the continue basic block of this loop. + uint32_t continue_bb_id = merge_inst->GetSingleWordOperand(1); + + // The merge target of this loop. + BasicBlock* merge_bb = context->cfg()->block(merge_bb_id); + + // The continue target of this loop. + BasicBlock* continue_bb = context->cfg()->block(continue_bb_id); + + // The basic block containing the merge instruction. + BasicBlock* header_bb = context->get_instr_block(merge_inst); + + // Add the loop to the list of all the loops in the function. + Loop* current_loop = + new Loop(context, dom_analysis, header_bb, continue_bb, merge_bb); + loops_.push_back(current_loop); + + // We have a bottom-up construction, so if this loop has nested-loops, + // they are by construction at the tail of the loop list. + for (auto itr = loops_.rbegin() + 1; itr != loops_.rend(); ++itr) { + Loop* previous_loop = *itr; + + // If the loop already has a parent, then it has been processed. + if (previous_loop->HasParent()) continue; + + // If the current loop does not dominates the previous loop then it is + // not nested loop. + if (!dom_analysis->Dominates(header_bb, + previous_loop->GetHeaderBlock())) + continue; + // If the current loop merge dominates the previous loop then it is + // not nested loop. + if (dom_analysis->Dominates(merge_bb, previous_loop->GetHeaderBlock())) + continue; + + current_loop->AddNestedLoop(previous_loop); + } + DominatorTreeNode* dom_merge_node = dom_tree.GetTreeNode(merge_bb); + for (DominatorTreeNode& loop_node : + make_range(node.df_begin(), node.df_end())) { + // Check if we are in the loop. + if (dom_tree.Dominates(dom_merge_node, &loop_node)) continue; + current_loop->AddBasicBlock(loop_node.bb_); + basic_block_to_loop_.insert( + std::make_pair(loop_node.bb_->id(), current_loop)); + } + } + } + for (Loop* loop : loops_) { + if (!loop->HasParent()) placeholder_top_loop_.nested_loops_.push_back(loop); + } +} + +std::vector LoopDescriptor::GetLoopsInBinaryLayoutOrder() { + std::vector ids{}; + + for (size_t i = 0; i < NumLoops(); ++i) { + ids.push_back(GetLoopByIndex(i).GetHeaderBlock()->id()); + } + + std::vector loops{}; + if (!ids.empty()) { + auto function = GetLoopByIndex(0).GetHeaderBlock()->GetParent(); + for (const auto& block : *function) { + auto block_id = block.id(); + + auto element = std::find(std::begin(ids), std::end(ids), block_id); + if (element != std::end(ids)) { + loops.push_back(&GetLoopByIndex(element - std::begin(ids))); + } + } + } + + return loops; +} + +BasicBlock* Loop::FindConditionBlock() const { + if (!loop_merge_) { + return nullptr; + } + BasicBlock* condition_block = nullptr; + + uint32_t in_loop_pred = 0; + for (uint32_t p : context_->cfg()->preds(loop_merge_->id())) { + if (IsInsideLoop(p)) { + if (in_loop_pred) { + // 2 in-loop predecessors. + return nullptr; + } + in_loop_pred = p; + } + } + if (!in_loop_pred) { + // Merge block is unreachable. + return nullptr; + } + + BasicBlock* bb = context_->cfg()->block(in_loop_pred); + + if (!bb) return nullptr; + + const Instruction& branch = *bb->ctail(); + + // Make sure the branch is a conditional branch. + if (branch.opcode() != spv::Op::OpBranchConditional) return nullptr; + + // Make sure one of the two possible branches is to the merge block. + if (branch.GetSingleWordInOperand(1) == loop_merge_->id() || + branch.GetSingleWordInOperand(2) == loop_merge_->id()) { + condition_block = bb; + } + + return condition_block; +} + +bool Loop::FindNumberOfIterations(const Instruction* induction, + const Instruction* branch_inst, + size_t* iterations_out, + int64_t* step_value_out, + int64_t* init_value_out) const { + // From the branch instruction find the branch condition. + analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr(); + + // Condition instruction from the OpConditionalBranch. + Instruction* condition = + def_use_manager->GetDef(branch_inst->GetSingleWordOperand(0)); + + assert(IsSupportedCondition(condition->opcode())); + + // Get the constant manager from the ir context. + analysis::ConstantManager* const_manager = context_->get_constant_mgr(); + + // Find the constant value used by the condition variable. Exit out if it + // isn't a constant int. + const analysis::Constant* upper_bound = + const_manager->FindDeclaredConstant(condition->GetSingleWordOperand(3)); + if (!upper_bound) return false; + + // Must be integer because of the opcode on the condition. + const analysis::Integer* type = upper_bound->type()->AsInteger(); + + if (!type || type->width() > 64) { + return false; + } + + int64_t condition_value = type->IsSigned() + ? upper_bound->GetSignExtendedValue() + : upper_bound->GetZeroExtendedValue(); + + // Find the instruction which is stepping through the loop. + // + // GetInductionStepOperation returns nullptr if |step_inst| is OpConstantNull. + Instruction* step_inst = GetInductionStepOperation(induction); + if (!step_inst) return false; + + // Find the constant value used by the condition variable. + const analysis::Constant* step_constant = + const_manager->FindDeclaredConstant(step_inst->GetSingleWordOperand(3)); + if (!step_constant) return false; + + // Must be integer because of the opcode on the condition. + int64_t step_value = 0; + + const analysis::Integer* step_type = + step_constant->AsIntConstant()->type()->AsInteger(); + + if (step_type->IsSigned()) { + step_value = step_constant->AsIntConstant()->GetS32BitValue(); + } else { + step_value = step_constant->AsIntConstant()->GetU32BitValue(); + } + + // If this is a subtraction step we should negate the step value. + if (step_inst->opcode() == spv::Op::OpISub) { + step_value = -step_value; + } + + // Find the initial value of the loop and make sure it is a constant integer. + int64_t init_value = 0; + if (!GetInductionInitValue(induction, &init_value)) return false; + + // If iterations is non null then store the value in that. + int64_t num_itrs = GetIterations(condition->opcode(), condition_value, + init_value, step_value); + + // If the loop body will not be reached return false. + if (num_itrs <= 0) { + return false; + } + + if (iterations_out) { + assert(static_cast(num_itrs) <= std::numeric_limits::max()); + *iterations_out = static_cast(num_itrs); + } + + if (step_value_out) { + *step_value_out = step_value; + } + + if (init_value_out) { + *init_value_out = init_value; + } + + return true; +} + +// We retrieve the number of iterations using the following formula, diff / +// |step_value| where diff is calculated differently according to the +// |condition| and uses the |condition_value| and |init_value|. If diff / +// |step_value| is NOT cleanly divisible then we add one to the sum. +int64_t Loop::GetIterations(spv::Op condition, int64_t condition_value, + int64_t init_value, int64_t step_value) const { + if (step_value == 0) { + return 0; + } + + int64_t diff = 0; + + switch (condition) { + case spv::Op::OpSLessThan: + case spv::Op::OpULessThan: { + // If the condition is not met to begin with the loop will never iterate. + if (!(init_value < condition_value)) return 0; + + diff = condition_value - init_value; + + // If the operation is a less then operation then the diff and step must + // have the same sign otherwise the induction will never cross the + // condition (either never true or always true). + if ((diff < 0 && step_value > 0) || (diff > 0 && step_value < 0)) { + return 0; + } + + break; + } + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThan: { + // If the condition is not met to begin with the loop will never iterate. + if (!(init_value > condition_value)) return 0; + + diff = init_value - condition_value; + + // If the operation is a greater than operation then the diff and step + // must have opposite signs. Otherwise the condition will always be true + // or will never be true. + if ((diff < 0 && step_value < 0) || (diff > 0 && step_value > 0)) { + return 0; + } + + break; + } + + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpUGreaterThanEqual: { + // If the condition is not met to begin with the loop will never iterate. + if (!(init_value >= condition_value)) return 0; + + // We subtract one to make it the same as spv::Op::OpGreaterThan as it is + // functionally equivalent. + diff = init_value - (condition_value - 1); + + // If the operation is a greater than operation then the diff and step + // must have opposite signs. Otherwise the condition will always be true + // or will never be true. + if ((diff > 0 && step_value > 0) || (diff < 0 && step_value < 0)) { + return 0; + } + + break; + } + + case spv::Op::OpSLessThanEqual: + case spv::Op::OpULessThanEqual: { + // If the condition is not met to begin with the loop will never iterate. + if (!(init_value <= condition_value)) return 0; + + // We add one to make it the same as spv::Op::OpLessThan as it is + // functionally equivalent. + diff = (condition_value + 1) - init_value; + + // If the operation is a less than operation then the diff and step must + // have the same sign otherwise the induction will never cross the + // condition (either never true or always true). + if ((diff < 0 && step_value > 0) || (diff > 0 && step_value < 0)) { + return 0; + } + + break; + } + + default: + assert(false && + "Could not retrieve number of iterations from the loop condition. " + "Condition is not supported."); + } + + // Take the abs of - step values. + step_value = llabs(step_value); + diff = llabs(diff); + int64_t result = diff / step_value; + + if (diff % step_value != 0) { + result += 1; + } + return result; +} + +// Returns the list of induction variables within the loop. +void Loop::GetInductionVariables( + std::vector& induction_variables) const { + for (Instruction& inst : *loop_header_) { + if (inst.opcode() == spv::Op::OpPhi) { + induction_variables.push_back(&inst); + } + } +} + +Instruction* Loop::FindConditionVariable( + const BasicBlock* condition_block) const { + // Find the branch instruction. + const Instruction& branch_inst = *condition_block->ctail(); + + Instruction* induction = nullptr; + // Verify that the branch instruction is a conditional branch. + if (branch_inst.opcode() == spv::Op::OpBranchConditional) { + // From the branch instruction find the branch condition. + analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr(); + + // Find the instruction representing the condition used in the conditional + // branch. + Instruction* condition = + def_use_manager->GetDef(branch_inst.GetSingleWordOperand(0)); + + // Ensure that the condition is a less than operation. + if (condition && IsSupportedCondition(condition->opcode())) { + // The left hand side operand of the operation. + Instruction* variable_inst = + def_use_manager->GetDef(condition->GetSingleWordOperand(2)); + + // Make sure the variable instruction used is a phi. + if (!variable_inst || variable_inst->opcode() != spv::Op::OpPhi) + return nullptr; + + // Make sure the phi instruction only has two incoming blocks. Each + // incoming block will be represented by two in operands in the phi + // instruction, the value and the block which that value came from. We + // assume the cannocalised phi will have two incoming values, one from the + // preheader and one from the continue block. + size_t max_supported_operands = 4; + if (variable_inst->NumInOperands() == max_supported_operands) { + // The operand index of the first incoming block label. + uint32_t operand_label_1 = 1; + + // The operand index of the second incoming block label. + uint32_t operand_label_2 = 3; + + // Make sure one of them is the preheader. + if (!IsInsideLoop( + variable_inst->GetSingleWordInOperand(operand_label_1)) && + !IsInsideLoop( + variable_inst->GetSingleWordInOperand(operand_label_2))) { + return nullptr; + } + + // And make sure that the other is the latch block. + if (variable_inst->GetSingleWordInOperand(operand_label_1) != + loop_latch_->id() && + variable_inst->GetSingleWordInOperand(operand_label_2) != + loop_latch_->id()) { + return nullptr; + } + } else { + return nullptr; + } + + if (!FindNumberOfIterations(variable_inst, &branch_inst, nullptr)) + return nullptr; + induction = variable_inst; + } + } + + return induction; +} + +bool LoopDescriptor::CreatePreHeaderBlocksIfMissing() { + auto modified = false; + + for (auto& loop : *this) { + if (!loop.GetPreHeaderBlock()) { + modified = true; + // TODO(1841): Handle failure to create pre-header. + loop.GetOrCreatePreHeaderBlock(); + } + } + + return modified; +} + +// Add and remove loops which have been marked for addition and removal to +// maintain the state of the loop descriptor class. +void LoopDescriptor::PostModificationCleanup() { + LoopContainerType loops_to_remove_; + for (Loop* loop : loops_) { + if (loop->IsMarkedForRemoval()) { + loops_to_remove_.push_back(loop); + if (loop->HasParent()) { + loop->GetParent()->RemoveChildLoop(loop); + } + } + } + + for (Loop* loop : loops_to_remove_) { + loops_.erase(std::find(loops_.begin(), loops_.end(), loop)); + delete loop; + } + + for (auto& pair : loops_to_add_) { + Loop* parent = pair.first; + std::unique_ptr loop = std::move(pair.second); + + if (parent) { + loop->SetParent(nullptr); + parent->AddNestedLoop(loop.get()); + + for (uint32_t block_id : loop->GetBlocks()) { + parent->AddBasicBlock(block_id); + } + } + + loops_.emplace_back(loop.release()); + } + + loops_to_add_.clear(); +} + +void LoopDescriptor::ClearLoops() { + for (Loop* loop : loops_) { + delete loop; + } + loops_.clear(); +} + +// Adds a new loop nest to the descriptor set. +Loop* LoopDescriptor::AddLoopNest(std::unique_ptr new_loop) { + Loop* loop = new_loop.release(); + if (!loop->HasParent()) placeholder_top_loop_.nested_loops_.push_back(loop); + // Iterate from inner to outer most loop, adding basic block to loop mapping + // as we go. + for (Loop& current_loop : + make_range(iterator::begin(loop), iterator::end(nullptr))) { + loops_.push_back(¤t_loop); + for (uint32_t bb_id : current_loop.GetBlocks()) + basic_block_to_loop_.insert(std::make_pair(bb_id, ¤t_loop)); + } + + return loop; +} + +void LoopDescriptor::RemoveLoop(Loop* loop) { + Loop* parent = loop->GetParent() ? loop->GetParent() : &placeholder_top_loop_; + parent->nested_loops_.erase(std::find(parent->nested_loops_.begin(), + parent->nested_loops_.end(), loop)); + std::for_each( + loop->nested_loops_.begin(), loop->nested_loops_.end(), + [loop](Loop* sub_loop) { sub_loop->SetParent(loop->GetParent()); }); + parent->nested_loops_.insert(parent->nested_loops_.end(), + loop->nested_loops_.begin(), + loop->nested_loops_.end()); + for (uint32_t bb_id : loop->GetBlocks()) { + Loop* l = FindLoopForBasicBlock(bb_id); + if (l == loop) { + SetBasicBlockToLoop(bb_id, l->GetParent()); + } else { + ForgetBasicBlock(bb_id); + } + } + + LoopContainerType::iterator it = + std::find(loops_.begin(), loops_.end(), loop); + assert(it != loops_.end()); + delete loop; + loops_.erase(it); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_descriptor.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_descriptor.h new file mode 100644 index 000000000000..d451496e771b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_descriptor.h @@ -0,0 +1,577 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_DESCRIPTOR_H_ +#define SOURCE_OPT_LOOP_DESCRIPTOR_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/dominator_analysis.h" +#include "source/opt/module.h" +#include "source/opt/tree_iterator.h" + +namespace spvtools { +namespace opt { + +class IRContext; +class CFG; +class LoopDescriptor; + +// A class to represent and manipulate a loop in structured control flow. +class Loop { + // The type used to represent nested child loops. + using ChildrenList = std::vector; + + public: + using iterator = ChildrenList::iterator; + using const_iterator = ChildrenList::const_iterator; + using BasicBlockListTy = std::unordered_set; + + explicit Loop(IRContext* context) + : context_(context), + loop_header_(nullptr), + loop_continue_(nullptr), + loop_merge_(nullptr), + loop_preheader_(nullptr), + loop_latch_(nullptr), + parent_(nullptr), + loop_is_marked_for_removal_(false) {} + + Loop(IRContext* context, DominatorAnalysis* analysis, BasicBlock* header, + BasicBlock* continue_target, BasicBlock* merge_target); + + // Iterators over the immediate sub-loops. + inline iterator begin() { return nested_loops_.begin(); } + inline iterator end() { return nested_loops_.end(); } + inline const_iterator begin() const { return cbegin(); } + inline const_iterator end() const { return cend(); } + inline const_iterator cbegin() const { return nested_loops_.begin(); } + inline const_iterator cend() const { return nested_loops_.end(); } + + // Returns the header (first basic block of the loop). This block contains the + // OpLoopMerge instruction. + inline BasicBlock* GetHeaderBlock() { return loop_header_; } + inline const BasicBlock* GetHeaderBlock() const { return loop_header_; } + inline void SetHeaderBlock(BasicBlock* header) { loop_header_ = header; } + + // Updates the OpLoopMerge instruction to reflect the current state of the + // loop. + inline void UpdateLoopMergeInst() { + assert(GetHeaderBlock()->GetLoopMergeInst() && + "The loop is not structured"); + Instruction* merge_inst = GetHeaderBlock()->GetLoopMergeInst(); + merge_inst->SetInOperand(0, {GetMergeBlock()->id()}); + } + + // Returns the continue target basic block. This is the block designated as + // the continue target by the OpLoopMerge instruction. + inline BasicBlock* GetContinueBlock() { return loop_continue_; } + inline const BasicBlock* GetContinueBlock() const { return loop_continue_; } + + // Returns the latch basic block (basic block that holds the back-edge). + // These functions return nullptr if the loop is not structured (i.e. if it + // has more than one backedge). + inline BasicBlock* GetLatchBlock() { return loop_latch_; } + inline const BasicBlock* GetLatchBlock() const { return loop_latch_; } + + // Sets |latch| as the loop unique block branching back to the header. + // A latch block must have the following properties: + // - |latch| must be in the loop; + // - must be the only block branching back to the header block. + void SetLatchBlock(BasicBlock* latch); + + // Sets |continue_block| as the continue block of the loop. This should be the + // continue target of the OpLoopMerge and should dominate the latch block. + void SetContinueBlock(BasicBlock* continue_block); + + // Returns the basic block which marks the end of the loop. + // These functions return nullptr if the loop is not structured. + inline BasicBlock* GetMergeBlock() { return loop_merge_; } + inline const BasicBlock* GetMergeBlock() const { return loop_merge_; } + // Sets |merge| as the loop merge block. A merge block must have the following + // properties: + // - |merge| must not be in the loop; + // - all its predecessors must be in the loop. + // - it must not be already used as merge block. + // If the loop has an OpLoopMerge in its header, this instruction is also + // updated. + void SetMergeBlock(BasicBlock* merge); + + // Returns the loop pre-header, nullptr means that the loop predecessor does + // not qualify as a preheader. + // The preheader is the unique predecessor that: + // - Dominates the loop header; + // - Has only the loop header as successor. + inline BasicBlock* GetPreHeaderBlock() { return loop_preheader_; } + + // Returns the loop pre-header. + inline const BasicBlock* GetPreHeaderBlock() const { return loop_preheader_; } + // Sets |preheader| as the loop preheader block. A preheader block must have + // the following properties: + // - |merge| must not be in the loop; + // - have an unconditional branch to the loop header. + void SetPreHeaderBlock(BasicBlock* preheader); + + // Returns the loop pre-header, if there is no suitable preheader it will be + // created. Returns |nullptr| if it fails to create the preheader. + BasicBlock* GetOrCreatePreHeaderBlock(); + + // Returns true if this loop contains any nested loops. + inline bool HasNestedLoops() const { return nested_loops_.size() != 0; } + + // Clears and fills |exit_blocks| with all basic blocks that are not in the + // loop and has at least one predecessor in the loop. + void GetExitBlocks(std::unordered_set* exit_blocks) const; + + // Clears and fills |merging_blocks| with all basic blocks that are + // post-dominated by the merge block. The merge block must exist. + // The set |merging_blocks| will only contain the merge block if it is + // unreachable. + void GetMergingBlocks(std::unordered_set* merging_blocks) const; + + // Returns true if the loop is in a Loop Closed SSA form. + // In LCSSA form, all in-loop definitions are used in the loop or in phi + // instructions in the loop exit blocks. + bool IsLCSSA() const; + + // Returns the depth of this loop in the loop nest. + // The outer-most loop has a depth of 1. + inline size_t GetDepth() const { + size_t lvl = 1; + for (const Loop* loop = GetParent(); loop; loop = loop->GetParent()) lvl++; + return lvl; + } + + inline size_t NumImmediateChildren() const { return nested_loops_.size(); } + + inline bool HasChildren() const { return !nested_loops_.empty(); } + // Adds |nested| as a nested loop of this loop. Automatically register |this| + // as the parent of |nested|. + inline void AddNestedLoop(Loop* nested) { + assert(!nested->GetParent() && "The loop has another parent."); + nested_loops_.push_back(nested); + nested->SetParent(this); + } + + inline Loop* GetParent() { return parent_; } + inline const Loop* GetParent() const { return parent_; } + + inline bool HasParent() const { return parent_; } + + // Returns true if this loop is itself nested within another loop. + inline bool IsNested() const { return parent_ != nullptr; } + + // Returns the set of all basic blocks contained within the loop. Will be all + // BasicBlocks dominated by the header which are not also dominated by the + // loop merge block. + inline const BasicBlockListTy& GetBlocks() const { + return loop_basic_blocks_; + } + + // Returns true if the basic block |bb| is inside this loop. + inline bool IsInsideLoop(const BasicBlock* bb) const { + return IsInsideLoop(bb->id()); + } + + // Returns true if the basic block id |bb_id| is inside this loop. + inline bool IsInsideLoop(uint32_t bb_id) const { + return loop_basic_blocks_.count(bb_id); + } + + // Returns true if the instruction |inst| is inside this loop. + bool IsInsideLoop(Instruction* inst) const; + + // Adds the Basic Block |bb| to this loop and its parents. + void AddBasicBlock(const BasicBlock* bb) { AddBasicBlock(bb->id()); } + + // Adds the Basic Block with |id| to this loop and its parents. + void AddBasicBlock(uint32_t id) { + for (Loop* loop = this; loop != nullptr; loop = loop->parent_) { + loop->loop_basic_blocks_.insert(id); + } + } + + // Removes the Basic Block id |bb_id| from this loop and its parents. + // It the user responsibility to make sure the removed block is not a merge, + // header or continue block. + void RemoveBasicBlock(uint32_t bb_id) { + for (Loop* loop = this; loop != nullptr; loop = loop->parent_) { + loop->loop_basic_blocks_.erase(bb_id); + } + } + + // Removes all the basic blocks from the set of basic blocks within the loop. + // This does not affect any of the stored pointers to the header, preheader, + // merge, or continue blocks. + void ClearBlocks() { loop_basic_blocks_.clear(); } + + // Adds the Basic Block |bb| this loop and its parents. + void AddBasicBlockToLoop(const BasicBlock* bb) { + assert(IsBasicBlockInLoopSlow(bb) && + "Basic block does not belong to the loop"); + + AddBasicBlock(bb); + } + + // Returns the list of induction variables within the loop. + void GetInductionVariables(std::vector& inductions) const; + + // This function uses the |condition| to find the induction variable which is + // used by the loop condition within the loop. This only works if the loop is + // bound by a single condition and single induction variable. + Instruction* FindConditionVariable(const BasicBlock* condition) const; + + // Returns the number of iterations within a loop when given the |induction| + // variable and the loop |condition| check. It stores the found number of + // iterations in the output parameter |iterations| and optionally, the step + // value in |step_value| and the initial value of the induction variable in + // |init_value|. + bool FindNumberOfIterations(const Instruction* induction, + const Instruction* condition, size_t* iterations, + int64_t* step_amount = nullptr, + int64_t* init_value = nullptr) const; + + // Returns the value of the OpLoopMerge control operand as a bool. Loop + // control can be None(0), Unroll(1), or DontUnroll(2). This function returns + // true if it is set to Unroll. + inline bool HasUnrollLoopControl() const { + assert(loop_header_); + if (!loop_header_->GetLoopMergeInst()) return false; + + return loop_header_->GetLoopMergeInst()->GetSingleWordOperand(2) == 1; + } + + // Finds the conditional block with a branch to the merge and continue blocks + // within the loop body. + BasicBlock* FindConditionBlock() const; + + // Remove the child loop form this loop. + inline void RemoveChildLoop(Loop* loop) { + nested_loops_.erase( + std::find(nested_loops_.begin(), nested_loops_.end(), loop)); + loop->SetParent(nullptr); + } + + // Mark this loop to be removed later by a call to + // LoopDescriptor::PostModificationCleanup. + inline void MarkLoopForRemoval() { loop_is_marked_for_removal_ = true; } + + // Returns whether or not this loop has been marked for removal. + inline bool IsMarkedForRemoval() const { return loop_is_marked_for_removal_; } + + // Returns true if all nested loops have been marked for removal. + inline bool AreAllChildrenMarkedForRemoval() const { + for (const Loop* child : nested_loops_) { + if (!child->IsMarkedForRemoval()) { + return false; + } + } + return true; + } + + // Checks if the loop contains any instruction that will prevent it from being + // cloned. If the loop is structured, the merge construct is also considered. + bool IsSafeToClone() const; + + // Sets the parent loop of this loop, that is, a loop which contains this loop + // as a nested child loop. + inline void SetParent(Loop* parent) { parent_ = parent; } + + // Returns true is the instruction is invariant and safe to move wrt loop. + bool ShouldHoistInstruction(const Instruction& inst) const; + + // Returns true if all operands of inst are in basic blocks not contained in + // loop. + bool AreAllOperandsOutsideLoop(const Instruction& inst) const; + + // Extract the initial value from the |induction| variable and store it in + // |value|. If the function couldn't find the initial value of |induction| + // return false. + bool GetInductionInitValue(const Instruction* induction, + int64_t* value) const; + + // Takes in a phi instruction |induction| and the loop |header| and returns + // the step operation of the loop. + Instruction* GetInductionStepOperation(const Instruction* induction) const; + + // Returns true if we can deduce the number of loop iterations in the step + // operation |step|. IsSupportedCondition must also be true for the condition + // instruction. + bool IsSupportedStepOp(spv::Op step) const; + + // Returns true if we can deduce the number of loop iterations in the + // condition operation |condition|. IsSupportedStepOp must also be true for + // the step instruction. + bool IsSupportedCondition(spv::Op condition) const; + + // Creates the list of the loop's basic block in structured order and store + // the result in |ordered_loop_blocks|. If |include_pre_header| is true, the + // pre-header block will also be included at the beginning of the list if it + // exist. If |include_merge| is true, the merge block will also be included at + // the end of the list if it exist. + void ComputeLoopStructuredOrder(std::vector* ordered_loop_blocks, + bool include_pre_header = false, + bool include_merge = false) const; + + // Given the loop |condition|, |initial_value|, |step_value|, the trip count + // |number_of_iterations|, and the |unroll_factor| requested, get the new + // condition value for the residual loop. + static int64_t GetResidualConditionValue(spv::Op condition, + int64_t initial_value, + int64_t step_value, + size_t number_of_iterations, + size_t unroll_factor); + + // Returns the condition instruction for entry into the loop + // Returns nullptr if it can't be found. + Instruction* GetConditionInst() const; + + // Returns the context associated this loop. + IRContext* GetContext() const { return context_; } + + // Looks at all the blocks with a branch to the header block to find one + // which is also dominated by the loop continue block. This block is the latch + // block. The specification mandates that this block should exist, therefore + // this function will assert if it is not found. + BasicBlock* FindLatchBlock(); + + private: + IRContext* context_; + // The block which marks the start of the loop. + BasicBlock* loop_header_; + + // The block which begins the body of the loop. + BasicBlock* loop_continue_; + + // The block which marks the end of the loop. + BasicBlock* loop_merge_; + + // The block immediately before the loop header. + BasicBlock* loop_preheader_; + + // The block containing the backedge to the loop header. + BasicBlock* loop_latch_; + + // A parent of a loop is the loop which contains it as a nested child loop. + Loop* parent_; + + // Nested child loops of this loop. + ChildrenList nested_loops_; + + // A set of all the basic blocks which comprise the loop structure. Will be + // computed only when needed on demand. + BasicBlockListTy loop_basic_blocks_; + + // Check that |bb| is inside the loop using domination property. + // Note: this is for assertion purposes only, IsInsideLoop should be used + // instead. + bool IsBasicBlockInLoopSlow(const BasicBlock* bb); + + // Returns the loop preheader if it exists, returns nullptr otherwise. + BasicBlock* FindLoopPreheader(DominatorAnalysis* dom_analysis); + + // Sets |latch| as the loop unique latch block. No checks are performed + // here. + inline void SetLatchBlockImpl(BasicBlock* latch) { loop_latch_ = latch; } + // Sets |merge| as the loop merge block. No checks are performed here. + inline void SetMergeBlockImpl(BasicBlock* merge) { loop_merge_ = merge; } + + // Each different loop |condition| affects how we calculate the number of + // iterations using the |condition_value|, |init_value|, and |step_values| of + // the induction variable. This method will return the number of iterations in + // a loop with those values for a given |condition|. Returns 0 if the number + // of iterations could not be computed. + int64_t GetIterations(spv::Op condition, int64_t condition_value, + int64_t init_value, int64_t step_value) const; + + // This is to allow for loops to be removed mid iteration without invalidating + // the iterators. + bool loop_is_marked_for_removal_; + + // This is only to allow LoopDescriptor::placeholder_top_loop_ to add top + // level loops as child. + friend class LoopDescriptor; + friend class LoopUtils; +}; + +// Loop descriptions class for a given function. +// For a given function, the class builds loop nests information. +// The analysis expects a structured control flow. +class LoopDescriptor { + public: + // Iterator interface (depth first postorder traversal). + using iterator = PostOrderTreeDFIterator; + using const_iterator = PostOrderTreeDFIterator; + + using pre_iterator = TreeDFIterator; + using const_pre_iterator = TreeDFIterator; + + // Creates a loop object for all loops found in |f|. + LoopDescriptor(IRContext* context, const Function* f); + + // Disable copy constructor, to avoid double-free on destruction. + LoopDescriptor(const LoopDescriptor&) = delete; + // Move constructor. + LoopDescriptor(LoopDescriptor&& other) : placeholder_top_loop_(nullptr) { + // We need to take ownership of the Loop objects in the other + // LoopDescriptor, to avoid double-free. + loops_ = std::move(other.loops_); + other.loops_.clear(); + basic_block_to_loop_ = std::move(other.basic_block_to_loop_); + other.basic_block_to_loop_.clear(); + placeholder_top_loop_ = std::move(other.placeholder_top_loop_); + } + + // Destructor + ~LoopDescriptor(); + + // Returns the number of loops found in the function. + inline size_t NumLoops() const { return loops_.size(); } + + // Returns the loop at a particular |index|. The |index| must be in bounds, + // check with NumLoops before calling. + inline Loop& GetLoopByIndex(size_t index) const { + assert(loops_.size() > index && + "Index out of range (larger than loop count)"); + return *loops_[index]; + } + + // Returns the loops in |this| in the order their headers appear in the + // binary. + std::vector GetLoopsInBinaryLayoutOrder(); + + // Returns the inner most loop that contains the basic block id |block_id|. + inline Loop* operator[](uint32_t block_id) const { + return FindLoopForBasicBlock(block_id); + } + + // Returns the inner most loop that contains the basic block |bb|. + inline Loop* operator[](const BasicBlock* bb) const { + return (*this)[bb->id()]; + } + + // Iterators for post order depth first traversal of the loops. + // Inner most loops will be visited first. + inline iterator begin() { return iterator::begin(&placeholder_top_loop_); } + inline iterator end() { return iterator::end(&placeholder_top_loop_); } + inline const_iterator begin() const { return cbegin(); } + inline const_iterator end() const { return cend(); } + inline const_iterator cbegin() const { + return const_iterator::begin(&placeholder_top_loop_); + } + inline const_iterator cend() const { + return const_iterator::end(&placeholder_top_loop_); + } + + // Iterators for pre-order depth first traversal of the loops. + // Inner most loops will be visited first. + inline pre_iterator pre_begin() { + return ++pre_iterator(&placeholder_top_loop_); + } + inline pre_iterator pre_end() { return pre_iterator(); } + inline const_pre_iterator pre_begin() const { return pre_cbegin(); } + inline const_pre_iterator pre_end() const { return pre_cend(); } + inline const_pre_iterator pre_cbegin() const { + return ++const_pre_iterator(&placeholder_top_loop_); + } + inline const_pre_iterator pre_cend() const { return const_pre_iterator(); } + + // Returns the inner most loop that contains the basic block |bb|. + inline void SetBasicBlockToLoop(uint32_t bb_id, Loop* loop) { + basic_block_to_loop_[bb_id] = loop; + } + + // Mark the loop |loop_to_add| as needing to be added when the user calls + // PostModificationCleanup. |parent| may be null. + inline void AddLoop(std::unique_ptr&& loop_to_add, Loop* parent) { + loops_to_add_.emplace_back(std::make_pair(parent, std::move(loop_to_add))); + } + + // Checks all loops in |this| and will create pre-headers for all loops + // that don't have one. Returns |true| if any blocks were created. + bool CreatePreHeaderBlocksIfMissing(); + + // Should be called to preserve the LoopAnalysis after loops have been marked + // for addition with AddLoop or MarkLoopForRemoval. + void PostModificationCleanup(); + + // Removes the basic block id |bb_id| from the block to loop mapping. + inline void ForgetBasicBlock(uint32_t bb_id) { + basic_block_to_loop_.erase(bb_id); + } + + // Adds the loop |new_loop| and all its nested loops to the descriptor set. + // The object takes ownership of all the loops. + Loop* AddLoopNest(std::unique_ptr new_loop); + + // Remove the loop |loop|. + void RemoveLoop(Loop* loop); + + void SetAsTopLoop(Loop* loop) { + assert(std::find(placeholder_top_loop_.begin(), placeholder_top_loop_.end(), + loop) == placeholder_top_loop_.end() && + "already registered"); + placeholder_top_loop_.nested_loops_.push_back(loop); + } + + Loop* GetPlaceholderRootLoop() { return &placeholder_top_loop_; } + const Loop* GetPlaceholderRootLoop() const { return &placeholder_top_loop_; } + + private: + // TODO(dneto): This should be a vector of unique_ptr. But VisualStudio 2013 + // is unable to compile it. + using LoopContainerType = std::vector; + + using LoopsToAddContainerType = + std::vector>>; + + // Creates loop descriptors for the function |f|. + void PopulateList(IRContext* context, const Function* f); + + // Returns the inner most loop that contains the basic block id |block_id|. + inline Loop* FindLoopForBasicBlock(uint32_t block_id) const { + std::unordered_map::const_iterator it = + basic_block_to_loop_.find(block_id); + return it != basic_block_to_loop_.end() ? it->second : nullptr; + } + + // Erase all the loop information. + void ClearLoops(); + + // A list of all the loops in the function. This variable owns the Loop + // objects. + LoopContainerType loops_; + + // Placeholder root: this "loop" is only there to help iterators creation. + Loop placeholder_top_loop_; + + std::unordered_map basic_block_to_loop_; + + // List of the loops marked for addition when PostModificationCleanup is + // called. + LoopsToAddContainerType loops_to_add_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_DESCRIPTOR_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_fission.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fission.cpp new file mode 100644 index 000000000000..2ae05c3c3f3b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fission.cpp @@ -0,0 +1,513 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/loop_fission.h" + +#include + +#include "source/opt/register_pressure.h" + +// Implement loop fission with an optional parameter to split only +// if the register pressure in a given loop meets a certain criteria. This is +// controlled via the constructors of LoopFissionPass. +// +// 1 - Build a list of loops to be split, these are top level loops (loops +// without child loops themselves) which meet the register pressure criteria, as +// determined by the ShouldSplitLoop method of LoopFissionPass. +// +// 2 - For each loop in the list, group each instruction into a set of related +// instructions by traversing each instructions users and operands recursively. +// We stop if we encounter an instruction we have seen before or an instruction +// which we don't consider relevant (i.e OpLoopMerge). We then group these +// groups into two different sets, one for the first loop and one for the +// second. +// +// 3 - We then run CanPerformSplit to check that it would be legal to split a +// loop using those two sets. We check that we haven't altered the relative +// order load/stores appear in the binary and that we aren't breaking any +// dependency between load/stores by splitting them into two loops. We also +// check that none of the OpBranch instructions are dependent on a load as we +// leave control flow structure intact and move only instructions in the body so +// we want to avoid any loads with side affects or aliasing. +// +// 4 - We then split the loop by calling SplitLoop. This function clones the +// loop and attaches it to the preheader and connects the new loops merge block +// to the current loop header block. We then use the two sets built in step 2 to +// remove instructions from each loop. If an instruction appears in the first +// set it is removed from the second loop and vice versa. +// +// 5 - If the multiple split passes flag is set we check if each of the loops +// still meet the register pressure criteria. If they do then we add them to the +// list of loops to be split (created in step one) to allow for loops to be +// split multiple times. +// + +namespace spvtools { +namespace opt { + +class LoopFissionImpl { + public: + LoopFissionImpl(IRContext* context, Loop* loop) + : context_(context), loop_(loop), load_used_in_condition_(false) {} + + // Group each instruction in the loop into sets of instructions related by + // their usedef chains. An instruction which uses another will appear in the + // same set. Then merge those sets into just two sets. Returns false if there + // was one or less sets created. + bool GroupInstructionsByUseDef(); + + // Check if the sets built by GroupInstructionsByUseDef violate any data + // dependence rules. + bool CanPerformSplit(); + + // Split the loop and return a pointer to the new loop. + Loop* SplitLoop(); + + // Checks if |inst| is safe to move. We can only move instructions which don't + // have any side effects and OpLoads and OpStores. + bool MovableInstruction(const Instruction& inst) const; + + private: + // Traverse the def use chain of |inst| and add the users and uses of |inst| + // which are in the same loop to the |returned_set|. + void TraverseUseDef(Instruction* inst, std::set* returned_set, + bool ignore_phi_users = false, bool report_loads = false); + + // We group the instructions in the block into two different groups, the + // instructions to be kept in the original loop and the ones to be cloned into + // the new loop. As the cloned loop is attached to the preheader it will be + // the first loop and the second loop will be the original. + std::set cloned_loop_instructions_; + std::set original_loop_instructions_; + + // We need a set of all the instructions to be seen so we can break any + // recursion and also so we can ignore certain instructions by preemptively + // adding them to this set. + std::set seen_instructions_; + + // A map of instructions to their relative position in the function. + std::map instruction_order_; + + IRContext* context_; + + Loop* loop_; + + // This is set to true by TraverseUseDef when traversing the instructions + // related to the loop condition and any if conditions should any of those + // instructions be a load. + bool load_used_in_condition_; +}; + +bool LoopFissionImpl::MovableInstruction(const Instruction& inst) const { + return inst.opcode() == spv::Op::OpLoad || + inst.opcode() == spv::Op::OpStore || + inst.opcode() == spv::Op::OpSelectionMerge || + inst.opcode() == spv::Op::OpPhi || inst.IsOpcodeCodeMotionSafe(); +} + +void LoopFissionImpl::TraverseUseDef(Instruction* inst, + std::set* returned_set, + bool ignore_phi_users, bool report_loads) { + assert(returned_set && "Set to be returned cannot be null."); + + analysis::DefUseManager* def_use = context_->get_def_use_mgr(); + std::set& inst_set = *returned_set; + + // We create this functor to traverse the use def chain to build the + // grouping of related instructions. The lambda captures the std::function + // to allow it to recurse. + std::function traverser_functor; + traverser_functor = [this, def_use, &inst_set, &traverser_functor, + ignore_phi_users, report_loads](Instruction* user) { + // If we've seen the instruction before or it is not inside the loop end the + // traversal. + if (!user || seen_instructions_.count(user) != 0 || + !context_->get_instr_block(user) || + !loop_->IsInsideLoop(context_->get_instr_block(user))) { + return; + } + + // Don't include labels or loop merge instructions in the instruction sets. + // Including them would mean we group instructions related only by using the + // same labels (i.e phis). We already preempt the inclusion of + // OpSelectionMerge by adding related instructions to the seen_instructions_ + // set. + if (user->opcode() == spv::Op::OpLoopMerge || + user->opcode() == spv::Op::OpLabel) + return; + + // If the |report_loads| flag is set, set the class field + // load_used_in_condition_ to false. This is used to check that none of the + // condition checks in the loop rely on loads. + if (user->opcode() == spv::Op::OpLoad && report_loads) { + load_used_in_condition_ = true; + } + + // Add the instruction to the set of instructions already seen, this breaks + // recursion and allows us to ignore certain instructions. + seen_instructions_.insert(user); + + inst_set.insert(user); + + // Wrapper functor to traverse the operands of each instruction. + auto traverse_operand = [&traverser_functor, def_use](const uint32_t* id) { + traverser_functor(def_use->GetDef(*id)); + }; + user->ForEachInOperand(traverse_operand); + + // For the first traversal we want to ignore the users of the phi. + if (ignore_phi_users && user->opcode() == spv::Op::OpPhi) return; + + // Traverse each user with this lambda. + def_use->ForEachUser(user, traverser_functor); + + // Wrapper functor for the use traversal. + auto traverse_use = [&traverser_functor](Instruction* use, uint32_t) { + traverser_functor(use); + }; + def_use->ForEachUse(user, traverse_use); + + }; + + // We start the traversal of the use def graph by invoking the above + // lambda with the |inst| parameter. + traverser_functor(inst); +} + +bool LoopFissionImpl::GroupInstructionsByUseDef() { + std::vector> sets{}; + + // We want to ignore all the instructions stemming from the loop condition + // instruction. + BasicBlock* condition_block = loop_->FindConditionBlock(); + + if (!condition_block) return false; + Instruction* condition = &*condition_block->tail(); + + // We iterate over the blocks via iterating over all the blocks in the + // function, we do this so we are iterating in the same order which the blocks + // appear in the binary. + Function& function = *loop_->GetHeaderBlock()->GetParent(); + + // Create a temporary set to ignore certain groups of instructions within the + // loop. We don't want any instructions related to control flow to be removed + // from either loop only instructions within the control flow bodies. + std::set instructions_to_ignore{}; + TraverseUseDef(condition, &instructions_to_ignore, true, true); + + // Traverse control flow instructions to ensure they are added to the + // seen_instructions_ set and will be ignored when it it called with actual + // sets. + for (BasicBlock& block : function) { + if (!loop_->IsInsideLoop(block.id())) continue; + + for (Instruction& inst : block) { + // Ignore all instructions related to control flow. + if (inst.opcode() == spv::Op::OpSelectionMerge || inst.IsBranch()) { + TraverseUseDef(&inst, &instructions_to_ignore, true, true); + } + } + } + + // Traverse the instructions and generate the sets, automatically ignoring any + // instructions in instructions_to_ignore. + for (BasicBlock& block : function) { + if (!loop_->IsInsideLoop(block.id()) || + loop_->GetHeaderBlock()->id() == block.id()) + continue; + + for (Instruction& inst : block) { + // Record the order that each load/store is seen. + if (inst.opcode() == spv::Op::OpLoad || + inst.opcode() == spv::Op::OpStore) { + instruction_order_[&inst] = instruction_order_.size(); + } + + // Ignore instructions already seen in a traversal. + if (seen_instructions_.count(&inst) != 0) { + continue; + } + + // Build the set. + std::set inst_set{}; + TraverseUseDef(&inst, &inst_set); + if (!inst_set.empty()) sets.push_back(std::move(inst_set)); + } + } + + // If we have one or zero sets return false to indicate that due to + // insufficient instructions we couldn't split the loop into two groups and + // thus the loop can't be split any further. + if (sets.size() < 2) { + return false; + } + + // Merge the loop sets into two different sets. In CanPerformSplit we will + // validate that we don't break the relative ordering of loads/stores by doing + // this. + for (size_t index = 0; index < sets.size() / 2; ++index) { + cloned_loop_instructions_.insert(sets[index].begin(), sets[index].end()); + } + for (size_t index = sets.size() / 2; index < sets.size(); ++index) { + original_loop_instructions_.insert(sets[index].begin(), sets[index].end()); + } + + return true; +} + +bool LoopFissionImpl::CanPerformSplit() { + // Return false if any of the condition instructions in the loop depend on a + // load. + if (load_used_in_condition_) { + return false; + } + + // Build a list of all parent loops of this loop. Loop dependence analysis + // needs this structure. + std::vector loops; + Loop* parent_loop = loop_; + while (parent_loop) { + loops.push_back(parent_loop); + parent_loop = parent_loop->GetParent(); + } + + LoopDependenceAnalysis analysis{context_, loops}; + + // A list of all the stores in the cloned loop. + std::vector set_one_stores{}; + + // A list of all the loads in the cloned loop. + std::vector set_one_loads{}; + + // Populate the above lists. + for (Instruction* inst : cloned_loop_instructions_) { + if (inst->opcode() == spv::Op::OpStore) { + set_one_stores.push_back(inst); + } else if (inst->opcode() == spv::Op::OpLoad) { + set_one_loads.push_back(inst); + } + + // If we find any instruction which we can't move (such as a barrier), + // return false. + if (!MovableInstruction(*inst)) return false; + } + + // We need to calculate the depth of the loop to create the loop dependency + // distance vectors. + const size_t loop_depth = loop_->GetDepth(); + + // Check the dependencies between loads in the cloned loop and stores in the + // original and vice versa. + for (Instruction* inst : original_loop_instructions_) { + // If we find any instruction which we can't move (such as a barrier), + // return false. + if (!MovableInstruction(*inst)) return false; + + // Look at the dependency between the loads in the original and stores in + // the cloned loops. + if (inst->opcode() == spv::Op::OpLoad) { + for (Instruction* store : set_one_stores) { + DistanceVector vec{loop_depth}; + + // If the store actually should appear after the load, return false. + // This means the store has been placed in the wrong grouping. + if (instruction_order_[store] > instruction_order_[inst]) { + return false; + } + // If not independent check the distance vector. + if (!analysis.GetDependence(store, inst, &vec)) { + for (DistanceEntry& entry : vec.GetEntries()) { + // A distance greater than zero means that the store in the cloned + // loop has a dependency on the load in the original loop. + if (entry.distance > 0) return false; + } + } + } + } else if (inst->opcode() == spv::Op::OpStore) { + for (Instruction* load : set_one_loads) { + DistanceVector vec{loop_depth}; + + // If the load actually should appear after the store, return false. + if (instruction_order_[load] > instruction_order_[inst]) { + return false; + } + + // If not independent check the distance vector. + if (!analysis.GetDependence(inst, load, &vec)) { + for (DistanceEntry& entry : vec.GetEntries()) { + // A distance less than zero means the load in the cloned loop is + // dependent on the store instruction in the original loop. + if (entry.distance < 0) return false; + } + } + } + } + } + return true; +} + +Loop* LoopFissionImpl::SplitLoop() { + // Clone the loop. + LoopUtils util{context_, loop_}; + LoopUtils::LoopCloningResult clone_results; + Loop* cloned_loop = util.CloneAndAttachLoopToHeader(&clone_results); + + // Update the OpLoopMerge in the cloned loop. + cloned_loop->UpdateLoopMergeInst(); + + // Add the loop_ to the module. + // TODO(1841): Handle failure to create pre-header. + Function::iterator it = + util.GetFunction()->FindBlock(loop_->GetOrCreatePreHeaderBlock()->id()); + util.GetFunction()->AddBasicBlocks(clone_results.cloned_bb_.begin(), + clone_results.cloned_bb_.end(), ++it); + loop_->SetPreHeaderBlock(cloned_loop->GetMergeBlock()); + + std::vector instructions_to_kill{}; + + // Kill all the instructions which should appear in the cloned loop but not in + // the original loop. + for (uint32_t id : loop_->GetBlocks()) { + BasicBlock* block = context_->cfg()->block(id); + + for (Instruction& inst : *block) { + // If the instruction appears in the cloned loop instruction group, kill + // it. + if (cloned_loop_instructions_.count(&inst) == 1 && + original_loop_instructions_.count(&inst) == 0) { + instructions_to_kill.push_back(&inst); + if (inst.opcode() == spv::Op::OpPhi) { + context_->ReplaceAllUsesWith( + inst.result_id(), clone_results.value_map_[inst.result_id()]); + } + } + } + } + + // Kill all instructions which should appear in the original loop and not in + // the cloned loop. + for (uint32_t id : cloned_loop->GetBlocks()) { + BasicBlock* block = context_->cfg()->block(id); + for (Instruction& inst : *block) { + Instruction* old_inst = clone_results.ptr_map_[&inst]; + // If the instruction belongs to the original loop instruction group, kill + // it. + if (cloned_loop_instructions_.count(old_inst) == 0 && + original_loop_instructions_.count(old_inst) == 1) { + instructions_to_kill.push_back(&inst); + } + } + } + + for (Instruction* i : instructions_to_kill) { + context_->KillInst(i); + } + + return cloned_loop; +} + +LoopFissionPass::LoopFissionPass(const size_t register_threshold_to_split, + bool split_multiple_times) + : split_multiple_times_(split_multiple_times) { + // Split if the number of registers in the loop exceeds + // |register_threshold_to_split|. + split_criteria_ = + [register_threshold_to_split]( + const RegisterLiveness::RegionRegisterLiveness& liveness) { + return liveness.used_registers_ > register_threshold_to_split; + }; +} + +LoopFissionPass::LoopFissionPass() : split_multiple_times_(false) { + // Split by default. + split_criteria_ = [](const RegisterLiveness::RegionRegisterLiveness&) { + return true; + }; +} + +bool LoopFissionPass::ShouldSplitLoop(const Loop& loop, IRContext* c) { + LivenessAnalysis* analysis = c->GetLivenessAnalysis(); + + RegisterLiveness::RegionRegisterLiveness liveness{}; + + Function* function = loop.GetHeaderBlock()->GetParent(); + analysis->Get(function)->ComputeLoopRegisterPressure(loop, &liveness); + + return split_criteria_(liveness); +} + +Pass::Status LoopFissionPass::Process() { + bool changed = false; + + for (Function& f : *context()->module()) { + // We collect all the inner most loops in the function and run the loop + // splitting util on each. The reason we do this is to allow us to iterate + // over each, as creating new loops will invalidate the loop iterator. + std::vector inner_most_loops{}; + LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(&f); + for (Loop& loop : loop_descriptor) { + if (!loop.HasChildren() && ShouldSplitLoop(loop, context())) { + inner_most_loops.push_back(&loop); + } + } + + // List of new loops which meet the criteria to be split again. + std::vector new_loops_to_split{}; + + while (!inner_most_loops.empty()) { + for (Loop* loop : inner_most_loops) { + LoopFissionImpl impl{context(), loop}; + + // Group the instructions in the loop into two different sets of related + // instructions. If we can't group the instructions into the two sets + // then we can't split the loop any further. + if (!impl.GroupInstructionsByUseDef()) { + continue; + } + + if (impl.CanPerformSplit()) { + Loop* second_loop = impl.SplitLoop(); + changed = true; + context()->InvalidateAnalysesExceptFor( + IRContext::kAnalysisLoopAnalysis); + + // If the newly created loop meets the criteria to be split, split it + // again. + if (ShouldSplitLoop(*second_loop, context())) + new_loops_to_split.push_back(second_loop); + + // If the original loop (now split) still meets the criteria to be + // split, split it again. + if (ShouldSplitLoop(*loop, context())) + new_loops_to_split.push_back(loop); + } + } + + // If the split multiple times flag has been set add the new loops which + // meet the splitting criteria into the list of loops to be split on the + // next iteration. + if (split_multiple_times_) { + inner_most_loops = std::move(new_loops_to_split); + } else { + break; + } + } + } + + return changed ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_fission.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fission.h new file mode 100644 index 000000000000..9bc12c0fdbad --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fission.h @@ -0,0 +1,78 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_FISSION_H_ +#define SOURCE_OPT_LOOP_FISSION_H_ + +#include +#include +#include +#include +#include + +#include "source/opt/cfg.h" +#include "source/opt/loop_dependence.h" +#include "source/opt/loop_utils.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" +#include "source/opt/tree_iterator.h" + +namespace spvtools { +namespace opt { + +class LoopFissionPass : public Pass { + public: + // Function used to determine if a given loop should be split. Takes register + // pressure region for that loop as a parameter and returns true if the loop + // should be split. + using FissionCriteriaFunction = + std::function; + + // Pass built with this constructor will split all loops regardless of + // register pressure. Will not split loops more than once. + LoopFissionPass(); + + // Split the loop if the number of registers used in the loop exceeds + // |register_threshold_to_split|. |split_multiple_times| flag determines + // whether or not the pass should split loops after already splitting them + // once. + LoopFissionPass(size_t register_threshold_to_split, + bool split_multiple_times = true); + + // Split loops whose register pressure meets the criteria of |functor|. + LoopFissionPass(FissionCriteriaFunction functor, + bool split_multiple_times = true) + : split_criteria_(functor), split_multiple_times_(split_multiple_times) {} + + const char* name() const override { return "loop-fission"; } + + Pass::Status Process() override; + + // Checks if |loop| meets the register pressure criteria to be split. + bool ShouldSplitLoop(const Loop& loop, IRContext* context); + + private: + // Functor to run in ShouldSplitLoop to determine if the register pressure + // criteria is met for splitting the loop. + FissionCriteriaFunction split_criteria_; + + // Flag designating whether or not we should also split the result of + // previously split loops if they meet the register presure criteria. + bool split_multiple_times_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_FISSION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion.cpp new file mode 100644 index 000000000000..dc6355306636 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion.cpp @@ -0,0 +1,733 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/loop_fusion.h" + +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/loop_dependence.h" +#include "source/opt/loop_descriptor.h" + +namespace spvtools { +namespace opt { +namespace { + +// Append all the loops nested in |loop| to |loops|. +void CollectChildren(Loop* loop, std::vector* loops) { + for (auto child : *loop) { + loops->push_back(child); + if (child->NumImmediateChildren() != 0) { + CollectChildren(child, loops); + } + } +} + +// Return the set of locations accessed by |stores| and |loads|. +std::set GetLocationsAccessed( + const std::map>& stores, + const std::map>& loads) { + std::set locations{}; + + for (const auto& kv : stores) { + locations.insert(std::get<0>(kv)); + } + + for (const auto& kv : loads) { + locations.insert(std::get<0>(kv)); + } + + return locations; +} + +// Append all dependences from |sources| to |destinations| to |dependences|. +void GetDependences(std::vector* dependences, + LoopDependenceAnalysis* analysis, + const std::vector& sources, + const std::vector& destinations, + size_t num_entries) { + for (auto source : sources) { + for (auto destination : destinations) { + DistanceVector dist(num_entries); + if (!analysis->GetDependence(source, destination, &dist)) { + dependences->push_back(dist); + } + } + } +} + +// Apped all instructions in |block| to |instructions|. +void AddInstructionsInBlock(std::vector* instructions, + BasicBlock* block) { + for (auto& inst : *block) { + instructions->push_back(&inst); + } + + instructions->push_back(block->GetLabelInst()); +} + +} // namespace + +bool LoopFusion::UsedInContinueOrConditionBlock(Instruction* phi_instruction, + Loop* loop) { + auto condition_block = loop->FindConditionBlock()->id(); + auto continue_block = loop->GetContinueBlock()->id(); + auto not_used = context_->get_def_use_mgr()->WhileEachUser( + phi_instruction, + [this, condition_block, continue_block](Instruction* instruction) { + auto block_id = context_->get_instr_block(instruction)->id(); + return block_id != condition_block && block_id != continue_block; + }); + + return !not_used; +} + +void LoopFusion::RemoveIfNotUsedContinueOrConditionBlock( + std::vector* instructions, Loop* loop) { + instructions->erase( + std::remove_if(std::begin(*instructions), std::end(*instructions), + [this, loop](Instruction* instruction) { + return !UsedInContinueOrConditionBlock(instruction, + loop); + }), + std::end(*instructions)); +} + +bool LoopFusion::AreCompatible() { + // Check that the loops are in the same function. + if (loop_0_->GetHeaderBlock()->GetParent() != + loop_1_->GetHeaderBlock()->GetParent()) { + return false; + } + + // Check that both loops have pre-header blocks. + if (!loop_0_->GetPreHeaderBlock() || !loop_1_->GetPreHeaderBlock()) { + return false; + } + + // Check there are no breaks. + if (context_->cfg()->preds(loop_0_->GetMergeBlock()->id()).size() != 1 || + context_->cfg()->preds(loop_1_->GetMergeBlock()->id()).size() != 1) { + return false; + } + + // Check there are no continues. + if (context_->cfg()->preds(loop_0_->GetContinueBlock()->id()).size() != 1 || + context_->cfg()->preds(loop_1_->GetContinueBlock()->id()).size() != 1) { + return false; + } + + // |GetInductionVariables| returns all OpPhi in the header. Check that both + // loops have exactly one that is used in the continue and condition blocks. + std::vector inductions_0{}, inductions_1{}; + loop_0_->GetInductionVariables(inductions_0); + RemoveIfNotUsedContinueOrConditionBlock(&inductions_0, loop_0_); + + if (inductions_0.size() != 1) { + return false; + } + + induction_0_ = inductions_0.front(); + + loop_1_->GetInductionVariables(inductions_1); + RemoveIfNotUsedContinueOrConditionBlock(&inductions_1, loop_1_); + + if (inductions_1.size() != 1) { + return false; + } + + induction_1_ = inductions_1.front(); + + if (!CheckInit()) { + return false; + } + + if (!CheckCondition()) { + return false; + } + + if (!CheckStep()) { + return false; + } + + // Check adjacency, |loop_0_| should come just before |loop_1_|. + // There is always at least one block between loops, even if it's empty. + // We'll check at most 2 preceding blocks. + + auto pre_header_1 = loop_1_->GetPreHeaderBlock(); + + std::vector block_to_check{}; + block_to_check.push_back(pre_header_1); + + if (loop_0_->GetMergeBlock() != loop_1_->GetPreHeaderBlock()) { + // Follow CFG for one more block. + auto preds = context_->cfg()->preds(pre_header_1->id()); + if (preds.size() == 1) { + auto block = &*containing_function_->FindBlock(preds.front()); + if (block == loop_0_->GetMergeBlock()) { + block_to_check.push_back(block); + } else { + return false; + } + } else { + return false; + } + } + + // Check that the separating blocks are either empty or only contains a store + // to a local variable that is never read (left behind by + // '--eliminate-local-multi-store'). Also allow OpPhi, since the loop could be + // in LCSSA form. + for (auto block : block_to_check) { + for (auto& inst : *block) { + if (inst.opcode() == spv::Op::OpStore) { + // Get the definition of the target to check it's function scope so + // there are no observable side effects. + auto variable = + context_->get_def_use_mgr()->GetDef(inst.GetSingleWordInOperand(0)); + + if (variable->opcode() != spv::Op::OpVariable || + spv::StorageClass(variable->GetSingleWordInOperand(0)) != + spv::StorageClass::Function) { + return false; + } + + // Check the target is never loaded. + auto is_used = false; + context_->get_def_use_mgr()->ForEachUse( + inst.GetSingleWordInOperand(0), + [&is_used](Instruction* use_inst, uint32_t) { + if (use_inst->opcode() == spv::Op::OpLoad) { + is_used = true; + } + }); + + if (is_used) { + return false; + } + } else if (inst.opcode() == spv::Op::OpPhi) { + if (inst.NumInOperands() != 2) { + return false; + } + } else if (inst.opcode() != spv::Op::OpBranch) { + return false; + } + } + } + + return true; +} // namespace opt + +bool LoopFusion::ContainsBarriersOrFunctionCalls(Loop* loop) { + for (const auto& block : loop->GetBlocks()) { + for (const auto& inst : *containing_function_->FindBlock(block)) { + auto opcode = inst.opcode(); + if (opcode == spv::Op::OpFunctionCall || + opcode == spv::Op::OpControlBarrier || + opcode == spv::Op::OpMemoryBarrier || + opcode == spv::Op::OpTypeNamedBarrier || + opcode == spv::Op::OpNamedBarrierInitialize || + opcode == spv::Op::OpMemoryNamedBarrier) { + return true; + } + } + } + + return false; +} + +bool LoopFusion::CheckInit() { + int64_t loop_0_init; + if (!loop_0_->GetInductionInitValue(induction_0_, &loop_0_init)) { + return false; + } + + int64_t loop_1_init; + if (!loop_1_->GetInductionInitValue(induction_1_, &loop_1_init)) { + return false; + } + + if (loop_0_init != loop_1_init) { + return false; + } + + return true; +} + +bool LoopFusion::CheckCondition() { + auto condition_0 = loop_0_->GetConditionInst(); + auto condition_1 = loop_1_->GetConditionInst(); + + if (!loop_0_->IsSupportedCondition(condition_0->opcode()) || + !loop_1_->IsSupportedCondition(condition_1->opcode())) { + return false; + } + + if (condition_0->opcode() != condition_1->opcode()) { + return false; + } + + for (uint32_t i = 0; i < condition_0->NumInOperandWords(); ++i) { + auto arg_0 = context_->get_def_use_mgr()->GetDef( + condition_0->GetSingleWordInOperand(i)); + auto arg_1 = context_->get_def_use_mgr()->GetDef( + condition_1->GetSingleWordInOperand(i)); + + if (arg_0 == induction_0_ && arg_1 == induction_1_) { + continue; + } + + if (arg_0 == induction_0_ && arg_1 != induction_1_) { + return false; + } + + if (arg_1 == induction_1_ && arg_0 != induction_0_) { + return false; + } + + if (arg_0 != arg_1) { + return false; + } + } + + return true; +} + +bool LoopFusion::CheckStep() { + auto scalar_analysis = context_->GetScalarEvolutionAnalysis(); + SENode* induction_node_0 = scalar_analysis->SimplifyExpression( + scalar_analysis->AnalyzeInstruction(induction_0_)); + if (!induction_node_0->AsSERecurrentNode()) { + return false; + } + + SENode* induction_step_0 = + induction_node_0->AsSERecurrentNode()->GetCoefficient(); + if (!induction_step_0->AsSEConstantNode()) { + return false; + } + + SENode* induction_node_1 = scalar_analysis->SimplifyExpression( + scalar_analysis->AnalyzeInstruction(induction_1_)); + if (!induction_node_1->AsSERecurrentNode()) { + return false; + } + + SENode* induction_step_1 = + induction_node_1->AsSERecurrentNode()->GetCoefficient(); + if (!induction_step_1->AsSEConstantNode()) { + return false; + } + + if (*induction_step_0 != *induction_step_1) { + return false; + } + + return true; +} + +std::map> LoopFusion::LocationToMemOps( + const std::vector& mem_ops) { + std::map> location_map{}; + + for (auto instruction : mem_ops) { + auto access_location = context_->get_def_use_mgr()->GetDef( + instruction->GetSingleWordInOperand(0)); + + while (access_location->opcode() == spv::Op::OpAccessChain) { + access_location = context_->get_def_use_mgr()->GetDef( + access_location->GetSingleWordInOperand(0)); + } + + location_map[access_location].push_back(instruction); + } + + return location_map; +} + +std::pair, std::vector> +LoopFusion::GetLoadsAndStoresInLoop(Loop* loop) { + std::vector loads{}; + std::vector stores{}; + + for (auto block_id : loop->GetBlocks()) { + if (block_id == loop->GetContinueBlock()->id()) { + continue; + } + + for (auto& instruction : *containing_function_->FindBlock(block_id)) { + if (instruction.opcode() == spv::Op::OpLoad) { + loads.push_back(&instruction); + } else if (instruction.opcode() == spv::Op::OpStore) { + stores.push_back(&instruction); + } + } + } + + return std::make_pair(loads, stores); +} + +bool LoopFusion::IsUsedInLoop(Instruction* instruction, Loop* loop) { + auto not_used = context_->get_def_use_mgr()->WhileEachUser( + instruction, [this, loop](Instruction* user) { + auto block_id = context_->get_instr_block(user)->id(); + return !loop->IsInsideLoop(block_id); + }); + + return !not_used; +} + +bool LoopFusion::IsLegal() { + assert(AreCompatible() && "Fusion can't be legal, loops are not compatible."); + + // Bail out if there are function calls as they could have side-effects that + // cause dependencies or if there are any barriers. + if (ContainsBarriersOrFunctionCalls(loop_0_) || + ContainsBarriersOrFunctionCalls(loop_1_)) { + return false; + } + + std::vector phi_instructions{}; + loop_0_->GetInductionVariables(phi_instructions); + + // Check no OpPhi in |loop_0_| is used in |loop_1_|. + for (auto phi_instruction : phi_instructions) { + if (IsUsedInLoop(phi_instruction, loop_1_)) { + return false; + } + } + + // Check no LCSSA OpPhi in merge block of |loop_0_| is used in |loop_1_|. + auto phi_used = false; + loop_0_->GetMergeBlock()->ForEachPhiInst( + [this, &phi_used](Instruction* phi_instruction) { + phi_used |= IsUsedInLoop(phi_instruction, loop_1_); + }); + + if (phi_used) { + return false; + } + + // Grab loads & stores from both loops. + auto loads_stores_0 = GetLoadsAndStoresInLoop(loop_0_); + auto loads_stores_1 = GetLoadsAndStoresInLoop(loop_1_); + + // Build memory location to operation maps. + auto load_locs_0 = LocationToMemOps(std::get<0>(loads_stores_0)); + auto store_locs_0 = LocationToMemOps(std::get<1>(loads_stores_0)); + + auto load_locs_1 = LocationToMemOps(std::get<0>(loads_stores_1)); + auto store_locs_1 = LocationToMemOps(std::get<1>(loads_stores_1)); + + // Get the locations accessed in both loops. + auto locations_0 = GetLocationsAccessed(store_locs_0, load_locs_0); + auto locations_1 = GetLocationsAccessed(store_locs_1, load_locs_1); + + std::vector potential_clashes{}; + + std::set_intersection(std::begin(locations_0), std::end(locations_0), + std::begin(locations_1), std::end(locations_1), + std::back_inserter(potential_clashes)); + + // If the loops don't access the same variables, the fusion is legal. + if (potential_clashes.empty()) { + return true; + } + + // Find variables that have at least one store. + std::vector potential_clashes_with_stores{}; + for (auto location : potential_clashes) { + if (store_locs_0.find(location) != std::end(store_locs_0) || + store_locs_1.find(location) != std::end(store_locs_1)) { + potential_clashes_with_stores.push_back(location); + } + } + + // If there are only loads to the same variables, the fusion is legal. + if (potential_clashes_with_stores.empty()) { + return true; + } + + // Else if loads and at least one store (across loops) to the same variable + // there is a potential dependence and we need to check the dependence + // distance. + + // Find all the loops in this loop nest for the dependency analysis. + std::vector loops{}; + + // Find the parents. + for (auto current_loop = loop_0_; current_loop != nullptr; + current_loop = current_loop->GetParent()) { + loops.push_back(current_loop); + } + + auto this_loop_position = loops.size() - 1; + std::reverse(std::begin(loops), std::end(loops)); + + // Find the children. + CollectChildren(loop_0_, &loops); + CollectChildren(loop_1_, &loops); + + // Check that any dependes created are legal. That means the fused loops do + // not have any dependencies with dependence distance greater than 0 that did + // not exist in the original loops. + + LoopDependenceAnalysis analysis(context_, loops); + + analysis.GetScalarEvolution()->AddLoopsToPretendAreTheSame( + {loop_0_, loop_1_}); + + for (auto location : potential_clashes_with_stores) { + // Analyse dependences from |loop_0_| to |loop_1_|. + std::vector dependences; + // Read-After-Write. + GetDependences(&dependences, &analysis, store_locs_0[location], + load_locs_1[location], loops.size()); + // Write-After-Read. + GetDependences(&dependences, &analysis, load_locs_0[location], + store_locs_1[location], loops.size()); + // Write-After-Write. + GetDependences(&dependences, &analysis, store_locs_0[location], + store_locs_1[location], loops.size()); + + // Check that the induction variables either don't appear in the subscripts + // or the dependence distance is negative. + for (const auto& dependence : dependences) { + const auto& entry = dependence.GetEntries()[this_loop_position]; + if ((entry.dependence_information == + DistanceEntry::DependenceInformation::DISTANCE && + entry.distance < 1) || + (entry.dependence_information == + DistanceEntry::DependenceInformation::IRRELEVANT)) { + continue; + } else { + return false; + } + } + } + + return true; +} + +void ReplacePhiParentWith(Instruction* inst, uint32_t orig_block, + uint32_t new_block) { + if (inst->GetSingleWordInOperand(1) == orig_block) { + inst->SetInOperand(1, {new_block}); + } else { + inst->SetInOperand(3, {new_block}); + } +} + +void LoopFusion::Fuse() { + assert(AreCompatible() && "Can't fuse, loops aren't compatible"); + assert(IsLegal() && "Can't fuse, illegal"); + + // Save the pointers/ids, won't be found in the middle of doing modifications. + auto header_1 = loop_1_->GetHeaderBlock()->id(); + auto condition_1 = loop_1_->FindConditionBlock()->id(); + auto continue_1 = loop_1_->GetContinueBlock()->id(); + auto continue_0 = loop_0_->GetContinueBlock()->id(); + auto condition_block_of_0 = loop_0_->FindConditionBlock(); + + // Find the blocks whose branches need updating. + auto first_block_of_1 = &*(++containing_function_->FindBlock(condition_1)); + auto last_block_of_1 = &*(--containing_function_->FindBlock(continue_1)); + auto last_block_of_0 = &*(--containing_function_->FindBlock(continue_0)); + + // Update the branch for |last_block_of_loop_0| to go to |first_block_of_1|. + last_block_of_0->ForEachSuccessorLabel( + [first_block_of_1](uint32_t* succ) { *succ = first_block_of_1->id(); }); + + // Update the branch for the |last_block_of_loop_1| to go to the continue + // block of |loop_0_|. + last_block_of_1->ForEachSuccessorLabel( + [this](uint32_t* succ) { *succ = loop_0_->GetContinueBlock()->id(); }); + + // Update merge block id in the header of |loop_0_| to the merge block of + // |loop_1_|. + loop_0_->GetHeaderBlock()->ForEachInst([this](Instruction* inst) { + if (inst->opcode() == spv::Op::OpLoopMerge) { + inst->SetInOperand(0, {loop_1_->GetMergeBlock()->id()}); + } + }); + + // Update condition branch target in |loop_0_| to the merge block of + // |loop_1_|. + condition_block_of_0->ForEachInst([this](Instruction* inst) { + if (inst->opcode() == spv::Op::OpBranchConditional) { + auto loop_0_merge_block_id = loop_0_->GetMergeBlock()->id(); + + if (inst->GetSingleWordInOperand(1) == loop_0_merge_block_id) { + inst->SetInOperand(1, {loop_1_->GetMergeBlock()->id()}); + } else { + inst->SetInOperand(2, {loop_1_->GetMergeBlock()->id()}); + } + } + }); + + // Move OpPhi instructions not corresponding to the induction variable from + // the header of |loop_1_| to the header of |loop_0_|. + std::vector instructions_to_move{}; + for (auto& instruction : *loop_1_->GetHeaderBlock()) { + if (instruction.opcode() == spv::Op::OpPhi && + &instruction != induction_1_) { + instructions_to_move.push_back(&instruction); + } + } + + for (auto& it : instructions_to_move) { + it->RemoveFromList(); + it->InsertBefore(induction_0_); + } + + // Update the OpPhi parents to the correct blocks in |loop_0_|. + loop_0_->GetHeaderBlock()->ForEachPhiInst([this](Instruction* i) { + ReplacePhiParentWith(i, loop_1_->GetPreHeaderBlock()->id(), + loop_0_->GetPreHeaderBlock()->id()); + + ReplacePhiParentWith(i, loop_1_->GetContinueBlock()->id(), + loop_0_->GetContinueBlock()->id()); + }); + + // Update instruction to block mapping & DefUseManager. + for (auto& phi_instruction : instructions_to_move) { + context_->set_instr_block(phi_instruction, loop_0_->GetHeaderBlock()); + context_->get_def_use_mgr()->AnalyzeInstUse(phi_instruction); + } + + // Replace the uses of the induction variable of |loop_1_| with that the + // induction variable of |loop_0_|. + context_->ReplaceAllUsesWith(induction_1_->result_id(), + induction_0_->result_id()); + + // Replace LCSSA OpPhi in merge block of |loop_0_|. + loop_0_->GetMergeBlock()->ForEachPhiInst([this](Instruction* instruction) { + context_->ReplaceAllUsesWith(instruction->result_id(), + instruction->GetSingleWordInOperand(0)); + }); + + // Update LCSSA OpPhi in merge block of |loop_1_|. + loop_1_->GetMergeBlock()->ForEachPhiInst( + [condition_block_of_0](Instruction* instruction) { + instruction->SetInOperand(1, {condition_block_of_0->id()}); + }); + + // Move the continue block of |loop_0_| after the last block of |loop_1_|. + containing_function_->MoveBasicBlockToAfter(continue_0, last_block_of_1); + + // Gather all instructions to be killed from |loop_1_| (induction variable + // initialisation, header, condition and continue blocks). + std::vector instr_to_delete{}; + AddInstructionsInBlock(&instr_to_delete, loop_1_->GetPreHeaderBlock()); + AddInstructionsInBlock(&instr_to_delete, loop_1_->GetHeaderBlock()); + AddInstructionsInBlock(&instr_to_delete, loop_1_->FindConditionBlock()); + AddInstructionsInBlock(&instr_to_delete, loop_1_->GetContinueBlock()); + + // There was an additional empty block between the loops, kill that too. + if (loop_0_->GetMergeBlock() != loop_1_->GetPreHeaderBlock()) { + AddInstructionsInBlock(&instr_to_delete, loop_0_->GetMergeBlock()); + } + + // Update the CFG, so it wouldn't need invalidating. + auto cfg = context_->cfg(); + + cfg->ForgetBlock(loop_1_->GetPreHeaderBlock()); + cfg->ForgetBlock(loop_1_->GetHeaderBlock()); + cfg->ForgetBlock(loop_1_->FindConditionBlock()); + cfg->ForgetBlock(loop_1_->GetContinueBlock()); + + if (loop_0_->GetMergeBlock() != loop_1_->GetPreHeaderBlock()) { + cfg->ForgetBlock(loop_0_->GetMergeBlock()); + } + + cfg->RemoveEdge(last_block_of_0->id(), loop_0_->GetContinueBlock()->id()); + cfg->AddEdge(last_block_of_0->id(), first_block_of_1->id()); + + cfg->AddEdge(last_block_of_1->id(), loop_0_->GetContinueBlock()->id()); + + cfg->AddEdge(loop_0_->GetContinueBlock()->id(), + loop_1_->GetHeaderBlock()->id()); + + cfg->AddEdge(condition_block_of_0->id(), loop_1_->GetMergeBlock()->id()); + + // Update DefUseManager. + auto def_use_mgr = context_->get_def_use_mgr(); + + // Uses of labels that are in updated branches need analysing. + def_use_mgr->AnalyzeInstUse(last_block_of_0->terminator()); + def_use_mgr->AnalyzeInstUse(last_block_of_1->terminator()); + def_use_mgr->AnalyzeInstUse(loop_0_->GetHeaderBlock()->GetLoopMergeInst()); + def_use_mgr->AnalyzeInstUse(condition_block_of_0->terminator()); + + // Update the LoopDescriptor, so it wouldn't need invalidating. + auto ld = context_->GetLoopDescriptor(containing_function_); + + // Create a copy, so the iterator wouldn't be invalidated. + std::vector loops_to_add_remove{}; + for (auto child_loop : *loop_1_) { + loops_to_add_remove.push_back(child_loop); + } + + for (auto child_loop : loops_to_add_remove) { + loop_1_->RemoveChildLoop(child_loop); + loop_0_->AddNestedLoop(child_loop); + } + + auto loop_1_blocks = loop_1_->GetBlocks(); + + for (auto block : loop_1_blocks) { + loop_1_->RemoveBasicBlock(block); + if (block != header_1 && block != condition_1 && block != continue_1) { + loop_0_->AddBasicBlock(block); + if ((*ld)[block] == loop_1_) { + ld->SetBasicBlockToLoop(block, loop_0_); + } + } + + if ((*ld)[block] == loop_1_) { + ld->ForgetBasicBlock(block); + } + } + + loop_1_->RemoveBasicBlock(loop_1_->GetPreHeaderBlock()->id()); + ld->ForgetBasicBlock(loop_1_->GetPreHeaderBlock()->id()); + + if (loop_0_->GetMergeBlock() != loop_1_->GetPreHeaderBlock()) { + loop_0_->RemoveBasicBlock(loop_0_->GetMergeBlock()->id()); + ld->ForgetBasicBlock(loop_0_->GetMergeBlock()->id()); + } + + loop_0_->SetMergeBlock(loop_1_->GetMergeBlock()); + + loop_1_->ClearBlocks(); + + ld->RemoveLoop(loop_1_); + + // Kill unnecessary instructions and remove all empty blocks. + for (auto inst : instr_to_delete) { + context_->KillInst(inst); + } + + containing_function_->RemoveEmptyBlocks(); + + // Invalidate analyses. + context_->InvalidateAnalysesExceptFor( + IRContext::Analysis::kAnalysisInstrToBlockMapping | + IRContext::Analysis::kAnalysisLoopAnalysis | + IRContext::Analysis::kAnalysisDefUse | IRContext::Analysis::kAnalysisCFG); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion.h new file mode 100644 index 000000000000..769da5f1afee --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion.h @@ -0,0 +1,114 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_FUSION_H_ +#define SOURCE_OPT_LOOP_FUSION_H_ + +#include +#include +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/loop_descriptor.h" +#include "source/opt/loop_utils.h" +#include "source/opt/scalar_analysis.h" + +namespace spvtools { +namespace opt { + +class LoopFusion { + public: + LoopFusion(IRContext* context, Loop* loop_0, Loop* loop_1) + : context_(context), + loop_0_(loop_0), + loop_1_(loop_1), + containing_function_(loop_0->GetHeaderBlock()->GetParent()) {} + + // Checks if the |loop_0| and |loop_1| are compatible for fusion. + // That means: + // * they both have one induction variable + // * they have the same upper and lower bounds + // - same initial value + // - same condition + // * they have the same update step + // * they are adjacent, with |loop_0| appearing before |loop_1| + // * there are no break/continue in either of them + // * they both have pre-header blocks (required for ScalarEvolutionAnalysis + // and dependence checking). + bool AreCompatible(); + + // Checks if compatible |loop_0| and |loop_1| are legal to fuse. + // * fused loops do not have any dependencies with dependence distance greater + // than 0 that did not exist in the original loops. + // * there are no function calls in the loops (could have side-effects) + bool IsLegal(); + + // Perform the actual fusion of |loop_0_| and |loop_1_|. The loops have to be + // compatible and the fusion has to be legal. + void Fuse(); + + private: + // Check that the initial values are the same. + bool CheckInit(); + + // Check that the conditions are the same. + bool CheckCondition(); + + // Check that the steps are the same. + bool CheckStep(); + + // Returns |true| if |instruction| is used in the continue or condition block + // of |loop|. + bool UsedInContinueOrConditionBlock(Instruction* instruction, Loop* loop); + + // Remove entries in |instructions| that are not used in the continue or + // condition block of |loop|. + void RemoveIfNotUsedContinueOrConditionBlock( + std::vector* instructions, Loop* loop); + + // Returns |true| if |instruction| is used in |loop|. + bool IsUsedInLoop(Instruction* instruction, Loop* loop); + + // Returns |true| if |loop| has at least one barrier or function call. + bool ContainsBarriersOrFunctionCalls(Loop* loop); + + // Get all instructions in the |loop| (except in the latch block) that have + // the opcode |opcode|. + std::pair, std::vector> + GetLoadsAndStoresInLoop(Loop* loop); + + // Given a vector of memory operations (OpLoad/OpStore), constructs a map from + // variables to the loads/stores that those variables. + std::map> LocationToMemOps( + const std::vector& mem_ops); + + IRContext* context_; + + // The original loops to be fused. + Loop* loop_0_; + Loop* loop_1_; + + // The function that contains |loop_0_| and |loop_1_|. + Function* containing_function_ = nullptr; + + // The induction variables for |loop_0_| and |loop_1_|. + Instruction* induction_0_ = nullptr; + Instruction* induction_1_ = nullptr; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_FUSION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion_pass.cpp new file mode 100644 index 000000000000..097430fcf121 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion_pass.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/loop_fusion_pass.h" + +#include "source/opt/loop_descriptor.h" +#include "source/opt/loop_fusion.h" +#include "source/opt/register_pressure.h" + +namespace spvtools { +namespace opt { + +Pass::Status LoopFusionPass::Process() { + bool modified = false; + Module* module = context()->module(); + + // Process each function in the module + for (Function& f : *module) { + modified |= ProcessFunction(&f); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool LoopFusionPass::ProcessFunction(Function* function) { + LoopDescriptor& ld = *context()->GetLoopDescriptor(function); + + // If a loop doesn't have a preheader needs then it needs to be created. Make + // sure to return Status::SuccessWithChange in that case. + auto modified = ld.CreatePreHeaderBlocksIfMissing(); + + // TODO(tremmelg): Could the only loop that |loop| could possibly be fused be + // picked out so don't have to check every loop + for (auto& loop_0 : ld) { + for (auto& loop_1 : ld) { + LoopFusion fusion(context(), &loop_0, &loop_1); + + if (fusion.AreCompatible() && fusion.IsLegal()) { + RegisterLiveness liveness(context(), function); + RegisterLiveness::RegionRegisterLiveness reg_pressure{}; + liveness.SimulateFusion(loop_0, loop_1, ®_pressure); + + if (reg_pressure.used_registers_ <= max_registers_per_loop_) { + fusion.Fuse(); + // Recurse, as the current iterators will have been invalidated. + ProcessFunction(function); + return true; + } + } + } + } + + return modified; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion_pass.h new file mode 100644 index 000000000000..9d5b7ccdae05 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_fusion_pass.h @@ -0,0 +1,51 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_FUSION_PASS_H_ +#define SOURCE_OPT_LOOP_FUSION_PASS_H_ + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// Implements a loop fusion pass. +// This pass will look for adjacent loops that are compatible and legal to be +// fused. It will fuse all such loops as long as the register usage for the +// fused loop stays under the threshold defined by |max_registers_per_loop|. +class LoopFusionPass : public Pass { + public: + explicit LoopFusionPass(size_t max_registers_per_loop) + : Pass(), max_registers_per_loop_(max_registers_per_loop) {} + + const char* name() const override { return "loop-fusion"; } + + // Processes the given |module|. Returns Status::Failure if errors occur when + // processing. Returns the corresponding Status::Success if processing is + // successful to indicate whether changes have been made to the module. + Status Process() override; + + private: + // Fuse loops in |function| if compatible, legal and the fused loop won't use + // too many registers. + bool ProcessFunction(Function* function); + + // The maximum number of registers a fused loop is allowed to use. + size_t max_registers_per_loop_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_FUSION_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_peeling.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_peeling.cpp new file mode 100644 index 000000000000..25c6db1207d2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_peeling.cpp @@ -0,0 +1,1086 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/loop_peeling.h" + +#include +#include +#include +#include + +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/opt/loop_descriptor.h" +#include "source/opt/loop_utils.h" +#include "source/opt/scalar_analysis.h" +#include "source/opt/scalar_analysis_nodes.h" + +namespace spvtools { +namespace opt { +namespace { +// Gather the set of blocks for all the path from |entry| to |root|. +void GetBlocksInPath(uint32_t block, uint32_t entry, + std::unordered_set* blocks_in_path, + const CFG& cfg) { + for (uint32_t pid : cfg.preds(block)) { + if (blocks_in_path->insert(pid).second) { + if (pid != entry) { + GetBlocksInPath(pid, entry, blocks_in_path, cfg); + } + } + } +} +} // namespace + +size_t LoopPeelingPass::code_grow_threshold_ = 1000; + +void LoopPeeling::DuplicateAndConnectLoop( + LoopUtils::LoopCloningResult* clone_results) { + CFG& cfg = *context_->cfg(); + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + assert(CanPeelLoop() && "Cannot peel loop!"); + + std::vector ordered_loop_blocks; + // TODO(1841): Handle failure to create pre-header. + BasicBlock* pre_header = loop_->GetOrCreatePreHeaderBlock(); + + loop_->ComputeLoopStructuredOrder(&ordered_loop_blocks); + + cloned_loop_ = loop_utils_.CloneLoop(clone_results, ordered_loop_blocks); + + // Add the basic block to the function. + Function::iterator it = + loop_utils_.GetFunction()->FindBlock(pre_header->id()); + assert(it != loop_utils_.GetFunction()->end() && + "Pre-header not found in the function."); + loop_utils_.GetFunction()->AddBasicBlocks( + clone_results->cloned_bb_.begin(), clone_results->cloned_bb_.end(), ++it); + + // Make the |loop_|'s preheader the |cloned_loop_| one. + BasicBlock* cloned_header = cloned_loop_->GetHeaderBlock(); + pre_header->ForEachSuccessorLabel( + [cloned_header](uint32_t* succ) { *succ = cloned_header->id(); }); + + // Update cfg. + cfg.RemoveEdge(pre_header->id(), loop_->GetHeaderBlock()->id()); + cloned_loop_->SetPreHeaderBlock(pre_header); + loop_->SetPreHeaderBlock(nullptr); + + // When cloning the loop, we didn't cloned the merge block, so currently + // |cloned_loop_| shares the same block as |loop_|. + // We mutate all branches from |cloned_loop_| block to |loop_|'s merge into a + // branch to |loop_|'s header (so header will also be the merge of + // |cloned_loop_|). + uint32_t cloned_loop_exit = 0; + for (uint32_t pred_id : cfg.preds(loop_->GetMergeBlock()->id())) { + if (loop_->IsInsideLoop(pred_id)) continue; + BasicBlock* bb = cfg.block(pred_id); + assert(cloned_loop_exit == 0 && "The loop has multiple exits."); + cloned_loop_exit = bb->id(); + bb->ForEachSuccessorLabel([this](uint32_t* succ) { + if (*succ == loop_->GetMergeBlock()->id()) + *succ = loop_->GetHeaderBlock()->id(); + }); + } + + // Update cfg. + cfg.RemoveNonExistingEdges(loop_->GetMergeBlock()->id()); + cfg.AddEdge(cloned_loop_exit, loop_->GetHeaderBlock()->id()); + + // Patch the phi of the original loop header: + // - Set the loop entry branch to come from the cloned loop exit block; + // - Set the initial value of the phi using the corresponding cloned loop + // exit values. + // + // We patch the iterating value initializers of the original loop using the + // corresponding cloned loop exit values. Connects the cloned loop iterating + // values to the original loop. This make sure that the initial value of the + // second loop starts with the last value of the first loop. + // + // For example, loops like: + // + // int z = 0; + // for (int i = 0; i++ < M; i += cst1) { + // if (cond) + // z += cst2; + // } + // + // Will become: + // + // int z = 0; + // int i = 0; + // for (; i++ < M; i += cst1) { + // if (cond) + // z += cst2; + // } + // for (; i++ < M; i += cst1) { + // if (cond) + // z += cst2; + // } + loop_->GetHeaderBlock()->ForEachPhiInst([cloned_loop_exit, def_use_mgr, + clone_results, + this](Instruction* phi) { + for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) { + if (!loop_->IsInsideLoop(phi->GetSingleWordInOperand(i + 1))) { + phi->SetInOperand(i, + {clone_results->value_map_.at( + exit_value_.at(phi->result_id())->result_id())}); + phi->SetInOperand(i + 1, {cloned_loop_exit}); + def_use_mgr->AnalyzeInstUse(phi); + return; + } + } + }); + + // Force the creation of a new preheader for the original loop and set it as + // the merge block for the cloned loop. + // TODO(1841): Handle failure to create pre-header. + cloned_loop_->SetMergeBlock(loop_->GetOrCreatePreHeaderBlock()); +} + +void LoopPeeling::InsertCanonicalInductionVariable( + LoopUtils::LoopCloningResult* clone_results) { + if (original_loop_canonical_induction_variable_) { + canonical_induction_variable_ = + context_->get_def_use_mgr()->GetDef(clone_results->value_map_.at( + original_loop_canonical_induction_variable_->result_id())); + return; + } + + BasicBlock::iterator insert_point = GetClonedLoop()->GetLatchBlock()->tail(); + if (GetClonedLoop()->GetLatchBlock()->GetMergeInst()) { + --insert_point; + } + InstructionBuilder builder( + context_, &*insert_point, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + Instruction* uint_1_cst = + builder.GetIntConstant(1, int_type_->IsSigned()); + // Create the increment. + // Note that we do "1 + 1" here, one of the operand should the phi + // value but we don't have it yet. The operand will be set latter. + Instruction* iv_inc = builder.AddIAdd( + uint_1_cst->type_id(), uint_1_cst->result_id(), uint_1_cst->result_id()); + + builder.SetInsertPoint(&*GetClonedLoop()->GetHeaderBlock()->begin()); + + canonical_induction_variable_ = builder.AddPhi( + uint_1_cst->type_id(), + {builder.GetIntConstant(0, int_type_->IsSigned())->result_id(), + GetClonedLoop()->GetPreHeaderBlock()->id(), iv_inc->result_id(), + GetClonedLoop()->GetLatchBlock()->id()}); + // Connect everything. + iv_inc->SetInOperand(0, {canonical_induction_variable_->result_id()}); + + // Update def/use manager. + context_->get_def_use_mgr()->AnalyzeInstUse(iv_inc); + + // If do-while form, use the incremented value. + if (do_while_form_) { + canonical_induction_variable_ = iv_inc; + } +} + +void LoopPeeling::GetIteratorUpdateOperations( + const Loop* loop, Instruction* iterator, + std::unordered_set* operations) { + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + operations->insert(iterator); + iterator->ForEachInId([def_use_mgr, loop, operations, this](uint32_t* id) { + Instruction* insn = def_use_mgr->GetDef(*id); + if (insn->opcode() == spv::Op::OpLabel) { + return; + } + if (operations->count(insn)) { + return; + } + if (!loop->IsInsideLoop(insn)) { + return; + } + GetIteratorUpdateOperations(loop, insn, operations); + }); +} + +bool LoopPeeling::IsConditionCheckSideEffectFree() const { + CFG& cfg = *context_->cfg(); + + // The "do-while" form does not cause issues, the algorithm takes into account + // the first iteration. + if (!do_while_form_) { + uint32_t condition_block_id = cfg.preds(loop_->GetMergeBlock()->id())[0]; + + std::unordered_set blocks_in_path; + + blocks_in_path.insert(condition_block_id); + GetBlocksInPath(condition_block_id, loop_->GetHeaderBlock()->id(), + &blocks_in_path, cfg); + + for (uint32_t bb_id : blocks_in_path) { + BasicBlock* bb = cfg.block(bb_id); + if (!bb->WhileEachInst([this](Instruction* insn) { + if (insn->IsBranch()) return true; + switch (insn->opcode()) { + case spv::Op::OpLabel: + case spv::Op::OpSelectionMerge: + case spv::Op::OpLoopMerge: + return true; + default: + break; + } + return context_->IsCombinatorInstruction(insn); + })) { + return false; + } + } + } + + return true; +} + +void LoopPeeling::GetIteratingExitValues() { + CFG& cfg = *context_->cfg(); + + loop_->GetHeaderBlock()->ForEachPhiInst( + [this](Instruction* phi) { exit_value_[phi->result_id()] = nullptr; }); + + if (!loop_->GetMergeBlock()) { + return; + } + if (cfg.preds(loop_->GetMergeBlock()->id()).size() != 1) { + return; + } + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + uint32_t condition_block_id = cfg.preds(loop_->GetMergeBlock()->id())[0]; + + auto& header_pred = cfg.preds(loop_->GetHeaderBlock()->id()); + do_while_form_ = std::find(header_pred.begin(), header_pred.end(), + condition_block_id) != header_pred.end(); + if (do_while_form_) { + loop_->GetHeaderBlock()->ForEachPhiInst( + [condition_block_id, def_use_mgr, this](Instruction* phi) { + std::unordered_set operations; + + for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) { + if (condition_block_id == phi->GetSingleWordInOperand(i + 1)) { + exit_value_[phi->result_id()] = + def_use_mgr->GetDef(phi->GetSingleWordInOperand(i)); + } + } + }); + } else { + DominatorTree* dom_tree = + &context_->GetDominatorAnalysis(loop_utils_.GetFunction()) + ->GetDomTree(); + BasicBlock* condition_block = cfg.block(condition_block_id); + + loop_->GetHeaderBlock()->ForEachPhiInst( + [dom_tree, condition_block, this](Instruction* phi) { + std::unordered_set operations; + + // Not the back-edge value, check if the phi instruction is the only + // possible candidate. + GetIteratorUpdateOperations(loop_, phi, &operations); + + for (Instruction* insn : operations) { + if (insn == phi) { + continue; + } + if (dom_tree->Dominates(context_->get_instr_block(insn), + condition_block)) { + return; + } + } + exit_value_[phi->result_id()] = phi; + }); + } +} + +void LoopPeeling::FixExitCondition( + const std::function& condition_builder) { + CFG& cfg = *context_->cfg(); + + uint32_t condition_block_id = 0; + for (uint32_t id : cfg.preds(GetClonedLoop()->GetMergeBlock()->id())) { + if (GetClonedLoop()->IsInsideLoop(id)) { + condition_block_id = id; + break; + } + } + assert(condition_block_id != 0 && "2nd loop in improperly connected"); + + BasicBlock* condition_block = cfg.block(condition_block_id); + Instruction* exit_condition = condition_block->terminator(); + assert(exit_condition->opcode() == spv::Op::OpBranchConditional); + BasicBlock::iterator insert_point = condition_block->tail(); + if (condition_block->GetMergeInst()) { + --insert_point; + } + + exit_condition->SetInOperand(0, {condition_builder(&*insert_point)}); + + uint32_t to_continue_block_idx = + GetClonedLoop()->IsInsideLoop(exit_condition->GetSingleWordInOperand(1)) + ? 1 + : 2; + exit_condition->SetInOperand( + 1, {exit_condition->GetSingleWordInOperand(to_continue_block_idx)}); + exit_condition->SetInOperand(2, {GetClonedLoop()->GetMergeBlock()->id()}); + + // Update def/use manager. + context_->get_def_use_mgr()->AnalyzeInstUse(exit_condition); +} + +BasicBlock* LoopPeeling::CreateBlockBefore(BasicBlock* bb) { + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + CFG& cfg = *context_->cfg(); + assert(cfg.preds(bb->id()).size() == 1 && "More than one predecessor"); + + // TODO(1841): Handle id overflow. + std::unique_ptr new_bb = + MakeUnique(std::unique_ptr(new Instruction( + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))); + // Update the loop descriptor. + Loop* in_loop = (*loop_utils_.GetLoopDescriptor())[bb]; + if (in_loop) { + in_loop->AddBasicBlock(new_bb.get()); + loop_utils_.GetLoopDescriptor()->SetBasicBlockToLoop(new_bb->id(), in_loop); + } + + context_->set_instr_block(new_bb->GetLabelInst(), new_bb.get()); + def_use_mgr->AnalyzeInstDefUse(new_bb->GetLabelInst()); + + BasicBlock* bb_pred = cfg.block(cfg.preds(bb->id())[0]); + bb_pred->tail()->ForEachInId([bb, &new_bb](uint32_t* id) { + if (*id == bb->id()) { + *id = new_bb->id(); + } + }); + cfg.RemoveEdge(bb_pred->id(), bb->id()); + cfg.AddEdge(bb_pred->id(), new_bb->id()); + def_use_mgr->AnalyzeInstUse(&*bb_pred->tail()); + + // Update the incoming branch. + bb->ForEachPhiInst([&new_bb, def_use_mgr](Instruction* phi) { + phi->SetInOperand(1, {new_bb->id()}); + def_use_mgr->AnalyzeInstUse(phi); + }); + InstructionBuilder( + context_, new_bb.get(), + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping) + .AddBranch(bb->id()); + cfg.RegisterBlock(new_bb.get()); + + // Add the basic block to the function. + Function::iterator it = loop_utils_.GetFunction()->FindBlock(bb->id()); + assert(it != loop_utils_.GetFunction()->end() && + "Basic block not found in the function."); + BasicBlock* ret = new_bb.get(); + loop_utils_.GetFunction()->AddBasicBlock(std::move(new_bb), it); + return ret; +} + +BasicBlock* LoopPeeling::ProtectLoop(Loop* loop, Instruction* condition, + BasicBlock* if_merge) { + // TODO(1841): Handle failure to create pre-header. + BasicBlock* if_block = loop->GetOrCreatePreHeaderBlock(); + // Will no longer be a pre-header because of the if. + loop->SetPreHeaderBlock(nullptr); + // Kill the branch to the header. + context_->KillInst(&*if_block->tail()); + + InstructionBuilder builder( + context_, if_block, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + builder.AddConditionalBranch(condition->result_id(), + loop->GetHeaderBlock()->id(), if_merge->id(), + if_merge->id()); + + return if_block; +} + +void LoopPeeling::PeelBefore(uint32_t peel_factor) { + assert(CanPeelLoop() && "Cannot peel loop"); + LoopUtils::LoopCloningResult clone_results; + + // Clone the loop and insert the cloned one before the loop. + DuplicateAndConnectLoop(&clone_results); + + // Add a canonical induction variable "canonical_induction_variable_". + InsertCanonicalInductionVariable(&clone_results); + + InstructionBuilder builder( + context_, &*cloned_loop_->GetPreHeaderBlock()->tail(), + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + Instruction* factor = + builder.GetIntConstant(peel_factor, int_type_->IsSigned()); + + Instruction* has_remaining_iteration = builder.AddLessThan( + factor->result_id(), loop_iteration_count_->result_id()); + Instruction* max_iteration = builder.AddSelect( + factor->type_id(), has_remaining_iteration->result_id(), + factor->result_id(), loop_iteration_count_->result_id()); + + // Change the exit condition of the cloned loop to be (exit when become + // false): + // "canonical_induction_variable_" < min("factor", "loop_iteration_count_") + FixExitCondition([max_iteration, this](Instruction* insert_before_point) { + return InstructionBuilder(context_, insert_before_point, + IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping) + .AddLessThan(canonical_induction_variable_->result_id(), + max_iteration->result_id()) + ->result_id(); + }); + + // "Protect" the second loop: the second loop can only be executed if + // |has_remaining_iteration| is true (i.e. factor < loop_iteration_count_). + BasicBlock* if_merge_block = loop_->GetMergeBlock(); + loop_->SetMergeBlock(CreateBlockBefore(loop_->GetMergeBlock())); + // Prevent the second loop from being executed if we already executed all the + // required iterations. + BasicBlock* if_block = + ProtectLoop(loop_, has_remaining_iteration, if_merge_block); + // Patch the phi of the merge block. + if_merge_block->ForEachPhiInst( + [&clone_results, if_block, this](Instruction* phi) { + // if_merge_block had previously only 1 predecessor. + uint32_t incoming_value = phi->GetSingleWordInOperand(0); + auto def_in_loop = clone_results.value_map_.find(incoming_value); + if (def_in_loop != clone_results.value_map_.end()) + incoming_value = def_in_loop->second; + phi->AddOperand( + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {incoming_value}}); + phi->AddOperand( + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {if_block->id()}}); + context_->get_def_use_mgr()->AnalyzeInstUse(phi); + }); + + context_->InvalidateAnalysesExceptFor( + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisCFG); +} + +void LoopPeeling::PeelAfter(uint32_t peel_factor) { + assert(CanPeelLoop() && "Cannot peel loop"); + LoopUtils::LoopCloningResult clone_results; + + // Clone the loop and insert the cloned one before the loop. + DuplicateAndConnectLoop(&clone_results); + + // Add a canonical induction variable "canonical_induction_variable_". + InsertCanonicalInductionVariable(&clone_results); + + InstructionBuilder builder( + context_, &*cloned_loop_->GetPreHeaderBlock()->tail(), + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + Instruction* factor = + builder.GetIntConstant(peel_factor, int_type_->IsSigned()); + + Instruction* has_remaining_iteration = builder.AddLessThan( + factor->result_id(), loop_iteration_count_->result_id()); + + // Change the exit condition of the cloned loop to be (exit when become + // false): + // "canonical_induction_variable_" + "factor" < "loop_iteration_count_" + FixExitCondition([factor, this](Instruction* insert_before_point) { + InstructionBuilder cond_builder( + context_, insert_before_point, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // Build the following check: canonical_induction_variable_ + factor < + // iteration_count + return cond_builder + .AddLessThan(cond_builder + .AddIAdd(canonical_induction_variable_->type_id(), + canonical_induction_variable_->result_id(), + factor->result_id()) + ->result_id(), + loop_iteration_count_->result_id()) + ->result_id(); + }); + + // "Protect" the first loop: the first loop can only be executed if + // factor < loop_iteration_count_. + + // The original loop's pre-header was the cloned loop merge block. + GetClonedLoop()->SetMergeBlock( + CreateBlockBefore(GetOriginalLoop()->GetPreHeaderBlock())); + // Use the second loop preheader as if merge block. + + // Prevent the first loop if only the peeled loop needs it. + BasicBlock* if_block = ProtectLoop(cloned_loop_, has_remaining_iteration, + GetOriginalLoop()->GetPreHeaderBlock()); + + // Patch the phi of the header block. + // We added an if to enclose the first loop and because the phi node are + // connected to the exit value of the first loop, the definition no longer + // dominate the preheader. + // We had to the preheader (our if merge block) the required phi instruction + // and patch the header phi. + GetOriginalLoop()->GetHeaderBlock()->ForEachPhiInst( + [&clone_results, if_block, this](Instruction* phi) { + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + auto find_value_idx = [](Instruction* phi_inst, Loop* loop) { + uint32_t preheader_value_idx = + !loop->IsInsideLoop(phi_inst->GetSingleWordInOperand(1)) ? 0 : 2; + return preheader_value_idx; + }; + + Instruction* cloned_phi = + def_use_mgr->GetDef(clone_results.value_map_.at(phi->result_id())); + uint32_t cloned_preheader_value = cloned_phi->GetSingleWordInOperand( + find_value_idx(cloned_phi, GetClonedLoop())); + + Instruction* new_phi = + InstructionBuilder(context_, + &*GetOriginalLoop()->GetPreHeaderBlock()->tail(), + IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping) + .AddPhi(phi->type_id(), + {phi->GetSingleWordInOperand( + find_value_idx(phi, GetOriginalLoop())), + GetClonedLoop()->GetMergeBlock()->id(), + cloned_preheader_value, if_block->id()}); + + phi->SetInOperand(find_value_idx(phi, GetOriginalLoop()), + {new_phi->result_id()}); + def_use_mgr->AnalyzeInstUse(phi); + }); + + context_->InvalidateAnalysesExceptFor( + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisCFG); +} + +Pass::Status LoopPeelingPass::Process() { + bool modified = false; + Module* module = context()->module(); + + // Process each function in the module + for (Function& f : *module) { + modified |= ProcessFunction(&f); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool LoopPeelingPass::ProcessFunction(Function* f) { + bool modified = false; + LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(f); + + std::vector to_process_loop; + to_process_loop.reserve(loop_descriptor.NumLoops()); + for (Loop& l : loop_descriptor) { + to_process_loop.push_back(&l); + } + + ScalarEvolutionAnalysis scev_analysis(context()); + + for (Loop* loop : to_process_loop) { + CodeMetrics loop_size; + loop_size.Analyze(*loop); + + auto try_peel = [&loop_size, &modified, this](Loop* loop_to_peel) -> Loop* { + if (!loop_to_peel->IsLCSSA()) { + LoopUtils(context(), loop_to_peel).MakeLoopClosedSSA(); + } + + bool peeled_loop; + Loop* still_peelable_loop; + std::tie(peeled_loop, still_peelable_loop) = + ProcessLoop(loop_to_peel, &loop_size); + + if (peeled_loop) { + modified = true; + } + + return still_peelable_loop; + }; + + Loop* still_peelable_loop = try_peel(loop); + // The pass is working out the maximum factor by which a loop can be peeled. + // If the loop can potentially be peeled again, then there is only one + // possible direction, so only one call is still needed. + if (still_peelable_loop) { + try_peel(loop); + } + } + + return modified; +} + +std::pair LoopPeelingPass::ProcessLoop(Loop* loop, + CodeMetrics* loop_size) { + ScalarEvolutionAnalysis* scev_analysis = + context()->GetScalarEvolutionAnalysis(); + // Default values for bailing out. + std::pair bail_out{false, nullptr}; + + BasicBlock* exit_block = loop->FindConditionBlock(); + if (!exit_block) { + return bail_out; + } + + Instruction* exiting_iv = loop->FindConditionVariable(exit_block); + if (!exiting_iv) { + return bail_out; + } + size_t iterations = 0; + if (!loop->FindNumberOfIterations(exiting_iv, &*exit_block->tail(), + &iterations)) { + return bail_out; + } + if (!iterations) { + return bail_out; + } + + Instruction* canonical_induction_variable = nullptr; + + loop->GetHeaderBlock()->WhileEachPhiInst([&canonical_induction_variable, + scev_analysis, + this](Instruction* insn) { + if (const SERecurrentNode* iv = + scev_analysis->AnalyzeInstruction(insn)->AsSERecurrentNode()) { + const SEConstantNode* offset = iv->GetOffset()->AsSEConstantNode(); + const SEConstantNode* coeff = iv->GetCoefficient()->AsSEConstantNode(); + if (offset && coeff && offset->FoldToSingleValue() == 0 && + coeff->FoldToSingleValue() == 1) { + if (context()->get_type_mgr()->GetType(insn->type_id())->AsInteger()) { + canonical_induction_variable = insn; + return false; + } + } + } + return true; + }); + + bool is_signed = canonical_induction_variable + ? context() + ->get_type_mgr() + ->GetType(canonical_induction_variable->type_id()) + ->AsInteger() + ->IsSigned() + : false; + + LoopPeeling peeler( + loop, + InstructionBuilder( + context(), loop->GetHeaderBlock(), + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping) + .GetIntConstant(static_cast(iterations), + is_signed), + canonical_induction_variable); + + if (!peeler.CanPeelLoop()) { + return bail_out; + } + + // For each basic block in the loop, check if it can be peeled. If it + // can, get the direction (before/after) and by which factor. + LoopPeelingInfo peel_info(loop, iterations, scev_analysis); + + uint32_t peel_before_factor = 0; + uint32_t peel_after_factor = 0; + + for (uint32_t block : loop->GetBlocks()) { + if (block == exit_block->id()) { + continue; + } + BasicBlock* bb = cfg()->block(block); + PeelDirection direction; + uint32_t factor; + std::tie(direction, factor) = peel_info.GetPeelingInfo(bb); + + if (direction == PeelDirection::kNone) { + continue; + } + if (direction == PeelDirection::kBefore) { + peel_before_factor = std::max(peel_before_factor, factor); + } else { + assert(direction == PeelDirection::kAfter); + peel_after_factor = std::max(peel_after_factor, factor); + } + } + PeelDirection direction = PeelDirection::kNone; + uint32_t factor = 0; + + // Find which direction we should peel. + if (peel_before_factor) { + factor = peel_before_factor; + direction = PeelDirection::kBefore; + } + if (peel_after_factor) { + if (peel_before_factor < peel_after_factor) { + // Favor a peel after here and give the peel before another shot later. + factor = peel_after_factor; + direction = PeelDirection::kAfter; + } + } + + // Do the peel if we can. + if (direction == PeelDirection::kNone) return bail_out; + + // This does not take into account branch elimination opportunities and + // the unrolling. It assumes the peeled loop will be unrolled as well. + if (factor * loop_size->roi_size_ > code_grow_threshold_) { + return bail_out; + } + loop_size->roi_size_ *= factor; + + // Find if a loop should be peeled again. + Loop* extra_opportunity = nullptr; + + if (direction == PeelDirection::kBefore) { + peeler.PeelBefore(factor); + if (stats_) { + stats_->peeled_loops_.emplace_back(loop, PeelDirection::kBefore, factor); + } + if (peel_after_factor) { + // We could have peeled after, give it another try. + extra_opportunity = peeler.GetOriginalLoop(); + } + } else { + peeler.PeelAfter(factor); + if (stats_) { + stats_->peeled_loops_.emplace_back(loop, PeelDirection::kAfter, factor); + } + if (peel_before_factor) { + // We could have peeled before, give it another try. + extra_opportunity = peeler.GetClonedLoop(); + } + } + + return {true, extra_opportunity}; +} + +uint32_t LoopPeelingPass::LoopPeelingInfo::GetFirstLoopInvariantOperand( + Instruction* condition) const { + for (uint32_t i = 0; i < condition->NumInOperands(); i++) { + BasicBlock* bb = + context_->get_instr_block(condition->GetSingleWordInOperand(i)); + if (bb && loop_->IsInsideLoop(bb)) { + return condition->GetSingleWordInOperand(i); + } + } + + return 0; +} + +uint32_t LoopPeelingPass::LoopPeelingInfo::GetFirstNonLoopInvariantOperand( + Instruction* condition) const { + for (uint32_t i = 0; i < condition->NumInOperands(); i++) { + BasicBlock* bb = + context_->get_instr_block(condition->GetSingleWordInOperand(i)); + if (!bb || !loop_->IsInsideLoop(bb)) { + return condition->GetSingleWordInOperand(i); + } + } + + return 0; +} + +static bool IsHandledCondition(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: + return true; + default: + return false; + } +} + +LoopPeelingPass::LoopPeelingInfo::Direction +LoopPeelingPass::LoopPeelingInfo::GetPeelingInfo(BasicBlock* bb) const { + if (bb->terminator()->opcode() != spv::Op::OpBranchConditional) { + return GetNoneDirection(); + } + + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + Instruction* condition = + def_use_mgr->GetDef(bb->terminator()->GetSingleWordInOperand(0)); + + if (!IsHandledCondition(condition->opcode())) { + return GetNoneDirection(); + } + + if (!GetFirstLoopInvariantOperand(condition)) { + // No loop invariant, it cannot be peeled by this pass. + return GetNoneDirection(); + } + if (!GetFirstNonLoopInvariantOperand(condition)) { + // Seems to be a job for the unswitch pass. + return GetNoneDirection(); + } + + // Left hand-side. + SExpression lhs = scev_analysis_->AnalyzeInstruction( + def_use_mgr->GetDef(condition->GetSingleWordInOperand(0))); + if (lhs->GetType() == SENode::CanNotCompute) { + // Can't make any conclusion. + return GetNoneDirection(); + } + + // Right hand-side. + SExpression rhs = scev_analysis_->AnalyzeInstruction( + def_use_mgr->GetDef(condition->GetSingleWordInOperand(1))); + if (rhs->GetType() == SENode::CanNotCompute) { + // Can't make any conclusion. + return GetNoneDirection(); + } + + // Only take into account recurrent expression over the current loop. + bool is_lhs_rec = !scev_analysis_->IsLoopInvariant(loop_, lhs); + bool is_rhs_rec = !scev_analysis_->IsLoopInvariant(loop_, rhs); + + if ((is_lhs_rec && is_rhs_rec) || (!is_lhs_rec && !is_rhs_rec)) { + return GetNoneDirection(); + } + + if (is_lhs_rec) { + if (!lhs->AsSERecurrentNode() || + lhs->AsSERecurrentNode()->GetLoop() != loop_) { + return GetNoneDirection(); + } + } + if (is_rhs_rec) { + if (!rhs->AsSERecurrentNode() || + rhs->AsSERecurrentNode()->GetLoop() != loop_) { + return GetNoneDirection(); + } + } + + // If the op code is ==, then we try a peel before or after. + // If opcode is not <, >, <= or >=, we bail out. + // + // For the remaining cases, we canonicalize the expression so that the + // constant expression is on the left hand side and the recurring expression + // is on the right hand side. If we swap hand side, then < becomes >, <= + // becomes >= etc. + // If the opcode is <=, then we add 1 to the right hand side and do the peel + // check on <. + // If the opcode is >=, then we add 1 to the left hand side and do the peel + // check on >. + + CmpOperator cmp_operator; + switch (condition->opcode()) { + default: + return GetNoneDirection(); + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + return HandleEquality(lhs, rhs); + case spv::Op::OpUGreaterThan: + case spv::Op::OpSGreaterThan: { + cmp_operator = CmpOperator::kGT; + break; + } + case spv::Op::OpULessThan: + case spv::Op::OpSLessThan: { + cmp_operator = CmpOperator::kLT; + break; + } + // We add one to transform >= into > and <= into <. + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpSGreaterThanEqual: { + cmp_operator = CmpOperator::kGE; + break; + } + case spv::Op::OpULessThanEqual: + case spv::Op::OpSLessThanEqual: { + cmp_operator = CmpOperator::kLE; + break; + } + } + + // Force the left hand side to be the non recurring expression. + if (is_lhs_rec) { + std::swap(lhs, rhs); + switch (cmp_operator) { + case CmpOperator::kLT: { + cmp_operator = CmpOperator::kGT; + break; + } + case CmpOperator::kGT: { + cmp_operator = CmpOperator::kLT; + break; + } + case CmpOperator::kLE: { + cmp_operator = CmpOperator::kGE; + break; + } + case CmpOperator::kGE: { + cmp_operator = CmpOperator::kLE; + break; + } + } + } + return HandleInequality(cmp_operator, lhs, rhs->AsSERecurrentNode()); +} + +SExpression LoopPeelingPass::LoopPeelingInfo::GetValueAtFirstIteration( + SERecurrentNode* rec) const { + return rec->GetOffset(); +} + +SExpression LoopPeelingPass::LoopPeelingInfo::GetValueAtIteration( + SERecurrentNode* rec, int64_t iteration) const { + SExpression coeff = rec->GetCoefficient(); + SExpression offset = rec->GetOffset(); + + return (coeff * iteration) + offset; +} + +SExpression LoopPeelingPass::LoopPeelingInfo::GetValueAtLastIteration( + SERecurrentNode* rec) const { + return GetValueAtIteration(rec, loop_max_iterations_ - 1); +} + +bool LoopPeelingPass::LoopPeelingInfo::EvalOperator(CmpOperator cmp_op, + SExpression lhs, + SExpression rhs, + bool* result) const { + assert(scev_analysis_->IsLoopInvariant(loop_, lhs)); + assert(scev_analysis_->IsLoopInvariant(loop_, rhs)); + // We perform the test: 0 cmp_op rhs - lhs + // What is left is then to determine the sign of the expression. + switch (cmp_op) { + case CmpOperator::kLT: { + return scev_analysis_->IsAlwaysGreaterThanZero(rhs - lhs, result); + } + case CmpOperator::kGT: { + return scev_analysis_->IsAlwaysGreaterThanZero(lhs - rhs, result); + } + case CmpOperator::kLE: { + return scev_analysis_->IsAlwaysGreaterOrEqualToZero(rhs - lhs, result); + } + case CmpOperator::kGE: { + return scev_analysis_->IsAlwaysGreaterOrEqualToZero(lhs - rhs, result); + } + } + return false; +} + +LoopPeelingPass::LoopPeelingInfo::Direction +LoopPeelingPass::LoopPeelingInfo::HandleEquality(SExpression lhs, + SExpression rhs) const { + { + // Try peel before opportunity. + SExpression lhs_cst = lhs; + if (SERecurrentNode* rec_node = lhs->AsSERecurrentNode()) { + lhs_cst = rec_node->GetOffset(); + } + SExpression rhs_cst = rhs; + if (SERecurrentNode* rec_node = rhs->AsSERecurrentNode()) { + rhs_cst = rec_node->GetOffset(); + } + + if (lhs_cst == rhs_cst) { + return Direction{LoopPeelingPass::PeelDirection::kBefore, 1}; + } + } + + { + // Try peel after opportunity. + SExpression lhs_cst = lhs; + if (SERecurrentNode* rec_node = lhs->AsSERecurrentNode()) { + // rec_node(x) = a * x + b + // assign to lhs: a * (loop_max_iterations_ - 1) + b + lhs_cst = GetValueAtLastIteration(rec_node); + } + SExpression rhs_cst = rhs; + if (SERecurrentNode* rec_node = rhs->AsSERecurrentNode()) { + // rec_node(x) = a * x + b + // assign to lhs: a * (loop_max_iterations_ - 1) + b + rhs_cst = GetValueAtLastIteration(rec_node); + } + + if (lhs_cst == rhs_cst) { + return Direction{LoopPeelingPass::PeelDirection::kAfter, 1}; + } + } + + return GetNoneDirection(); +} + +LoopPeelingPass::LoopPeelingInfo::Direction +LoopPeelingPass::LoopPeelingInfo::HandleInequality(CmpOperator cmp_op, + SExpression lhs, + SERecurrentNode* rhs) const { + SExpression offset = rhs->GetOffset(); + SExpression coefficient = rhs->GetCoefficient(); + // Compute (cst - B) / A. + std::pair flip_iteration = (lhs - offset) / coefficient; + if (!flip_iteration.first->AsSEConstantNode()) { + return GetNoneDirection(); + } + // note: !!flip_iteration.second normalize to 0/1 (via bool cast). + int64_t iteration = + flip_iteration.first->AsSEConstantNode()->FoldToSingleValue() + + !!flip_iteration.second; + if (iteration <= 0 || + loop_max_iterations_ <= static_cast(iteration)) { + // Always true or false within the loop bounds. + return GetNoneDirection(); + } + // If this is a <= or >= operator and the iteration, make sure |iteration| is + // the one flipping the condition. + // If (cst - B) and A are not divisible, this equivalent to a < or > check, so + // we skip this test. + if (!flip_iteration.second && + (cmp_op == CmpOperator::kLE || cmp_op == CmpOperator::kGE)) { + bool first_iteration; + bool current_iteration; + if (!EvalOperator(cmp_op, lhs, offset, &first_iteration) || + !EvalOperator(cmp_op, lhs, GetValueAtIteration(rhs, iteration), + ¤t_iteration)) { + return GetNoneDirection(); + } + // If the condition did not flip the next will. + if (first_iteration == current_iteration) { + iteration++; + } + } + + uint32_t cast_iteration = 0; + // Integrity check: can we fit |iteration| in a uint32_t ? + if (static_cast(iteration) < std::numeric_limits::max()) { + cast_iteration = static_cast(iteration); + } + + if (cast_iteration) { + // Peel before if we are closer to the start, after if closer to the end. + if (loop_max_iterations_ / 2 > cast_iteration) { + return Direction{LoopPeelingPass::PeelDirection::kBefore, cast_iteration}; + } else { + return Direction{ + LoopPeelingPass::PeelDirection::kAfter, + static_cast(loop_max_iterations_ - cast_iteration)}; + } + } + + return GetNoneDirection(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_peeling.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_peeling.h new file mode 100644 index 000000000000..2a55fe44dadc --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_peeling.h @@ -0,0 +1,336 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_PEELING_H_ +#define SOURCE_OPT_LOOP_PEELING_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/loop_descriptor.h" +#include "source/opt/loop_utils.h" +#include "source/opt/pass.h" +#include "source/opt/scalar_analysis.h" + +namespace spvtools { +namespace opt { + +// Utility class to perform the peeling of a given loop. +// The loop peeling transformation make a certain amount of a loop iterations to +// be executed either before (peel before) or after (peel after) the transformed +// loop. +// +// For peeling cases the transformation does the following steps: +// - It clones the loop and inserts the cloned loop before the original loop; +// - It connects all iterating values of the cloned loop with the +// corresponding original loop values so that the second loop starts with +// the appropriate values. +// - It inserts a new induction variable "i" is inserted into the cloned that +// starts with the value 0 and increment by step of one. +// +// The last step is specific to each case: +// - Peel before: the transformation is to peel the "N" first iterations. +// The exit condition of the cloned loop is changed so that the loop +// exits when "i < N" becomes false. The original loop is then protected to +// only execute if there is any iteration left to do. +// - Peel after: the transformation is to peel the "N" last iterations, +// then the exit condition of the cloned loop is changed so that the loop +// exits when "i + N < max_iteration" becomes false, where "max_iteration" +// is the upper bound of the loop. The cloned loop is then protected to +// only execute if there is any iteration left to do no covered by the +// second. +// +// To be peelable: +// - The loop must be in LCSSA form; +// - The loop must not contain any breaks; +// - The loop must not have any ambiguous iterators updates (see +// "CanPeelLoop"). +// The method "CanPeelLoop" checks that those constrained are met. +class LoopPeeling { + public: + // LoopPeeling constructor. + // |loop| is the loop to peel. + // |loop_iteration_count| is the instruction holding the |loop| iteration + // count, must be invariant for |loop| and must be of an int 32 type (signed + // or unsigned). + // |canonical_induction_variable| is an induction variable that can be used to + // count the number of iterations, must be of the same type as + // |loop_iteration_count| and start at 0 and increase by step of one at each + // iteration. The value nullptr is interpreted as no suitable variable exists + // and one will be created. + LoopPeeling(Loop* loop, Instruction* loop_iteration_count, + Instruction* canonical_induction_variable = nullptr) + : context_(loop->GetContext()), + loop_utils_(loop->GetContext(), loop), + loop_(loop), + loop_iteration_count_(!loop->IsInsideLoop(loop_iteration_count) + ? loop_iteration_count + : nullptr), + int_type_(nullptr), + original_loop_canonical_induction_variable_( + canonical_induction_variable), + canonical_induction_variable_(nullptr) { + if (loop_iteration_count_) { + int_type_ = context_->get_type_mgr() + ->GetType(loop_iteration_count_->type_id()) + ->AsInteger(); + if (canonical_induction_variable_) { + assert(canonical_induction_variable_->type_id() == + loop_iteration_count_->type_id() && + "loop_iteration_count and canonical_induction_variable do not " + "have the same type"); + } + } + GetIteratingExitValues(); + } + + // Returns true if the loop can be peeled. + // To be peelable, all operation involved in the update of the loop iterators + // must not dominates the exit condition. This restriction is a work around to + // not miss compile code like: + // + // for (int i = 0; i + 1 < N; i++) {} + // for (int i = 0; ++i < N; i++) {} + // + // The increment will happen before the test on the exit condition leading to + // very look-a-like code. + // + // This restriction will not apply if a loop rotate is applied before (i.e. + // becomes a do-while loop). + bool CanPeelLoop() const { + CFG& cfg = *context_->cfg(); + + if (!loop_iteration_count_) { + return false; + } + if (!int_type_) { + return false; + } + if (int_type_->width() != 32) { + return false; + } + if (!loop_->IsLCSSA()) { + return false; + } + if (!loop_->GetMergeBlock()) { + return false; + } + if (cfg.preds(loop_->GetMergeBlock()->id()).size() != 1) { + return false; + } + if (!IsConditionCheckSideEffectFree()) { + return false; + } + + return !std::any_of(exit_value_.cbegin(), exit_value_.cend(), + [](std::pair it) { + return it.second == nullptr; + }); + } + + // Moves the execution of the |factor| first iterations of the loop into a + // dedicated loop. + void PeelBefore(uint32_t factor); + + // Moves the execution of the |factor| last iterations of the loop into a + // dedicated loop. + void PeelAfter(uint32_t factor); + + // Returns the cloned loop. + Loop* GetClonedLoop() { return cloned_loop_; } + // Returns the original loop. + Loop* GetOriginalLoop() { return loop_; } + + private: + IRContext* context_; + LoopUtils loop_utils_; + // The original loop. + Loop* loop_; + // The initial |loop_| upper bound. + Instruction* loop_iteration_count_; + // The int type to use for the canonical_induction_variable_. + analysis::Integer* int_type_; + // The cloned loop. + Loop* cloned_loop_; + // This is set to true when the exit and back-edge branch instruction is the + // same. + bool do_while_form_; + // The canonical induction variable from the original loop if it exists. + Instruction* original_loop_canonical_induction_variable_; + // The canonical induction variable of the cloned loop. The induction variable + // is initialized to 0 and incremented by step of 1. + Instruction* canonical_induction_variable_; + // Map between loop iterators and exit values. Loop iterators + std::unordered_map exit_value_; + + // Duplicate |loop_| and place the new loop before the cloned loop. Iterating + // values from the cloned loop are then connected to the original loop as + // initializer. + void DuplicateAndConnectLoop(LoopUtils::LoopCloningResult* clone_results); + + // Insert the canonical induction variable into the first loop as a simplified + // counter. + void InsertCanonicalInductionVariable( + LoopUtils::LoopCloningResult* clone_results); + + // Fixes the exit condition of the before loop. The function calls + // |condition_builder| to get the condition to use in the conditional branch + // of the loop exit. The loop will be exited if the condition evaluate to + // true. |condition_builder| takes an Instruction* that represent the + // insertion point. + void FixExitCondition( + const std::function& condition_builder); + + // Gathers all operations involved in the update of |iterator| into + // |operations|. + void GetIteratorUpdateOperations( + const Loop* loop, Instruction* iterator, + std::unordered_set* operations); + + // Gathers exiting iterator values. The function builds a map between each + // iterating value in the loop (a phi instruction in the loop header) and its + // SSA value when it exit the loop. If no exit value can be accurately found, + // it is map to nullptr (see comment on CanPeelLoop). + void GetIteratingExitValues(); + + // Returns true if a for-loop has no instruction with effects before the + // condition check. + bool IsConditionCheckSideEffectFree() const; + + // Creates a new basic block and insert it between |bb| and the predecessor of + // |bb|. + BasicBlock* CreateBlockBefore(BasicBlock* bb); + + // Inserts code to only execute |loop| only if the given |condition| is true. + // |if_merge| is a suitable basic block to be used by the if condition as + // merge block. + // The function returns the if block protecting the loop. + BasicBlock* ProtectLoop(Loop* loop, Instruction* condition, + BasicBlock* if_merge); +}; + +// Implements a loop peeling optimization. +// For each loop, the pass will try to peel it if there is conditions that +// are true for the "N" first or last iterations of the loop. +// To avoid code size explosion, too large loops will not be peeled. +class LoopPeelingPass : public Pass { + public: + // Describes the peeling direction. + enum class PeelDirection { + kNone, // Cannot peel + kBefore, // Can peel before + kAfter // Can peel last + }; + + // Holds some statistics about peeled function. + struct LoopPeelingStats { + std::vector> peeled_loops_; + }; + + LoopPeelingPass(LoopPeelingStats* stats = nullptr) : stats_(stats) {} + + // Sets the loop peeling growth threshold. If the code size increase is above + // |code_grow_threshold|, the loop will not be peeled. The code size is + // measured in terms of SPIR-V instructions. + static void SetLoopPeelingThreshold(size_t code_grow_threshold) { + code_grow_threshold_ = code_grow_threshold; + } + + // Returns the loop peeling code growth threshold. + static size_t GetLoopPeelingThreshold() { return code_grow_threshold_; } + + const char* name() const override { return "loop-peeling"; } + + // Processes the given |module|. Returns Status::Failure if errors occur when + // processing. Returns the corresponding Status::Success if processing is + // successful to indicate whether changes have been made to the module. + Pass::Status Process() override; + + private: + // Describes the peeling direction. + enum class CmpOperator { + kLT, // less than + kGT, // greater than + kLE, // less than or equal + kGE, // greater than or equal + }; + + class LoopPeelingInfo { + public: + using Direction = std::pair; + + LoopPeelingInfo(Loop* loop, size_t loop_max_iterations, + ScalarEvolutionAnalysis* scev_analysis) + : context_(loop->GetContext()), + loop_(loop), + scev_analysis_(scev_analysis), + loop_max_iterations_(loop_max_iterations) {} + + // Returns by how much and to which direction a loop should be peeled to + // make the conditional branch of the basic block |bb| an unconditional + // branch. If |bb|'s terminator is not a conditional branch or the condition + // is not workable then it returns PeelDirection::kNone and a 0 factor. + Direction GetPeelingInfo(BasicBlock* bb) const; + + private: + // Returns the id of the loop invariant operand of the conditional + // expression |condition|. It returns if no operand is invariant. + uint32_t GetFirstLoopInvariantOperand(Instruction* condition) const; + // Returns the id of the non loop invariant operand of the conditional + // expression |condition|. It returns if all operands are invariant. + uint32_t GetFirstNonLoopInvariantOperand(Instruction* condition) const; + + // Returns the value of |rec| at the first loop iteration. + SExpression GetValueAtFirstIteration(SERecurrentNode* rec) const; + // Returns the value of |rec| at the given |iteration|. + SExpression GetValueAtIteration(SERecurrentNode* rec, + int64_t iteration) const; + // Returns the value of |rec| at the last loop iteration. + SExpression GetValueAtLastIteration(SERecurrentNode* rec) const; + + bool EvalOperator(CmpOperator cmp_op, SExpression lhs, SExpression rhs, + bool* result) const; + + Direction HandleEquality(SExpression lhs, SExpression rhs) const; + Direction HandleInequality(CmpOperator cmp_op, SExpression lhs, + SERecurrentNode* rhs) const; + + static Direction GetNoneDirection() { + return Direction{LoopPeelingPass::PeelDirection::kNone, 0}; + } + IRContext* context_; + Loop* loop_; + ScalarEvolutionAnalysis* scev_analysis_; + size_t loop_max_iterations_; + }; + // Peel profitable loops in |f|. + bool ProcessFunction(Function* f); + // Peel |loop| if profitable. + std::pair ProcessLoop(Loop* loop, CodeMetrics* loop_size); + + static size_t code_grow_threshold_; + LoopPeelingStats* stats_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_PEELING_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_unroller.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_unroller.cpp new file mode 100644 index 000000000000..d9e34f242318 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_unroller.cpp @@ -0,0 +1,1143 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/loop_unroller.h" + +#include +#include +#include +#include +#include + +#include "source/opt/ir_builder.h" +#include "source/opt/loop_utils.h" + +// Implements loop util unrolling functionality for fully and partially +// unrolling loops. Given a factor it will duplicate the loop that many times, +// appending each one to the end of the old loop and removing backedges, to +// create a new unrolled loop. +// +// 1 - User calls LoopUtils::FullyUnroll or LoopUtils::PartiallyUnroll with a +// loop they wish to unroll. LoopUtils::CanPerformUnroll is used to +// validate that a given loop can be unrolled. That method (along with the +// constructor of loop) checks that the IR is in the expected canonicalised +// format. +// +// 2 - The LoopUtils methods create a LoopUnrollerUtilsImpl object to actually +// perform the unrolling. This implements helper methods to copy the loop basic +// blocks and remap the ids of instructions used inside them. +// +// 3 - The core of LoopUnrollerUtilsImpl is the Unroll method, this method +// actually performs the loop duplication. It does this by creating a +// LoopUnrollState object and then copying the loop as given by the factor +// parameter. The LoopUnrollState object retains the state of the unroller +// between the loop body copies as each iteration needs information on the last +// to adjust the phi induction variable, adjust the OpLoopMerge instruction in +// the main loop header, and change the previous continue block to point to the +// new header and the new continue block to the main loop header. +// +// 4 - If the loop is to be fully unrolled then it is simply closed after step +// 3, with the OpLoopMerge being deleted, the backedge removed, and the +// condition blocks folded. +// +// 5 - If it is being partially unrolled: if the unrolling factor leaves the +// loop with an even number of bodies with respect to the number of loop +// iterations then step 3 is all that is needed. If it is uneven then we need to +// duplicate the loop completely and unroll the duplicated loop to cover the +// residual part and adjust the first loop to cover only the "even" part. For +// instance if you request an unroll factor of 3 on a loop with 10 iterations +// then copying the body three times would leave you with three bodies in the +// loop +// where the loop still iterates over each 4 times. So we make two loops one +// iterating once then a second loop of three iterating 3 times. + +namespace spvtools { +namespace opt { +namespace { + +// Loop control constant value for DontUnroll flag. +constexpr uint32_t kLoopControlDontUnrollIndex = 2; + +// Operand index of the loop control parameter of the OpLoopMerge. +constexpr uint32_t kLoopControlIndex = 2; + +// This utility class encapsulates some of the state we need to maintain between +// loop unrolls. Specifically it maintains key blocks and the induction variable +// in the current loop duplication step and the blocks from the previous one. +// This is because each step of the unroll needs to use data from both the +// preceding step and the original loop. +struct LoopUnrollState { + LoopUnrollState() + : previous_phi_(nullptr), + previous_latch_block_(nullptr), + previous_condition_block_(nullptr), + new_phi(nullptr), + new_continue_block(nullptr), + new_condition_block(nullptr), + new_header_block(nullptr) {} + + // Initialize from the loop descriptor class. + LoopUnrollState(Instruction* induction, BasicBlock* latch_block, + BasicBlock* condition, std::vector&& phis) + : previous_phi_(induction), + previous_latch_block_(latch_block), + previous_condition_block_(condition), + new_phi(nullptr), + new_continue_block(nullptr), + new_condition_block(nullptr), + new_header_block(nullptr) { + previous_phis_ = std::move(phis); + } + + // Swap the state so that the new nodes are now the previous nodes. + void NextIterationState() { + previous_phi_ = new_phi; + previous_latch_block_ = new_latch_block; + previous_condition_block_ = new_condition_block; + previous_phis_ = std::move(new_phis_); + + // Clear new nodes. + new_phi = nullptr; + new_continue_block = nullptr; + new_condition_block = nullptr; + new_header_block = nullptr; + new_latch_block = nullptr; + + // Clear new block/instruction maps. + new_blocks.clear(); + new_inst.clear(); + ids_to_new_inst.clear(); + } + + // The induction variable from the immediately preceding loop body. + Instruction* previous_phi_; + + // All the phi nodes from the previous loop iteration. + std::vector previous_phis_; + + std::vector new_phis_; + + // The previous latch block. The backedge will be removed from this and + // added to the new latch block. + BasicBlock* previous_latch_block_; + + // The previous condition block. This may be folded to flatten the loop. + BasicBlock* previous_condition_block_; + + // The new induction variable. + Instruction* new_phi; + + // The new continue block. + BasicBlock* new_continue_block; + + // The new condition block. + BasicBlock* new_condition_block; + + // The new header block. + BasicBlock* new_header_block; + + // The new latch block. + BasicBlock* new_latch_block; + + // A mapping of new block ids to the original blocks which they were copied + // from. + std::unordered_map new_blocks; + + // A mapping of the original instruction ids to the instruction ids to their + // copies. + std::unordered_map new_inst; + + std::unordered_map ids_to_new_inst; +}; + +// This class implements the actual unrolling. It uses a LoopUnrollState to +// maintain the state of the unrolling in between steps. +class LoopUnrollerUtilsImpl { + public: + using BasicBlockListTy = std::vector>; + + LoopUnrollerUtilsImpl(IRContext* c, Function* function) + : context_(c), + function_(*function), + loop_condition_block_(nullptr), + loop_induction_variable_(nullptr), + number_of_loop_iterations_(0), + loop_step_value_(0), + loop_init_value_(0) {} + + // Unroll the |loop| by given |factor| by copying the whole body |factor| + // times. The resulting basicblock structure will remain a loop. + void PartiallyUnroll(Loop*, size_t factor); + + // If partially unrolling the |loop| would leave the loop with too many bodies + // for its number of iterations then this method should be used. This method + // will duplicate the |loop| completely, making the duplicated loop the + // successor of the original's merge block. The original loop will have its + // condition changed to loop over the residual part and the duplicate will be + // partially unrolled. The resulting structure will be two loops. + void PartiallyUnrollResidualFactor(Loop* loop, size_t factor); + + // Fully unroll the |loop| by copying the full body by the total number of + // loop iterations, folding all conditions, and removing the backedge from the + // continue block to the header. + void FullyUnroll(Loop* loop); + + // Get the ID of the variable in the |phi| paired with |label|. + uint32_t GetPhiDefID(const Instruction* phi, uint32_t label) const; + + // Close the loop by removing the OpLoopMerge from the |loop| header block and + // making the backedge point to the merge block. + void CloseUnrolledLoop(Loop* loop); + + // Remove the OpConditionalBranch instruction inside |conditional_block| used + // to branch to either exit or continue the loop and replace it with an + // unconditional OpBranch to block |new_target|. + void FoldConditionBlock(BasicBlock* condtion_block, uint32_t new_target); + + // Add all blocks_to_add_ to function_ at the |insert_point|. + void AddBlocksToFunction(const BasicBlock* insert_point); + + // Duplicates the |old_loop|, cloning each body and remapping the ids without + // removing instructions or changing relative structure. Result will be stored + // in |new_loop|. + void DuplicateLoop(Loop* old_loop, Loop* new_loop); + + inline size_t GetLoopIterationCount() const { + return number_of_loop_iterations_; + } + + // Extracts the initial state information from the |loop|. + void Init(Loop* loop); + + // Replace the uses of each induction variable outside the loop with the final + // value of the induction variable before the loop exit. To reflect the proper + // state of a fully unrolled loop. + void ReplaceInductionUseWithFinalValue(Loop* loop); + + // Remove all the instructions in the invalidated_instructions_ vector. + void RemoveDeadInstructions(); + + // Replace any use of induction variables outwith the loop with the final + // value of the induction variable in the unrolled loop. + void ReplaceOutsideLoopUseWithFinalValue(Loop* loop); + + // Set the LoopControl operand of the OpLoopMerge instruction to be + // DontUnroll. + void MarkLoopControlAsDontUnroll(Loop* loop) const; + + private: + // Remap all the in |basic_block| to new IDs and keep the mapping of new ids + // to old + // ids. |loop| is used to identify special loop blocks (header, continue, + // etc). + void AssignNewResultIds(BasicBlock* basic_block); + + // Using the map built by AssignNewResultIds, replace the uses in |inst| + // by the id that the use maps to. + void RemapOperands(Instruction* inst); + + // Using the map built by AssignNewResultIds, for each instruction in + // |basic_block| use + // that map to substitute the IDs used by instructions (in the operands) with + // the new ids. + void RemapOperands(BasicBlock* basic_block); + + // Copy the whole body of the loop, all blocks dominated by the |loop| header + // and not dominated by the |loop| merge. The copied body will be linked to by + // the old |loop| continue block and the new body will link to the |loop| + // header via the new continue block. |eliminate_conditions| is used to decide + // whether or not to fold all the condition blocks other than the last one. + void CopyBody(Loop* loop, bool eliminate_conditions); + + // Copy a given |block_to_copy| in the |loop| and record the mapping of the + // old/new ids. |preserve_instructions| determines whether or not the method + // will modify (other than result_id) instructions which are copied. + void CopyBasicBlock(Loop* loop, const BasicBlock* block_to_copy, + bool preserve_instructions); + + // The actual implementation of the unroll step. Unrolls |loop| by given + // |factor| by copying the body by |factor| times. Also propagates the + // induction variable value throughout the copies. + void Unroll(Loop* loop, size_t factor); + + // Fills the loop_blocks_inorder_ field with the ordered list of basic blocks + // as computed by the method ComputeLoopOrderedBlocks. + void ComputeLoopOrderedBlocks(Loop* loop); + + // Adds the blocks_to_add_ to both the |loop| and to the parent of |loop| if + // the parent exists. + void AddBlocksToLoop(Loop* loop) const; + + // After the partially unroll step the phi instructions in the header block + // will be in an illegal format. This function makes the phis legal by making + // the edge from the latch block come from the new latch block and the value + // to be the actual value of the phi at that point. + void LinkLastPhisToStart(Loop* loop) const; + + // Kill all debug declaration instructions from |bb|. + void KillDebugDeclares(BasicBlock* bb); + + // A pointer to the IRContext. Used to add/remove instructions and for usedef + // chains. + IRContext* context_; + + // A reference the function the loop is within. + Function& function_; + + // A list of basic blocks to be added to the loop at the end of an unroll + // step. + BasicBlockListTy blocks_to_add_; + + // List of instructions which are now dead and can be removed. + std::vector invalidated_instructions_; + + // Maintains the current state of the transform between calls to unroll. + LoopUnrollState state_; + + // An ordered list containing the loop basic blocks. + std::vector loop_blocks_inorder_; + + // The block containing the condition check which contains a conditional + // branch to the merge and continue block. + BasicBlock* loop_condition_block_; + + // The induction variable of the loop. + Instruction* loop_induction_variable_; + + // Phis used in the loop need to be remapped to use the actual result values + // and then be remapped at the end. + std::vector loop_phi_instructions_; + + // The number of loop iterations that the loop would perform pre-unroll. + size_t number_of_loop_iterations_; + + // The amount that the loop steps each iteration. + int64_t loop_step_value_; + + // The value the loop starts stepping from. + int64_t loop_init_value_; +}; + +/* + * Static helper functions. + */ + +// Retrieve the index of the OpPhi instruction |phi| which corresponds to the +// incoming |block| id. +uint32_t GetPhiIndexFromLabel(const BasicBlock* block, const Instruction* phi) { + for (uint32_t i = 1; i < phi->NumInOperands(); i += 2) { + if (block->id() == phi->GetSingleWordInOperand(i)) { + return i; + } + } + assert(false && "Could not find operand in instruction."); + return 0; +} + +void LoopUnrollerUtilsImpl::Init(Loop* loop) { + loop_condition_block_ = loop->FindConditionBlock(); + + // When we reinit the second loop during PartiallyUnrollResidualFactor we need + // to use the cached value from the duplicate step as the dominator tree + // basded solution, loop->FindConditionBlock, requires all the nodes to be + // connected up with the correct branches. They won't be at this point. + if (!loop_condition_block_) { + loop_condition_block_ = state_.new_condition_block; + } + assert(loop_condition_block_); + + loop_induction_variable_ = loop->FindConditionVariable(loop_condition_block_); + assert(loop_induction_variable_); + + bool found = loop->FindNumberOfIterations( + loop_induction_variable_, &*loop_condition_block_->ctail(), + &number_of_loop_iterations_, &loop_step_value_, &loop_init_value_); + (void)found; // To silence unused variable warning on release builds. + assert(found); + + // Blocks are stored in an unordered set of ids in the loop class, we need to + // create the dominator ordered list. + ComputeLoopOrderedBlocks(loop); +} + +// This function is used to partially unroll the loop when the factor provided +// would normally lead to an illegal optimization. Instead of just unrolling the +// loop it creates two loops and unrolls one and adjusts the condition on the +// other. The end result being that the new loop pair iterates over the correct +// number of bodies. +void LoopUnrollerUtilsImpl::PartiallyUnrollResidualFactor(Loop* loop, + size_t factor) { + // TODO(1841): Handle id overflow. + std::unique_ptr new_label{new Instruction( + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {})}; + std::unique_ptr new_exit_bb{new BasicBlock(std::move(new_label))}; + new_exit_bb->SetParent(&function_); + + // Save the id of the block before we move it. + uint32_t new_merge_id = new_exit_bb->id(); + + // Add the block the list of blocks to add, we want this merge block to be + // right at the start of the new blocks. + blocks_to_add_.push_back(std::move(new_exit_bb)); + BasicBlock* new_exit_bb_raw = blocks_to_add_[0].get(); + Instruction& original_conditional_branch = *loop_condition_block_->tail(); + // Duplicate the loop, providing access to the blocks of both loops. + // This is a naked new due to the VS2013 requirement of not having unique + // pointers in vectors, as it will be inserted into a vector with + // loop_descriptor.AddLoop. + std::unique_ptr new_loop = MakeUnique(*loop); + + // Clear the basic blocks of the new loop. + new_loop->ClearBlocks(); + + DuplicateLoop(loop, new_loop.get()); + + // Add the blocks to the function. + AddBlocksToFunction(loop->GetMergeBlock()); + blocks_to_add_.clear(); + + // Create a new merge block for the first loop. + InstructionBuilder builder{context_, new_exit_bb_raw}; + // Make the first loop branch to the second. + builder.AddBranch(new_loop->GetHeaderBlock()->id()); + + loop_condition_block_ = state_.new_condition_block; + loop_induction_variable_ = state_.new_phi; + // Unroll the new loop by the factor with the usual -1 to account for the + // existing block iteration. + Unroll(new_loop.get(), factor); + + LinkLastPhisToStart(new_loop.get()); + AddBlocksToLoop(new_loop.get()); + + // Add the new merge block to the back of the list of blocks to be added. It + // needs to be the last block added to maintain dominator order in the binary. + blocks_to_add_.push_back( + std::unique_ptr(new_loop->GetMergeBlock())); + + // Add the blocks to the function. + AddBlocksToFunction(loop->GetMergeBlock()); + + // Reset the usedef analysis. + context_->InvalidateAnalysesExceptFor( + IRContext::Analysis::kAnalysisLoopAnalysis); + analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr(); + + // The loop condition. + Instruction* condition_check = def_use_manager->GetDef( + original_conditional_branch.GetSingleWordOperand(0)); + + // This should have been checked by the LoopUtils::CanPerformUnroll function + // before entering this. + assert(loop->IsSupportedCondition(condition_check->opcode())); + + // We need to account for the initial body when calculating the remainder. + int64_t remainder = Loop::GetResidualConditionValue( + condition_check->opcode(), loop_init_value_, loop_step_value_, + number_of_loop_iterations_, factor); + + assert(remainder > std::numeric_limits::min() && + remainder < std::numeric_limits::max()); + + Instruction* new_constant = nullptr; + + // If the remainder is negative then we add a signed constant, otherwise just + // add an unsigned constant. + if (remainder < 0) { + new_constant = builder.GetSintConstant(static_cast(remainder)); + } else { + new_constant = builder.GetUintConstant(static_cast(remainder)); + } + + uint32_t constant_id = new_constant->result_id(); + + // Update the condition check. + condition_check->SetInOperand(1, {constant_id}); + + // Update the next phi node. The phi will have a constant value coming in from + // the preheader block. For the duplicated loop we need to update the constant + // to be the amount of iterations covered by the first loop and the incoming + // block to be the first loops new merge block. + std::vector new_inductions; + new_loop->GetInductionVariables(new_inductions); + + std::vector old_inductions; + loop->GetInductionVariables(old_inductions); + for (size_t index = 0; index < new_inductions.size(); ++index) { + Instruction* new_induction = new_inductions[index]; + Instruction* old_induction = old_inductions[index]; + // Get the index of the loop initalizer, the value coming in from the + // preheader. + uint32_t initalizer_index = + GetPhiIndexFromLabel(new_loop->GetPreHeaderBlock(), old_induction); + + // Replace the second loop initalizer with the phi from the first + new_induction->SetInOperand(initalizer_index - 1, + {old_induction->result_id()}); + new_induction->SetInOperand(initalizer_index, {new_merge_id}); + + // If the use of the first loop induction variable is outside of the loop + // then replace that use with the second loop induction variable. + uint32_t second_loop_induction = new_induction->result_id(); + auto replace_use_outside_of_loop = [loop, second_loop_induction]( + Instruction* user, + uint32_t operand_index) { + if (!loop->IsInsideLoop(user)) { + user->SetOperand(operand_index, {second_loop_induction}); + } + }; + + context_->get_def_use_mgr()->ForEachUse(old_induction, + replace_use_outside_of_loop); + } + + context_->InvalidateAnalysesExceptFor( + IRContext::Analysis::kAnalysisLoopAnalysis); + + context_->ReplaceAllUsesWith(loop->GetMergeBlock()->id(), new_merge_id); + + LoopDescriptor& loop_descriptor = *context_->GetLoopDescriptor(&function_); + + loop_descriptor.AddLoop(std::move(new_loop), loop->GetParent()); + + RemoveDeadInstructions(); +} + +// Mark this loop as DontUnroll as it will already be unrolled and it may not +// be safe to unroll a previously partially unrolled loop. +void LoopUnrollerUtilsImpl::MarkLoopControlAsDontUnroll(Loop* loop) const { + Instruction* loop_merge_inst = loop->GetHeaderBlock()->GetLoopMergeInst(); + assert(loop_merge_inst && + "Loop merge instruction could not be found after entering unroller " + "(should have exited before this)"); + loop_merge_inst->SetInOperand(kLoopControlIndex, + {kLoopControlDontUnrollIndex}); +} + +// Duplicate the |loop| body |factor| - 1 number of times while keeping the loop +// backedge intact. This will leave the loop with |factor| number of bodies +// after accounting for the initial body. +void LoopUnrollerUtilsImpl::Unroll(Loop* loop, size_t factor) { + // If we unroll a loop partially it will not be safe to unroll it further. + // This is due to the current method of calculating the number of loop + // iterations. + MarkLoopControlAsDontUnroll(loop); + + std::vector inductions; + loop->GetInductionVariables(inductions); + state_ = LoopUnrollState{loop_induction_variable_, loop->GetLatchBlock(), + loop_condition_block_, std::move(inductions)}; + for (size_t i = 0; i < factor - 1; ++i) { + CopyBody(loop, true); + } +} + +void LoopUnrollerUtilsImpl::RemoveDeadInstructions() { + // Remove the dead instructions. + for (Instruction* inst : invalidated_instructions_) { + context_->KillInst(inst); + } +} + +void LoopUnrollerUtilsImpl::ReplaceInductionUseWithFinalValue(Loop* loop) { + context_->InvalidateAnalysesExceptFor( + IRContext::Analysis::kAnalysisLoopAnalysis | + IRContext::Analysis::kAnalysisDefUse | + IRContext::Analysis::kAnalysisInstrToBlockMapping); + + std::vector inductions; + loop->GetInductionVariables(inductions); + + for (size_t index = 0; index < inductions.size(); ++index) { + uint32_t trip_step_id = GetPhiDefID(state_.previous_phis_[index], + state_.previous_latch_block_->id()); + context_->ReplaceAllUsesWith(inductions[index]->result_id(), trip_step_id); + invalidated_instructions_.push_back(inductions[index]); + } +} + +// Fully unroll the loop by partially unrolling it by the number of loop +// iterations minus one for the body already accounted for. +void LoopUnrollerUtilsImpl::FullyUnroll(Loop* loop) { + // We unroll the loop by number of iterations in the loop. + Unroll(loop, number_of_loop_iterations_); + + // The first condition block is preserved until now so it can be copied. + FoldConditionBlock(loop_condition_block_, 1); + + // Delete the OpLoopMerge and remove the backedge to the header. + CloseUnrolledLoop(loop); + + // Mark the loop for later deletion. This allows us to preserve the loop + // iterators but still disregard dead loops. + loop->MarkLoopForRemoval(); + + // If the loop has a parent add the new blocks to the parent. + if (loop->GetParent()) { + AddBlocksToLoop(loop->GetParent()); + } + + // Add the blocks to the function. + AddBlocksToFunction(loop->GetMergeBlock()); + + ReplaceInductionUseWithFinalValue(loop); + + RemoveDeadInstructions(); + // Invalidate all analyses. + context_->InvalidateAnalysesExceptFor( + IRContext::Analysis::kAnalysisLoopAnalysis | + IRContext::Analysis::kAnalysisDefUse); +} + +void LoopUnrollerUtilsImpl::KillDebugDeclares(BasicBlock* bb) { + // We cannot kill an instruction inside BasicBlock::ForEachInst() + // because it will generate dangling pointers. We use |to_be_killed| + // to kill them after the loop. + std::vector to_be_killed; + + bb->ForEachInst([&to_be_killed, this](Instruction* inst) { + if (context_->get_debug_info_mgr()->IsDebugDeclare(inst)) { + to_be_killed.push_back(inst); + } + }); + for (auto* inst : to_be_killed) context_->KillInst(inst); +} + +// Copy a given basic block, give it a new result_id, and store the new block +// and the id mapping in the state. |preserve_instructions| is used to determine +// whether or not this function should edit instructions other than the +// |result_id|. +void LoopUnrollerUtilsImpl::CopyBasicBlock(Loop* loop, const BasicBlock* itr, + bool preserve_instructions) { + // Clone the block exactly, including the IDs. + BasicBlock* basic_block = itr->Clone(context_); + basic_block->SetParent(itr->GetParent()); + + // We do not want to duplicate DebugDeclare. + KillDebugDeclares(basic_block); + + // Assign each result a new unique ID and keep a mapping of the old ids to + // the new ones. + AssignNewResultIds(basic_block); + + // If this is the continue block we are copying. + if (itr == loop->GetContinueBlock()) { + // Make the OpLoopMerge point to this block for the continue. + if (!preserve_instructions) { + Instruction* merge_inst = loop->GetHeaderBlock()->GetLoopMergeInst(); + merge_inst->SetInOperand(1, {basic_block->id()}); + context_->UpdateDefUse(merge_inst); + } + + state_.new_continue_block = basic_block; + } + + // If this is the header block we are copying. + if (itr == loop->GetHeaderBlock()) { + state_.new_header_block = basic_block; + + if (!preserve_instructions) { + // Remove the loop merge instruction if it exists. + Instruction* merge_inst = basic_block->GetLoopMergeInst(); + if (merge_inst) invalidated_instructions_.push_back(merge_inst); + } + } + + // If this is the latch block being copied, record it in the state. + if (itr == loop->GetLatchBlock()) state_.new_latch_block = basic_block; + + // If this is the condition block we are copying. + if (itr == loop_condition_block_) { + state_.new_condition_block = basic_block; + } + + // Add this block to the list of blocks to add to the function at the end of + // the unrolling process. + blocks_to_add_.push_back(std::unique_ptr(basic_block)); + + // Keep tracking the old block via a map. + state_.new_blocks[itr->id()] = basic_block; +} + +void LoopUnrollerUtilsImpl::CopyBody(Loop* loop, bool eliminate_conditions) { + // Copy each basic block in the loop, give them new ids, and save state + // information. + for (const BasicBlock* itr : loop_blocks_inorder_) { + CopyBasicBlock(loop, itr, false); + } + + // Set the previous latch block to point to the new header. + Instruction* latch_branch = state_.previous_latch_block_->terminator(); + latch_branch->SetInOperand(0, {state_.new_header_block->id()}); + context_->UpdateDefUse(latch_branch); + + // As the algorithm copies the original loop blocks exactly, the tail of the + // latch block on iterations after the first one will be a branch to the new + // header and not the actual loop header. The last continue block in the loop + // should always be a backedge to the global header. + Instruction* new_latch_branch = state_.new_latch_block->terminator(); + new_latch_branch->SetInOperand(0, {loop->GetHeaderBlock()->id()}); + context_->AnalyzeUses(new_latch_branch); + + std::vector inductions; + loop->GetInductionVariables(inductions); + for (size_t index = 0; index < inductions.size(); ++index) { + Instruction* primary_copy = inductions[index]; + + assert(primary_copy->result_id() != 0); + Instruction* induction_clone = + state_.ids_to_new_inst[state_.new_inst[primary_copy->result_id()]]; + + state_.new_phis_.push_back(induction_clone); + assert(induction_clone->result_id() != 0); + + if (!state_.previous_phis_.empty()) { + state_.new_inst[primary_copy->result_id()] = GetPhiDefID( + state_.previous_phis_[index], state_.previous_latch_block_->id()); + } else { + // Do not replace the first phi block ids. + state_.new_inst[primary_copy->result_id()] = primary_copy->result_id(); + } + } + + if (eliminate_conditions && + state_.new_condition_block != loop_condition_block_) { + FoldConditionBlock(state_.new_condition_block, 1); + } + + // Only reference to the header block is the backedge in the latch block, + // don't change this. + state_.new_inst[loop->GetHeaderBlock()->id()] = loop->GetHeaderBlock()->id(); + + for (auto& pair : state_.new_blocks) { + RemapOperands(pair.second); + } + + for (Instruction* dead_phi : state_.new_phis_) + invalidated_instructions_.push_back(dead_phi); + + // Swap the state so the new is now the previous. + state_.NextIterationState(); +} + +uint32_t LoopUnrollerUtilsImpl::GetPhiDefID(const Instruction* phi, + uint32_t label) const { + for (uint32_t operand = 3; operand < phi->NumOperands(); operand += 2) { + if (phi->GetSingleWordOperand(operand) == label) { + return phi->GetSingleWordOperand(operand - 1); + } + } + assert(false && "Could not find a phi index matching the provided label"); + return 0; +} + +void LoopUnrollerUtilsImpl::FoldConditionBlock(BasicBlock* condition_block, + uint32_t operand_label) { + // Remove the old conditional branch to the merge and continue blocks. + Instruction& old_branch = *condition_block->tail(); + uint32_t new_target = old_branch.GetSingleWordOperand(operand_label); + + DebugScope scope = old_branch.GetDebugScope(); + const std::vector lines = old_branch.dbg_line_insts(); + + context_->KillInst(&old_branch); + // Add the new unconditional branch to the merge block. + InstructionBuilder builder( + context_, condition_block, + IRContext::Analysis::kAnalysisDefUse | + IRContext::Analysis::kAnalysisInstrToBlockMapping); + Instruction* new_branch = builder.AddBranch(new_target); + + if (!lines.empty()) new_branch->AddDebugLine(&lines.back()); + new_branch->SetDebugScope(scope); +} + +void LoopUnrollerUtilsImpl::CloseUnrolledLoop(Loop* loop) { + // Remove the OpLoopMerge instruction from the function. + Instruction* merge_inst = loop->GetHeaderBlock()->GetLoopMergeInst(); + invalidated_instructions_.push_back(merge_inst); + + // Remove the final backedge to the header and make it point instead to the + // merge block. + Instruction* latch_instruction = state_.previous_latch_block_->terminator(); + latch_instruction->SetInOperand(0, {loop->GetMergeBlock()->id()}); + context_->UpdateDefUse(latch_instruction); + + // Remove all induction variables as the phis will now be invalid. Replace all + // uses with the constant initializer value (all uses of phis will be in + // the first iteration with the subsequent phis already having been removed). + std::vector inductions; + loop->GetInductionVariables(inductions); + + // We can use the state instruction mechanism to replace all internal loop + // values within the first loop trip (as the subsequent ones will be updated + // by the copy function) with the value coming in from the preheader and then + // use context ReplaceAllUsesWith for the uses outside the loop with the final + // trip phi value. + state_.new_inst.clear(); + for (Instruction* induction : inductions) { + uint32_t initalizer_id = + GetPhiDefID(induction, loop->GetPreHeaderBlock()->id()); + + state_.new_inst[induction->result_id()] = initalizer_id; + } + + for (BasicBlock* block : loop_blocks_inorder_) { + RemapOperands(block); + } + for (auto& block_itr : blocks_to_add_) { + RemapOperands(block_itr.get()); + } + + // Rewrite the last phis, since they may still reference the original phi. + for (Instruction* last_phi : state_.previous_phis_) { + RemapOperands(last_phi); + } +} + +// Uses the first loop to create a copy of the loop with new IDs. +void LoopUnrollerUtilsImpl::DuplicateLoop(Loop* old_loop, Loop* new_loop) { + std::vector new_block_order; + + // Copy every block in the old loop. + for (const BasicBlock* itr : loop_blocks_inorder_) { + CopyBasicBlock(old_loop, itr, true); + new_block_order.push_back(blocks_to_add_.back().get()); + } + + // Clone the merge block, give it a new id and record it in the state. + BasicBlock* new_merge = old_loop->GetMergeBlock()->Clone(context_); + new_merge->SetParent(old_loop->GetMergeBlock()->GetParent()); + AssignNewResultIds(new_merge); + state_.new_blocks[old_loop->GetMergeBlock()->id()] = new_merge; + + // Remap the operands of every instruction in the loop to point to the new + // copies. + for (auto& pair : state_.new_blocks) { + RemapOperands(pair.second); + } + + loop_blocks_inorder_ = std::move(new_block_order); + + AddBlocksToLoop(new_loop); + + new_loop->SetHeaderBlock(state_.new_header_block); + new_loop->SetContinueBlock(state_.new_continue_block); + new_loop->SetLatchBlock(state_.new_latch_block); + new_loop->SetMergeBlock(new_merge); +} + +// Whenever the utility copies a block it stores it in a temporary buffer, this +// function adds the buffer into the Function. The blocks will be inserted +// after the block |insert_point|. +void LoopUnrollerUtilsImpl::AddBlocksToFunction( + const BasicBlock* insert_point) { + for (auto basic_block_iterator = function_.begin(); + basic_block_iterator != function_.end(); ++basic_block_iterator) { + if (basic_block_iterator->id() == insert_point->id()) { + basic_block_iterator.InsertBefore(&blocks_to_add_); + return; + } + } + + assert( + false && + "Could not add basic blocks to function as insert point was not found."); +} + +// Assign all result_ids in |basic_block| instructions to new IDs and preserve +// the mapping of new ids to old ones. +void LoopUnrollerUtilsImpl::AssignNewResultIds(BasicBlock* basic_block) { + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + // Label instructions aren't covered by normal traversal of the + // instructions. + // TODO(1841): Handle id overflow. + uint32_t new_label_id = context_->TakeNextId(); + + // Assign a new id to the label. + state_.new_inst[basic_block->GetLabelInst()->result_id()] = new_label_id; + basic_block->GetLabelInst()->SetResultId(new_label_id); + def_use_mgr->AnalyzeInstDefUse(basic_block->GetLabelInst()); + + for (Instruction& inst : *basic_block) { + // Do def/use analysis on new lines + for (auto& line : inst.dbg_line_insts()) + def_use_mgr->AnalyzeInstDefUse(&line); + + uint32_t old_id = inst.result_id(); + + // Ignore stores etc. + if (old_id == 0) { + continue; + } + + // Give the instruction a new id. + // TODO(1841): Handle id overflow. + inst.SetResultId(context_->TakeNextId()); + def_use_mgr->AnalyzeInstDef(&inst); + + // Save the mapping of old_id -> new_id. + state_.new_inst[old_id] = inst.result_id(); + // Check if this instruction is the induction variable. + if (loop_induction_variable_->result_id() == old_id) { + // Save a pointer to the new copy of it. + state_.new_phi = &inst; + } + state_.ids_to_new_inst[inst.result_id()] = &inst; + } +} + +void LoopUnrollerUtilsImpl::RemapOperands(Instruction* inst) { + auto remap_operands_to_new_ids = [this](uint32_t* id) { + auto itr = state_.new_inst.find(*id); + + if (itr != state_.new_inst.end()) { + *id = itr->second; + } + }; + + inst->ForEachInId(remap_operands_to_new_ids); + context_->AnalyzeUses(inst); +} + +void LoopUnrollerUtilsImpl::RemapOperands(BasicBlock* basic_block) { + for (Instruction& inst : *basic_block) { + RemapOperands(&inst); + } +} + +// Generate the ordered list of basic blocks in the |loop| and cache it for +// later use. +void LoopUnrollerUtilsImpl::ComputeLoopOrderedBlocks(Loop* loop) { + loop_blocks_inorder_.clear(); + loop->ComputeLoopStructuredOrder(&loop_blocks_inorder_); +} + +// Adds the blocks_to_add_ to both the loop and to the parent. +void LoopUnrollerUtilsImpl::AddBlocksToLoop(Loop* loop) const { + // Add the blocks to this loop. + for (auto& block_itr : blocks_to_add_) { + loop->AddBasicBlock(block_itr.get()); + } + + // Add the blocks to the parent as well. + if (loop->GetParent()) AddBlocksToLoop(loop->GetParent()); +} + +void LoopUnrollerUtilsImpl::LinkLastPhisToStart(Loop* loop) const { + std::vector inductions; + loop->GetInductionVariables(inductions); + + for (size_t i = 0; i < inductions.size(); ++i) { + Instruction* last_phi_in_block = state_.previous_phis_[i]; + + uint32_t phi_index = + GetPhiIndexFromLabel(state_.previous_latch_block_, last_phi_in_block); + uint32_t phi_variable = + last_phi_in_block->GetSingleWordInOperand(phi_index - 1); + uint32_t phi_label = last_phi_in_block->GetSingleWordInOperand(phi_index); + + Instruction* phi = inductions[i]; + phi->SetInOperand(phi_index - 1, {phi_variable}); + phi->SetInOperand(phi_index, {phi_label}); + } +} + +// Duplicate the |loop| body |factor| number of times while keeping the loop +// backedge intact. +void LoopUnrollerUtilsImpl::PartiallyUnroll(Loop* loop, size_t factor) { + Unroll(loop, factor); + LinkLastPhisToStart(loop); + AddBlocksToLoop(loop); + AddBlocksToFunction(loop->GetMergeBlock()); + RemoveDeadInstructions(); +} + +/* + * End LoopUtilsImpl. + */ + +} // namespace + +/* + * + * Begin Utils. + * + * */ + +bool LoopUtils::CanPerformUnroll() { + // The loop is expected to be in structured order. + if (!loop_->GetHeaderBlock()->GetMergeInst()) { + return false; + } + + // Find check the loop has a condition we can find and evaluate. + const BasicBlock* condition = loop_->FindConditionBlock(); + if (!condition) return false; + + // Check that we can find and process the induction variable. + const Instruction* induction = loop_->FindConditionVariable(condition); + if (!induction || induction->opcode() != spv::Op::OpPhi) return false; + + // Check that we can find the number of loop iterations. + if (!loop_->FindNumberOfIterations(induction, &*condition->ctail(), nullptr)) + return false; + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + // ClusterFuzz/OSS-Fuzz is likely to yield examples with very high loop + // iteration counts. This can cause timeouts and memouts during fuzzing that + // are not classed as bugs. To avoid this noise, loop unrolling is not applied + // to loops with large iteration counts when fuzzing. + constexpr size_t kFuzzerIterationLimit = 100; + size_t num_iterations; + loop_->FindNumberOfIterations(induction, &*condition->ctail(), + &num_iterations); + if (num_iterations > kFuzzerIterationLimit) { + return false; + } +#endif + + // Make sure the latch block is a unconditional branch to the header + // block. + const Instruction& branch = *loop_->GetLatchBlock()->ctail(); + bool branching_assumption = + branch.opcode() == spv::Op::OpBranch && + branch.GetSingleWordInOperand(0) == loop_->GetHeaderBlock()->id(); + if (!branching_assumption) { + return false; + } + + std::vector inductions; + loop_->GetInductionVariables(inductions); + + // Ban breaks within the loop. + const std::vector& merge_block_preds = + context_->cfg()->preds(loop_->GetMergeBlock()->id()); + if (merge_block_preds.size() != 1) { + return false; + } + + // Ban continues within the loop. + const std::vector& continue_block_preds = + context_->cfg()->preds(loop_->GetContinueBlock()->id()); + if (continue_block_preds.size() != 1) { + return false; + } + + // Ban returns in the loop. + // Iterate over all the blocks within the loop and check that none of them + // exit the loop. + for (uint32_t label_id : loop_->GetBlocks()) { + const BasicBlock* block = context_->cfg()->block(label_id); + if (block->ctail()->opcode() == spv::Op::OpKill || + block->ctail()->opcode() == spv::Op::OpReturn || + block->ctail()->opcode() == spv::Op::OpReturnValue || + block->ctail()->opcode() == spv::Op::OpTerminateInvocation) { + return false; + } + } + // Can only unroll inner loops. + if (!loop_->AreAllChildrenMarkedForRemoval()) { + return false; + } + + return true; +} + +bool LoopUtils::PartiallyUnroll(size_t factor) { + if (factor == 1 || !CanPerformUnroll()) return false; + + // Create the unroller utility. + LoopUnrollerUtilsImpl unroller{context_, + loop_->GetHeaderBlock()->GetParent()}; + unroller.Init(loop_); + + // If the unrolling factor is larger than or the same size as the loop just + // fully unroll the loop. + if (factor >= unroller.GetLoopIterationCount()) { + unroller.FullyUnroll(loop_); + return true; + } + + // If the loop unrolling factor is an residual number of iterations we need to + // let run the loop for the residual part then let it branch into the unrolled + // remaining part. We add one when calucating the remainder to take into + // account the one iteration already in the loop. + if (unroller.GetLoopIterationCount() % factor != 0) { + unroller.PartiallyUnrollResidualFactor(loop_, factor); + } else { + unroller.PartiallyUnroll(loop_, factor); + } + + return true; +} + +bool LoopUtils::FullyUnroll() { + if (!CanPerformUnroll()) return false; + + std::vector inductions; + loop_->GetInductionVariables(inductions); + + LoopUnrollerUtilsImpl unroller{context_, + loop_->GetHeaderBlock()->GetParent()}; + + unroller.Init(loop_); + unroller.FullyUnroll(loop_); + + return true; +} + +void LoopUtils::Finalize() { + // Clean up the loop descriptor to preserve the analysis. + + LoopDescriptor* LD = context_->GetLoopDescriptor(&function_); + LD->PostModificationCleanup(); +} + +/* + * + * Begin Pass. + * + */ + +Pass::Status LoopUnroller::Process() { + bool changed = false; + for (Function& f : *context()->module()) { + if (f.IsDeclaration()) { + continue; + } + + LoopDescriptor* LD = context()->GetLoopDescriptor(&f); + for (Loop& loop : *LD) { + LoopUtils loop_utils{context(), &loop}; + if (!loop.HasUnrollLoopControl() || !loop_utils.CanPerformUnroll()) { + continue; + } + + if (fully_unroll_) { + loop_utils.FullyUnroll(); + } else { + loop_utils.PartiallyUnroll(unroll_factor_); + } + changed = true; + } + LD->PostModificationCleanup(); + } + + return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_unroller.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_unroller.h new file mode 100644 index 000000000000..71e7cca3167f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_unroller.h @@ -0,0 +1,49 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_UNROLLER_H_ +#define SOURCE_OPT_LOOP_UNROLLER_H_ + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +class LoopUnroller : public Pass { + public: + LoopUnroller() : Pass(), fully_unroll_(true), unroll_factor_(0) {} + LoopUnroller(bool fully_unroll, int unroll_factor) + : Pass(), fully_unroll_(fully_unroll), unroll_factor_(unroll_factor) {} + + const char* name() const override { return "loop-unroll"; } + + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + bool fully_unroll_; + int unroll_factor_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_UNROLLER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_unswitch_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_unswitch_pass.cpp new file mode 100644 index 000000000000..41f1a804bf34 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_unswitch_pass.cpp @@ -0,0 +1,614 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/loop_unswitch_pass.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/dominator_tree.h" +#include "source/opt/fold.h" +#include "source/opt/function.h" +#include "source/opt/instruction.h" +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/opt/loop_descriptor.h" +#include "source/opt/loop_utils.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kTypePointerStorageClassInIdx = 0; + +// This class handle the unswitch procedure for a given loop. +// The unswitch will not happen if: +// - The loop has any instruction that will prevent it; +// - The loop invariant condition is not uniform. +class LoopUnswitch { + public: + LoopUnswitch(IRContext* context, Function* function, Loop* loop, + LoopDescriptor* loop_desc) + : function_(function), + loop_(loop), + loop_desc_(*loop_desc), + context_(context), + switch_block_(nullptr) {} + + // Returns true if the loop can be unswitched. + // Can be unswitch if: + // - The loop has no instructions that prevents it (such as barrier); + // - The loop has one conditional branch or switch that do not depends on the + // loop; + // - The loop invariant condition is uniform; + bool CanUnswitchLoop() { + if (switch_block_) return true; + if (loop_->IsSafeToClone()) return false; + + CFG& cfg = *context_->cfg(); + + for (uint32_t bb_id : loop_->GetBlocks()) { + BasicBlock* bb = cfg.block(bb_id); + if (loop_->GetLatchBlock() == bb) { + continue; + } + + if (bb->terminator()->IsBranch() && + bb->terminator()->opcode() != spv::Op::OpBranch) { + if (IsConditionNonConstantLoopInvariant(bb->terminator())) { + switch_block_ = bb; + break; + } + } + } + + return switch_block_; + } + + // Return the iterator to the basic block |bb|. + Function::iterator FindBasicBlockPosition(BasicBlock* bb_to_find) { + Function::iterator it = function_->FindBlock(bb_to_find->id()); + assert(it != function_->end() && "Basic Block not found"); + return it; + } + + // Creates a new basic block and insert it into the function |fn| at the + // position |ip|. This function preserves the def/use and instr to block + // managers. + BasicBlock* CreateBasicBlock(Function::iterator ip) { + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + // TODO(1841): Handle id overflow. + BasicBlock* bb = &*ip.InsertBefore(std::unique_ptr( + new BasicBlock(std::unique_ptr(new Instruction( + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))))); + bb->SetParent(function_); + def_use_mgr->AnalyzeInstDef(bb->GetLabelInst()); + context_->set_instr_block(bb->GetLabelInst(), bb); + + return bb; + } + + Instruction* GetValueForDefaultPathForSwitch(Instruction* switch_inst) { + assert(switch_inst->opcode() == spv::Op::OpSwitch && + "The given instructoin must be an OpSwitch."); + + // Find a value that can be used to select the default path. + // If none are possible, then it will just use 0. The value does not matter + // because this path will never be taken because the new switch outside of + // the loop cannot select this path either. + std::vector existing_values; + for (uint32_t i = 2; i < switch_inst->NumInOperands(); i += 2) { + existing_values.push_back(switch_inst->GetSingleWordInOperand(i)); + } + std::sort(existing_values.begin(), existing_values.end()); + uint32_t value_for_default_path = 0; + if (existing_values.size() < std::numeric_limits::max()) { + for (value_for_default_path = 0; + value_for_default_path < existing_values.size(); + value_for_default_path++) { + if (existing_values[value_for_default_path] != value_for_default_path) { + break; + } + } + } + InstructionBuilder builder( + context_, static_cast(nullptr), + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + return builder.GetUintConstant(value_for_default_path); + } + + // Unswitches |loop_|. + void PerformUnswitch() { + assert(CanUnswitchLoop() && + "Cannot unswitch if there is not constant condition"); + assert(loop_->GetPreHeaderBlock() && "This loop has no pre-header block"); + assert(loop_->IsLCSSA() && "This loop is not in LCSSA form"); + + CFG& cfg = *context_->cfg(); + DominatorTree* dom_tree = + &context_->GetDominatorAnalysis(function_)->GetDomTree(); + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + LoopUtils loop_utils(context_, loop_); + + ////////////////////////////////////////////////////////////////////////////// + // Step 1: Create the if merge block for structured modules. + // To do so, the |loop_| merge block will become the if's one and we + // create a merge for the loop. This will limit the amount of duplicated + // code the structured control flow imposes. + // For non structured program, the new loop will be connected to + // the old loop's exit blocks. + ////////////////////////////////////////////////////////////////////////////// + + // Get the merge block if it exists. + BasicBlock* if_merge_block = loop_->GetMergeBlock(); + // The merge block is only created if the loop has a unique exit block. We + // have this guarantee for structured loops, for compute loop it will + // trivially help maintain both a structured-like form and LCSAA. + BasicBlock* loop_merge_block = + if_merge_block + ? CreateBasicBlock(FindBasicBlockPosition(if_merge_block)) + : nullptr; + if (loop_merge_block) { + // Add the instruction and update managers. + InstructionBuilder builder( + context_, loop_merge_block, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + builder.AddBranch(if_merge_block->id()); + builder.SetInsertPoint(&*loop_merge_block->begin()); + cfg.RegisterBlock(loop_merge_block); + def_use_mgr->AnalyzeInstDef(loop_merge_block->GetLabelInst()); + // Update CFG. + if_merge_block->ForEachPhiInst( + [loop_merge_block, &builder, this](Instruction* phi) { + Instruction* cloned = phi->Clone(context_); + cloned->SetResultId(TakeNextId()); + builder.AddInstruction(std::unique_ptr(cloned)); + phi->SetInOperand(0, {cloned->result_id()}); + phi->SetInOperand(1, {loop_merge_block->id()}); + for (uint32_t j = phi->NumInOperands() - 1; j > 1; j--) + phi->RemoveInOperand(j); + }); + // Copy the predecessor list (will get invalidated otherwise). + std::vector preds = cfg.preds(if_merge_block->id()); + for (uint32_t pid : preds) { + if (pid == loop_merge_block->id()) continue; + BasicBlock* p_bb = cfg.block(pid); + p_bb->ForEachSuccessorLabel( + [if_merge_block, loop_merge_block](uint32_t* id) { + if (*id == if_merge_block->id()) *id = loop_merge_block->id(); + }); + cfg.AddEdge(pid, loop_merge_block->id()); + } + cfg.RemoveNonExistingEdges(if_merge_block->id()); + // Update loop descriptor. + if (Loop* ploop = loop_->GetParent()) { + ploop->AddBasicBlock(loop_merge_block); + loop_desc_.SetBasicBlockToLoop(loop_merge_block->id(), ploop); + } + // Update the dominator tree. + DominatorTreeNode* loop_merge_dtn = + dom_tree->GetOrInsertNode(loop_merge_block); + DominatorTreeNode* if_merge_block_dtn = + dom_tree->GetOrInsertNode(if_merge_block); + loop_merge_dtn->parent_ = if_merge_block_dtn->parent_; + loop_merge_dtn->children_.push_back(if_merge_block_dtn); + loop_merge_dtn->parent_->children_.push_back(loop_merge_dtn); + if_merge_block_dtn->parent_->children_.erase(std::find( + if_merge_block_dtn->parent_->children_.begin(), + if_merge_block_dtn->parent_->children_.end(), if_merge_block_dtn)); + + loop_->SetMergeBlock(loop_merge_block); + } + + //////////////////////////////////////////////////////////////////////////// + // Step 2: Build a new preheader for |loop_|, use the old one + // for the invariant branch. + //////////////////////////////////////////////////////////////////////////// + + BasicBlock* if_block = loop_->GetPreHeaderBlock(); + // If this preheader is the parent loop header, + // we need to create a dedicated block for the if. + BasicBlock* loop_pre_header = + CreateBasicBlock(++FindBasicBlockPosition(if_block)); + InstructionBuilder( + context_, loop_pre_header, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping) + .AddBranch(loop_->GetHeaderBlock()->id()); + + if_block->tail()->SetInOperand(0, {loop_pre_header->id()}); + + // Update loop descriptor. + if (Loop* ploop = loop_desc_[if_block]) { + ploop->AddBasicBlock(loop_pre_header); + loop_desc_.SetBasicBlockToLoop(loop_pre_header->id(), ploop); + } + + // Update the CFG. + cfg.RegisterBlock(loop_pre_header); + def_use_mgr->AnalyzeInstDef(loop_pre_header->GetLabelInst()); + cfg.AddEdge(if_block->id(), loop_pre_header->id()); + cfg.RemoveNonExistingEdges(loop_->GetHeaderBlock()->id()); + + loop_->GetHeaderBlock()->ForEachPhiInst( + [loop_pre_header, if_block](Instruction* phi) { + phi->ForEachInId([loop_pre_header, if_block](uint32_t* id) { + if (*id == if_block->id()) { + *id = loop_pre_header->id(); + } + }); + }); + loop_->SetPreHeaderBlock(loop_pre_header); + + // Update the dominator tree. + DominatorTreeNode* loop_pre_header_dtn = + dom_tree->GetOrInsertNode(loop_pre_header); + DominatorTreeNode* if_block_dtn = dom_tree->GetTreeNode(if_block); + loop_pre_header_dtn->parent_ = if_block_dtn; + assert( + if_block_dtn->children_.size() == 1 && + "A loop preheader should only have the header block as a child in the " + "dominator tree"); + loop_pre_header_dtn->children_.push_back(if_block_dtn->children_[0]); + if_block_dtn->children_.clear(); + if_block_dtn->children_.push_back(loop_pre_header_dtn); + + // Make domination queries valid. + dom_tree->ResetDFNumbering(); + + // Compute an ordered list of basic block to clone: loop blocks + pre-header + // + merge block. + loop_->ComputeLoopStructuredOrder(&ordered_loop_blocks_, true, true); + + ///////////////////////////// + // Do the actual unswitch: // + // - Clone the loop // + // - Connect exits // + // - Specialize the loop // + ///////////////////////////// + + Instruction* iv_condition = &*switch_block_->tail(); + spv::Op iv_opcode = iv_condition->opcode(); + Instruction* condition = + def_use_mgr->GetDef(iv_condition->GetOperand(0).words[0]); + + analysis::ConstantManager* cst_mgr = context_->get_constant_mgr(); + const analysis::Type* cond_type = + context_->get_type_mgr()->GetType(condition->type_id()); + + // Build the list of value for which we need to clone and specialize the + // loop. + std::vector> constant_branch; + // Special case for the original loop + Instruction* original_loop_constant_value; + if (iv_opcode == spv::Op::OpBranchConditional) { + constant_branch.emplace_back( + cst_mgr->GetDefiningInstruction(cst_mgr->GetConstant(cond_type, {0})), + nullptr); + original_loop_constant_value = + cst_mgr->GetDefiningInstruction(cst_mgr->GetConstant(cond_type, {1})); + } else { + // We are looking to take the default branch, so we can't provide a + // specific value. + original_loop_constant_value = + GetValueForDefaultPathForSwitch(iv_condition); + + for (uint32_t i = 2; i < iv_condition->NumInOperands(); i += 2) { + constant_branch.emplace_back( + cst_mgr->GetDefiningInstruction(cst_mgr->GetConstant( + cond_type, iv_condition->GetInOperand(i).words)), + nullptr); + } + } + + // Get the loop landing pads. + std::unordered_set if_merging_blocks; + std::function is_from_original_loop; + if (loop_->GetHeaderBlock()->GetLoopMergeInst()) { + if_merging_blocks.insert(if_merge_block->id()); + is_from_original_loop = [this](uint32_t id) { + return loop_->IsInsideLoop(id) || loop_->GetMergeBlock()->id() == id; + }; + } else { + loop_->GetExitBlocks(&if_merging_blocks); + is_from_original_loop = [this](uint32_t id) { + return loop_->IsInsideLoop(id); + }; + } + + for (auto& specialisation_pair : constant_branch) { + Instruction* specialisation_value = specialisation_pair.first; + ////////////////////////////////////////////////////////// + // Step 3: Duplicate |loop_|. + ////////////////////////////////////////////////////////// + LoopUtils::LoopCloningResult clone_result; + + Loop* cloned_loop = + loop_utils.CloneLoop(&clone_result, ordered_loop_blocks_); + specialisation_pair.second = cloned_loop->GetPreHeaderBlock(); + + //////////////////////////////////// + // Step 4: Specialize the loop. // + //////////////////////////////////// + + { + SpecializeLoop(cloned_loop, condition, specialisation_value); + + /////////////////////////////////////////////////////////// + // Step 5: Connect convergent edges to the landing pads. // + /////////////////////////////////////////////////////////// + + for (uint32_t merge_bb_id : if_merging_blocks) { + BasicBlock* merge = context_->cfg()->block(merge_bb_id); + // We are in LCSSA so we only care about phi instructions. + merge->ForEachPhiInst( + [is_from_original_loop, &clone_result](Instruction* phi) { + uint32_t num_in_operands = phi->NumInOperands(); + for (uint32_t i = 0; i < num_in_operands; i += 2) { + uint32_t pred = phi->GetSingleWordInOperand(i + 1); + if (is_from_original_loop(pred)) { + pred = clone_result.value_map_.at(pred); + uint32_t incoming_value_id = phi->GetSingleWordInOperand(i); + // Not all the incoming values are coming from the loop. + ValueMapTy::iterator new_value = + clone_result.value_map_.find(incoming_value_id); + if (new_value != clone_result.value_map_.end()) { + incoming_value_id = new_value->second; + } + phi->AddOperand({SPV_OPERAND_TYPE_ID, {incoming_value_id}}); + phi->AddOperand({SPV_OPERAND_TYPE_ID, {pred}}); + } + } + }); + } + } + function_->AddBasicBlocks(clone_result.cloned_bb_.begin(), + clone_result.cloned_bb_.end(), + ++FindBasicBlockPosition(if_block)); + } + + // Specialize the existing loop. + SpecializeLoop(loop_, condition, original_loop_constant_value); + BasicBlock* original_loop_target = loop_->GetPreHeaderBlock(); + + ///////////////////////////////////// + // Finally: connect the new loops. // + ///////////////////////////////////// + + // Delete the old jump + context_->KillInst(&*if_block->tail()); + InstructionBuilder builder(context_, if_block); + if (iv_opcode == spv::Op::OpBranchConditional) { + assert(constant_branch.size() == 1); + builder.AddConditionalBranch( + condition->result_id(), original_loop_target->id(), + constant_branch[0].second->id(), + if_merge_block ? if_merge_block->id() : kInvalidId); + } else { + std::vector> targets; + for (auto& t : constant_branch) { + targets.emplace_back(t.first->GetInOperand(0).words, t.second->id()); + } + + builder.AddSwitch(condition->result_id(), original_loop_target->id(), + targets, + if_merge_block ? if_merge_block->id() : kInvalidId); + } + + switch_block_ = nullptr; + ordered_loop_blocks_.clear(); + + context_->InvalidateAnalysesExceptFor( + IRContext::Analysis::kAnalysisLoopAnalysis); + } + + private: + using ValueMapTy = std::unordered_map; + using BlockMapTy = std::unordered_map; + + Function* function_; + Loop* loop_; + LoopDescriptor& loop_desc_; + IRContext* context_; + + BasicBlock* switch_block_; + // Map between instructions and if they are dynamically uniform. + std::unordered_map dynamically_uniform_; + // The loop basic blocks in structured order. + std::vector ordered_loop_blocks_; + + // Returns the next usable id for the context. + uint32_t TakeNextId() { + // TODO(1841): Handle id overflow. + return context_->TakeNextId(); + } + + // Simplifies |loop| assuming the instruction |to_version_insn| takes the + // value |cst_value|. |block_range| is an iterator range returning the loop + // basic blocks in a structured order (dominator first). + // The function will ignore basic blocks returned by |block_range| if they + // does not belong to the loop. + // The set |dead_blocks| will contain all the dead basic blocks. + // + // Requirements: + // - |loop| must be in the LCSSA form; + // - |cst_value| must be constant. + void SpecializeLoop(Loop* loop, Instruction* to_version_insn, + Instruction* cst_value) { + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + std::function ignore_node; + ignore_node = [loop](uint32_t bb_id) { return !loop->IsInsideLoop(bb_id); }; + + std::vector> use_list; + def_use_mgr->ForEachUse(to_version_insn, + [&use_list, &ignore_node, this]( + Instruction* inst, uint32_t operand_index) { + BasicBlock* bb = context_->get_instr_block(inst); + + if (!bb || ignore_node(bb->id())) { + // Out of the loop, the specialization does not + // apply any more. + return; + } + use_list.emplace_back(inst, operand_index); + }); + + // First pass: inject the specialized value into the loop (and only the + // loop). + for (auto use : use_list) { + Instruction* inst = use.first; + uint32_t operand_index = use.second; + + // To also handle switch, cst_value can be nullptr: this case + // means that we are looking to branch to the default target of + // the switch. We don't actually know its value so we don't touch + // it if it not a switch. + assert(cst_value && "We do not have a value to use."); + inst->SetOperand(operand_index, {cst_value->result_id()}); + def_use_mgr->AnalyzeInstUse(inst); + } + } + + // Returns true if |var| is dynamically uniform. + // Note: this is currently approximated as uniform. + bool IsDynamicallyUniform(Instruction* var, const BasicBlock* entry, + const DominatorTree& post_dom_tree) { + assert(post_dom_tree.IsPostDominator()); + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + auto it = dynamically_uniform_.find(var->result_id()); + + if (it != dynamically_uniform_.end()) return it->second; + + analysis::DecorationManager* dec_mgr = context_->get_decoration_mgr(); + + bool& is_uniform = dynamically_uniform_[var->result_id()]; + is_uniform = false; + + dec_mgr->WhileEachDecoration(var->result_id(), + uint32_t(spv::Decoration::Uniform), + [&is_uniform](const Instruction&) { + is_uniform = true; + return false; + }); + if (is_uniform) { + return is_uniform; + } + + BasicBlock* parent = context_->get_instr_block(var); + if (!parent) { + return is_uniform = true; + } + + if (!post_dom_tree.Dominates(parent->id(), entry->id())) { + return is_uniform = false; + } + if (var->opcode() == spv::Op::OpLoad) { + const uint32_t PtrTypeId = + def_use_mgr->GetDef(var->GetSingleWordInOperand(0))->type_id(); + const Instruction* PtrTypeInst = def_use_mgr->GetDef(PtrTypeId); + auto storage_class = spv::StorageClass( + PtrTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx)); + if (storage_class != spv::StorageClass::Uniform && + storage_class != spv::StorageClass::UniformConstant) { + return is_uniform = false; + } + } else { + if (!context_->IsCombinatorInstruction(var)) { + return is_uniform = false; + } + } + + return is_uniform = var->WhileEachInId([entry, &post_dom_tree, + this](const uint32_t* id) { + return IsDynamicallyUniform(context_->get_def_use_mgr()->GetDef(*id), + entry, post_dom_tree); + }); + } + + // Returns true if |insn| is not a constant, but is loop invariant and + // dynamically uniform. + bool IsConditionNonConstantLoopInvariant(Instruction* insn) { + assert(insn->IsBranch()); + assert(insn->opcode() != spv::Op::OpBranch); + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + Instruction* condition = def_use_mgr->GetDef(insn->GetOperand(0).words[0]); + if (condition->IsConstant()) { + return false; + } + + if (loop_->IsInsideLoop(condition)) { + return false; + } + + return IsDynamicallyUniform( + condition, function_->entry().get(), + context_->GetPostDominatorAnalysis(function_)->GetDomTree()); + } +}; + +} // namespace + +Pass::Status LoopUnswitchPass::Process() { + bool modified = false; + Module* module = context()->module(); + + // Process each function in the module + for (Function& f : *module) { + modified |= ProcessFunction(&f); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool LoopUnswitchPass::ProcessFunction(Function* f) { + bool modified = false; + std::unordered_set processed_loop; + + LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(f); + + bool loop_changed = true; + while (loop_changed) { + loop_changed = false; + for (Loop& loop : make_range( + ++TreeDFIterator(loop_descriptor.GetPlaceholderRootLoop()), + TreeDFIterator())) { + if (processed_loop.count(&loop)) continue; + processed_loop.insert(&loop); + + LoopUnswitch unswitcher(context(), f, &loop, &loop_descriptor); + while (unswitcher.CanUnswitchLoop()) { + if (!loop.IsLCSSA()) { + LoopUtils(context(), &loop).MakeLoopClosedSSA(); + } + modified = true; + loop_changed = true; + unswitcher.PerformUnswitch(); + } + if (loop_changed) break; + } + } + + return modified; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_unswitch_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_unswitch_pass.h new file mode 100644 index 000000000000..4f7295d437d3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_unswitch_pass.h @@ -0,0 +1,43 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_UNSWITCH_PASS_H_ +#define SOURCE_OPT_LOOP_UNSWITCH_PASS_H_ + +#include "source/opt/loop_descriptor.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// Implements the loop unswitch optimization. +// The loop unswitch hoists invariant "if" statements if the conditions are +// constant within the loop and clones the loop for each branch. +class LoopUnswitchPass : public Pass { + public: + const char* name() const override { return "loop-unswitch"; } + + // Processes the given |module|. Returns Status::Failure if errors occur when + // processing. Returns the corresponding Status::Success if processing is + // successful to indicate whether changes have been made to the module. + Pass::Status Process() override; + + private: + bool ProcessFunction(Function* f); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_UNSWITCH_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_utils.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/loop_utils.cpp new file mode 100644 index 000000000000..20494e12bae2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_utils.cpp @@ -0,0 +1,693 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include + +#include "source/cfa.h" +#include "source/opt/cfg.h" +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/opt/loop_descriptor.h" +#include "source/opt/loop_utils.h" + +namespace spvtools { +namespace opt { +namespace { +// Return true if |bb| is dominated by at least one block in |exits| +inline bool DominatesAnExit(BasicBlock* bb, + const std::unordered_set& exits, + const DominatorTree& dom_tree) { + for (BasicBlock* e_bb : exits) + if (dom_tree.Dominates(bb, e_bb)) return true; + return false; +} + +// Utility class to rewrite out-of-loop uses of an in-loop definition in terms +// of phi instructions to achieve a LCSSA form. +// For a given definition, the class user registers phi instructions using that +// definition in all loop exit blocks by which the definition escapes. +// Then, when rewriting a use of the definition, the rewriter walks the +// paths from the use the loop exits. At each step, it will insert a phi +// instruction to merge the incoming value according to exit blocks definition. +class LCSSARewriter { + public: + LCSSARewriter(IRContext* context, const DominatorTree& dom_tree, + const std::unordered_set& exit_bb, + BasicBlock* merge_block) + : context_(context), + cfg_(context_->cfg()), + dom_tree_(dom_tree), + exit_bb_(exit_bb), + merge_block_id_(merge_block ? merge_block->id() : 0) {} + + struct UseRewriter { + explicit UseRewriter(LCSSARewriter* base, const Instruction& def_insn) + : base_(base), def_insn_(def_insn) {} + // Rewrites the use of |def_insn_| by the instruction |user| at the index + // |operand_index| in terms of phi instruction. This recursively builds new + // phi instructions from |user| to the loop exit blocks' phis. The use of + // |def_insn_| in |user| is replaced by the relevant phi instruction at the + // end of the operation. + // It is assumed that |user| does not dominates any of the loop exit basic + // block. This operation does not update the def/use manager, instead it + // records what needs to be updated. The actual update is performed by + // UpdateManagers. + void RewriteUse(BasicBlock* bb, Instruction* user, uint32_t operand_index) { + assert( + (user->opcode() != spv::Op::OpPhi || bb != GetParent(user)) && + "The root basic block must be the incoming edge if |user| is a phi " + "instruction"); + assert((user->opcode() == spv::Op::OpPhi || bb == GetParent(user)) && + "The root basic block must be the instruction parent if |user| is " + "not " + "phi instruction"); + + Instruction* new_def = GetOrBuildIncoming(bb->id()); + + user->SetOperand(operand_index, {new_def->result_id()}); + rewritten_.insert(user); + } + + // In-place update of some managers (avoid full invalidation). + inline void UpdateManagers() { + analysis::DefUseManager* def_use_mgr = base_->context_->get_def_use_mgr(); + // Register all new definitions. + for (Instruction* insn : rewritten_) { + def_use_mgr->AnalyzeInstDef(insn); + } + // Register all new uses. + for (Instruction* insn : rewritten_) { + def_use_mgr->AnalyzeInstUse(insn); + } + } + + private: + // Return the basic block that |instr| belongs to. + BasicBlock* GetParent(Instruction* instr) { + return base_->context_->get_instr_block(instr); + } + + // Builds a phi instruction for the basic block |bb|. The function assumes + // that |defining_blocks| contains the list of basic block that define the + // usable value for each predecessor of |bb|. + inline Instruction* CreatePhiInstruction( + BasicBlock* bb, const std::vector& defining_blocks) { + std::vector incomings; + const std::vector& bb_preds = base_->cfg_->preds(bb->id()); + assert(bb_preds.size() == defining_blocks.size()); + for (size_t i = 0; i < bb_preds.size(); i++) { + incomings.push_back( + GetOrBuildIncoming(defining_blocks[i])->result_id()); + incomings.push_back(bb_preds[i]); + } + InstructionBuilder builder(base_->context_, &*bb->begin(), + IRContext::kAnalysisInstrToBlockMapping); + Instruction* incoming_phi = + builder.AddPhi(def_insn_.type_id(), incomings); + + rewritten_.insert(incoming_phi); + return incoming_phi; + } + + // Builds a phi instruction for the basic block |bb|, all incoming values + // will be |value|. + inline Instruction* CreatePhiInstruction(BasicBlock* bb, + const Instruction& value) { + std::vector incomings; + const std::vector& bb_preds = base_->cfg_->preds(bb->id()); + for (size_t i = 0; i < bb_preds.size(); i++) { + incomings.push_back(value.result_id()); + incomings.push_back(bb_preds[i]); + } + InstructionBuilder builder(base_->context_, &*bb->begin(), + IRContext::kAnalysisInstrToBlockMapping); + Instruction* incoming_phi = + builder.AddPhi(def_insn_.type_id(), incomings); + + rewritten_.insert(incoming_phi); + return incoming_phi; + } + + // Return the new def to use for the basic block |bb_id|. + // If |bb_id| does not have a suitable def to use then we: + // - return the common def used by all predecessors; + // - if there is no common def, then we build a new phi instr at the + // beginning of |bb_id| and return this new instruction. + Instruction* GetOrBuildIncoming(uint32_t bb_id) { + assert(base_->cfg_->block(bb_id) != nullptr && "Unknown basic block"); + + Instruction*& incoming_phi = bb_to_phi_[bb_id]; + if (incoming_phi) { + return incoming_phi; + } + + BasicBlock* bb = &*base_->cfg_->block(bb_id); + // If this is an exit basic block, look if there already is an eligible + // phi instruction. An eligible phi has |def_insn_| as all incoming + // values. + if (base_->exit_bb_.count(bb)) { + // Look if there is an eligible phi in this block. + if (!bb->WhileEachPhiInst([&incoming_phi, this](Instruction* phi) { + for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) { + if (phi->GetSingleWordInOperand(i) != def_insn_.result_id()) + return true; + } + incoming_phi = phi; + rewritten_.insert(incoming_phi); + return false; + })) { + return incoming_phi; + } + incoming_phi = CreatePhiInstruction(bb, def_insn_); + return incoming_phi; + } + + // Get the block that defines the value to use for each predecessor. + // If the vector has 1 value, then it means that this block does not need + // to build a phi instruction unless |bb_id| is the loop merge block. + const std::vector& defining_blocks = + base_->GetDefiningBlocks(bb_id); + + // Special case for structured loops: merge block might be different from + // the exit block set. To maintain structured properties it will ease + // transformations if the merge block also holds a phi instruction like + // the exit ones. + if (defining_blocks.size() > 1 || bb_id == base_->merge_block_id_) { + if (defining_blocks.size() > 1) { + incoming_phi = CreatePhiInstruction(bb, defining_blocks); + } else { + assert(bb_id == base_->merge_block_id_); + incoming_phi = + CreatePhiInstruction(bb, *GetOrBuildIncoming(defining_blocks[0])); + } + } else { + incoming_phi = GetOrBuildIncoming(defining_blocks[0]); + } + + return incoming_phi; + } + + LCSSARewriter* base_; + const Instruction& def_insn_; + std::unordered_map bb_to_phi_; + std::unordered_set rewritten_; + }; + + private: + // Return the new def to use for the basic block |bb_id|. + // If |bb_id| does not have a suitable def to use then we: + // - return the common def used by all predecessors; + // - if there is no common def, then we build a new phi instr at the + // beginning of |bb_id| and return this new instruction. + const std::vector& GetDefiningBlocks(uint32_t bb_id) { + assert(cfg_->block(bb_id) != nullptr && "Unknown basic block"); + std::vector& defining_blocks = bb_to_defining_blocks_[bb_id]; + + if (defining_blocks.size()) return defining_blocks; + + // Check if one of the loop exit basic block dominates |bb_id|. + for (const BasicBlock* e_bb : exit_bb_) { + if (dom_tree_.Dominates(e_bb->id(), bb_id)) { + defining_blocks.push_back(e_bb->id()); + return defining_blocks; + } + } + + // Process parents, they will returns their suitable blocks. + // If they are all the same, this means this basic block is dominated by a + // common block, so we won't need to build a phi instruction. + for (uint32_t pred_id : cfg_->preds(bb_id)) { + const std::vector& pred_blocks = GetDefiningBlocks(pred_id); + if (pred_blocks.size() == 1) + defining_blocks.push_back(pred_blocks[0]); + else + defining_blocks.push_back(pred_id); + } + assert(defining_blocks.size()); + if (std::all_of(defining_blocks.begin(), defining_blocks.end(), + [&defining_blocks](uint32_t id) { + return id == defining_blocks[0]; + })) { + // No need for a phi. + defining_blocks.resize(1); + } + + return defining_blocks; + } + + IRContext* context_; + CFG* cfg_; + const DominatorTree& dom_tree_; + const std::unordered_set& exit_bb_; + uint32_t merge_block_id_; + // This map represent the set of known paths. For each key, the vector + // represent the set of blocks holding the definition to be used to build the + // phi instruction. + // If the vector has 0 value, then the path is unknown yet, and must be built. + // If the vector has 1 value, then the value defined by that basic block + // should be used. + // If the vector has more than 1 value, then a phi node must be created, the + // basic block ordering is the same as the predecessor ordering. + std::unordered_map> bb_to_defining_blocks_; +}; + +// Make the set |blocks| closed SSA. The set is closed SSA if all the uses +// outside the set are phi instructions in exiting basic block set (hold by +// |lcssa_rewriter|). +inline void MakeSetClosedSSA(IRContext* context, Function* function, + const std::unordered_set& blocks, + const std::unordered_set& exit_bb, + LCSSARewriter* lcssa_rewriter) { + CFG& cfg = *context->cfg(); + DominatorTree& dom_tree = + context->GetDominatorAnalysis(function)->GetDomTree(); + analysis::DefUseManager* def_use_manager = context->get_def_use_mgr(); + + for (uint32_t bb_id : blocks) { + BasicBlock* bb = cfg.block(bb_id); + // If bb does not dominate an exit block, then it cannot have escaping defs. + if (!DominatesAnExit(bb, exit_bb, dom_tree)) continue; + for (Instruction& inst : *bb) { + LCSSARewriter::UseRewriter rewriter(lcssa_rewriter, inst); + def_use_manager->ForEachUse( + &inst, [&blocks, &rewriter, &exit_bb, context]( + Instruction* use, uint32_t operand_index) { + BasicBlock* use_parent = context->get_instr_block(use); + assert(use_parent); + if (blocks.count(use_parent->id())) return; + + if (use->opcode() == spv::Op::OpPhi) { + // If the use is a Phi instruction and the incoming block is + // coming from the loop, then that's consistent with LCSSA form. + if (exit_bb.count(use_parent)) { + return; + } else { + // That's not an exit block, but the user is a phi instruction. + // Consider the incoming branch only. + use_parent = context->get_instr_block( + use->GetSingleWordOperand(operand_index + 1)); + } + } + // Rewrite the use. Note that this call does not invalidate the + // def/use manager. So this operation is safe. + rewriter.RewriteUse(use_parent, use, operand_index); + }); + rewriter.UpdateManagers(); + } + } +} + +} // namespace + +void LoopUtils::CreateLoopDedicatedExits() { + Function* function = loop_->GetHeaderBlock()->GetParent(); + LoopDescriptor& loop_desc = *context_->GetLoopDescriptor(function); + CFG& cfg = *context_->cfg(); + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + const IRContext::Analysis PreservedAnalyses = + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping; + + // Gathers the set of basic block that are not in this loop and have at least + // one predecessor in the loop and one not in the loop. + std::unordered_set exit_bb_set; + loop_->GetExitBlocks(&exit_bb_set); + + std::unordered_set new_loop_exits; + bool made_change = false; + // For each block, we create a new one that gathers all branches from + // the loop and fall into the block. + for (uint32_t non_dedicate_id : exit_bb_set) { + BasicBlock* non_dedicate = cfg.block(non_dedicate_id); + const std::vector& bb_pred = cfg.preds(non_dedicate_id); + // Ignore the block if all the predecessors are in the loop. + if (std::all_of(bb_pred.begin(), bb_pred.end(), + [this](uint32_t id) { return loop_->IsInsideLoop(id); })) { + new_loop_exits.insert(non_dedicate); + continue; + } + + made_change = true; + Function::iterator insert_pt = function->begin(); + for (; insert_pt != function->end() && &*insert_pt != non_dedicate; + ++insert_pt) { + } + assert(insert_pt != function->end() && "Basic Block not found"); + + // Create the dedicate exit basic block. + // TODO(1841): Handle id overflow. + BasicBlock& exit = *insert_pt.InsertBefore(std::unique_ptr( + new BasicBlock(std::unique_ptr(new Instruction( + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))))); + exit.SetParent(function); + + // Redirect in loop predecessors to |exit| block. + for (uint32_t exit_pred_id : bb_pred) { + if (loop_->IsInsideLoop(exit_pred_id)) { + BasicBlock* pred_block = cfg.block(exit_pred_id); + pred_block->ForEachSuccessorLabel([non_dedicate, &exit](uint32_t* id) { + if (*id == non_dedicate->id()) *id = exit.id(); + }); + // Update the CFG. + // |non_dedicate|'s predecessor list will be updated at the end of the + // loop. + cfg.RegisterBlock(pred_block); + } + } + + // Register the label to the def/use manager, requires for the phi patching. + def_use_mgr->AnalyzeInstDefUse(exit.GetLabelInst()); + context_->set_instr_block(exit.GetLabelInst(), &exit); + + InstructionBuilder builder(context_, &exit, PreservedAnalyses); + // Now jump from our dedicate basic block to the old exit. + // We also reset the insert point so all instructions are inserted before + // the branch. + builder.SetInsertPoint(builder.AddBranch(non_dedicate->id())); + non_dedicate->ForEachPhiInst( + [&builder, &exit, def_use_mgr, this](Instruction* phi) { + // New phi operands for this instruction. + std::vector new_phi_op; + // Phi operands for the dedicated exit block. + std::vector exit_phi_op; + for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) { + uint32_t def_id = phi->GetSingleWordInOperand(i); + uint32_t incoming_id = phi->GetSingleWordInOperand(i + 1); + if (loop_->IsInsideLoop(incoming_id)) { + exit_phi_op.push_back(def_id); + exit_phi_op.push_back(incoming_id); + } else { + new_phi_op.push_back(def_id); + new_phi_op.push_back(incoming_id); + } + } + + // Build the new phi instruction dedicated exit block. + Instruction* exit_phi = builder.AddPhi(phi->type_id(), exit_phi_op); + // Build the new incoming branch. + new_phi_op.push_back(exit_phi->result_id()); + new_phi_op.push_back(exit.id()); + // Rewrite operands. + uint32_t idx = 0; + for (; idx < new_phi_op.size(); idx++) + phi->SetInOperand(idx, {new_phi_op[idx]}); + // Remove extra operands, from last to first (more efficient). + for (uint32_t j = phi->NumInOperands() - 1; j >= idx; j--) + phi->RemoveInOperand(j); + // Update the def/use manager for this |phi|. + def_use_mgr->AnalyzeInstUse(phi); + }); + // Update the CFG. + cfg.RegisterBlock(&exit); + cfg.RemoveNonExistingEdges(non_dedicate->id()); + new_loop_exits.insert(&exit); + // If non_dedicate is in a loop, add the new dedicated exit in that loop. + if (Loop* parent_loop = loop_desc[non_dedicate]) + parent_loop->AddBasicBlock(&exit); + } + + if (new_loop_exits.size() == 1) { + loop_->SetMergeBlock(*new_loop_exits.begin()); + } + + if (made_change) { + context_->InvalidateAnalysesExceptFor( + PreservedAnalyses | IRContext::kAnalysisCFG | + IRContext::Analysis::kAnalysisLoopAnalysis); + } +} + +void LoopUtils::MakeLoopClosedSSA() { + CreateLoopDedicatedExits(); + + Function* function = loop_->GetHeaderBlock()->GetParent(); + CFG& cfg = *context_->cfg(); + DominatorTree& dom_tree = + context_->GetDominatorAnalysis(function)->GetDomTree(); + + std::unordered_set exit_bb; + { + std::unordered_set exit_bb_id; + loop_->GetExitBlocks(&exit_bb_id); + for (uint32_t bb_id : exit_bb_id) { + exit_bb.insert(cfg.block(bb_id)); + } + } + + LCSSARewriter lcssa_rewriter(context_, dom_tree, exit_bb, + loop_->GetMergeBlock()); + MakeSetClosedSSA(context_, function, loop_->GetBlocks(), exit_bb, + &lcssa_rewriter); + + // Make sure all defs post-dominated by the merge block have their last use no + // further than the merge block. + if (loop_->GetMergeBlock()) { + std::unordered_set merging_bb_id; + loop_->GetMergingBlocks(&merging_bb_id); + merging_bb_id.erase(loop_->GetMergeBlock()->id()); + // Reset the exit set, now only the merge block is the exit. + exit_bb.clear(); + exit_bb.insert(loop_->GetMergeBlock()); + // LCSSARewriter is reusable here only because it forces the creation of a + // phi instruction in the merge block. + MakeSetClosedSSA(context_, function, merging_bb_id, exit_bb, + &lcssa_rewriter); + } + + context_->InvalidateAnalysesExceptFor( + IRContext::Analysis::kAnalysisCFG | + IRContext::Analysis::kAnalysisDominatorAnalysis | + IRContext::Analysis::kAnalysisLoopAnalysis); +} + +Loop* LoopUtils::CloneLoop(LoopCloningResult* cloning_result) const { + // Compute the structured order of the loop basic blocks and store it in the + // vector ordered_loop_blocks. + std::vector ordered_loop_blocks; + loop_->ComputeLoopStructuredOrder(&ordered_loop_blocks); + + // Clone the loop. + return CloneLoop(cloning_result, ordered_loop_blocks); +} + +Loop* LoopUtils::CloneAndAttachLoopToHeader(LoopCloningResult* cloning_result) { + // Clone the loop. + Loop* new_loop = CloneLoop(cloning_result); + + // Create a new exit block/label for the new loop. + // TODO(1841): Handle id overflow. + std::unique_ptr new_label{new Instruction( + context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {})}; + std::unique_ptr new_exit_bb{new BasicBlock(std::move(new_label))}; + new_exit_bb->SetParent(loop_->GetMergeBlock()->GetParent()); + + // Create an unconditional branch to the header block. + InstructionBuilder builder{context_, new_exit_bb.get()}; + builder.AddBranch(loop_->GetHeaderBlock()->id()); + + // Save the ids of the new and old merge block. + const uint32_t old_merge_block = loop_->GetMergeBlock()->id(); + const uint32_t new_merge_block = new_exit_bb->id(); + + // Replace the uses of the old merge block in the new loop with the new merge + // block. + for (std::unique_ptr& basic_block : cloning_result->cloned_bb_) { + for (Instruction& inst : *basic_block) { + // For each operand in each instruction check if it is using the old merge + // block and change it to be the new merge block. + auto replace_merge_use = [old_merge_block, + new_merge_block](uint32_t* id) { + if (*id == old_merge_block) *id = new_merge_block; + }; + inst.ForEachInOperand(replace_merge_use); + } + } + + const uint32_t old_header = loop_->GetHeaderBlock()->id(); + const uint32_t new_header = new_loop->GetHeaderBlock()->id(); + analysis::DefUseManager* def_use = context_->get_def_use_mgr(); + + def_use->ForEachUse(old_header, + [new_header, this](Instruction* inst, uint32_t operand) { + if (!this->loop_->IsInsideLoop(inst)) + inst->SetOperand(operand, {new_header}); + }); + + // TODO(1841): Handle failure to create pre-header. + def_use->ForEachUse( + loop_->GetOrCreatePreHeaderBlock()->id(), + [new_merge_block, this](Instruction* inst, uint32_t operand) { + if (this->loop_->IsInsideLoop(inst)) + inst->SetOperand(operand, {new_merge_block}); + + }); + new_loop->SetMergeBlock(new_exit_bb.get()); + + new_loop->SetPreHeaderBlock(loop_->GetPreHeaderBlock()); + + // Add the new block into the cloned instructions. + cloning_result->cloned_bb_.push_back(std::move(new_exit_bb)); + + return new_loop; +} + +Loop* LoopUtils::CloneLoop( + LoopCloningResult* cloning_result, + const std::vector& ordered_loop_blocks) const { + analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); + + std::unique_ptr new_loop = MakeUnique(context_); + + CFG& cfg = *context_->cfg(); + + // Clone and place blocks in a SPIR-V compliant order (dominators first). + for (BasicBlock* old_bb : ordered_loop_blocks) { + // For each basic block in the loop, we clone it and register the mapping + // between old and new ids. + BasicBlock* new_bb = old_bb->Clone(context_); + new_bb->SetParent(&function_); + // TODO(1841): Handle id overflow. + new_bb->GetLabelInst()->SetResultId(context_->TakeNextId()); + def_use_mgr->AnalyzeInstDef(new_bb->GetLabelInst()); + context_->set_instr_block(new_bb->GetLabelInst(), new_bb); + cloning_result->cloned_bb_.emplace_back(new_bb); + + cloning_result->old_to_new_bb_[old_bb->id()] = new_bb; + cloning_result->new_to_old_bb_[new_bb->id()] = old_bb; + cloning_result->value_map_[old_bb->id()] = new_bb->id(); + + if (loop_->IsInsideLoop(old_bb)) new_loop->AddBasicBlock(new_bb); + + for (auto new_inst = new_bb->begin(), old_inst = old_bb->begin(); + new_inst != new_bb->end(); ++new_inst, ++old_inst) { + cloning_result->ptr_map_[&*new_inst] = &*old_inst; + if (new_inst->HasResultId()) { + // TODO(1841): Handle id overflow. + new_inst->SetResultId(context_->TakeNextId()); + cloning_result->value_map_[old_inst->result_id()] = + new_inst->result_id(); + + // Only look at the defs for now, uses are not updated yet. + def_use_mgr->AnalyzeInstDef(&*new_inst); + } + } + } + + // All instructions (including all labels) have been cloned, + // remap instruction operands id with the new ones. + for (std::unique_ptr& bb_ref : cloning_result->cloned_bb_) { + BasicBlock* bb = bb_ref.get(); + + for (Instruction& insn : *bb) { + insn.ForEachInId([cloning_result](uint32_t* old_id) { + // If the operand is defined in the loop, remap the id. + auto id_it = cloning_result->value_map_.find(*old_id); + if (id_it != cloning_result->value_map_.end()) { + *old_id = id_it->second; + } + }); + // Only look at what the instruction uses. All defs are register, so all + // should be fine now. + def_use_mgr->AnalyzeInstUse(&insn); + context_->set_instr_block(&insn, bb); + } + cfg.RegisterBlock(bb); + } + + PopulateLoopNest(new_loop.get(), *cloning_result); + + return new_loop.release(); +} + +void LoopUtils::PopulateLoopNest( + Loop* new_loop, const LoopCloningResult& cloning_result) const { + std::unordered_map loop_mapping; + loop_mapping[loop_] = new_loop; + + if (loop_->HasParent()) loop_->GetParent()->AddNestedLoop(new_loop); + PopulateLoopDesc(new_loop, loop_, cloning_result); + + for (Loop& sub_loop : + make_range(++TreeDFIterator(loop_), TreeDFIterator())) { + Loop* cloned = new Loop(context_); + if (Loop* parent = loop_mapping[sub_loop.GetParent()]) + parent->AddNestedLoop(cloned); + loop_mapping[&sub_loop] = cloned; + PopulateLoopDesc(cloned, &sub_loop, cloning_result); + } + + loop_desc_->AddLoopNest(std::unique_ptr(new_loop)); +} + +// Populates |new_loop| descriptor according to |old_loop|'s one. +void LoopUtils::PopulateLoopDesc( + Loop* new_loop, Loop* old_loop, + const LoopCloningResult& cloning_result) const { + for (uint32_t bb_id : old_loop->GetBlocks()) { + BasicBlock* bb = cloning_result.old_to_new_bb_.at(bb_id); + new_loop->AddBasicBlock(bb); + } + new_loop->SetHeaderBlock( + cloning_result.old_to_new_bb_.at(old_loop->GetHeaderBlock()->id())); + if (old_loop->GetLatchBlock()) + new_loop->SetLatchBlock( + cloning_result.old_to_new_bb_.at(old_loop->GetLatchBlock()->id())); + if (old_loop->GetContinueBlock()) + new_loop->SetContinueBlock( + cloning_result.old_to_new_bb_.at(old_loop->GetContinueBlock()->id())); + if (old_loop->GetMergeBlock()) { + auto it = + cloning_result.old_to_new_bb_.find(old_loop->GetMergeBlock()->id()); + BasicBlock* bb = it != cloning_result.old_to_new_bb_.end() + ? it->second + : old_loop->GetMergeBlock(); + new_loop->SetMergeBlock(bb); + } + if (old_loop->GetPreHeaderBlock()) { + auto it = + cloning_result.old_to_new_bb_.find(old_loop->GetPreHeaderBlock()->id()); + if (it != cloning_result.old_to_new_bb_.end()) { + new_loop->SetPreHeaderBlock(it->second); + } + } +} + +// Class to gather some metrics about a region of interest. +void CodeMetrics::Analyze(const Loop& loop) { + CFG& cfg = *loop.GetContext()->cfg(); + + roi_size_ = 0; + block_sizes_.clear(); + + for (uint32_t id : loop.GetBlocks()) { + const BasicBlock* bb = cfg.block(id); + size_t bb_size = 0; + bb->ForEachInst([&bb_size](const Instruction* insn) { + if (insn->opcode() == spv::Op::OpLabel) return; + if (insn->IsNop()) return; + if (insn->opcode() == spv::Op::OpPhi) return; + bb_size++; + }); + block_sizes_[bb->id()] = bb_size; + roi_size_ += bb_size; + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/loop_utils.h b/thirdparty/glslang/External/spirv-tools/source/opt/loop_utils.h new file mode 100644 index 000000000000..70060fc4f00a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/loop_utils.h @@ -0,0 +1,182 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_LOOP_UTILS_H_ +#define SOURCE_OPT_LOOP_UTILS_H_ + +#include +#include +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/loop_descriptor.h" + +namespace spvtools { + +namespace opt { + +// Class to gather some metrics about a Region Of Interest (ROI). +// So far it counts the number of instructions in a ROI (excluding debug +// and label instructions) per basic block and in total. +struct CodeMetrics { + void Analyze(const Loop& loop); + + // The number of instructions per basic block in the ROI. + std::unordered_map block_sizes_; + + // Number of instruction in the ROI. + size_t roi_size_; +}; + +// LoopUtils is used to encapsulte loop optimizations and from the passes which +// use them. Any pass which needs a loop optimization should do it through this +// or through a pass which is using this. +class LoopUtils { + public: + // Holds a auxiliary results of the loop cloning procedure. + struct LoopCloningResult { + using ValueMapTy = std::unordered_map; + using BlockMapTy = std::unordered_map; + using PtrMap = std::unordered_map; + + PtrMap ptr_map_; + + // Mapping between the original loop ids and the new one. + ValueMapTy value_map_; + // Mapping between original loop blocks to the cloned one. + BlockMapTy old_to_new_bb_; + // Mapping between the cloned loop blocks to original one. + BlockMapTy new_to_old_bb_; + // List of cloned basic block. + std::vector> cloned_bb_; + }; + + LoopUtils(IRContext* context, Loop* loop) + : context_(context), + loop_desc_( + context->GetLoopDescriptor(loop->GetHeaderBlock()->GetParent())), + loop_(loop), + function_(*loop_->GetHeaderBlock()->GetParent()) {} + + // The converts the current loop to loop closed SSA form. + // In the loop closed SSA, all loop exiting values go through a dedicated Phi + // instruction. For instance: + // + // for (...) { + // A1 = ... + // if (...) + // A2 = ... + // A = phi A1, A2 + // } + // ... = op A ... + // + // Becomes + // + // for (...) { + // A1 = ... + // if (...) + // A2 = ... + // A = phi A1, A2 + // } + // C = phi A + // ... = op C ... + // + // This makes some loop transformations (such as loop unswitch) simpler + // (removes the needs to take care of exiting variables). + void MakeLoopClosedSSA(); + + // Create dedicate exit basic block. This ensure all exit basic blocks has the + // loop as sole predecessors. + // By construction, structured control flow already has a dedicated exit + // block. + // Preserves: CFG, def/use and instruction to block mapping. + void CreateLoopDedicatedExits(); + + // Clone |loop_| and remap its instructions. Newly created blocks + // will be added to the |cloning_result.cloned_bb_| list, correctly ordered to + // be inserted into a function. + // It is assumed that |ordered_loop_blocks| is compatible with the result of + // |Loop::ComputeLoopStructuredOrder|. If the preheader and merge block are in + // the list they will also be cloned. If not, the resulting loop will share + // them with the original loop. + // The function preserves the def/use, cfg and instr to block analyses. + // The cloned loop nest will be added to the loop descriptor and will have + // ownership. + Loop* CloneLoop(LoopCloningResult* cloning_result, + const std::vector& ordered_loop_blocks) const; + // Clone |loop_| and remap its instructions, as above. Overload to compute + // loop block ordering within method rather than taking in as parameter. + Loop* CloneLoop(LoopCloningResult* cloning_result) const; + + // Clone the |loop_| and make the new loop branch to the second loop on exit. + Loop* CloneAndAttachLoopToHeader(LoopCloningResult* cloning_result); + + // Perform a partial unroll of |loop| by given |factor|. This will copy the + // body of the loop |factor| times. So a |factor| of one would give a new loop + // with the original body plus one unrolled copy body. + bool PartiallyUnroll(size_t factor); + + // Fully unroll |loop|. + bool FullyUnroll(); + + // This function validates that |loop| meets the assumptions made by the + // implementation of the loop unroller. As the implementation accommodates + // more types of loops this function can reduce its checks. + // + // The conditions checked to ensure the loop can be unrolled are as follows: + // 1. That the loop is in structured order. + // 2. That the continue block is a branch to the header. + // 3. That the only phi used in the loop is the induction variable. + // TODO(stephen@codeplay.com): This is a temporary measure, after the loop is + // converted into LCSAA form and has a single entry and exit we can rewrite + // the other phis. + // 4. That this is an inner most loop, or that loops contained within this + // loop have already been fully unrolled. + // 5. That each instruction in the loop is only used within the loop. + // (Related to the above phi condition). + bool CanPerformUnroll(); + + // Maintains the loop descriptor object after the unroll functions have been + // called, otherwise the analysis should be invalidated. + void Finalize(); + + // Returns the context associate to |loop_|. + IRContext* GetContext() { return context_; } + // Returns the loop descriptor owning |loop_|. + LoopDescriptor* GetLoopDescriptor() { return loop_desc_; } + // Returns the loop on which the object operates on. + Loop* GetLoop() const { return loop_; } + // Returns the function that |loop_| belong to. + Function* GetFunction() const { return &function_; } + + private: + IRContext* context_; + LoopDescriptor* loop_desc_; + Loop* loop_; + Function& function_; + + // Populates the loop nest of |new_loop| according to |loop_| nest. + void PopulateLoopNest(Loop* new_loop, + const LoopCloningResult& cloning_result) const; + + // Populates |new_loop| descriptor according to |old_loop|'s one. + void PopulateLoopDesc(Loop* new_loop, Loop* old_loop, + const LoopCloningResult& cloning_result) const; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_LOOP_UTILS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/mem_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/mem_pass.cpp new file mode 100644 index 000000000000..9972c4f75f5f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/mem_pass.cpp @@ -0,0 +1,512 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/mem_pass.h" + +#include +#include +#include + +#include "source/cfa.h" +#include "source/opt/basic_block.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kCopyObjectOperandInIdx = 0; +constexpr uint32_t kTypePointerStorageClassInIdx = 0; +constexpr uint32_t kTypePointerTypeIdInIdx = 1; +} // namespace + +bool MemPass::IsBaseTargetType(const Instruction* typeInst) const { + switch (typeInst->opcode()) { + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeBool: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypePointer: + return true; + default: + break; + } + return false; +} + +bool MemPass::IsTargetType(const Instruction* typeInst) const { + if (IsBaseTargetType(typeInst)) return true; + if (typeInst->opcode() == spv::Op::OpTypeArray) { + if (!IsTargetType( + get_def_use_mgr()->GetDef(typeInst->GetSingleWordOperand(1)))) { + return false; + } + return true; + } + if (typeInst->opcode() != spv::Op::OpTypeStruct) return false; + // All struct members must be math type + return typeInst->WhileEachInId([this](const uint32_t* tid) { + Instruction* compTypeInst = get_def_use_mgr()->GetDef(*tid); + if (!IsTargetType(compTypeInst)) return false; + return true; + }); +} + +bool MemPass::IsNonPtrAccessChain(const spv::Op opcode) const { + return opcode == spv::Op::OpAccessChain || + opcode == spv::Op::OpInBoundsAccessChain; +} + +bool MemPass::IsPtr(uint32_t ptrId) { + uint32_t varId = ptrId; + Instruction* ptrInst = get_def_use_mgr()->GetDef(varId); + if (ptrInst->opcode() == spv::Op::OpFunction) { + // A function is not a pointer, but it's return type could be, which will + // erroneously lead to this function returning true later on + return false; + } + while (ptrInst->opcode() == spv::Op::OpCopyObject) { + varId = ptrInst->GetSingleWordInOperand(kCopyObjectOperandInIdx); + ptrInst = get_def_use_mgr()->GetDef(varId); + } + const spv::Op op = ptrInst->opcode(); + if (op == spv::Op::OpVariable || IsNonPtrAccessChain(op)) return true; + const uint32_t varTypeId = ptrInst->type_id(); + if (varTypeId == 0) return false; + const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); + return varTypeInst->opcode() == spv::Op::OpTypePointer; +} + +Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) { + *varId = ptrId; + Instruction* ptrInst = get_def_use_mgr()->GetDef(*varId); + Instruction* varInst; + + if (ptrInst->opcode() == spv::Op::OpConstantNull) { + *varId = 0; + return ptrInst; + } + + if (ptrInst->opcode() != spv::Op::OpVariable && + ptrInst->opcode() != spv::Op::OpFunctionParameter) { + varInst = ptrInst->GetBaseAddress(); + } else { + varInst = ptrInst; + } + if (varInst->opcode() == spv::Op::OpVariable) { + *varId = varInst->result_id(); + } else { + *varId = 0; + } + + while (ptrInst->opcode() == spv::Op::OpCopyObject) { + uint32_t temp = ptrInst->GetSingleWordInOperand(0); + ptrInst = get_def_use_mgr()->GetDef(temp); + } + + return ptrInst; +} + +Instruction* MemPass::GetPtr(Instruction* ip, uint32_t* varId) { + assert(ip->opcode() == spv::Op::OpStore || ip->opcode() == spv::Op::OpLoad || + ip->opcode() == spv::Op::OpImageTexelPointer || + ip->IsAtomicWithLoad()); + + // All of these opcode place the pointer in position 0. + const uint32_t ptrId = ip->GetSingleWordInOperand(0); + return GetPtr(ptrId, varId); +} + +bool MemPass::HasOnlyNamesAndDecorates(uint32_t id) const { + return get_def_use_mgr()->WhileEachUser(id, [this](Instruction* user) { + spv::Op op = user->opcode(); + if (op != spv::Op::OpName && !IsNonTypeDecorate(op)) { + return false; + } + return true; + }); +} + +void MemPass::KillAllInsts(BasicBlock* bp, bool killLabel) { + bp->KillAllInsts(killLabel); +} + +bool MemPass::HasLoads(uint32_t varId) const { + return !get_def_use_mgr()->WhileEachUser(varId, [this](Instruction* user) { + spv::Op op = user->opcode(); + // TODO(): The following is slightly conservative. Could be + // better handling of non-store/name. + if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { + if (HasLoads(user->result_id())) { + return false; + } + } else if (op != spv::Op::OpStore && op != spv::Op::OpName && + !IsNonTypeDecorate(op)) { + return false; + } + return true; + }); +} + +bool MemPass::IsLiveVar(uint32_t varId) const { + const Instruction* varInst = get_def_use_mgr()->GetDef(varId); + // assume live if not a variable eg. function parameter + if (varInst->opcode() != spv::Op::OpVariable) return true; + // non-function scope vars are live + const uint32_t varTypeId = varInst->type_id(); + const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); + if (spv::StorageClass(varTypeInst->GetSingleWordInOperand( + kTypePointerStorageClassInIdx)) != spv::StorageClass::Function) + return true; + // test if variable is loaded from + return HasLoads(varId); +} + +void MemPass::AddStores(uint32_t ptr_id, std::queue* insts) { + get_def_use_mgr()->ForEachUser(ptr_id, [this, insts](Instruction* user) { + spv::Op op = user->opcode(); + if (IsNonPtrAccessChain(op)) { + AddStores(user->result_id(), insts); + } else if (op == spv::Op::OpStore) { + insts->push(user); + } + }); +} + +void MemPass::DCEInst(Instruction* inst, + const std::function& call_back) { + std::queue deadInsts; + deadInsts.push(inst); + while (!deadInsts.empty()) { + Instruction* di = deadInsts.front(); + // Don't delete labels + if (di->opcode() == spv::Op::OpLabel) { + deadInsts.pop(); + continue; + } + // Remember operands + std::set ids; + di->ForEachInId([&ids](uint32_t* iid) { ids.insert(*iid); }); + uint32_t varId = 0; + // Remember variable if dead load + if (di->opcode() == spv::Op::OpLoad) (void)GetPtr(di, &varId); + if (call_back) { + call_back(di); + } + context()->KillInst(di); + // For all operands with no remaining uses, add their instruction + // to the dead instruction queue. + for (auto id : ids) + if (HasOnlyNamesAndDecorates(id)) { + Instruction* odi = get_def_use_mgr()->GetDef(id); + if (context()->IsCombinatorInstruction(odi)) deadInsts.push(odi); + } + // if a load was deleted and it was the variable's + // last load, add all its stores to dead queue + if (varId != 0 && !IsLiveVar(varId)) AddStores(varId, &deadInsts); + deadInsts.pop(); + } +} + +MemPass::MemPass() {} + +bool MemPass::HasOnlySupportedRefs(uint32_t varId) { + return get_def_use_mgr()->WhileEachUser(varId, [this](Instruction* user) { + auto dbg_op = user->GetCommonDebugOpcode(); + if (dbg_op == CommonDebugInfoDebugDeclare || + dbg_op == CommonDebugInfoDebugValue) { + return true; + } + spv::Op op = user->opcode(); + if (op != spv::Op::OpStore && op != spv::Op::OpLoad && + op != spv::Op::OpName && !IsNonTypeDecorate(op)) { + return false; + } + return true; + }); +} + +uint32_t MemPass::Type2Undef(uint32_t type_id) { + const auto uitr = type2undefs_.find(type_id); + if (uitr != type2undefs_.end()) return uitr->second; + const uint32_t undefId = TakeNextId(); + if (undefId == 0) { + return 0; + } + + std::unique_ptr undef_inst( + new Instruction(context(), spv::Op::OpUndef, type_id, undefId, {})); + get_def_use_mgr()->AnalyzeInstDefUse(&*undef_inst); + get_module()->AddGlobalValue(std::move(undef_inst)); + type2undefs_[type_id] = undefId; + return undefId; +} + +bool MemPass::IsTargetVar(uint32_t varId) { + if (varId == 0) { + return false; + } + + if (seen_non_target_vars_.find(varId) != seen_non_target_vars_.end()) + return false; + if (seen_target_vars_.find(varId) != seen_target_vars_.end()) return true; + const Instruction* varInst = get_def_use_mgr()->GetDef(varId); + if (varInst->opcode() != spv::Op::OpVariable) return false; + const uint32_t varTypeId = varInst->type_id(); + const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); + if (spv::StorageClass(varTypeInst->GetSingleWordInOperand( + kTypePointerStorageClassInIdx)) != spv::StorageClass::Function) { + seen_non_target_vars_.insert(varId); + return false; + } + const uint32_t varPteTypeId = + varTypeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx); + Instruction* varPteTypeInst = get_def_use_mgr()->GetDef(varPteTypeId); + if (!IsTargetType(varPteTypeInst)) { + seen_non_target_vars_.insert(varId); + return false; + } + seen_target_vars_.insert(varId); + return true; +} + +// Remove all |phi| operands coming from unreachable blocks (i.e., blocks not in +// |reachable_blocks|). There are two types of removal that this function can +// perform: +// +// 1- Any operand that comes directly from an unreachable block is completely +// removed. Since the block is unreachable, the edge between the unreachable +// block and the block holding |phi| has been removed. +// +// 2- Any operand that comes via a live block and was defined at an unreachable +// block gets its value replaced with an OpUndef value. Since the argument +// was generated in an unreachable block, it no longer exists, so it cannot +// be referenced. However, since the value does not reach |phi| directly +// from the unreachable block, the operand cannot be removed from |phi|. +// Therefore, we replace the argument value with OpUndef. +// +// For example, in the switch() below, assume that we want to remove the +// argument with value %11 coming from block %41. +// +// [ ... ] +// %41 = OpLabel <--- Unreachable block +// %11 = OpLoad %int %y +// [ ... ] +// OpSelectionMerge %16 None +// OpSwitch %12 %16 10 %13 13 %14 18 %15 +// %13 = OpLabel +// OpBranch %16 +// %14 = OpLabel +// OpStore %outparm %int_14 +// OpBranch %16 +// %15 = OpLabel +// OpStore %outparm %int_15 +// OpBranch %16 +// %16 = OpLabel +// %30 = OpPhi %int %11 %41 %int_42 %13 %11 %14 %11 %15 +// +// Since %41 is now an unreachable block, the first operand of |phi| needs to +// be removed completely. But the operands (%11 %14) and (%11 %15) cannot be +// removed because %14 and %15 are reachable blocks. Since %11 no longer exist, +// in those arguments, we replace all references to %11 with an OpUndef value. +// This results in |phi| looking like: +// +// %50 = OpUndef %int +// [ ... ] +// %30 = OpPhi %int %int_42 %13 %50 %14 %50 %15 +void MemPass::RemovePhiOperands( + Instruction* phi, const std::unordered_set& reachable_blocks) { + std::vector keep_operands; + uint32_t type_id = 0; + // The id of an undefined value we've generated. + uint32_t undef_id = 0; + + // Traverse all the operands in |phi|. Build the new operand vector by adding + // all the original operands from |phi| except the unwanted ones. + for (uint32_t i = 0; i < phi->NumOperands();) { + if (i < 2) { + // The first two arguments are always preserved. + keep_operands.push_back(phi->GetOperand(i)); + ++i; + continue; + } + + // The remaining Phi arguments come in pairs. Index 'i' contains the + // variable id, index 'i + 1' is the originating block id. + assert(i % 2 == 0 && i < phi->NumOperands() - 1 && + "malformed Phi arguments"); + + BasicBlock* in_block = cfg()->block(phi->GetSingleWordOperand(i + 1)); + if (reachable_blocks.find(in_block) == reachable_blocks.end()) { + // If the incoming block is unreachable, remove both operands as this + // means that the |phi| has lost an incoming edge. + i += 2; + continue; + } + + // In all other cases, the operand must be kept but may need to be changed. + uint32_t arg_id = phi->GetSingleWordOperand(i); + Instruction* arg_def_instr = get_def_use_mgr()->GetDef(arg_id); + BasicBlock* def_block = context()->get_instr_block(arg_def_instr); + if (def_block && + reachable_blocks.find(def_block) == reachable_blocks.end()) { + // If the current |phi| argument was defined in an unreachable block, it + // means that this |phi| argument is no longer defined. Replace it with + // |undef_id|. + if (!undef_id) { + type_id = arg_def_instr->type_id(); + undef_id = Type2Undef(type_id); + } + keep_operands.push_back( + Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {undef_id})); + } else { + // Otherwise, the argument comes from a reachable block or from no block + // at all (meaning that it was defined in the global section of the + // program). In both cases, keep the argument intact. + keep_operands.push_back(phi->GetOperand(i)); + } + + keep_operands.push_back(phi->GetOperand(i + 1)); + + i += 2; + } + + context()->ForgetUses(phi); + phi->ReplaceOperands(keep_operands); + context()->AnalyzeUses(phi); +} + +void MemPass::RemoveBlock(Function::iterator* bi) { + auto& rm_block = **bi; + + // Remove instructions from the block. + rm_block.ForEachInst([&rm_block, this](Instruction* inst) { + // Note that we do not kill the block label instruction here. The label + // instruction is needed to identify the block, which is needed by the + // removal of phi operands. + if (inst != rm_block.GetLabelInst()) { + context()->KillInst(inst); + } + }); + + // Remove the label instruction last. + auto label = rm_block.GetLabelInst(); + context()->KillInst(label); + + *bi = bi->Erase(); +} + +bool MemPass::RemoveUnreachableBlocks(Function* func) { + bool modified = false; + + // Mark reachable all blocks reachable from the function's entry block. + std::unordered_set reachable_blocks; + std::unordered_set visited_blocks; + std::queue worklist; + reachable_blocks.insert(func->entry().get()); + + // Initially mark the function entry point as reachable. + worklist.push(func->entry().get()); + + auto mark_reachable = [&reachable_blocks, &visited_blocks, &worklist, + this](uint32_t label_id) { + auto successor = cfg()->block(label_id); + if (visited_blocks.count(successor) == 0) { + reachable_blocks.insert(successor); + worklist.push(successor); + visited_blocks.insert(successor); + } + }; + + // Transitively mark all blocks reachable from the entry as reachable. + while (!worklist.empty()) { + BasicBlock* block = worklist.front(); + worklist.pop(); + + // All the successors of a live block are also live. + static_cast(block)->ForEachSuccessorLabel( + mark_reachable); + + // All the Merge and ContinueTarget blocks of a live block are also live. + block->ForMergeAndContinueLabel(mark_reachable); + } + + // Update operands of Phi nodes that reference unreachable blocks. + for (auto& block : *func) { + // If the block is about to be removed, don't bother updating its + // Phi instructions. + if (reachable_blocks.count(&block) == 0) { + continue; + } + + // If the block is reachable and has Phi instructions, remove all + // operands from its Phi instructions that reference unreachable blocks. + // If the block has no Phi instructions, this is a no-op. + block.ForEachPhiInst([&reachable_blocks, this](Instruction* phi) { + RemovePhiOperands(phi, reachable_blocks); + }); + } + + // Erase unreachable blocks. + for (auto ebi = func->begin(); ebi != func->end();) { + if (reachable_blocks.count(&*ebi) == 0) { + RemoveBlock(&ebi); + modified = true; + } else { + ++ebi; + } + } + + return modified; +} + +bool MemPass::CFGCleanup(Function* func) { + bool modified = false; + modified |= RemoveUnreachableBlocks(func); + return modified; +} + +void MemPass::CollectTargetVars(Function* func) { + seen_target_vars_.clear(); + seen_non_target_vars_.clear(); + type2undefs_.clear(); + + // Collect target (and non-) variable sets. Remove variables with + // non-load/store refs from target variable set + for (auto& blk : *func) { + for (auto& inst : blk) { + switch (inst.opcode()) { + case spv::Op::OpStore: + case spv::Op::OpLoad: { + uint32_t varId; + (void)GetPtr(&inst, &varId); + if (!IsTargetVar(varId)) break; + if (HasOnlySupportedRefs(varId)) break; + seen_non_target_vars_.insert(varId); + seen_target_vars_.erase(varId); + } break; + default: + break; + } + } + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/mem_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/mem_pass.h new file mode 100644 index 000000000000..aef9e5ffa77b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/mem_pass.h @@ -0,0 +1,164 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_MEM_PASS_H_ +#define SOURCE_OPT_MEM_PASS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/dominator_analysis.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// A common base class for mem2reg-type passes. Provides common +// utility functions and supporting state. +class MemPass : public Pass { + public: + virtual ~MemPass() override = default; + + // Returns an undef value for the given |var_id|'s type. + uint32_t GetUndefVal(uint32_t var_id) { + return Type2Undef(GetPointeeTypeId(get_def_use_mgr()->GetDef(var_id))); + } + + // Given a load or store |ip|, return the pointer instruction. + // Also return the base variable's id in |varId|. If no base variable is + // found, |varId| will be 0. + Instruction* GetPtr(Instruction* ip, uint32_t* varId); + + // Return true if |varId| is a previously identified target variable. + // Return false if |varId| is a previously identified non-target variable. + // + // Non-target variables are variable of function scope of a target type that + // are accessed with constant-index access chains. not accessed with + // non-constant-index access chains. Also cache non-target variables. + // + // If variable is not cached, return true if variable is a function scope + // variable of target type, false otherwise. Updates caches of target and + // non-target variables. + bool IsTargetVar(uint32_t varId); + + // Collect target SSA variables. This traverses all the loads and stores in + // function |func| looking for variables that can be replaced with SSA IDs. It + // populates the sets |seen_target_vars_| and |seen_non_target_vars_|. + void CollectTargetVars(Function* func); + + protected: + MemPass(); + + // Returns true if |typeInst| is a scalar type + // or a vector or matrix + bool IsBaseTargetType(const Instruction* typeInst) const; + + // Returns true if |typeInst| is a math type or a struct or array + // of a math type. + // TODO(): Add more complex types to convert + bool IsTargetType(const Instruction* typeInst) const; + + // Returns true if |opcode| is a non-ptr access chain op + bool IsNonPtrAccessChain(const spv::Op opcode) const; + + // Given the id |ptrId|, return true if the top-most non-CopyObj is + // a variable, a non-ptr access chain or a parameter of pointer type. + bool IsPtr(uint32_t ptrId); + + // Given the id of a pointer |ptrId|, return the top-most non-CopyObj. + // Also return the base variable's id in |varId|. If no base variable is + // found, |varId| will be 0. + Instruction* GetPtr(uint32_t ptrId, uint32_t* varId); + + // Return true if all uses of |id| are only name or decorate ops. + bool HasOnlyNamesAndDecorates(uint32_t id) const; + + // Kill all instructions in block |bp|. Whether or not to kill the label is + // indicated by |killLabel|. + void KillAllInsts(BasicBlock* bp, bool killLabel = true); + + // Return true if any instruction loads from |varId| + bool HasLoads(uint32_t varId) const; + + // Return true if |varId| is not a function variable or if it has + // a load + bool IsLiveVar(uint32_t varId) const; + + // Add stores using |ptr_id| to |insts| + void AddStores(uint32_t ptr_id, std::queue* insts); + + // Delete |inst| and iterate DCE on all its operands if they are now + // useless. If a load is deleted and its variable has no other loads, + // delete all its variable's stores. + void DCEInst(Instruction* inst, const std::function&); + + // Call all the cleanup helper functions on |func|. + bool CFGCleanup(Function* func); + + // Return true if |op| is supported decorate. + inline bool IsNonTypeDecorate(spv::Op op) const { + return (op == spv::Op::OpDecorate || op == spv::Op::OpDecorateId); + } + + // Return the id of an undef value with type |type_id|. Create and insert an + // undef after the first non-variable in the function if it doesn't already + // exist. Add undef to function undef map. Returns 0 of the value does not + // exist, and cannot be created. + uint32_t Type2Undef(uint32_t type_id); + + // Cache of verified target vars + std::unordered_set seen_target_vars_; + + // Cache of verified non-target vars + std::unordered_set seen_non_target_vars_; + + private: + // Return true if all uses of |varId| are only through supported reference + // operations ie. loads and store. Also cache in supported_ref_vars_. + // TODO(dnovillo): This function is replicated in other passes and it's + // slightly different in every pass. Is it possible to make one common + // implementation? + bool HasOnlySupportedRefs(uint32_t varId); + + // Remove all the unreachable basic blocks in |func|. + bool RemoveUnreachableBlocks(Function* func); + + // Remove the block pointed by the iterator |*bi|. This also removes + // all the instructions in the pointed-to block. + void RemoveBlock(Function::iterator* bi); + + // Remove Phi operands in |phi| that are coming from blocks not in + // |reachable_blocks|. + void RemovePhiOperands( + Instruction* phi, + const std::unordered_set& reachable_blocks); + + // Map from type to undef + std::unordered_map type2undefs_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_MEM_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/merge_return_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/merge_return_pass.cpp new file mode 100644 index 000000000000..c262ea073a5d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/merge_return_pass.cpp @@ -0,0 +1,896 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/merge_return_pass.h" + +#include +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/opt/reflect.h" +#include "source/util/bit_vector.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { + +Pass::Status MergeReturnPass::Process() { + bool is_shader = + context()->get_feature_mgr()->HasCapability(spv::Capability::Shader); + + bool failed = false; + ProcessFunction pfn = [&failed, is_shader, this](Function* function) { + std::vector return_blocks = CollectReturnBlocks(function); + if (return_blocks.size() <= 1) { + if (!is_shader || return_blocks.size() == 0) { + return false; + } + bool isInConstruct = + context()->GetStructuredCFGAnalysis()->ContainingConstruct( + return_blocks[0]->id()) != 0; + bool endsWithReturn = return_blocks[0] == function->tail(); + if (!isInConstruct && endsWithReturn) { + return false; + } + } + + function_ = function; + return_flag_ = nullptr; + return_value_ = nullptr; + final_return_block_ = nullptr; + + if (is_shader) { + if (!ProcessStructured(function, return_blocks)) { + failed = true; + } + } else { + MergeReturnBlocks(function, return_blocks); + } + return true; + }; + + bool modified = context()->ProcessReachableCallTree(pfn); + + if (failed) { + return Status::Failure; + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +void MergeReturnPass::GenerateState(BasicBlock* block) { + if (Instruction* mergeInst = block->GetMergeInst()) { + if (mergeInst->opcode() == spv::Op::OpLoopMerge) { + // If new loop, break to this loop merge block + state_.emplace_back(mergeInst, mergeInst); + } else { + auto branchInst = mergeInst->NextNode(); + if (branchInst->opcode() == spv::Op::OpSwitch) { + // If switch inside of loop, break to innermost loop merge block. + // Otherwise need to break to this switch merge block. + auto lastMergeInst = state_.back().BreakMergeInst(); + if (lastMergeInst && lastMergeInst->opcode() == spv::Op::OpLoopMerge) + state_.emplace_back(lastMergeInst, mergeInst); + else + state_.emplace_back(mergeInst, mergeInst); + } else { + // If branch conditional inside loop, always break to innermost + // loop merge block. If branch conditional inside switch, break to + // innermost switch merge block. + auto lastMergeInst = state_.back().BreakMergeInst(); + state_.emplace_back(lastMergeInst, mergeInst); + } + } + } +} + +bool MergeReturnPass::ProcessStructured( + Function* function, const std::vector& return_blocks) { + if (HasNontrivialUnreachableBlocks(function)) { + if (consumer()) { + std::string message = + "Module contains unreachable blocks during merge return. Run dead " + "branch elimination before merge return."; + consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); + } + return false; + } + + RecordImmediateDominators(function); + if (!AddSingleCaseSwitchAroundFunction()) { + return false; + } + + std::list order; + cfg()->ComputeStructuredOrder(function, &*function->begin(), &order); + + state_.clear(); + state_.emplace_back(nullptr, nullptr); + for (auto block : order) { + if (cfg()->IsPseudoEntryBlock(block) || cfg()->IsPseudoExitBlock(block) || + block == final_return_block_) { + continue; + } + + auto blockId = block->GetLabelInst()->result_id(); + if (blockId == CurrentState().CurrentMergeId()) { + // Pop the current state as we've hit the merge + state_.pop_back(); + } + + ProcessStructuredBlock(block); + + // Generate state for next block if warranted + GenerateState(block); + } + + state_.clear(); + state_.emplace_back(nullptr, nullptr); + std::unordered_set predicated; + for (auto block : order) { + if (cfg()->IsPseudoEntryBlock(block) || cfg()->IsPseudoExitBlock(block)) { + continue; + } + + auto blockId = block->id(); + if (blockId == CurrentState().CurrentMergeId()) { + // Pop the current state as we've hit the merge + state_.pop_back(); + } + + // Predicate successors of the original return blocks as necessary. + if (std::find(return_blocks.begin(), return_blocks.end(), block) != + return_blocks.end()) { + if (!PredicateBlocks(block, &predicated, &order)) { + return false; + } + } + + // Generate state for next block if warranted + GenerateState(block); + } + + // We have not kept the dominator tree up-to-date. + // Invalidate it at this point to make sure it will be rebuilt. + context()->RemoveDominatorAnalysis(function); + AddNewPhiNodes(); + return true; +} + +void MergeReturnPass::CreateReturnBlock() { + // Create a label for the new return block + std::unique_ptr return_label( + new Instruction(context(), spv::Op::OpLabel, 0u, TakeNextId(), {})); + + // Create the new basic block + std::unique_ptr return_block( + new BasicBlock(std::move(return_label))); + function_->AddBasicBlock(std::move(return_block)); + final_return_block_ = &*(--function_->end()); + context()->AnalyzeDefUse(final_return_block_->GetLabelInst()); + context()->set_instr_block(final_return_block_->GetLabelInst(), + final_return_block_); + assert(final_return_block_->GetParent() == function_ && + "The function should have been set when the block was created."); +} + +void MergeReturnPass::CreateReturn(BasicBlock* block) { + AddReturnValue(); + + if (return_value_) { + // Load and return the final return value + uint32_t loadId = TakeNextId(); + block->AddInstruction(MakeUnique( + context(), spv::Op::OpLoad, function_->type_id(), loadId, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {return_value_->result_id()}}})); + Instruction* var_inst = block->terminator(); + context()->AnalyzeDefUse(var_inst); + context()->set_instr_block(var_inst, block); + context()->get_decoration_mgr()->CloneDecorations( + return_value_->result_id(), loadId, + {spv::Decoration::RelaxedPrecision}); + + block->AddInstruction(MakeUnique( + context(), spv::Op::OpReturnValue, 0, 0, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {loadId}}})); + context()->AnalyzeDefUse(block->terminator()); + context()->set_instr_block(block->terminator(), block); + } else { + block->AddInstruction( + MakeUnique(context(), spv::Op::OpReturn)); + context()->AnalyzeDefUse(block->terminator()); + context()->set_instr_block(block->terminator(), block); + } +} + +void MergeReturnPass::ProcessStructuredBlock(BasicBlock* block) { + spv::Op tail_opcode = block->tail()->opcode(); + if (tail_opcode == spv::Op::OpReturn || + tail_opcode == spv::Op::OpReturnValue) { + if (!return_flag_) { + AddReturnFlag(); + } + } + + if (tail_opcode == spv::Op::OpReturn || + tail_opcode == spv::Op::OpReturnValue || + tail_opcode == spv::Op::OpUnreachable) { + assert(CurrentState().InBreakable() && + "Should be in the placeholder construct."); + BranchToBlock(block, CurrentState().BreakMergeId()); + return_blocks_.insert(block->id()); + } +} + +void MergeReturnPass::BranchToBlock(BasicBlock* block, uint32_t target) { + if (block->tail()->opcode() == spv::Op::OpReturn || + block->tail()->opcode() == spv::Op::OpReturnValue) { + RecordReturned(block); + RecordReturnValue(block); + } + + BasicBlock* target_block = context()->get_instr_block(target); + if (target_block->GetLoopMergeInst()) { + cfg()->SplitLoopHeader(target_block); + } + UpdatePhiNodes(block, target_block); + + Instruction* return_inst = block->terminator(); + return_inst->SetOpcode(spv::Op::OpBranch); + return_inst->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {target}}}); + context()->get_def_use_mgr()->AnalyzeInstDefUse(return_inst); + new_edges_[target_block].insert(block->id()); + cfg()->AddEdge(block->id(), target); +} + +void MergeReturnPass::UpdatePhiNodes(BasicBlock* new_source, + BasicBlock* target) { + target->ForEachPhiInst([this, new_source](Instruction* inst) { + uint32_t undefId = Type2Undef(inst->type_id()); + inst->AddOperand({SPV_OPERAND_TYPE_ID, {undefId}}); + inst->AddOperand({SPV_OPERAND_TYPE_ID, {new_source->id()}}); + context()->UpdateDefUse(inst); + }); +} + +void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block, + Instruction& inst) { + DominatorAnalysis* dom_tree = + context()->GetDominatorAnalysis(merge_block->GetParent()); + + if (inst.result_id() != 0) { + BasicBlock* inst_bb = context()->get_instr_block(&inst); + std::vector users_to_update; + context()->get_def_use_mgr()->ForEachUser( + &inst, + [&users_to_update, &dom_tree, &inst, inst_bb, this](Instruction* user) { + BasicBlock* user_bb = nullptr; + if (user->opcode() != spv::Op::OpPhi) { + user_bb = context()->get_instr_block(user); + } else { + // For OpPhi, the use should be considered to be in the predecessor. + for (uint32_t i = 0; i < user->NumInOperands(); i += 2) { + if (user->GetSingleWordInOperand(i) == inst.result_id()) { + uint32_t user_bb_id = user->GetSingleWordInOperand(i + 1); + user_bb = context()->get_instr_block(user_bb_id); + break; + } + } + } + + // If |user_bb| is nullptr, then |user| is not in the function. It is + // something like an OpName or decoration, which should not be + // replaced with the result of the OpPhi. + if (user_bb && !dom_tree->Dominates(inst_bb, user_bb)) { + users_to_update.push_back(user); + } + }); + + if (users_to_update.empty()) { + return; + } + + // There is at least one values that needs to be replaced. + // First create the OpPhi instruction. + uint32_t undef_id = Type2Undef(inst.type_id()); + std::vector phi_operands; + const std::set& new_edges = new_edges_[merge_block]; + + // Add the OpPhi operands. If the predecessor is a return block use undef, + // otherwise use |inst|'s id. + std::vector preds = cfg()->preds(merge_block->id()); + for (uint32_t pred_id : preds) { + if (new_edges.count(pred_id)) { + phi_operands.push_back(undef_id); + } else { + phi_operands.push_back(inst.result_id()); + } + phi_operands.push_back(pred_id); + } + + Instruction* new_phi = nullptr; + // If the instruction is a pointer and variable pointers are not an option, + // then we have to regenerate the instruction instead of creating an OpPhi + // instruction. If not, the Spir-V will be invalid. + Instruction* inst_type = get_def_use_mgr()->GetDef(inst.type_id()); + bool regenerateInstruction = false; + if (inst_type->opcode() == spv::Op::OpTypePointer) { + if (!context()->get_feature_mgr()->HasCapability( + spv::Capability::VariablePointers)) { + regenerateInstruction = true; + } + + auto storage_class = + spv::StorageClass(inst_type->GetSingleWordInOperand(0)); + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::StorageBuffer) { + regenerateInstruction = true; + } + } + + if (regenerateInstruction) { + std::unique_ptr regen_inst(inst.Clone(context())); + uint32_t new_id = TakeNextId(); + regen_inst->SetResultId(new_id); + Instruction* insert_pos = &*merge_block->begin(); + while (insert_pos->opcode() == spv::Op::OpPhi) { + insert_pos = insert_pos->NextNode(); + } + new_phi = insert_pos->InsertBefore(std::move(regen_inst)); + get_def_use_mgr()->AnalyzeInstDefUse(new_phi); + context()->set_instr_block(new_phi, merge_block); + + new_phi->ForEachInId([dom_tree, merge_block, this](uint32_t* use_id) { + Instruction* use = get_def_use_mgr()->GetDef(*use_id); + BasicBlock* use_bb = context()->get_instr_block(use); + if (use_bb != nullptr && !dom_tree->Dominates(use_bb, merge_block)) { + CreatePhiNodesForInst(merge_block, *use); + } + }); + } else { + InstructionBuilder builder( + context(), &*merge_block->begin(), + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + new_phi = builder.AddPhi(inst.type_id(), phi_operands); + } + uint32_t result_of_phi = new_phi->result_id(); + + // Update all of the users to use the result of the new OpPhi. + for (Instruction* user : users_to_update) { + user->ForEachInId([&inst, result_of_phi](uint32_t* id) { + if (*id == inst.result_id()) { + *id = result_of_phi; + } + }); + context()->AnalyzeUses(user); + } + } +} + +bool MergeReturnPass::PredicateBlocks( + BasicBlock* return_block, std::unordered_set* predicated, + std::list* order) { + // The CFG is being modified as the function proceeds so avoid caching + // successors. + + if (predicated->count(return_block)) { + return true; + } + + BasicBlock* block = nullptr; + const BasicBlock* const_block = const_cast(return_block); + const_block->ForEachSuccessorLabel([this, &block](const uint32_t idx) { + BasicBlock* succ_block = context()->get_instr_block(idx); + assert(block == nullptr); + block = succ_block; + }); + assert(block && + "Return blocks should have returns already replaced by a single " + "unconditional branch."); + + auto state = state_.rbegin(); + std::unordered_set seen; + if (block->id() == state->CurrentMergeId()) { + state++; + } else if (block->id() == state->BreakMergeId()) { + while (state->BreakMergeId() == block->id()) { + state++; + } + } + + while (block != nullptr && block != final_return_block_) { + if (!predicated->insert(block).second) break; + // Skip structured subgraphs. + assert(state->InBreakable() && + "Should be in the placeholder construct at the very least."); + Instruction* break_merge_inst = state->BreakMergeInst(); + uint32_t merge_block_id = break_merge_inst->GetSingleWordInOperand(0); + while (state->BreakMergeId() == merge_block_id) { + state++; + } + if (!BreakFromConstruct(block, predicated, order, break_merge_inst)) { + return false; + } + block = context()->get_instr_block(merge_block_id); + } + return true; +} + +bool MergeReturnPass::BreakFromConstruct( + BasicBlock* block, std::unordered_set* predicated, + std::list* order, Instruction* break_merge_inst) { + // Make sure the CFG is build here. If we don't then it becomes very hard + // to know which new blocks need to be updated. + context()->InvalidateAnalyses(IRContext::kAnalysisCFG); + context()->BuildInvalidAnalyses(IRContext::kAnalysisCFG); + + // When predicating, be aware of whether this block is a header block, a + // merge block or both. + // + // If this block is a merge block, ensure the appropriate header stays + // up-to-date with any changes (i.e. points to the pre-header). + // + // If this block is a header block, predicate the entire structured + // subgraph. This can act recursively. + + // If |block| is a loop header, then the back edge must jump to the original + // code, not the new header. + if (block->GetLoopMergeInst()) { + if (cfg()->SplitLoopHeader(block) == nullptr) { + return false; + } + } + + uint32_t merge_block_id = break_merge_inst->GetSingleWordInOperand(0); + BasicBlock* merge_block = context()->get_instr_block(merge_block_id); + if (merge_block->GetLoopMergeInst()) { + cfg()->SplitLoopHeader(merge_block); + } + + // Leave the phi instructions behind. + auto iter = block->begin(); + while (iter->opcode() == spv::Op::OpPhi) { + ++iter; + } + + // Forget about the edges leaving block. They will be removed. + cfg()->RemoveSuccessorEdges(block); + + auto old_body_id = TakeNextId(); + BasicBlock* old_body = block->SplitBasicBlock(context(), old_body_id, iter); + predicated->insert(old_body); + + // If a return block is being split, mark the new body block also as a return + // block. + if (return_blocks_.count(block->id())) { + return_blocks_.insert(old_body_id); + } + + // If |block| was a continue target for a loop |old_body| is now the correct + // continue target. + if (break_merge_inst->opcode() == spv::Op::OpLoopMerge && + break_merge_inst->GetSingleWordInOperand(1) == block->id()) { + break_merge_inst->SetInOperand(1, {old_body->id()}); + context()->UpdateDefUse(break_merge_inst); + } + + // Update |order| so old_block will be traversed. + InsertAfterElement(block, old_body, order); + + // Within the new header we need the following: + // 1. Load of the return status flag + // 2. Branch to |merge_block| (true) or old body (false) + // 3. Update OpPhi instructions in |merge_block|. + // 4. Update the CFG. + // + // Since we are branching to the merge block of the current construct, there + // is no need for an OpSelectionMerge. + + InstructionBuilder builder( + context(), block, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // 1. Load of the return status flag + analysis::Bool bool_type; + uint32_t bool_id = context()->get_type_mgr()->GetId(&bool_type); + assert(bool_id != 0); + uint32_t load_id = + builder.AddLoad(bool_id, return_flag_->result_id())->result_id(); + + // 2. Branch to |merge_block| (true) or |old_body| (false) + builder.AddConditionalBranch(load_id, merge_block->id(), old_body->id(), + old_body->id()); + + if (!new_edges_[merge_block].insert(block->id()).second) { + // It is possible that we already inserted a new edge to the merge block. + // If so, that edge now goes from |old_body| to |merge_block|. + new_edges_[merge_block].insert(old_body->id()); + } + + // 3. Update OpPhi instructions in |merge_block|. + UpdatePhiNodes(block, merge_block); + + // 4. Update the CFG. We do this after updating the OpPhi instructions + // because |UpdatePhiNodes| assumes the edge from |block| has not been added + // to the CFG yet. + cfg()->AddEdges(block); + cfg()->RegisterBlock(old_body); + + assert(old_body->begin() != old_body->end()); + assert(block->begin() != block->end()); + return true; +} + +void MergeReturnPass::RecordReturned(BasicBlock* block) { + if (block->tail()->opcode() != spv::Op::OpReturn && + block->tail()->opcode() != spv::Op::OpReturnValue) + return; + + assert(return_flag_ && "Did not generate the return flag variable."); + + if (!constant_true_) { + analysis::Bool temp; + const analysis::Bool* bool_type = + context()->get_type_mgr()->GetRegisteredType(&temp)->AsBool(); + + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + const analysis::Constant* true_const = + const_mgr->GetConstant(bool_type, {true}); + constant_true_ = const_mgr->GetDefiningInstruction(true_const); + context()->UpdateDefUse(constant_true_); + } + + std::unique_ptr return_store(new Instruction( + context(), spv::Op::OpStore, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {return_flag_->result_id()}}, + {SPV_OPERAND_TYPE_ID, {constant_true_->result_id()}}})); + + Instruction* store_inst = + &*block->tail().InsertBefore(std::move(return_store)); + context()->set_instr_block(store_inst, block); + context()->AnalyzeDefUse(store_inst); +} + +void MergeReturnPass::RecordReturnValue(BasicBlock* block) { + auto terminator = *block->tail(); + if (terminator.opcode() != spv::Op::OpReturnValue) { + return; + } + + assert(return_value_ && + "Did not generate the variable to hold the return value."); + + std::unique_ptr value_store(new Instruction( + context(), spv::Op::OpStore, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {return_value_->result_id()}}, + {SPV_OPERAND_TYPE_ID, {terminator.GetSingleWordInOperand(0u)}}})); + + Instruction* store_inst = + &*block->tail().InsertBefore(std::move(value_store)); + context()->set_instr_block(store_inst, block); + context()->AnalyzeDefUse(store_inst); +} + +void MergeReturnPass::AddReturnValue() { + if (return_value_) return; + + uint32_t return_type_id = function_->type_id(); + if (get_def_use_mgr()->GetDef(return_type_id)->opcode() == + spv::Op::OpTypeVoid) + return; + + uint32_t return_ptr_type = context()->get_type_mgr()->FindPointerToType( + return_type_id, spv::StorageClass::Function); + + uint32_t var_id = TakeNextId(); + std::unique_ptr returnValue( + new Instruction(context(), spv::Op::OpVariable, return_ptr_type, var_id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(spv::StorageClass::Function)}}})); + + auto insert_iter = function_->begin()->begin(); + insert_iter.InsertBefore(std::move(returnValue)); + BasicBlock* entry_block = &*function_->begin(); + return_value_ = &*entry_block->begin(); + context()->AnalyzeDefUse(return_value_); + context()->set_instr_block(return_value_, entry_block); + + context()->get_decoration_mgr()->CloneDecorations( + function_->result_id(), var_id, {spv::Decoration::RelaxedPrecision}); +} + +void MergeReturnPass::AddReturnFlag() { + if (return_flag_) return; + + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + + analysis::Bool temp; + uint32_t bool_id = type_mgr->GetTypeInstruction(&temp); + analysis::Bool* bool_type = type_mgr->GetType(bool_id)->AsBool(); + + const analysis::Constant* false_const = + const_mgr->GetConstant(bool_type, {false}); + uint32_t const_false_id = + const_mgr->GetDefiningInstruction(false_const)->result_id(); + + uint32_t bool_ptr_id = + type_mgr->FindPointerToType(bool_id, spv::StorageClass::Function); + + uint32_t var_id = TakeNextId(); + std::unique_ptr returnFlag(new Instruction( + context(), spv::Op::OpVariable, bool_ptr_id, var_id, + std::initializer_list{{SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(spv::StorageClass::Function)}}, + {SPV_OPERAND_TYPE_ID, {const_false_id}}})); + + auto insert_iter = function_->begin()->begin(); + + insert_iter.InsertBefore(std::move(returnFlag)); + BasicBlock* entry_block = &*function_->begin(); + return_flag_ = &*entry_block->begin(); + context()->AnalyzeDefUse(return_flag_); + context()->set_instr_block(return_flag_, entry_block); +} + +std::vector MergeReturnPass::CollectReturnBlocks( + Function* function) { + std::vector return_blocks; + for (auto& block : *function) { + Instruction& terminator = *block.tail(); + if (terminator.opcode() == spv::Op::OpReturn || + terminator.opcode() == spv::Op::OpReturnValue) { + return_blocks.push_back(&block); + } + } + return return_blocks; +} + +void MergeReturnPass::MergeReturnBlocks( + Function* function, const std::vector& return_blocks) { + if (return_blocks.size() <= 1) { + // No work to do. + return; + } + + CreateReturnBlock(); + uint32_t return_id = final_return_block_->id(); + auto ret_block_iter = --function->end(); + // Create the PHI for the merged block (if necessary). + // Create new return. + std::vector phi_ops; + for (auto block : return_blocks) { + if (block->tail()->opcode() == spv::Op::OpReturnValue) { + phi_ops.push_back( + {SPV_OPERAND_TYPE_ID, {block->tail()->GetSingleWordInOperand(0u)}}); + phi_ops.push_back({SPV_OPERAND_TYPE_ID, {block->id()}}); + } + } + + if (!phi_ops.empty()) { + // Need a PHI node to select the correct return value. + uint32_t phi_result_id = TakeNextId(); + uint32_t phi_type_id = function->type_id(); + std::unique_ptr phi_inst(new Instruction( + context(), spv::Op::OpPhi, phi_type_id, phi_result_id, phi_ops)); + ret_block_iter->AddInstruction(std::move(phi_inst)); + BasicBlock::iterator phiIter = ret_block_iter->tail(); + + std::unique_ptr return_inst( + new Instruction(context(), spv::Op::OpReturnValue, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {phi_result_id}}})); + ret_block_iter->AddInstruction(std::move(return_inst)); + BasicBlock::iterator ret = ret_block_iter->tail(); + + // Register the phi def and mark instructions for use updates. + get_def_use_mgr()->AnalyzeInstDefUse(&*phiIter); + get_def_use_mgr()->AnalyzeInstDef(&*ret); + } else { + std::unique_ptr return_inst( + new Instruction(context(), spv::Op::OpReturn)); + ret_block_iter->AddInstruction(std::move(return_inst)); + } + + // Replace returns with branches + for (auto block : return_blocks) { + context()->ForgetUses(block->terminator()); + block->tail()->SetOpcode(spv::Op::OpBranch); + block->tail()->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {return_id}}}); + get_def_use_mgr()->AnalyzeInstUse(block->terminator()); + get_def_use_mgr()->AnalyzeInstUse(block->GetLabelInst()); + } + + get_def_use_mgr()->AnalyzeInstDefUse(ret_block_iter->GetLabelInst()); +} + +void MergeReturnPass::AddNewPhiNodes() { + std::list order; + cfg()->ComputeStructuredOrder(function_, &*function_->begin(), &order); + + for (BasicBlock* bb : order) { + AddNewPhiNodes(bb); + } +} + +void MergeReturnPass::AddNewPhiNodes(BasicBlock* bb) { + // New phi nodes are needed for any id whose definition used to dominate |bb|, + // but no longer dominates |bb|. These are found by walking the dominator + // tree starting at the original immediate dominator of |bb| and ending at its + // current dominator. + + // Because we are walking the updated dominator tree it is important that the + // new phi nodes for the original dominators of |bb| have already been added. + // Otherwise some ids might be missed. Consider the case where bb1 dominates + // bb2, and bb2 dominates bb3. Suppose there are changes such that bb1 no + // longer dominates bb2 and the same for bb2 and bb3. This algorithm will not + // look at the ids defined in bb1. However, calling |AddNewPhiNodes(bb2)| + // first will add a phi node in bb2 for that value. Then a call to + // |AddNewPhiNodes(bb3)| will process that value by processing the phi in bb2. + DominatorAnalysis* dom_tree = context()->GetDominatorAnalysis(function_); + + BasicBlock* dominator = dom_tree->ImmediateDominator(bb); + if (dominator == nullptr) { + return; + } + + BasicBlock* current_bb = context()->get_instr_block(original_dominator_[bb]); + while (current_bb != nullptr && current_bb != dominator) { + for (Instruction& inst : *current_bb) { + CreatePhiNodesForInst(bb, inst); + } + current_bb = dom_tree->ImmediateDominator(current_bb); + } +} + +void MergeReturnPass::RecordImmediateDominators(Function* function) { + DominatorAnalysis* dom_tree = context()->GetDominatorAnalysis(function); + for (BasicBlock& bb : *function) { + BasicBlock* dominator_bb = dom_tree->ImmediateDominator(&bb); + if (dominator_bb && dominator_bb != cfg()->pseudo_entry_block()) { + original_dominator_[&bb] = dominator_bb->terminator(); + } else { + original_dominator_[&bb] = nullptr; + } + } +} + +void MergeReturnPass::InsertAfterElement(BasicBlock* element, + BasicBlock* new_element, + std::list* list) { + auto pos = std::find(list->begin(), list->end(), element); + assert(pos != list->end()); + ++pos; + list->insert(pos, new_element); +} + +bool MergeReturnPass::AddSingleCaseSwitchAroundFunction() { + CreateReturnBlock(); + CreateReturn(final_return_block_); + + if (context()->AreAnalysesValid(IRContext::kAnalysisCFG)) { + cfg()->RegisterBlock(final_return_block_); + } + + if (!CreateSingleCaseSwitch(final_return_block_)) { + return false; + } + return true; +} + +BasicBlock* MergeReturnPass::CreateContinueTarget(uint32_t header_label_id) { + std::unique_ptr label( + new Instruction(context(), spv::Op::OpLabel, 0u, TakeNextId(), {})); + + // Create the new basic block + std::unique_ptr block(new BasicBlock(std::move(label))); + + // Insert the new block just before the return block + auto pos = function_->end(); + assert(pos != function_->begin()); + pos--; + assert(pos != function_->begin()); + assert(&*pos == final_return_block_); + auto new_block = &*pos.InsertBefore(std::move(block)); + new_block->SetParent(function_); + + context()->AnalyzeDefUse(new_block->GetLabelInst()); + context()->set_instr_block(new_block->GetLabelInst(), new_block); + + InstructionBuilder builder( + context(), new_block, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + builder.AddBranch(header_label_id); + + if (context()->AreAnalysesValid(IRContext::kAnalysisCFG)) { + cfg()->RegisterBlock(new_block); + } + + return new_block; +} + +bool MergeReturnPass::CreateSingleCaseSwitch(BasicBlock* merge_target) { + // Insert the switch before any code is run. We have to split the entry + // block to make sure the OpVariable instructions remain in the entry block. + BasicBlock* start_block = &*function_->begin(); + auto split_pos = start_block->begin(); + while (split_pos->opcode() == spv::Op::OpVariable) { + ++split_pos; + } + + BasicBlock* old_block = + start_block->SplitBasicBlock(context(), TakeNextId(), split_pos); + + // Add the switch to the end of the entry block. + InstructionBuilder builder( + context(), start_block, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + + uint32_t const_zero_id = builder.GetUintConstantId(0u); + if (const_zero_id == 0) { + return false; + } + builder.AddSwitch(const_zero_id, old_block->id(), {}, merge_target->id()); + + if (context()->AreAnalysesValid(IRContext::kAnalysisCFG)) { + cfg()->RegisterBlock(old_block); + cfg()->AddEdges(start_block); + } + return true; +} + +bool MergeReturnPass::HasNontrivialUnreachableBlocks(Function* function) { + utils::BitVector reachable_blocks; + cfg()->ForEachBlockInPostOrder( + function->entry().get(), + [&reachable_blocks](BasicBlock* bb) { reachable_blocks.Set(bb->id()); }); + + for (auto& bb : *function) { + if (reachable_blocks.Get(bb.id())) { + continue; + } + + StructuredCFGAnalysis* struct_cfg_analysis = + context()->GetStructuredCFGAnalysis(); + if (struct_cfg_analysis->IsContinueBlock(bb.id())) { + // |bb| must be an empty block ending with a branch to the header. + Instruction* inst = &*bb.begin(); + if (inst->opcode() != spv::Op::OpBranch) { + return true; + } + + if (inst->GetSingleWordInOperand(0) != + struct_cfg_analysis->ContainingLoop(bb.id())) { + return true; + } + } else if (struct_cfg_analysis->IsMergeBlock(bb.id())) { + // |bb| must be an empty block ending with OpUnreachable. + if (bb.begin()->opcode() != spv::Op::OpUnreachable) { + return true; + } + } else { + return true; + } + } + return false; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/merge_return_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/merge_return_pass.h new file mode 100644 index 000000000000..d15db2f671d3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/merge_return_pass.h @@ -0,0 +1,335 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_MERGE_RETURN_PASS_H_ +#define SOURCE_OPT_MERGE_RETURN_PASS_H_ + +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/function.h" +#include "source/opt/mem_pass.h" + +namespace spvtools { +namespace opt { + +/******************************************************************************* + * + * Handling Structured Control Flow: + * + * Structured control flow guarantees that the CFG will converge at a given + * point (the merge block). Within structured control flow, all blocks must be + * post-dominated by the merge block, except return blocks and break blocks. + * A break block is a block that branches to a containing construct's merge + * block. + * + * Beyond this, we further assume that all unreachable blocks have been + * cleaned up. This means that the only unreachable blocks are those necessary + * for valid structured control flow. + * + * Algorithm: + * + * If a return is encountered, it should record that: i) the function has + * "returned" and ii) the value of the return. The return should be replaced + * with a branch. If current block is not within structured control flow, this + * is the final return. This block should branch to the new return block (its + * direct successor). If the current block is within structured control flow, + * the branch destination should be the innermost construct's merge. This + * merge will always exist because a single case switch is added around the + * entire function. If the merge block produces any live values it will need to + * be predicated. While the merge is nested in structured control flow, the + * predication path should branch to the merge block of the inner-most loop + * (or switch if no loop) it is contained in. Once structured control flow has + * been exited, it will be at the merge of the single case switch, which will + * simply return. + * + * In the final return block, the return value should be loaded and returned. + * Memory promotion passes should be able to promote the newly introduced + * variables ("has returned" and "return value"). + * + * Predicating the Final Merge: + * + * At each merge block predication needs to be introduced (optimization: only if + * that block produces value live beyond it). This needs to be done carefully. + * The merge block should be split into multiple blocks. + * + * 1 (loop header) + * / \ + * (ret) 2 3 (merge) + * + * || + * \/ + * + * 0 (single case switch header) + * | + * 1 (loop header) + * / \ + * 2 | (merge) + * \ / + * 3' (merge) + * / \ + * | 3 (original code in 3) + * \ / + * (ret) 4 (single case switch merge) + * + * In the above (simple) example, the return originally in |2| is passed through + * the loop merge. That merge is predicated such that the old body of the block + * is the else branch. The branch condition is based on the value of the "has + * returned" variable. + * + ******************************************************************************/ + +// Documented in optimizer.hpp +class MergeReturnPass : public MemPass { + public: + MergeReturnPass() + : function_(nullptr), + return_flag_(nullptr), + return_value_(nullptr), + constant_true_(nullptr), + final_return_block_(nullptr) {} + + const char* name() const override { return "merge-return"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // This class is used to store the a break merge instruction and a current + // merge instruction. The intended use is to keep track of the block to + // break to and the current innermost control flow construct merge block. + class StructuredControlState { + public: + StructuredControlState(Instruction* break_merge, Instruction* merge) + : break_merge_(break_merge), current_merge_(merge) {} + + bool InBreakable() const { return break_merge_; } + bool InStructuredFlow() const { return CurrentMergeId() != 0; } + + uint32_t CurrentMergeId() const { + return current_merge_ ? current_merge_->GetSingleWordInOperand(0u) : 0u; + } + + uint32_t CurrentMergeHeader() const { + return current_merge_ ? current_merge_->context() + ->get_instr_block(current_merge_) + ->id() + : 0; + } + + uint32_t BreakMergeId() const { + return break_merge_ ? break_merge_->GetSingleWordInOperand(0u) : 0u; + } + + Instruction* BreakMergeInst() const { return break_merge_; } + + private: + Instruction* break_merge_; + Instruction* current_merge_; + }; + + // Returns all BasicBlocks terminated by OpReturn or OpReturnValue in + // |function|. + std::vector CollectReturnBlocks(Function* function); + + // Creates a new basic block with a single return. If |function| returns a + // value, a phi node is created to select the correct value to return. + // Replaces old returns with an unconditional branch to the new block. + void MergeReturnBlocks(Function* function, + const std::vector& returnBlocks); + + // Generate and push new control flow state if |block| contains a merge. + void GenerateState(BasicBlock* block); + + // Merges the return instruction in |function| so that it has a single return + // statement. It is assumed that |function| has structured control flow, and + // that |return_blocks| is a list of all of the basic blocks in |function| + // that have a return. + bool ProcessStructured(Function* function, + const std::vector& return_blocks); + + // Changes an OpReturn* or OpUnreachable instruction at the end of |block| + // into a store to |return_flag_|, a store to |return_value_| (if necessary), + // and a branch to the appropriate merge block. + // + // Is is assumed that |AddReturnValue| have already been called to created the + // variable to store a return value if there is one. + // + // Note this will break the semantics. To fix this, PredicateBlock will have + // to be called on the merge block the branch targets. + void ProcessStructuredBlock(BasicBlock* block); + + // Creates a variable used to store whether or not the control flow has + // traversed a block that used to have a return. A pointer to the instruction + // declaring the variable is stored in |return_flag_|. + void AddReturnFlag(); + + // Creates the variable used to store the return value when passing through + // a block that use to contain an OpReturnValue. + void AddReturnValue(); + + // Adds a store that stores true to |return_flag_| immediately before the + // terminator of |block|. It is assumed that |AddReturnFlag| has already been + // called. + void RecordReturned(BasicBlock* block); + + // Adds an instruction that stores the value being returned in the + // OpReturnValue in |block|. The value is stored to |return_value_|, and the + // store is placed before the OpReturnValue. + // + // If |block| does not contain an OpReturnValue, then this function has no + // effect. If |block| contains an OpReturnValue, then |AddReturnValue| must + // have already been called to create the variable to store to. + void RecordReturnValue(BasicBlock* block); + + // Adds an unconditional branch in |block| that branches to |target|. It also + // adds stores to |return_flag_| and |return_value_| as needed. + // |AddReturnFlag| and |AddReturnValue| must have already been called. + void BranchToBlock(BasicBlock* block, uint32_t target); + + // For every basic block that is reachable from |return_block|, extra code is + // added to jump around any code that should not be executed because the + // original code would have already returned. This involves adding new + // selections constructs to jump around these instructions. + // + // If new blocks that are created will be added to |order|. This way a call + // can traverse these new block in structured order. + // + // Returns true if successful. + bool PredicateBlocks(BasicBlock* return_block, + std::unordered_set* pSet, + std::list* order); + + // Add a conditional branch at the start of |block| that either jumps to + // the merge block of |break_merge_inst| or the original code in |block| + // depending on the value in |return_flag_|. The continue target in + // |break_merge_inst| will be updated if needed. + // + // If new blocks that are created will be added to |order|. This way a call + // can traverse these new block in structured order. + // + // Returns true if successful. + bool BreakFromConstruct(BasicBlock* block, + std::unordered_set* predicated, + std::list* order, + Instruction* break_merge_inst); + + // Add an |OpReturn| or |OpReturnValue| to the end of |block|. If an + // |OpReturnValue| is needed, the return value is loaded from |return_value_|. + void CreateReturn(BasicBlock* block); + + // Creates a block at the end of the function that will become the single + // return block at the end of the pass. + void CreateReturnBlock(); + + // Creates a Phi node in |merge_block| for the result of |inst|. + // Any uses of the result of |inst| that are no longer + // dominated by |inst|, are replaced with the result of the new |OpPhi| + // instruction. + void CreatePhiNodesForInst(BasicBlock* merge_block, Instruction& inst); + + // Add new phi nodes for any id that no longer dominate all of it uses. A phi + // node is added to a block |bb| for an id if the id is defined between the + // original immediate dominator of |bb| and its new immediate dominator. It + // is assumed that at this point there are no unreachable blocks in the + // control flow graph. + void AddNewPhiNodes(); + + // Creates any new phi nodes that are needed in |bb|. |AddNewPhiNodes| must + // have already been called on the original dominators of |bb|. + void AddNewPhiNodes(BasicBlock* bb); + + // Records the terminator of immediate dominator for every basic block in + // |function|. + void RecordImmediateDominators(Function* function); + + // Modifies existing OpPhi instruction in |target| block to account for the + // new edge from |new_source|. The value for that edge will be an Undef. + // + // The CFG must not include the edge from |new_source| to |target| yet. + void UpdatePhiNodes(BasicBlock* new_source, BasicBlock* target); + + StructuredControlState& CurrentState() { return state_.back(); } + + // Inserts |new_element| into |list| after the first occurrence of |element|. + // |element| must be in |list| at least once. + void InsertAfterElement(BasicBlock* element, BasicBlock* new_element, + std::list* list); + + // Creates a single case switch around all of the executable code of the + // current function where the switch and case value are both zero and the + // default is the merge block. Returns after the switch is executed. Sets + // |final_return_block_|. + bool AddSingleCaseSwitchAroundFunction(); + + // Creates a new basic block that branches to |header_label_id|. Returns the + // new basic block. The block will be the second last basic block in the + // function. + BasicBlock* CreateContinueTarget(uint32_t header_label_id); + + // Creates a one case switch around the executable code of the function with + // |merge_target| as the merge node. + bool CreateSingleCaseSwitch(BasicBlock* merge_target); + + // Returns true if |function| has an unreachable block that is not a continue + // target that simply branches back to the header, or a merge block containing + // 1 instruction which is OpUnreachable. + bool HasNontrivialUnreachableBlocks(Function* function); + + // A stack used to keep track of the break and current control flow construct + // merge blocks. + std::vector state_; + + // The current function being transformed. + Function* function_; + + // The |OpVariable| instruction defining a boolean variable used to keep track + // of whether or not the function is trying to return. + Instruction* return_flag_; + + // The |OpVariable| instruction defining a variabled to used to keep track of + // the value that was returned when passing through a block that use to + // contain an |OpReturnValue|. + Instruction* return_value_; + + // The instruction defining the boolean constant true. + Instruction* constant_true_; + + // The basic block that is suppose to become the contain the only return value + // after processing the current function. + BasicBlock* final_return_block_; + + // This is a map from a node to its original immediate dominator identified by + // the terminator if that block. We use the terminator because the block we + // want may change if the block is split. + std::unordered_map original_dominator_; + + // A map from a basic block, bb, to the set of basic blocks which represent + // the new edges that reach |bb|. + std::unordered_map> new_edges_; + + // Contains all return blocks that are merged. This is set is populated while + // processing structured blocks and used to properly construct OpPhi + // instructions. + std::unordered_set return_blocks_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_MERGE_RETURN_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/modify_maximal_reconvergence.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/modify_maximal_reconvergence.cpp new file mode 100644 index 000000000000..dd79b6283fe5 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/modify_maximal_reconvergence.cpp @@ -0,0 +1,103 @@ +// Copyright (c) 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "modify_maximal_reconvergence.h" + +#include "source/opt/ir_context.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { + +Pass::Status ModifyMaximalReconvergence::Process() { + bool changed = false; + if (add_) { + changed = AddMaximalReconvergence(); + } else { + changed = RemoveMaximalReconvergence(); + } + return changed ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +bool ModifyMaximalReconvergence::AddMaximalReconvergence() { + bool changed = false; + bool has_extension = false; + bool has_shader = + context()->get_feature_mgr()->HasCapability(spv::Capability::Shader); + for (auto extension : context()->extensions()) { + if (extension.GetOperand(0).AsString() == "SPV_KHR_maximal_reconvergence") { + has_extension = true; + break; + } + } + + std::unordered_set entry_points_with_mode; + for (auto mode : get_module()->execution_modes()) { + if (spv::ExecutionMode(mode.GetSingleWordInOperand(1)) == + spv::ExecutionMode::MaximallyReconvergesKHR) { + entry_points_with_mode.insert(mode.GetSingleWordInOperand(0)); + } + } + + for (auto entry_point : get_module()->entry_points()) { + const uint32_t id = entry_point.GetSingleWordInOperand(1); + if (!entry_points_with_mode.count(id)) { + changed = true; + if (!has_extension) { + context()->AddExtension("SPV_KHR_maximal_reconvergence"); + has_extension = true; + } + if (!has_shader) { + context()->AddCapability(spv::Capability::Shader); + has_shader = true; + } + context()->AddExecutionMode(MakeUnique( + context(), spv::Op::OpExecutionMode, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {id}}, + {SPV_OPERAND_TYPE_EXECUTION_MODE, + {static_cast( + spv::ExecutionMode::MaximallyReconvergesKHR)}}})); + entry_points_with_mode.insert(id); + } + } + + return changed; +} + +bool ModifyMaximalReconvergence::RemoveMaximalReconvergence() { + bool changed = false; + std::vector to_remove; + Instruction* mode = &*get_module()->execution_mode_begin(); + while (mode) { + if (mode->opcode() != spv::Op::OpExecutionMode && + mode->opcode() != spv::Op::OpExecutionModeId) { + break; + } + if (spv::ExecutionMode(mode->GetSingleWordInOperand(1)) == + spv::ExecutionMode::MaximallyReconvergesKHR) { + mode = context()->KillInst(mode); + changed = true; + } else { + mode = mode->NextNode(); + } + } + + changed |= + context()->RemoveExtension(Extension::kSPV_KHR_maximal_reconvergence); + return changed; +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/modify_maximal_reconvergence.h b/thirdparty/glslang/External/spirv-tools/source/opt/modify_maximal_reconvergence.h new file mode 100644 index 000000000000..8d9a698e9e49 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/modify_maximal_reconvergence.h @@ -0,0 +1,53 @@ +// Copyright (c) 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBSPIRV_OPT_MODIFY_MAXIMAL_RECONVERGENCE_H_ +#define LIBSPIRV_OPT_MODIFY_MAXIMAL_RECONVERGENCE_H_ + +#include "pass.h" + +namespace spvtools { +namespace opt { + +// Modifies entry points to either add or remove MaximallyReconvergesKHR +// +// This pass will either add or remove MaximallyReconvergesKHR to all entry +// points in the module. When adding the execution mode, it does not attempt to +// determine whether any ray tracing invocation repack instructions might be +// executed because it is a runtime restriction. That is left to the user. +class ModifyMaximalReconvergence : public Pass { + public: + const char* name() const override { return "modify-maximal-reconvergence"; } + Status Process() override; + + explicit ModifyMaximalReconvergence(bool add = true) : Pass(), add_(add) {} + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + bool AddMaximalReconvergence(); + bool RemoveMaximalReconvergence(); + + bool add_; +}; +} // namespace opt +} // namespace spvtools + +#endif // LIBSPIRV_OPT_MODIFY_MAXIMAL_RECONVERGENCE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/module.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/module.cpp new file mode 100644 index 000000000000..a9710c6a3c20 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/module.cpp @@ -0,0 +1,286 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/module.h" + +#include +#include +#include + +#include "source/operand.h" +#include "source/opt/ir_context.h" +#include "source/opt/reflect.h" + +namespace spvtools { +namespace opt { + +uint32_t Module::TakeNextIdBound() { + if (context()) { + if (id_bound() >= context()->max_id_bound()) { + return 0; + } + } else if (id_bound() >= kDefaultMaxIdBound) { + return 0; + } + + return header_.bound++; +} + +std::vector Module::GetTypes() { + std::vector type_insts; + for (auto& inst : types_values_) { + if (IsTypeInst(inst.opcode())) type_insts.push_back(&inst); + } + return type_insts; +} + +std::vector Module::GetTypes() const { + std::vector type_insts; + for (auto& inst : types_values_) { + if (IsTypeInst(inst.opcode())) type_insts.push_back(&inst); + } + return type_insts; +} + +std::vector Module::GetConstants() { + std::vector const_insts; + for (auto& inst : types_values_) { + if (IsConstantInst(inst.opcode())) const_insts.push_back(&inst); + } + return const_insts; +} + +std::vector Module::GetConstants() const { + std::vector const_insts; + for (auto& inst : types_values_) { + if (IsConstantInst(inst.opcode())) const_insts.push_back(&inst); + } + return const_insts; +} + +uint32_t Module::GetGlobalValue(spv::Op opcode) const { + for (auto& inst : types_values_) { + if (inst.opcode() == opcode) return inst.result_id(); + } + return 0; +} + +void Module::AddGlobalValue(spv::Op opcode, uint32_t result_id, + uint32_t type_id) { + std::unique_ptr newGlobal( + new Instruction(context(), opcode, type_id, result_id, {})); + AddGlobalValue(std::move(newGlobal)); +} + +void Module::ForEachInst(const std::function& f, + bool run_on_debug_line_insts) { +#define DELEGATE(list) list.ForEachInst(f, run_on_debug_line_insts) + DELEGATE(capabilities_); + DELEGATE(extensions_); + DELEGATE(ext_inst_imports_); + if (memory_model_) memory_model_->ForEachInst(f, run_on_debug_line_insts); + if (sampled_image_address_mode_) + sampled_image_address_mode_->ForEachInst(f, run_on_debug_line_insts); + DELEGATE(entry_points_); + DELEGATE(execution_modes_); + DELEGATE(debugs1_); + DELEGATE(debugs2_); + DELEGATE(debugs3_); + DELEGATE(ext_inst_debuginfo_); + DELEGATE(annotations_); + DELEGATE(types_values_); + for (auto& i : functions_) { + i->ForEachInst(f, run_on_debug_line_insts, + /* run_on_non_semantic_insts = */ true); + } +#undef DELEGATE +} + +void Module::ForEachInst(const std::function& f, + bool run_on_debug_line_insts) const { +#define DELEGATE(i) i.ForEachInst(f, run_on_debug_line_insts) + for (auto& i : capabilities_) DELEGATE(i); + for (auto& i : extensions_) DELEGATE(i); + for (auto& i : ext_inst_imports_) DELEGATE(i); + if (memory_model_) + static_cast(memory_model_.get()) + ->ForEachInst(f, run_on_debug_line_insts); + if (sampled_image_address_mode_) + static_cast(sampled_image_address_mode_.get()) + ->ForEachInst(f, run_on_debug_line_insts); + for (auto& i : entry_points_) DELEGATE(i); + for (auto& i : execution_modes_) DELEGATE(i); + for (auto& i : debugs1_) DELEGATE(i); + for (auto& i : debugs2_) DELEGATE(i); + for (auto& i : debugs3_) DELEGATE(i); + for (auto& i : annotations_) DELEGATE(i); + for (auto& i : types_values_) DELEGATE(i); + for (auto& i : ext_inst_debuginfo_) DELEGATE(i); + for (auto& i : functions_) { + static_cast(i.get())->ForEachInst( + f, run_on_debug_line_insts, + /* run_on_non_semantic_insts = */ true); + } + if (run_on_debug_line_insts) { + for (auto& i : trailing_dbg_line_info_) DELEGATE(i); + } +#undef DELEGATE +} + +void Module::ToBinary(std::vector* binary, bool skip_nop) const { + binary->push_back(header_.magic_number); + binary->push_back(header_.version); + // TODO(antiagainst): should we change the generator number? + binary->push_back(header_.generator); + binary->push_back(header_.bound); + binary->push_back(header_.schema); + + size_t bound_idx = binary->size() - 2; + DebugScope last_scope(kNoDebugScope, kNoInlinedAt); + const Instruction* last_line_inst = nullptr; + bool between_merge_and_branch = false; + bool between_label_and_phi_var = false; + auto write_inst = [binary, skip_nop, &last_scope, &last_line_inst, + &between_merge_and_branch, &between_label_and_phi_var, + this](const Instruction* i) { + // Skip emitting line instructions between merge and branch instructions. + auto opcode = i->opcode(); + if (between_merge_and_branch && i->IsLineInst()) { + return; + } + if (last_line_inst != nullptr) { + // If the current instruction is OpLine or DebugLine and it is the same + // as the last line instruction that is still effective (can be applied + // to the next instruction), we skip writing the current instruction. + if (i->IsLine()) { + uint32_t operand_index = 0; + if (last_line_inst->WhileEachInOperand( + [&operand_index, i](const uint32_t* word) { + assert(i->NumInOperandWords() > operand_index); + return *word == i->GetSingleWordInOperand(operand_index++); + })) { + return; + } + } else if (!i->IsNoLine() && i->dbg_line_insts().empty()) { + // If the current instruction does not have the line information, + // the last line information is not effective any more. Emit OpNoLine + // or DebugNoLine to specify it. + uint32_t shader_set_id = context() + ->get_feature_mgr() + ->GetExtInstImportId_Shader100DebugInfo(); + if (shader_set_id != 0) { + binary->push_back((5 << 16) | + static_cast(spv::Op::OpExtInst)); + binary->push_back(context()->get_type_mgr()->GetVoidTypeId()); + binary->push_back(context()->TakeNextId()); + binary->push_back(shader_set_id); + binary->push_back(NonSemanticShaderDebugInfo100DebugNoLine); + } else { + binary->push_back((1 << 16) | + static_cast(spv::Op::OpNoLine)); + } + last_line_inst = nullptr; + } + } + + if (opcode == spv::Op::OpLabel) { + between_label_and_phi_var = true; + } else if (opcode != spv::Op::OpVariable && opcode != spv::Op::OpPhi && + !spvtools::opt::IsOpLineInst(opcode)) { + between_label_and_phi_var = false; + } + + if (!(skip_nop && i->IsNop())) { + const auto& scope = i->GetDebugScope(); + if (scope != last_scope && !between_merge_and_branch) { + // Can only emit nonsemantic instructions after all phi instructions + // in a block so don't emit scope instructions before phi instructions + // for NonSemantic.Shader.DebugInfo.100. + if (!between_label_and_phi_var || + context() + ->get_feature_mgr() + ->GetExtInstImportId_OpenCL100DebugInfo()) { + // Emit DebugScope |scope| to |binary|. + auto dbg_inst = ext_inst_debuginfo_.begin(); + scope.ToBinary(dbg_inst->type_id(), context()->TakeNextId(), + dbg_inst->GetSingleWordOperand(2), binary); + } + last_scope = scope; + } + + i->ToBinaryWithoutAttachedDebugInsts(binary); + } + // Update the last line instruction. + between_merge_and_branch = false; + if (spvOpcodeIsBlockTerminator(opcode) || i->IsNoLine()) { + last_line_inst = nullptr; + } else if (opcode == spv::Op::OpLoopMerge || + opcode == spv::Op::OpSelectionMerge) { + between_merge_and_branch = true; + last_line_inst = nullptr; + } else if (i->IsLine()) { + last_line_inst = i; + } + }; + ForEachInst(write_inst, true); + + // We create new instructions for DebugScope and DebugNoLine. The bound must + // be updated. + binary->data()[bound_idx] = header_.bound; +} + +uint32_t Module::ComputeIdBound() const { + uint32_t highest = 0; + + ForEachInst( + [&highest](const Instruction* inst) { + for (const auto& operand : *inst) { + if (spvIsIdType(operand.type)) { + highest = std::max(highest, operand.words[0]); + } + } + }, + true /* scan debug line insts as well */); + + return highest + 1; +} + +bool Module::HasExplicitCapability(uint32_t cap) { + for (auto& ci : capabilities_) { + uint32_t tcap = ci.GetSingleWordOperand(0); + if (tcap == cap) { + return true; + } + } + return false; +} + +uint32_t Module::GetExtInstImportId(const char* extstr) { + for (auto& ei : ext_inst_imports_) + if (!ei.GetInOperand(0).AsString().compare(extstr)) return ei.result_id(); + return 0; +} + +std::ostream& operator<<(std::ostream& str, const Module& module) { + module.ForEachInst([&str](const Instruction* inst) { + str << *inst; + if (inst->opcode() != spv::Op::OpFunctionEnd) { + str << std::endl; + } + }); + return str; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/module.h b/thirdparty/glslang/External/spirv-tools/source/opt/module.h new file mode 100644 index 000000000000..98c16dc4c9e9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/module.h @@ -0,0 +1,558 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_MODULE_H_ +#define SOURCE_OPT_MODULE_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/function.h" +#include "source/opt/instruction.h" +#include "source/opt/iterator.h" + +namespace spvtools { +namespace opt { + +class IRContext; + +// A struct for containing the module header information. +struct ModuleHeader { + uint32_t magic_number; + uint32_t version; + uint32_t generator; + uint32_t bound; + uint32_t schema; +}; + +// A SPIR-V module. It contains all the information for a SPIR-V module and +// serves as the backbone of optimization transformations. +class Module { + public: + using iterator = UptrVectorIterator; + using const_iterator = UptrVectorIterator; + using inst_iterator = InstructionList::iterator; + using const_inst_iterator = InstructionList::const_iterator; + + // Creates an empty module with zero'd header. + Module() : header_({}), contains_debug_info_(false) {} + + // Sets the header to the given |header|. + void SetHeader(const ModuleHeader& header) { header_ = header; } + + // Sets the Id bound. The Id bound cannot be set to 0. + void SetIdBound(uint32_t bound) { + assert(bound != 0); + header_.bound = bound; + } + + // Returns the Id bound. + uint32_t IdBound() const { return header_.bound; } + + // Returns the current Id bound and increases it to the next available value. + // If the id bound has already reached its maximum value, then 0 is returned. + // The maximum value for the id bound is obtained from the context. If there + // is none, then the minimum that limit can be according to the spir-v + // specification. + // TODO(1841): Update the uses to check for a 0 return value. + uint32_t TakeNextIdBound(); + + // Appends a capability instruction to this module. + inline void AddCapability(std::unique_ptr c); + + // Appends an extension instruction to this module. + inline void AddExtension(std::unique_ptr e); + + // Appends an extended instruction set instruction to this module. + inline void AddExtInstImport(std::unique_ptr e); + + // Set the memory model for this module. + inline void SetMemoryModel(std::unique_ptr m); + + // Set the sampled image addressing mode for this module. + inline void SetSampledImageAddressMode(std::unique_ptr m); + + // Appends an entry point instruction to this module. + inline void AddEntryPoint(std::unique_ptr e); + + // Appends an execution mode instruction to this module. + inline void AddExecutionMode(std::unique_ptr e); + + // Appends a debug 1 instruction (excluding OpLine & OpNoLine) to this module. + // "debug 1" instructions are the ones in layout section 7.a), see section + // 2.4 Logical Layout of a Module from the SPIR-V specification. + inline void AddDebug1Inst(std::unique_ptr d); + + // Appends a debug 2 instruction (excluding OpLine & OpNoLine) to this module. + // "debug 2" instructions are the ones in layout section 7.b), see section + // 2.4 Logical Layout of a Module from the SPIR-V specification. + inline void AddDebug2Inst(std::unique_ptr d); + + // Appends a debug 3 instruction (OpModuleProcessed) to this module. + // This is due to decision by the SPIR Working Group, pending publication. + inline void AddDebug3Inst(std::unique_ptr d); + + // Appends a debug info extension (OpenCL.DebugInfo.100, + // NonSemantic.Shader.DebugInfo.100, or DebugInfo) instruction to this module. + inline void AddExtInstDebugInfo(std::unique_ptr d); + + // Appends an annotation instruction to this module. + inline void AddAnnotationInst(std::unique_ptr a); + + // Appends a type-declaration instruction to this module. + inline void AddType(std::unique_ptr t); + + // Appends a constant, global variable, or OpUndef instruction to this module. + inline void AddGlobalValue(std::unique_ptr v); + + // Prepends a function declaration to this module. + inline void AddFunctionDeclaration(std::unique_ptr f); + + // Appends a function to this module. + inline void AddFunction(std::unique_ptr f); + + // Sets |contains_debug_info_| as true. + inline void SetContainsDebugInfo(); + inline bool ContainsDebugInfo() { return contains_debug_info_; } + + // Returns a vector of pointers to type-declaration instructions in this + // module. + std::vector GetTypes(); + std::vector GetTypes() const; + // Returns a vector of pointers to constant-creation instructions in this + // module. + std::vector GetConstants(); + std::vector GetConstants() const; + + // Return result id of global value with |opcode|, 0 if not present. + uint32_t GetGlobalValue(spv::Op opcode) const; + + // Add global value with |opcode|, |result_id| and |type_id| + void AddGlobalValue(spv::Op opcode, uint32_t result_id, uint32_t type_id); + + inline uint32_t id_bound() const { return header_.bound; } + + inline uint32_t version() const { return header_.version; } + inline uint32_t generator() const { return header_.generator; } + inline uint32_t schema() const { return header_.schema; } + + inline void set_version(uint32_t v) { header_.version = v; } + + // Iterators for capabilities instructions contained in this module. + inline inst_iterator capability_begin(); + inline inst_iterator capability_end(); + inline IteratorRange capabilities(); + inline IteratorRange capabilities() const; + + // Iterators for ext_inst_imports instructions contained in this module. + inline inst_iterator ext_inst_import_begin(); + inline inst_iterator ext_inst_import_end(); + inline IteratorRange ext_inst_imports(); + inline IteratorRange ext_inst_imports() const; + + // Return the memory model instruction contained in this module. + inline Instruction* GetMemoryModel() { return memory_model_.get(); } + inline const Instruction* GetMemoryModel() const { + return memory_model_.get(); + } + + // Return the sampled image address mode instruction contained in this module. + inline Instruction* GetSampledImageAddressMode() { + return sampled_image_address_mode_.get(); + } + inline const Instruction* GetSampledImageAddressMode() const { + return sampled_image_address_mode_.get(); + } + + // There are several kinds of debug instructions, according to where they can + // appear in the logical layout of a module: + // - Section 7a: OpString, OpSourceExtension, OpSource, OpSourceContinued + // - Section 7b: OpName, OpMemberName + // - Section 7c: OpModuleProcessed + // - Mostly anywhere: OpLine and OpNoLine + // + + // Iterators for debug 1 instructions (excluding OpLine & OpNoLine) contained + // in this module. These are for layout section 7a. + inline inst_iterator debug1_begin(); + inline inst_iterator debug1_end(); + inline IteratorRange debugs1(); + inline IteratorRange debugs1() const; + + // Iterators for debug 2 instructions (excluding OpLine & OpNoLine) contained + // in this module. These are for layout section 7b. + inline inst_iterator debug2_begin(); + inline inst_iterator debug2_end(); + inline IteratorRange debugs2(); + inline IteratorRange debugs2() const; + + // Iterators for debug 3 instructions (excluding OpLine & OpNoLine) contained + // in this module. These are for layout section 7c. + inline inst_iterator debug3_begin(); + inline inst_iterator debug3_end(); + inline IteratorRange debugs3(); + inline IteratorRange debugs3() const; + + // Iterators for debug info instructions (excluding OpLine & OpNoLine) + // contained in this module. These are OpExtInst for DebugInfo extension + // placed between section 9 and 10. + inline inst_iterator ext_inst_debuginfo_begin(); + inline inst_iterator ext_inst_debuginfo_end(); + inline IteratorRange ext_inst_debuginfo(); + inline IteratorRange ext_inst_debuginfo() const; + + // Iterators for entry point instructions contained in this module + inline IteratorRange entry_points(); + inline IteratorRange entry_points() const; + + // Iterators for execution_modes instructions contained in this module. + inline inst_iterator execution_mode_begin(); + inline inst_iterator execution_mode_end(); + inline IteratorRange execution_modes(); + inline IteratorRange execution_modes() const; + + // Iterators for annotation instructions contained in this module. + inline inst_iterator annotation_begin(); + inline inst_iterator annotation_end(); + IteratorRange annotations(); + IteratorRange annotations() const; + + // Iterators for extension instructions contained in this module. + inline inst_iterator extension_begin(); + inline inst_iterator extension_end(); + IteratorRange extensions(); + IteratorRange extensions() const; + + // Iterators for types, constants and global variables instructions. + inline inst_iterator types_values_begin(); + inline inst_iterator types_values_end(); + inline IteratorRange types_values(); + inline IteratorRange types_values() const; + + // Iterators for functions contained in this module. + iterator begin() { return iterator(&functions_, functions_.begin()); } + iterator end() { return iterator(&functions_, functions_.end()); } + const_iterator begin() const { return cbegin(); } + const_iterator end() const { return cend(); } + inline const_iterator cbegin() const; + inline const_iterator cend() const; + + // Invokes function |f| on all instructions in this module, and optionally on + // the debug line instructions that precede them. + void ForEachInst(const std::function& f, + bool run_on_debug_line_insts = false); + void ForEachInst(const std::function& f, + bool run_on_debug_line_insts = false) const; + + // Pushes the binary segments for this instruction into the back of *|binary|. + // If |skip_nop| is true and this is a OpNop, do nothing. + void ToBinary(std::vector* binary, bool skip_nop) const; + + // Returns 1 more than the maximum Id value mentioned in the module. + uint32_t ComputeIdBound() const; + + // Returns true if module has capability |cap| + bool HasExplicitCapability(uint32_t cap); + + // Returns id for OpExtInst instruction for extension |extstr|. + // Returns 0 if not found. + uint32_t GetExtInstImportId(const char* extstr); + + // Sets the associated context for this module + void SetContext(IRContext* c) { context_ = c; } + + // Gets the associated context for this module + IRContext* context() const { return context_; } + + // Sets the trailing debug line info to |dbg_line_info|. + void SetTrailingDbgLineInfo(std::vector&& dbg_line_info) { + trailing_dbg_line_info_ = std::move(dbg_line_info); + } + + std::vector& trailing_dbg_line_info() { + return trailing_dbg_line_info_; + } + + const std::vector& trailing_dbg_line_info() const { + return trailing_dbg_line_info_; + } + + private: + ModuleHeader header_; // Module header + + // The following fields respect the "Logical Layout of a Module" in + // Section 2.4 of the SPIR-V specification. + IRContext* context_; + InstructionList capabilities_; + InstructionList extensions_; + InstructionList ext_inst_imports_; + // A module only has one memory model instruction. + std::unique_ptr memory_model_; + // A module can only have one optional sampled image addressing mode + std::unique_ptr sampled_image_address_mode_; + InstructionList entry_points_; + InstructionList execution_modes_; + InstructionList debugs1_; + InstructionList debugs2_; + InstructionList debugs3_; + InstructionList ext_inst_debuginfo_; + InstructionList annotations_; + // Type declarations, constants, and global variable declarations. + InstructionList types_values_; + std::vector> functions_; + + // If the module ends with Op*Line instruction, they will not be attached to + // any instruction. We record them here, so they will not be lost. + std::vector trailing_dbg_line_info_; + + // This module contains DebugScope/DebugNoScope or OpLine/OpNoLine. + bool contains_debug_info_; +}; + +// Pretty-prints |module| to |str|. Returns |str|. +std::ostream& operator<<(std::ostream& str, const Module& module); + +inline void Module::AddCapability(std::unique_ptr c) { + capabilities_.push_back(std::move(c)); +} + +inline void Module::AddExtension(std::unique_ptr e) { + extensions_.push_back(std::move(e)); +} + +inline void Module::AddExtInstImport(std::unique_ptr e) { + ext_inst_imports_.push_back(std::move(e)); +} + +inline void Module::SetMemoryModel(std::unique_ptr m) { + memory_model_ = std::move(m); +} + +inline void Module::SetSampledImageAddressMode(std::unique_ptr m) { + sampled_image_address_mode_ = std::move(m); +} + +inline void Module::AddEntryPoint(std::unique_ptr e) { + entry_points_.push_back(std::move(e)); +} + +inline void Module::AddExecutionMode(std::unique_ptr e) { + execution_modes_.push_back(std::move(e)); +} + +inline void Module::AddDebug1Inst(std::unique_ptr d) { + debugs1_.push_back(std::move(d)); +} + +inline void Module::AddDebug2Inst(std::unique_ptr d) { + debugs2_.push_back(std::move(d)); +} + +inline void Module::AddDebug3Inst(std::unique_ptr d) { + debugs3_.push_back(std::move(d)); +} + +inline void Module::AddExtInstDebugInfo(std::unique_ptr d) { + ext_inst_debuginfo_.push_back(std::move(d)); +} + +inline void Module::AddAnnotationInst(std::unique_ptr a) { + annotations_.push_back(std::move(a)); +} + +inline void Module::AddType(std::unique_ptr t) { + types_values_.push_back(std::move(t)); +} + +inline void Module::AddGlobalValue(std::unique_ptr v) { + types_values_.push_back(std::move(v)); +} + +inline void Module::AddFunctionDeclaration(std::unique_ptr f) { + // function declarations must come before function definitions. + functions_.emplace(functions_.begin(), std::move(f)); +} + +inline void Module::AddFunction(std::unique_ptr f) { + functions_.emplace_back(std::move(f)); +} + +inline void Module::SetContainsDebugInfo() { contains_debug_info_ = true; } + +inline Module::inst_iterator Module::capability_begin() { + return capabilities_.begin(); +} +inline Module::inst_iterator Module::capability_end() { + return capabilities_.end(); +} + +inline IteratorRange Module::capabilities() { + return make_range(capabilities_.begin(), capabilities_.end()); +} + +inline IteratorRange Module::capabilities() const { + return make_range(capabilities_.begin(), capabilities_.end()); +} + +inline Module::inst_iterator Module::ext_inst_import_begin() { + return ext_inst_imports_.begin(); +} +inline Module::inst_iterator Module::ext_inst_import_end() { + return ext_inst_imports_.end(); +} + +inline IteratorRange Module::ext_inst_imports() { + return make_range(ext_inst_imports_.begin(), ext_inst_imports_.end()); +} + +inline IteratorRange Module::ext_inst_imports() + const { + return make_range(ext_inst_imports_.begin(), ext_inst_imports_.end()); +} + +inline Module::inst_iterator Module::debug1_begin() { return debugs1_.begin(); } +inline Module::inst_iterator Module::debug1_end() { return debugs1_.end(); } + +inline IteratorRange Module::debugs1() { + return make_range(debugs1_.begin(), debugs1_.end()); +} + +inline IteratorRange Module::debugs1() const { + return make_range(debugs1_.begin(), debugs1_.end()); +} + +inline Module::inst_iterator Module::debug2_begin() { return debugs2_.begin(); } +inline Module::inst_iterator Module::debug2_end() { return debugs2_.end(); } + +inline IteratorRange Module::debugs2() { + return make_range(debugs2_.begin(), debugs2_.end()); +} + +inline IteratorRange Module::debugs2() const { + return make_range(debugs2_.begin(), debugs2_.end()); +} + +inline Module::inst_iterator Module::debug3_begin() { return debugs3_.begin(); } +inline Module::inst_iterator Module::debug3_end() { return debugs3_.end(); } + +inline IteratorRange Module::debugs3() { + return make_range(debugs3_.begin(), debugs3_.end()); +} + +inline IteratorRange Module::debugs3() const { + return make_range(debugs3_.begin(), debugs3_.end()); +} + +inline Module::inst_iterator Module::ext_inst_debuginfo_begin() { + return ext_inst_debuginfo_.begin(); +} +inline Module::inst_iterator Module::ext_inst_debuginfo_end() { + return ext_inst_debuginfo_.end(); +} + +inline IteratorRange Module::ext_inst_debuginfo() { + return make_range(ext_inst_debuginfo_.begin(), ext_inst_debuginfo_.end()); +} + +inline IteratorRange Module::ext_inst_debuginfo() + const { + return make_range(ext_inst_debuginfo_.begin(), ext_inst_debuginfo_.end()); +} + +inline IteratorRange Module::entry_points() { + return make_range(entry_points_.begin(), entry_points_.end()); +} + +inline IteratorRange Module::entry_points() const { + return make_range(entry_points_.begin(), entry_points_.end()); +} + +inline Module::inst_iterator Module::execution_mode_begin() { + return execution_modes_.begin(); +} +inline Module::inst_iterator Module::execution_mode_end() { + return execution_modes_.end(); +} + +inline IteratorRange Module::execution_modes() { + return make_range(execution_modes_.begin(), execution_modes_.end()); +} + +inline IteratorRange Module::execution_modes() + const { + return make_range(execution_modes_.begin(), execution_modes_.end()); +} + +inline Module::inst_iterator Module::annotation_begin() { + return annotations_.begin(); +} +inline Module::inst_iterator Module::annotation_end() { + return annotations_.end(); +} + +inline IteratorRange Module::annotations() { + return make_range(annotations_.begin(), annotations_.end()); +} + +inline IteratorRange Module::annotations() const { + return make_range(annotations_.begin(), annotations_.end()); +} + +inline Module::inst_iterator Module::extension_begin() { + return extensions_.begin(); +} +inline Module::inst_iterator Module::extension_end() { + return extensions_.end(); +} + +inline IteratorRange Module::extensions() { + return make_range(extensions_.begin(), extensions_.end()); +} + +inline IteratorRange Module::extensions() const { + return make_range(extensions_.begin(), extensions_.end()); +} + +inline Module::inst_iterator Module::types_values_begin() { + return types_values_.begin(); +} + +inline Module::inst_iterator Module::types_values_end() { + return types_values_.end(); +} + +inline IteratorRange Module::types_values() { + return make_range(types_values_.begin(), types_values_.end()); +} + +inline IteratorRange Module::types_values() const { + return make_range(types_values_.begin(), types_values_.end()); +} + +inline Module::const_iterator Module::cbegin() const { + return const_iterator(&functions_, functions_.cbegin()); +} + +inline Module::const_iterator Module::cend() const { + return const_iterator(&functions_, functions_.cend()); +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_MODULE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/null_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/null_pass.h new file mode 100644 index 000000000000..2b5974fb9baa --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/null_pass.h @@ -0,0 +1,34 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_NULL_PASS_H_ +#define SOURCE_OPT_NULL_PASS_H_ + +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class NullPass : public Pass { + public: + const char* name() const override { return "null"; } + Status Process() override { return Status::SuccessWithoutChange; } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_NULL_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/optimizer.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/optimizer.cpp new file mode 100644 index 000000000000..c4c2b0f554ac --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/optimizer.cpp @@ -0,0 +1,1267 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "spirv-tools/optimizer.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/build_module.h" +#include "source/opt/graphics_robust_access_pass.h" +#include "source/opt/log.h" +#include "source/opt/pass_manager.h" +#include "source/opt/passes.h" +#include "source/spirv_optimizer_options.h" +#include "source/util/make_unique.h" +#include "source/util/string_utils.h" + +namespace spvtools { + +std::vector GetVectorOfStrings(const char** strings, + const size_t string_count) { + std::vector result; + for (uint32_t i = 0; i < string_count; i++) { + result.emplace_back(strings[i]); + } + return result; +} + +struct Optimizer::PassToken::Impl { + Impl(std::unique_ptr p) : pass(std::move(p)) {} + + std::unique_ptr pass; // Internal implementation pass. +}; + +Optimizer::PassToken::PassToken( + std::unique_ptr impl) + : impl_(std::move(impl)) {} + +Optimizer::PassToken::PassToken(std::unique_ptr&& pass) + : impl_(MakeUnique(std::move(pass))) {} + +Optimizer::PassToken::PassToken(PassToken&& that) + : impl_(std::move(that.impl_)) {} + +Optimizer::PassToken& Optimizer::PassToken::operator=(PassToken&& that) { + impl_ = std::move(that.impl_); + return *this; +} + +Optimizer::PassToken::~PassToken() {} + +struct Optimizer::Impl { + explicit Impl(spv_target_env env) : target_env(env), pass_manager() {} + + spv_target_env target_env; // Target environment. + opt::PassManager pass_manager; // Internal implementation pass manager. + std::unordered_set live_locs; // Arg to debug dead output passes +}; + +Optimizer::Optimizer(spv_target_env env) : impl_(new Impl(env)) { + assert(env != SPV_ENV_WEBGPU_0); +} + +Optimizer::~Optimizer() {} + +void Optimizer::SetMessageConsumer(MessageConsumer c) { + // All passes' message consumer needs to be updated. + for (uint32_t i = 0; i < impl_->pass_manager.NumPasses(); ++i) { + impl_->pass_manager.GetPass(i)->SetMessageConsumer(c); + } + impl_->pass_manager.SetMessageConsumer(std::move(c)); +} + +const MessageConsumer& Optimizer::consumer() const { + return impl_->pass_manager.consumer(); +} + +Optimizer& Optimizer::RegisterPass(PassToken&& p) { + // Change to use the pass manager's consumer. + p.impl_->pass->SetMessageConsumer(consumer()); + impl_->pass_manager.AddPass(std::move(p.impl_->pass)); + return *this; +} + +// The legalization passes take a spir-v shader generated by an HLSL front-end +// and turn it into a valid vulkan spir-v shader. There are two ways in which +// the code will be invalid at the start: +// +// 1) There will be opaque objects, like images, which will be passed around +// in intermediate objects. Valid spir-v will have to replace the use of +// the opaque object with an intermediate object that is the result of the +// load of the global opaque object. +// +// 2) There will be variables that contain pointers to structured or uniform +// buffers. It be legal, the variables must be eliminated, and the +// references to the structured buffers must use the result of OpVariable +// in the Uniform storage class. +// +// Optimization in this list must accept shaders with these relaxation of the +// rules. There is not guarantee that this list of optimizations is able to +// legalize all inputs, but it is on a best effort basis. +// +// The legalization problem is essentially a very general copy propagation +// problem. The optimization we use are all used to either do copy propagation +// or enable more copy propagation. +Optimizer& Optimizer::RegisterLegalizationPasses(bool preserve_interface) { + return + // Wrap OpKill instructions so all other code can be inlined. + RegisterPass(CreateWrapOpKillPass()) + // Remove unreachable block so that merge return works. + .RegisterPass(CreateDeadBranchElimPass()) + // Merge the returns so we can inline. + .RegisterPass(CreateMergeReturnPass()) + // Make sure uses and definitions are in the same function. + .RegisterPass(CreateInlineExhaustivePass()) + // Make private variable function scope + .RegisterPass(CreateEliminateDeadFunctionsPass()) + .RegisterPass(CreatePrivateToLocalPass()) + // Fix up the storage classes that DXC may have purposely generated + // incorrectly. All functions are inlined, and a lot of dead code has + // been removed. + .RegisterPass(CreateFixStorageClassPass()) + // Propagate the value stored to the loads in very simple cases. + .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) + .RegisterPass(CreateLocalSingleStoreElimPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + // Split up aggregates so they are easier to deal with. + .RegisterPass(CreateScalarReplacementPass(0)) + // Remove loads and stores so everything is in intermediate values. + // Takes care of copy propagation of non-members. + .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) + .RegisterPass(CreateLocalSingleStoreElimPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateLocalMultiStoreElimPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + // Propagate constants to get as many constant conditions on branches + // as possible. + .RegisterPass(CreateCCPPass()) + .RegisterPass(CreateLoopUnrollPass(true)) + .RegisterPass(CreateDeadBranchElimPass()) + // Copy propagate members. Cleans up code sequences generated by + // scalar replacement. Also important for removing OpPhi nodes. + .RegisterPass(CreateSimplificationPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateCopyPropagateArraysPass()) + // May need loop unrolling here see + // https://github.com/Microsoft/DirectXShaderCompiler/pull/930 + // Get rid of unused code that contain traces of illegal code + // or unused references to unbound external objects + .RegisterPass(CreateVectorDCEPass()) + .RegisterPass(CreateDeadInsertElimPass()) + .RegisterPass(CreateReduceLoadSizePass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateRemoveUnusedInterfaceVariablesPass()) + .RegisterPass(CreateInterpolateFixupPass()) + .RegisterPass(CreateInvocationInterlockPlacementPass()); +} + +Optimizer& Optimizer::RegisterLegalizationPasses() { + return RegisterLegalizationPasses(false); +} + +Optimizer& Optimizer::RegisterPerformancePasses(bool preserve_interface) { + return RegisterPass(CreateWrapOpKillPass()) + .RegisterPass(CreateDeadBranchElimPass()) + .RegisterPass(CreateMergeReturnPass()) + .RegisterPass(CreateInlineExhaustivePass()) + .RegisterPass(CreateEliminateDeadFunctionsPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreatePrivateToLocalPass()) + .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) + .RegisterPass(CreateLocalSingleStoreElimPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateScalarReplacementPass()) + .RegisterPass(CreateLocalAccessChainConvertPass()) + .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) + .RegisterPass(CreateLocalSingleStoreElimPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateLocalMultiStoreElimPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateCCPPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateLoopUnrollPass(true)) + .RegisterPass(CreateDeadBranchElimPass()) + .RegisterPass(CreateRedundancyEliminationPass()) + .RegisterPass(CreateCombineAccessChainsPass()) + .RegisterPass(CreateSimplificationPass()) + .RegisterPass(CreateScalarReplacementPass()) + .RegisterPass(CreateLocalAccessChainConvertPass()) + .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) + .RegisterPass(CreateLocalSingleStoreElimPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateSSARewritePass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateVectorDCEPass()) + .RegisterPass(CreateDeadInsertElimPass()) + .RegisterPass(CreateDeadBranchElimPass()) + .RegisterPass(CreateSimplificationPass()) + .RegisterPass(CreateIfConversionPass()) + .RegisterPass(CreateCopyPropagateArraysPass()) + .RegisterPass(CreateReduceLoadSizePass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateBlockMergePass()) + .RegisterPass(CreateRedundancyEliminationPass()) + .RegisterPass(CreateDeadBranchElimPass()) + .RegisterPass(CreateBlockMergePass()) + .RegisterPass(CreateSimplificationPass()); +} + +Optimizer& Optimizer::RegisterPerformancePasses() { + return RegisterPerformancePasses(false); +} + +Optimizer& Optimizer::RegisterSizePasses(bool preserve_interface) { + return RegisterPass(CreateWrapOpKillPass()) + .RegisterPass(CreateDeadBranchElimPass()) + .RegisterPass(CreateMergeReturnPass()) + .RegisterPass(CreateInlineExhaustivePass()) + .RegisterPass(CreateEliminateDeadFunctionsPass()) + .RegisterPass(CreatePrivateToLocalPass()) + .RegisterPass(CreateScalarReplacementPass(0)) + .RegisterPass(CreateLocalMultiStoreElimPass()) + .RegisterPass(CreateCCPPass()) + .RegisterPass(CreateLoopUnrollPass(true)) + .RegisterPass(CreateDeadBranchElimPass()) + .RegisterPass(CreateSimplificationPass()) + .RegisterPass(CreateScalarReplacementPass(0)) + .RegisterPass(CreateLocalSingleStoreElimPass()) + .RegisterPass(CreateIfConversionPass()) + .RegisterPass(CreateSimplificationPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateDeadBranchElimPass()) + .RegisterPass(CreateBlockMergePass()) + .RegisterPass(CreateLocalAccessChainConvertPass()) + .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateCopyPropagateArraysPass()) + .RegisterPass(CreateVectorDCEPass()) + .RegisterPass(CreateDeadInsertElimPass()) + .RegisterPass(CreateEliminateDeadMembersPass()) + .RegisterPass(CreateLocalSingleStoreElimPass()) + .RegisterPass(CreateBlockMergePass()) + .RegisterPass(CreateLocalMultiStoreElimPass()) + .RegisterPass(CreateRedundancyEliminationPass()) + .RegisterPass(CreateSimplificationPass()) + .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateCFGCleanupPass()); +} + +Optimizer& Optimizer::RegisterSizePasses() { return RegisterSizePasses(false); } + +bool Optimizer::RegisterPassesFromFlags(const std::vector& flags) { + return RegisterPassesFromFlags(flags, false); +} + +bool Optimizer::RegisterPassesFromFlags(const std::vector& flags, + bool preserve_interface) { + for (const auto& flag : flags) { + if (!RegisterPassFromFlag(flag, preserve_interface)) { + return false; + } + } + + return true; +} + +bool Optimizer::FlagHasValidForm(const std::string& flag) const { + if (flag == "-O" || flag == "-Os") { + return true; + } else if (flag.size() > 2 && flag.substr(0, 2) == "--") { + return true; + } + + Errorf(consumer(), nullptr, {}, + "%s is not a valid flag. Flag passes should have the form " + "'--pass_name[=pass_args]'. Special flag names also accepted: -O " + "and -Os.", + flag.c_str()); + return false; +} + +bool Optimizer::RegisterPassFromFlag(const std::string& flag) { + return RegisterPassFromFlag(flag, false); +} + +bool Optimizer::RegisterPassFromFlag(const std::string& flag, + bool preserve_interface) { + if (!FlagHasValidForm(flag)) { + return false; + } + + // Split flags of the form --pass_name=pass_args. + auto p = utils::SplitFlagArgs(flag); + std::string pass_name = p.first; + std::string pass_args = p.second; + + // FIXME(dnovillo): This should be re-factored so that pass names can be + // automatically checked against Pass::name() and PassToken instances created + // via a template function. Additionally, class Pass should have a desc() + // method that describes the pass (so it can be used in --help). + // + // Both Pass::name() and Pass::desc() should be static class members so they + // can be invoked without creating a pass instance. + if (pass_name == "strip-debug") { + RegisterPass(CreateStripDebugInfoPass()); + } else if (pass_name == "strip-reflect") { + RegisterPass(CreateStripReflectInfoPass()); + } else if (pass_name == "strip-nonsemantic") { + RegisterPass(CreateStripNonSemanticInfoPass()); + } else if (pass_name == "set-spec-const-default-value") { + if (pass_args.size() > 0) { + auto spec_ids_vals = + opt::SetSpecConstantDefaultValuePass::ParseDefaultValuesString( + pass_args.c_str()); + if (!spec_ids_vals) { + Errorf(consumer(), nullptr, {}, + "Invalid argument for --set-spec-const-default-value: %s", + pass_args.c_str()); + return false; + } + RegisterPass( + CreateSetSpecConstantDefaultValuePass(std::move(*spec_ids_vals))); + } else { + Errorf(consumer(), nullptr, {}, + "Invalid spec constant value string '%s'. Expected a string of " + ": pairs.", + pass_args.c_str()); + return false; + } + } else if (pass_name == "if-conversion") { + RegisterPass(CreateIfConversionPass()); + } else if (pass_name == "freeze-spec-const") { + RegisterPass(CreateFreezeSpecConstantValuePass()); + } else if (pass_name == "inline-entry-points-exhaustive") { + RegisterPass(CreateInlineExhaustivePass()); + } else if (pass_name == "inline-entry-points-opaque") { + RegisterPass(CreateInlineOpaquePass()); + } else if (pass_name == "combine-access-chains") { + RegisterPass(CreateCombineAccessChainsPass()); + } else if (pass_name == "convert-local-access-chains") { + RegisterPass(CreateLocalAccessChainConvertPass()); + } else if (pass_name == "replace-desc-array-access-using-var-index") { + RegisterPass(CreateReplaceDescArrayAccessUsingVarIndexPass()); + } else if (pass_name == "spread-volatile-semantics") { + RegisterPass(CreateSpreadVolatileSemanticsPass()); + } else if (pass_name == "descriptor-scalar-replacement") { + RegisterPass(CreateDescriptorScalarReplacementPass()); + } else if (pass_name == "eliminate-dead-code-aggressive") { + RegisterPass(CreateAggressiveDCEPass(preserve_interface)); + } else if (pass_name == "eliminate-insert-extract") { + RegisterPass(CreateInsertExtractElimPass()); + } else if (pass_name == "eliminate-local-single-block") { + RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()); + } else if (pass_name == "eliminate-local-single-store") { + RegisterPass(CreateLocalSingleStoreElimPass()); + } else if (pass_name == "merge-blocks") { + RegisterPass(CreateBlockMergePass()); + } else if (pass_name == "merge-return") { + RegisterPass(CreateMergeReturnPass()); + } else if (pass_name == "eliminate-dead-branches") { + RegisterPass(CreateDeadBranchElimPass()); + } else if (pass_name == "eliminate-dead-functions") { + RegisterPass(CreateEliminateDeadFunctionsPass()); + } else if (pass_name == "eliminate-local-multi-store") { + RegisterPass(CreateLocalMultiStoreElimPass()); + } else if (pass_name == "eliminate-dead-const") { + RegisterPass(CreateEliminateDeadConstantPass()); + } else if (pass_name == "eliminate-dead-inserts") { + RegisterPass(CreateDeadInsertElimPass()); + } else if (pass_name == "eliminate-dead-variables") { + RegisterPass(CreateDeadVariableEliminationPass()); + } else if (pass_name == "eliminate-dead-members") { + RegisterPass(CreateEliminateDeadMembersPass()); + } else if (pass_name == "fold-spec-const-op-composite") { + RegisterPass(CreateFoldSpecConstantOpAndCompositePass()); + } else if (pass_name == "loop-unswitch") { + RegisterPass(CreateLoopUnswitchPass()); + } else if (pass_name == "scalar-replacement") { + if (pass_args.size() == 0) { + RegisterPass(CreateScalarReplacementPass()); + } else { + int limit = -1; + if (pass_args.find_first_not_of("0123456789") == std::string::npos) { + limit = atoi(pass_args.c_str()); + } + + if (limit >= 0) { + RegisterPass(CreateScalarReplacementPass(limit)); + } else { + Error(consumer(), nullptr, {}, + "--scalar-replacement must have no arguments or a non-negative " + "integer argument"); + return false; + } + } + } else if (pass_name == "strength-reduction") { + RegisterPass(CreateStrengthReductionPass()); + } else if (pass_name == "unify-const") { + RegisterPass(CreateUnifyConstantPass()); + } else if (pass_name == "flatten-decorations") { + RegisterPass(CreateFlattenDecorationPass()); + } else if (pass_name == "compact-ids") { + RegisterPass(CreateCompactIdsPass()); + } else if (pass_name == "cfg-cleanup") { + RegisterPass(CreateCFGCleanupPass()); + } else if (pass_name == "local-redundancy-elimination") { + RegisterPass(CreateLocalRedundancyEliminationPass()); + } else if (pass_name == "loop-invariant-code-motion") { + RegisterPass(CreateLoopInvariantCodeMotionPass()); + } else if (pass_name == "reduce-load-size") { + if (pass_args.size() == 0) { + RegisterPass(CreateReduceLoadSizePass()); + } else { + double load_replacement_threshold = 0.9; + if (pass_args.find_first_not_of(".0123456789") == std::string::npos) { + load_replacement_threshold = atof(pass_args.c_str()); + } + + if (load_replacement_threshold >= 0) { + RegisterPass(CreateReduceLoadSizePass(load_replacement_threshold)); + } else { + Error(consumer(), nullptr, {}, + "--reduce-load-size must have no arguments or a non-negative " + "double argument"); + return false; + } + } + } else if (pass_name == "redundancy-elimination") { + RegisterPass(CreateRedundancyEliminationPass()); + } else if (pass_name == "private-to-local") { + RegisterPass(CreatePrivateToLocalPass()); + } else if (pass_name == "remove-duplicates") { + RegisterPass(CreateRemoveDuplicatesPass()); + } else if (pass_name == "workaround-1209") { + RegisterPass(CreateWorkaround1209Pass()); + } else if (pass_name == "replace-invalid-opcode") { + RegisterPass(CreateReplaceInvalidOpcodePass()); + } else if (pass_name == "inst-bindless-check" || + pass_name == "inst-desc-idx-check" || + pass_name == "inst-buff-oob-check") { + // preserve legacy names + RegisterPass(CreateInstBindlessCheckPass(23)); + RegisterPass(CreateSimplificationPass()); + RegisterPass(CreateDeadBranchElimPass()); + RegisterPass(CreateBlockMergePass()); + } else if (pass_name == "inst-buff-addr-check") { + RegisterPass(CreateInstBuffAddrCheckPass(23)); + } else if (pass_name == "convert-relaxed-to-half") { + RegisterPass(CreateConvertRelaxedToHalfPass()); + } else if (pass_name == "relax-float-ops") { + RegisterPass(CreateRelaxFloatOpsPass()); + } else if (pass_name == "inst-debug-printf") { + // This private option is not for user consumption. + // It is here to assist in debugging and fixing the debug printf + // instrumentation pass. + // For users who wish to utilize debug printf, see the white paper at + // https://www.lunarg.com/wp-content/uploads/2021/08/Using-Debug-Printf-02August2021.pdf + RegisterPass(CreateInstDebugPrintfPass(7, 23)); + } else if (pass_name == "simplify-instructions") { + RegisterPass(CreateSimplificationPass()); + } else if (pass_name == "ssa-rewrite") { + RegisterPass(CreateSSARewritePass()); + } else if (pass_name == "copy-propagate-arrays") { + RegisterPass(CreateCopyPropagateArraysPass()); + } else if (pass_name == "loop-fission") { + int register_threshold_to_split = + (pass_args.size() > 0) ? atoi(pass_args.c_str()) : -1; + if (register_threshold_to_split > 0) { + RegisterPass(CreateLoopFissionPass( + static_cast(register_threshold_to_split))); + } else { + Error(consumer(), nullptr, {}, + "--loop-fission must have a positive integer argument"); + return false; + } + } else if (pass_name == "loop-fusion") { + int max_registers_per_loop = + (pass_args.size() > 0) ? atoi(pass_args.c_str()) : -1; + if (max_registers_per_loop > 0) { + RegisterPass( + CreateLoopFusionPass(static_cast(max_registers_per_loop))); + } else { + Error(consumer(), nullptr, {}, + "--loop-fusion must have a positive integer argument"); + return false; + } + } else if (pass_name == "loop-unroll") { + RegisterPass(CreateLoopUnrollPass(true)); + } else if (pass_name == "upgrade-memory-model") { + RegisterPass(CreateUpgradeMemoryModelPass()); + } else if (pass_name == "vector-dce") { + RegisterPass(CreateVectorDCEPass()); + } else if (pass_name == "loop-unroll-partial") { + int factor = (pass_args.size() > 0) ? atoi(pass_args.c_str()) : 0; + if (factor > 0) { + RegisterPass(CreateLoopUnrollPass(false, factor)); + } else { + Error(consumer(), nullptr, {}, + "--loop-unroll-partial must have a positive integer argument"); + return false; + } + } else if (pass_name == "loop-peeling") { + RegisterPass(CreateLoopPeelingPass()); + } else if (pass_name == "loop-peeling-threshold") { + int factor = (pass_args.size() > 0) ? atoi(pass_args.c_str()) : 0; + if (factor > 0) { + opt::LoopPeelingPass::SetLoopPeelingThreshold(factor); + } else { + Error(consumer(), nullptr, {}, + "--loop-peeling-threshold must have a positive integer argument"); + return false; + } + } else if (pass_name == "ccp") { + RegisterPass(CreateCCPPass()); + } else if (pass_name == "code-sink") { + RegisterPass(CreateCodeSinkingPass()); + } else if (pass_name == "fix-storage-class") { + RegisterPass(CreateFixStorageClassPass()); + } else if (pass_name == "O") { + RegisterPerformancePasses(preserve_interface); + } else if (pass_name == "Os") { + RegisterSizePasses(preserve_interface); + } else if (pass_name == "legalize-hlsl") { + RegisterLegalizationPasses(preserve_interface); + } else if (pass_name == "remove-unused-interface-variables") { + RegisterPass(CreateRemoveUnusedInterfaceVariablesPass()); + } else if (pass_name == "graphics-robust-access") { + RegisterPass(CreateGraphicsRobustAccessPass()); + } else if (pass_name == "wrap-opkill") { + RegisterPass(CreateWrapOpKillPass()); + } else if (pass_name == "amd-ext-to-khr") { + RegisterPass(CreateAmdExtToKhrPass()); + } else if (pass_name == "interpolate-fixup") { + RegisterPass(CreateInterpolateFixupPass()); + } else if (pass_name == "remove-dont-inline") { + RegisterPass(CreateRemoveDontInlinePass()); + } else if (pass_name == "eliminate-dead-input-components") { + RegisterPass(CreateEliminateDeadInputComponentsSafePass()); + } else if (pass_name == "fix-func-call-param") { + RegisterPass(CreateFixFuncCallArgumentsPass()); + } else if (pass_name == "convert-to-sampled-image") { + if (pass_args.size() > 0) { + auto descriptor_set_binding_pairs = + opt::ConvertToSampledImagePass::ParseDescriptorSetBindingPairsString( + pass_args.c_str()); + if (!descriptor_set_binding_pairs) { + Errorf(consumer(), nullptr, {}, + "Invalid argument for --convert-to-sampled-image: %s", + pass_args.c_str()); + return false; + } + RegisterPass(CreateConvertToSampledImagePass( + std::move(*descriptor_set_binding_pairs))); + } else { + Errorf(consumer(), nullptr, {}, + "Invalid pairs of descriptor set and binding '%s'. Expected a " + "string of : pairs.", + pass_args.c_str()); + return false; + } + } else if (pass_name == "switch-descriptorset") { + if (pass_args.size() == 0) { + Error(consumer(), nullptr, {}, + "--switch-descriptorset requires a from:to argument."); + return false; + } + uint32_t from_set = 0, to_set = 0; + const char* start = pass_args.data(); + const char* end = pass_args.data() + pass_args.size(); + + auto result = std::from_chars(start, end, from_set); + if (result.ec != std::errc()) { + Errorf(consumer(), nullptr, {}, + "Invalid argument for --switch-descriptorset: %s", + pass_args.c_str()); + return false; + } + start = result.ptr; + if (start[0] != ':') { + Errorf(consumer(), nullptr, {}, + "Invalid argument for --switch-descriptorset: %s", + pass_args.c_str()); + return false; + } + start++; + result = std::from_chars(start, end, to_set); + if (result.ec != std::errc() || result.ptr != end) { + Errorf(consumer(), nullptr, {}, + "Invalid argument for --switch-descriptorset: %s", + pass_args.c_str()); + return false; + } + RegisterPass(CreateSwitchDescriptorSetPass(from_set, to_set)); + } else if (pass_name == "modify-maximal-reconvergence") { + if (pass_args.size() == 0) { + Error(consumer(), nullptr, {}, + "--modify-maximal-reconvergence requires an argument"); + return false; + } + if (pass_args == "add") { + RegisterPass(CreateModifyMaximalReconvergencePass(true)); + } else if (pass_args == "remove") { + RegisterPass(CreateModifyMaximalReconvergencePass(false)); + } else { + Errorf(consumer(), nullptr, {}, + "Invalid argument for --modify-maximal-reconvergence: %s (must be " + "'add' or 'remove')", + pass_args.c_str()); + return false; + } + } else if (pass_name == "trim-capabilities") { + RegisterPass(CreateTrimCapabilitiesPass()); + } else { + Errorf(consumer(), nullptr, {}, + "Unknown flag '--%s'. Use --help for a list of valid flags", + pass_name.c_str()); + return false; + } + + return true; +} + +void Optimizer::SetTargetEnv(const spv_target_env env) { + impl_->target_env = env; +} + +bool Optimizer::Run(const uint32_t* original_binary, + const size_t original_binary_size, + std::vector* optimized_binary) const { + return Run(original_binary, original_binary_size, optimized_binary, + OptimizerOptions()); +} + +bool Optimizer::Run(const uint32_t* original_binary, + const size_t original_binary_size, + std::vector* optimized_binary, + const ValidatorOptions& validator_options, + bool skip_validation) const { + OptimizerOptions opt_options; + opt_options.set_run_validator(!skip_validation); + opt_options.set_validator_options(validator_options); + return Run(original_binary, original_binary_size, optimized_binary, + opt_options); +} + +bool Optimizer::Run(const uint32_t* original_binary, + const size_t original_binary_size, + std::vector* optimized_binary, + const spv_optimizer_options opt_options) const { + spvtools::SpirvTools tools(impl_->target_env); + tools.SetMessageConsumer(impl_->pass_manager.consumer()); + if (opt_options->run_validator_ && + !tools.Validate(original_binary, original_binary_size, + &opt_options->val_options_)) { + return false; + } + + std::unique_ptr context = BuildModule( + impl_->target_env, consumer(), original_binary, original_binary_size); + if (context == nullptr) return false; + + context->set_max_id_bound(opt_options->max_id_bound_); + context->set_preserve_bindings(opt_options->preserve_bindings_); + context->set_preserve_spec_constants(opt_options->preserve_spec_constants_); + + impl_->pass_manager.SetValidatorOptions(&opt_options->val_options_); + impl_->pass_manager.SetTargetEnv(impl_->target_env); + auto status = impl_->pass_manager.Run(context.get()); + + if (status == opt::Pass::Status::Failure) { + return false; + } + +#ifndef NDEBUG + // We do not keep the result id of DebugScope in struct DebugScope. + // Instead, we assign random ids for them, which results in integrity + // check failures. In addition, propagating the OpLine/OpNoLine to preserve + // the debug information through transformations results in integrity + // check failures. We want to skip the integrity check when the module + // contains DebugScope or OpLine/OpNoLine instructions. + if (status == opt::Pass::Status::SuccessWithoutChange && + !context->module()->ContainsDebugInfo()) { + std::vector optimized_binary_with_nop; + context->module()->ToBinary(&optimized_binary_with_nop, + /* skip_nop = */ false); + assert(optimized_binary_with_nop.size() == original_binary_size && + "Binary size unexpectedly changed despite the optimizer saying " + "there was no change"); + + // Compare the magic number to make sure the binaries were encoded in the + // endianness. If not, the contents of the binaries will be different, so + // do not check the contents. + if (optimized_binary_with_nop[0] == original_binary[0]) { + assert(memcmp(optimized_binary_with_nop.data(), original_binary, + original_binary_size) == 0 && + "Binary content unexpectedly changed despite the optimizer saying " + "there was no change"); + } + } +#endif // !NDEBUG + + // Note that |original_binary| and |optimized_binary| may share the same + // buffer and the below will invalidate |original_binary|. + optimized_binary->clear(); + context->module()->ToBinary(optimized_binary, /* skip_nop = */ true); + + return true; +} + +Optimizer& Optimizer::SetPrintAll(std::ostream* out) { + impl_->pass_manager.SetPrintAll(out); + return *this; +} + +Optimizer& Optimizer::SetTimeReport(std::ostream* out) { + impl_->pass_manager.SetTimeReport(out); + return *this; +} + +Optimizer& Optimizer::SetValidateAfterAll(bool validate) { + impl_->pass_manager.SetValidateAfterAll(validate); + return *this; +} + +Optimizer::PassToken CreateNullPass() { + return MakeUnique(MakeUnique()); +} + +Optimizer::PassToken CreateStripDebugInfoPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateStripReflectInfoPass() { + return CreateStripNonSemanticInfoPass(); +} + +Optimizer::PassToken CreateStripNonSemanticInfoPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateEliminateDeadFunctionsPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateEliminateDeadMembersPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateSetSpecConstantDefaultValuePass( + const std::unordered_map& id_value_map) { + return MakeUnique( + MakeUnique(id_value_map)); +} + +Optimizer::PassToken CreateSetSpecConstantDefaultValuePass( + const std::unordered_map>& id_value_map) { + return MakeUnique( + MakeUnique(id_value_map)); +} + +Optimizer::PassToken CreateFlattenDecorationPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateFreezeSpecConstantValuePass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateFoldSpecConstantOpAndCompositePass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateUnifyConstantPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateEliminateDeadConstantPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateDeadVariableEliminationPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateStrengthReductionPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateBlockMergePass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateInlineExhaustivePass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateInlineOpaquePass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateLocalAccessChainConvertPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateLocalSingleBlockLoadStoreElimPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateLocalSingleStoreElimPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateInsertExtractElimPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateDeadInsertElimPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateDeadBranchElimPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateLocalMultiStoreElimPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateAggressiveDCEPass() { + return MakeUnique( + MakeUnique(false, false)); +} + +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface) { + return MakeUnique( + MakeUnique(preserve_interface, false)); +} + +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface, + bool remove_outputs) { + return MakeUnique( + MakeUnique(preserve_interface, remove_outputs)); +} + +Optimizer::PassToken CreateRemoveUnusedInterfaceVariablesPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreatePropagateLineInfoPass() { + return MakeUnique(MakeUnique()); +} + +Optimizer::PassToken CreateRedundantLineInfoElimPass() { + return MakeUnique(MakeUnique()); +} + +Optimizer::PassToken CreateCompactIdsPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateMergeReturnPass() { + return MakeUnique( + MakeUnique()); +} + +std::vector Optimizer::GetPassNames() const { + std::vector v; + for (uint32_t i = 0; i < impl_->pass_manager.NumPasses(); i++) { + v.push_back(impl_->pass_manager.GetPass(i)->name()); + } + return v; +} + +Optimizer::PassToken CreateCFGCleanupPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateLocalRedundancyEliminationPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateLoopFissionPass(size_t threshold) { + return MakeUnique( + MakeUnique(threshold)); +} + +Optimizer::PassToken CreateLoopFusionPass(size_t max_registers_per_loop) { + return MakeUnique( + MakeUnique(max_registers_per_loop)); +} + +Optimizer::PassToken CreateLoopInvariantCodeMotionPass() { + return MakeUnique(MakeUnique()); +} + +Optimizer::PassToken CreateLoopPeelingPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateLoopUnswitchPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateRedundancyEliminationPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateRemoveDuplicatesPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateScalarReplacementPass(uint32_t size_limit) { + return MakeUnique( + MakeUnique(size_limit)); +} + +Optimizer::PassToken CreatePrivateToLocalPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateCCPPass() { + return MakeUnique(MakeUnique()); +} + +Optimizer::PassToken CreateWorkaround1209Pass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateIfConversionPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateReplaceInvalidOpcodePass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateSimplificationPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateLoopUnrollPass(bool fully_unroll, int factor) { + return MakeUnique( + MakeUnique(fully_unroll, factor)); +} + +Optimizer::PassToken CreateSSARewritePass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateCopyPropagateArraysPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateVectorDCEPass() { + return MakeUnique(MakeUnique()); +} + +Optimizer::PassToken CreateReduceLoadSizePass( + double load_replacement_threshold) { + return MakeUnique( + MakeUnique(load_replacement_threshold)); +} + +Optimizer::PassToken CreateCombineAccessChainsPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateUpgradeMemoryModelPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id) { + return MakeUnique( + MakeUnique(shader_id)); +} + +Optimizer::PassToken CreateInstDebugPrintfPass(uint32_t desc_set, + uint32_t shader_id) { + return MakeUnique( + MakeUnique(desc_set, shader_id)); +} + +Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id) { + return MakeUnique( + MakeUnique(shader_id)); +} + +Optimizer::PassToken CreateConvertRelaxedToHalfPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateRelaxFloatOpsPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateCodeSinkingPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateFixStorageClassPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateGraphicsRobustAccessPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateReplaceDescArrayAccessUsingVarIndexPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateSpreadVolatileSemanticsPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateDescriptorScalarReplacementPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateWrapOpKillPass() { + return MakeUnique(MakeUnique()); +} + +Optimizer::PassToken CreateAmdExtToKhrPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateInterpolateFixupPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateEliminateDeadInputComponentsPass() { + return MakeUnique( + MakeUnique(spv::StorageClass::Input, + /* safe_mode */ false)); +} + +Optimizer::PassToken CreateEliminateDeadOutputComponentsPass() { + return MakeUnique( + MakeUnique(spv::StorageClass::Output, + /* safe_mode */ false)); +} + +Optimizer::PassToken CreateEliminateDeadInputComponentsSafePass() { + return MakeUnique( + MakeUnique(spv::StorageClass::Input, + /* safe_mode */ true)); +} + +Optimizer::PassToken CreateAnalyzeLiveInputPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins) { + return MakeUnique( + MakeUnique(live_locs, live_builtins)); +} + +Optimizer::PassToken CreateEliminateDeadOutputStoresPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins) { + return MakeUnique( + MakeUnique(live_locs, live_builtins)); +} + +Optimizer::PassToken CreateConvertToSampledImagePass( + const std::vector& + descriptor_set_binding_pairs) { + return MakeUnique( + MakeUnique(descriptor_set_binding_pairs)); +} + +Optimizer::PassToken CreateInterfaceVariableScalarReplacementPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateRemoveDontInlinePass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateFixFuncCallArgumentsPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateTrimCapabilitiesPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t from, uint32_t to) { + return MakeUnique( + MakeUnique(from, to)); +} + +Optimizer::PassToken CreateInvocationInterlockPlacementPass() { + return MakeUnique( + MakeUnique()); +} + +Optimizer::PassToken CreateModifyMaximalReconvergencePass(bool add) { + return MakeUnique( + MakeUnique(add)); +} +} // namespace spvtools + +extern "C" { + +SPIRV_TOOLS_EXPORT spv_optimizer_t* spvOptimizerCreate(spv_target_env env) { + return reinterpret_cast(new spvtools::Optimizer(env)); +} + +SPIRV_TOOLS_EXPORT void spvOptimizerDestroy(spv_optimizer_t* optimizer) { + delete reinterpret_cast(optimizer); +} + +SPIRV_TOOLS_EXPORT void spvOptimizerSetMessageConsumer( + spv_optimizer_t* optimizer, spv_message_consumer consumer) { + reinterpret_cast(optimizer)-> + SetMessageConsumer( + [consumer](spv_message_level_t level, const char* source, + const spv_position_t& position, const char* message) { + return consumer(level, source, &position, message); + }); +} + +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterLegalizationPasses( + spv_optimizer_t* optimizer) { + reinterpret_cast(optimizer)-> + RegisterLegalizationPasses(); +} + +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterPerformancePasses( + spv_optimizer_t* optimizer) { + reinterpret_cast(optimizer)-> + RegisterPerformancePasses(); +} + +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterSizePasses( + spv_optimizer_t* optimizer) { + reinterpret_cast(optimizer)->RegisterSizePasses(); +} + +SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag( + spv_optimizer_t* optimizer, const char* flag) +{ + return reinterpret_cast(optimizer)-> + RegisterPassFromFlag(flag); +} + +SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags( + spv_optimizer_t* optimizer, const char** flags, const size_t flag_count) { + std::vector opt_flags = + spvtools::GetVectorOfStrings(flags, flag_count); + return reinterpret_cast(optimizer) + ->RegisterPassesFromFlags(opt_flags, false); +} + +SPIRV_TOOLS_EXPORT bool +spvOptimizerRegisterPassesFromFlagsWhilePreservingTheInterface( + spv_optimizer_t* optimizer, const char** flags, const size_t flag_count) { + std::vector opt_flags = + spvtools::GetVectorOfStrings(flags, flag_count); + return reinterpret_cast(optimizer) + ->RegisterPassesFromFlags(opt_flags, true); +} + +SPIRV_TOOLS_EXPORT +spv_result_t spvOptimizerRun(spv_optimizer_t* optimizer, + const uint32_t* binary, + const size_t word_count, + spv_binary* optimized_binary, + const spv_optimizer_options options) { + std::vector optimized; + + if (!reinterpret_cast(optimizer)-> + Run(binary, word_count, &optimized, options)) { + return SPV_ERROR_INTERNAL; + } + + auto result_binary = new spv_binary_t(); + if (!result_binary) { + *optimized_binary = nullptr; + return SPV_ERROR_OUT_OF_MEMORY; + } + + result_binary->code = new uint32_t[optimized.size()]; + if (!result_binary->code) { + delete result_binary; + *optimized_binary = nullptr; + return SPV_ERROR_OUT_OF_MEMORY; + } + result_binary->wordCount = optimized.size(); + + memcpy(result_binary->code, optimized.data(), + optimized.size() * sizeof(uint32_t)); + + *optimized_binary = result_binary; + + return SPV_SUCCESS; +} + +} // extern "C" diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/pass.cpp new file mode 100644 index 000000000000..75c37407fdf3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/pass.cpp @@ -0,0 +1,152 @@ +// Copyright (c) 2017 The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/pass.h" + +#include "source/opt/ir_builder.h" +#include "source/opt/iterator.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kTypePointerTypeIdInIdx = 1; +} // namespace + +Pass::Pass() : consumer_(nullptr), context_(nullptr), already_run_(false) {} + +Pass::Status Pass::Run(IRContext* ctx) { + if (already_run_) { + return Status::Failure; + } + already_run_ = true; + + context_ = ctx; + Pass::Status status = Process(); + context_ = nullptr; + + if (status == Status::SuccessWithChange) { + ctx->InvalidateAnalysesExceptFor(GetPreservedAnalyses()); + } + if (!(status == Status::Failure || ctx->IsConsistent())) + assert(false && "An analysis in the context is out of date."); + return status; +} + +uint32_t Pass::GetPointeeTypeId(const Instruction* ptrInst) const { + const uint32_t ptrTypeId = ptrInst->type_id(); + const Instruction* ptrTypeInst = get_def_use_mgr()->GetDef(ptrTypeId); + return ptrTypeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx); +} + +Instruction* Pass::GetBaseType(uint32_t ty_id) { + Instruction* ty_inst = get_def_use_mgr()->GetDef(ty_id); + if (ty_inst->opcode() == spv::Op::OpTypeMatrix) { + uint32_t vty_id = ty_inst->GetSingleWordInOperand(0); + ty_inst = get_def_use_mgr()->GetDef(vty_id); + } + if (ty_inst->opcode() == spv::Op::OpTypeVector) { + uint32_t cty_id = ty_inst->GetSingleWordInOperand(0); + ty_inst = get_def_use_mgr()->GetDef(cty_id); + } + return ty_inst; +} + +bool Pass::IsFloat(uint32_t ty_id, uint32_t width) { + Instruction* ty_inst = GetBaseType(ty_id); + if (ty_inst->opcode() != spv::Op::OpTypeFloat) return false; + return ty_inst->GetSingleWordInOperand(0) == width; +} + +uint32_t Pass::GetNullId(uint32_t type_id) { + if (IsFloat(type_id, 16)) context()->AddCapability(spv::Capability::Float16); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + const analysis::Type* type = type_mgr->GetType(type_id); + const analysis::Constant* null_const = const_mgr->GetConstant(type, {}); + Instruction* null_inst = + const_mgr->GetDefiningInstruction(null_const, type_id); + return null_inst->result_id(); +} + +uint32_t Pass::GenerateCopy(Instruction* object_to_copy, uint32_t new_type_id, + Instruction* insertion_position) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + + uint32_t original_type_id = object_to_copy->type_id(); + if (original_type_id == new_type_id) { + return object_to_copy->result_id(); + } + + InstructionBuilder ir_builder( + context(), insertion_position, + IRContext::kAnalysisInstrToBlockMapping | IRContext::kAnalysisDefUse); + + analysis::Type* original_type = type_mgr->GetType(original_type_id); + analysis::Type* new_type = type_mgr->GetType(new_type_id); + + if (const analysis::Array* original_array_type = original_type->AsArray()) { + uint32_t original_element_type_id = + type_mgr->GetId(original_array_type->element_type()); + + analysis::Array* new_array_type = new_type->AsArray(); + assert(new_array_type != nullptr && "Can't copy an array to a non-array."); + uint32_t new_element_type_id = + type_mgr->GetId(new_array_type->element_type()); + + std::vector element_ids; + const analysis::Constant* length_const = + const_mgr->FindDeclaredConstant(original_array_type->LengthId()); + assert(length_const->AsIntConstant()); + uint32_t array_length = length_const->AsIntConstant()->GetU32(); + for (uint32_t i = 0; i < array_length; i++) { + Instruction* extract = ir_builder.AddCompositeExtract( + original_element_type_id, object_to_copy->result_id(), {i}); + element_ids.push_back( + GenerateCopy(extract, new_element_type_id, insertion_position)); + } + + return ir_builder.AddCompositeConstruct(new_type_id, element_ids) + ->result_id(); + } else if (const analysis::Struct* original_struct_type = + original_type->AsStruct()) { + analysis::Struct* new_struct_type = new_type->AsStruct(); + + const std::vector& original_types = + original_struct_type->element_types(); + const std::vector& new_types = + new_struct_type->element_types(); + std::vector element_ids; + for (uint32_t i = 0; i < original_types.size(); i++) { + Instruction* extract = ir_builder.AddCompositeExtract( + type_mgr->GetId(original_types[i]), object_to_copy->result_id(), {i}); + element_ids.push_back(GenerateCopy(extract, type_mgr->GetId(new_types[i]), + insertion_position)); + } + return ir_builder.AddCompositeConstruct(new_type_id, element_ids) + ->result_id(); + } else { + // If we do not have an aggregate type, then we have a problem. Either we + // found multiple instances of the same type, or we are copying to an + // incompatible type. Either way the code is illegal. + assert(false && + "Don't know how to copy this type. Code is likely illegal."); + } + return 0; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/pass.h new file mode 100644 index 000000000000..b2303e2316cf --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/pass.h @@ -0,0 +1,171 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_PASS_H_ +#define SOURCE_OPT_PASS_H_ + +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "spirv-tools/libspirv.hpp" +#include "types.h" + +// Avoid unused variable warning/error on Linux +#ifndef NDEBUG +#define USE_ASSERT(x) assert(x) +#else +#define USE_ASSERT(x) ((void)(x)) +#endif + +namespace spvtools { +namespace opt { + +// Abstract class of a pass. All passes should implement this abstract class +// and all analysis and transformation is done via the Process() method. +class Pass { + public: + // The status of processing a module using a pass. + // + // The numbers for the cases are assigned to make sure that Failure & anything + // is Failure, SuccessWithChange & any success is SuccessWithChange. + enum class Status { + Failure = 0x00, + SuccessWithChange = 0x10, + SuccessWithoutChange = 0x11, + }; + + using ProcessFunction = std::function; + + // Destructs the pass. + virtual ~Pass() = default; + + // Returns a descriptive name for this pass. + // + // NOTE: When deriving a new pass class, make sure you make the name + // compatible with the corresponding spirv-opt command-line flag. For example, + // if you add the flag --my-pass to spirv-opt, make this function return + // "my-pass" (no leading hyphens). + virtual const char* name() const = 0; + + // Sets the message consumer to the given |consumer|. |consumer| which will be + // invoked every time there is a message to be communicated to the outside. + void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); } + + // Returns the reference to the message consumer for this pass. + const MessageConsumer& consumer() const { return consumer_; } + + // Returns the def-use manager used for this pass. TODO(dnovillo): This should + // be handled by the pass manager. + analysis::DefUseManager* get_def_use_mgr() const { + return context()->get_def_use_mgr(); + } + + analysis::DecorationManager* get_decoration_mgr() const { + return context()->get_decoration_mgr(); + } + + FeatureManager* get_feature_mgr() const { + return context()->get_feature_mgr(); + } + + // Returns a pointer to the current module for this pass. + Module* get_module() const { return context_->module(); } + + // Sets the pointer to the current context for this pass. + void SetContextForTesting(IRContext* ctx) { context_ = ctx; } + + // Returns a pointer to the current context for this pass. + IRContext* context() const { return context_; } + + // Returns a pointer to the CFG for current module. + CFG* cfg() const { return context()->cfg(); } + + // Run the pass on the given |module|. Returns Status::Failure if errors occur + // when processing. Returns the corresponding Status::Success if processing is + // successful to indicate whether changes are made to the module. If there + // were any changes it will also invalidate the analyses in the IRContext + // that are not preserved. + // + // It is an error if |Run| is called twice with the same instance of the pass. + // If this happens the return value will be |Failure|. + Status Run(IRContext* ctx); + + // Returns the set of analyses that the pass is guaranteed to preserve. + virtual IRContext::Analysis GetPreservedAnalyses() { + return IRContext::kAnalysisNone; + } + + // Return type id for |ptrInst|'s pointee + uint32_t GetPointeeTypeId(const Instruction* ptrInst) const; + + // Return base type of |ty_id| type + Instruction* GetBaseType(uint32_t ty_id); + + // Return true if |inst| returns scalar, vector or matrix type with base + // float and |width| + bool IsFloat(uint32_t ty_id, uint32_t width); + + // Return the id of OpConstantNull of type |type_id|. Create if necessary. + uint32_t GetNullId(uint32_t type_id); + + protected: + // Constructs a new pass. + // + // The constructed instance will have an empty message consumer, which just + // ignores all messages from the library. Use SetMessageConsumer() to supply + // one if messages are of concern. + Pass(); + + // Processes the given |module|. Returns Status::Failure if errors occur when + // processing. Returns the corresponding Status::Success if processing is + // successful to indicate whether changes are made to the module. + virtual Status Process() = 0; + + // Return the next available SSA id and increment it. + // TODO(1841): Handle id overflow. + uint32_t TakeNextId() { return context_->TakeNextId(); } + + // Returns the id whose value is the same as |object_to_copy| except its type + // is |new_type_id|. Any instructions needed to generate this value will be + // inserted before |insertion_position|. + uint32_t GenerateCopy(Instruction* object_to_copy, uint32_t new_type_id, + Instruction* insertion_position); + + private: + MessageConsumer consumer_; // Message consumer. + + // The context that this pass belongs to. + IRContext* context_; + + // An instance of a pass can only be run once because it is too hard to + // enforce proper resetting of internal state for each instance. This member + // is used to check that we do not run the same instance twice. + bool already_run_; +}; + +inline Pass::Status CombineStatus(Pass::Status a, Pass::Status b) { + return std::min(a, b); +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/pass_manager.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/pass_manager.cpp new file mode 100644 index 000000000000..d3c47e7f309c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/pass_manager.cpp @@ -0,0 +1,93 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/pass_manager.h" + +#include +#include +#include + +#include "source/opt/ir_context.h" +#include "source/util/timer.h" +#include "spirv-tools/libspirv.hpp" + +namespace spvtools { + +namespace opt { + +Pass::Status PassManager::Run(IRContext* context) { + auto status = Pass::Status::SuccessWithoutChange; + + // If print_all_stream_ is not null, prints the disassembly of the module + // to that stream, with the given preamble and optionally the pass name. + auto print_disassembly = [&context, this](const char* preamble, Pass* pass) { + if (print_all_stream_) { + std::vector binary; + context->module()->ToBinary(&binary, false); + SpirvTools t(target_env_); + t.SetMessageConsumer(consumer()); + std::string disassembly; + std::string pass_name = (pass ? pass->name() : ""); + if (!t.Disassemble(binary, &disassembly)) { + std::string msg = "Disassembly failed before pass "; + msg += pass_name + "\n"; + spv_position_t null_pos{0, 0, 0}; + consumer()(SPV_MSG_WARNING, "", null_pos, msg.c_str()); + return; + } + *print_all_stream_ << preamble << pass_name << "\n" + << disassembly << std::endl; + } + }; + + SPIRV_TIMER_DESCRIPTION(time_report_stream_, /* measure_mem_usage = */ true); + for (auto& pass : passes_) { + print_disassembly("; IR before pass ", pass.get()); + SPIRV_TIMER_SCOPED(time_report_stream_, (pass ? pass->name() : ""), true); + const auto one_status = pass->Run(context); + if (one_status == Pass::Status::Failure) return one_status; + if (one_status == Pass::Status::SuccessWithChange) status = one_status; + + if (validate_after_all_) { + spvtools::SpirvTools tools(target_env_); + tools.SetMessageConsumer(consumer()); + std::vector binary; + context->module()->ToBinary(&binary, true); + if (!tools.Validate(binary.data(), binary.size(), val_options_)) { + std::string msg = "Validation failed after pass "; + msg += pass->name(); + spv_position_t null_pos{0, 0, 0}; + consumer()(SPV_MSG_INTERNAL_ERROR, "", null_pos, msg.c_str()); + return Pass::Status::Failure; + } + } + + // Reset the pass to free any memory used by the pass. + pass.reset(nullptr); + } + print_disassembly("; IR after last pass", nullptr); + + // Set the Id bound in the header in case a pass forgot to do so. + // + // TODO(dnovillo): This should be unnecessary and automatically maintained by + // the IRContext. + if (status == Pass::Status::SuccessWithChange) { + context->module()->SetIdBound(context->module()->ComputeIdBound()); + } + passes_.clear(); + return status; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/pass_manager.h b/thirdparty/glslang/External/spirv-tools/source/opt/pass_manager.h new file mode 100644 index 000000000000..11961a3305df --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/pass_manager.h @@ -0,0 +1,158 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_PASS_MANAGER_H_ +#define SOURCE_OPT_PASS_MANAGER_H_ + +#include +#include +#include +#include + +#include "source/opt/log.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +#include "source/opt/ir_context.h" +#include "spirv-tools/libspirv.hpp" + +namespace spvtools { +namespace opt { + +// The pass manager, responsible for tracking and running passes. +// Clients should first call AddPass() to add passes and then call Run() +// to run on a module. Passes are executed in the exact order of addition. +class PassManager { + public: + // Constructs a pass manager. + // + // The constructed instance will have an empty message consumer, which just + // ignores all messages from the library. Use SetMessageConsumer() to supply + // one if messages are of concern. + PassManager() + : consumer_(nullptr), + print_all_stream_(nullptr), + time_report_stream_(nullptr), + target_env_(SPV_ENV_UNIVERSAL_1_2), + val_options_(nullptr), + validate_after_all_(false) {} + + // Sets the message consumer to the given |consumer|. + void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); } + + // Adds an externally constructed pass. + void AddPass(std::unique_ptr pass); + // Uses the argument |args| to construct a pass instance of type |T|, and adds + // the pass instance to this pass manager. The pass added will use this pass + // manager's message consumer. + template + void AddPass(Args&&... args); + + // Returns the number of passes added. + uint32_t NumPasses() const; + // Returns a pointer to the |index|th pass added. + inline Pass* GetPass(uint32_t index) const; + + // Returns the message consumer. + inline const MessageConsumer& consumer() const; + + // Runs all passes on the given |module|. Returns Status::Failure if errors + // occur when processing using one of the registered passes. All passes + // registered after the error-reporting pass will be skipped. Returns the + // corresponding Status::Success if processing is successful to indicate + // whether changes are made to the module. + // + // After running all the passes, they are removed from the list. + Pass::Status Run(IRContext* context); + + // Sets the option to print the disassembly before each pass and after the + // last pass. Output is written to |out| if that is not null. No output + // is generated if |out| is null. + PassManager& SetPrintAll(std::ostream* out) { + print_all_stream_ = out; + return *this; + } + + // Sets the option to print the resource utilization of each pass. Output is + // written to |out| if that is not null. No output is generated if |out| is + // null. + PassManager& SetTimeReport(std::ostream* out) { + time_report_stream_ = out; + return *this; + } + + // Sets the target environment for validation. + PassManager& SetTargetEnv(spv_target_env env) { + target_env_ = env; + return *this; + } + + // Sets the validation options. + PassManager& SetValidatorOptions(spv_validator_options options) { + val_options_ = options; + return *this; + } + + // Sets the option to validate after each pass. + PassManager& SetValidateAfterAll(bool validate) { + validate_after_all_ = validate; + return *this; + } + + private: + // Consumer for messages. + MessageConsumer consumer_; + // A vector of passes. Order matters. + std::vector> passes_; + // The output stream to write disassembly to before each pass, and after + // the last pass. If this is null, no output is generated. + std::ostream* print_all_stream_; + // The output stream to write the resource utilization of each pass. If this + // is null, no output is generated. + std::ostream* time_report_stream_; + // The target environment. + spv_target_env target_env_; + // The validator options (used when validating each pass). + spv_validator_options val_options_; + // Controls whether validation occurs after every pass. + bool validate_after_all_; +}; + +inline void PassManager::AddPass(std::unique_ptr pass) { + passes_.push_back(std::move(pass)); +} + +template +inline void PassManager::AddPass(Args&&... args) { + passes_.emplace_back(new T(std::forward(args)...)); + passes_.back()->SetMessageConsumer(consumer_); +} + +inline uint32_t PassManager::NumPasses() const { + return static_cast(passes_.size()); +} + +inline Pass* PassManager::GetPass(uint32_t index) const { + SPIRV_ASSERT(consumer_, index < passes_.size(), "index out of bound"); + return passes_[index].get(); +} + +inline const MessageConsumer& PassManager::consumer() const { + return consumer_; +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_PASS_MANAGER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/passes.h b/thirdparty/glslang/External/spirv-tools/source/opt/passes.h new file mode 100644 index 000000000000..9d027fbf4c3e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/passes.h @@ -0,0 +1,95 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_PASSES_H_ +#define SOURCE_OPT_PASSES_H_ + +// A single header to include all passes. + +#include "source/opt/aggressive_dead_code_elim_pass.h" +#include "source/opt/amd_ext_to_khr.h" +#include "source/opt/analyze_live_input_pass.h" +#include "source/opt/block_merge_pass.h" +#include "source/opt/ccp_pass.h" +#include "source/opt/cfg_cleanup_pass.h" +#include "source/opt/code_sink.h" +#include "source/opt/combine_access_chains.h" +#include "source/opt/compact_ids_pass.h" +#include "source/opt/convert_to_half_pass.h" +#include "source/opt/convert_to_sampled_image_pass.h" +#include "source/opt/copy_prop_arrays.h" +#include "source/opt/dead_branch_elim_pass.h" +#include "source/opt/dead_insert_elim_pass.h" +#include "source/opt/dead_variable_elimination.h" +#include "source/opt/desc_sroa.h" +#include "source/opt/eliminate_dead_constant_pass.h" +#include "source/opt/eliminate_dead_functions_pass.h" +#include "source/opt/eliminate_dead_io_components_pass.h" +#include "source/opt/eliminate_dead_members_pass.h" +#include "source/opt/eliminate_dead_output_stores_pass.h" +#include "source/opt/empty_pass.h" +#include "source/opt/fix_func_call_arguments.h" +#include "source/opt/fix_storage_class.h" +#include "source/opt/flatten_decoration_pass.h" +#include "source/opt/fold_spec_constant_op_and_composite_pass.h" +#include "source/opt/freeze_spec_constant_value_pass.h" +#include "source/opt/graphics_robust_access_pass.h" +#include "source/opt/if_conversion.h" +#include "source/opt/inline_exhaustive_pass.h" +#include "source/opt/inline_opaque_pass.h" +#include "source/opt/inst_bindless_check_pass.h" +#include "source/opt/inst_buff_addr_check_pass.h" +#include "source/opt/inst_debug_printf_pass.h" +#include "source/opt/interface_var_sroa.h" +#include "source/opt/interp_fixup_pass.h" +#include "source/opt/invocation_interlock_placement_pass.h" +#include "source/opt/licm_pass.h" +#include "source/opt/local_access_chain_convert_pass.h" +#include "source/opt/local_redundancy_elimination.h" +#include "source/opt/local_single_block_elim_pass.h" +#include "source/opt/local_single_store_elim_pass.h" +#include "source/opt/loop_fission.h" +#include "source/opt/loop_fusion_pass.h" +#include "source/opt/loop_peeling.h" +#include "source/opt/loop_unroller.h" +#include "source/opt/loop_unswitch_pass.h" +#include "source/opt/merge_return_pass.h" +#include "source/opt/modify_maximal_reconvergence.h" +#include "source/opt/null_pass.h" +#include "source/opt/private_to_local_pass.h" +#include "source/opt/reduce_load_size.h" +#include "source/opt/redundancy_elimination.h" +#include "source/opt/relax_float_ops_pass.h" +#include "source/opt/remove_dontinline_pass.h" +#include "source/opt/remove_duplicates_pass.h" +#include "source/opt/remove_unused_interface_variables_pass.h" +#include "source/opt/replace_desc_array_access_using_var_index.h" +#include "source/opt/replace_invalid_opc.h" +#include "source/opt/scalar_replacement_pass.h" +#include "source/opt/set_spec_constant_default_value_pass.h" +#include "source/opt/simplification_pass.h" +#include "source/opt/spread_volatile_semantics.h" +#include "source/opt/ssa_rewrite_pass.h" +#include "source/opt/strength_reduction_pass.h" +#include "source/opt/strip_debug_info_pass.h" +#include "source/opt/strip_nonsemantic_info_pass.h" +#include "source/opt/switch_descriptorset_pass.h" +#include "source/opt/trim_capabilities_pass.h" +#include "source/opt/unify_const_pass.h" +#include "source/opt/upgrade_memory_model.h" +#include "source/opt/vector_dce.h" +#include "source/opt/workaround1209.h" +#include "source/opt/wrap_opkill.h" + +#endif // SOURCE_OPT_PASSES_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/pch_source_opt.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/pch_source_opt.cpp new file mode 100644 index 000000000000..f45448dc56c7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/pch_source_opt.cpp @@ -0,0 +1,15 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "pch_source_opt.h" diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/pch_source_opt.h b/thirdparty/glslang/External/spirv-tools/source/opt/pch_source_opt.h new file mode 100644 index 000000000000..73566510e647 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/pch_source_opt.h @@ -0,0 +1,32 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "source/opt/basic_block.h" +#include "source/opt/decoration_manager.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/mem_pass.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" +#include "source/util/hex_float.h" +#include "source/util/make_unique.h" diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/private_to_local_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/private_to_local_pass.cpp new file mode 100644 index 000000000000..4904e058b3d9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/private_to_local_pass.cpp @@ -0,0 +1,236 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/private_to_local_pass.h" + +#include +#include +#include + +#include "source/opt/ir_context.h" +#include "source/spirv_constant.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kVariableStorageClassInIdx = 0; +constexpr uint32_t kSpvTypePointerTypeIdInIdx = 1; +} // namespace + +Pass::Status PrivateToLocalPass::Process() { + bool modified = false; + + // Private variables require the shader capability. If this is not a shader, + // there is no work to do. + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) + return Status::SuccessWithoutChange; + + std::vector> variables_to_move; + std::unordered_set localized_variables; + for (auto& inst : context()->types_values()) { + if (inst.opcode() != spv::Op::OpVariable) { + continue; + } + + if (spv::StorageClass(inst.GetSingleWordInOperand( + kVariableStorageClassInIdx)) != spv::StorageClass::Private) { + continue; + } + + Function* target_function = FindLocalFunction(inst); + if (target_function != nullptr) { + variables_to_move.push_back({&inst, target_function}); + } + } + + modified = !variables_to_move.empty(); + for (auto p : variables_to_move) { + if (!MoveVariable(p.first, p.second)) { + return Status::Failure; + } + localized_variables.insert(p.first->result_id()); + } + + if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // In SPIR-V 1.4 and later entry points must list private storage class + // variables that are statically used by the entry point. Go through the + // entry points and remove any references to variables that were localized. + for (auto& entry : get_module()->entry_points()) { + std::vector new_operands; + for (uint32_t i = 0; i < entry.NumInOperands(); ++i) { + // Execution model, function id and name are always kept. + if (i < 3 || + !localized_variables.count(entry.GetSingleWordInOperand(i))) { + new_operands.push_back(entry.GetInOperand(i)); + } + } + if (new_operands.size() != entry.NumInOperands()) { + entry.SetInOperands(std::move(new_operands)); + context()->AnalyzeUses(&entry); + } + } + } + + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +Function* PrivateToLocalPass::FindLocalFunction(const Instruction& inst) const { + bool found_first_use = false; + Function* target_function = nullptr; + context()->get_def_use_mgr()->ForEachUser( + inst.result_id(), + [&target_function, &found_first_use, this](Instruction* use) { + BasicBlock* current_block = context()->get_instr_block(use); + if (current_block == nullptr) { + return; + } + + if (!IsValidUse(use)) { + found_first_use = true; + target_function = nullptr; + return; + } + Function* current_function = current_block->GetParent(); + if (!found_first_use) { + found_first_use = true; + target_function = current_function; + } else if (target_function != current_function) { + target_function = nullptr; + } + }); + return target_function; +} // namespace opt + +bool PrivateToLocalPass::MoveVariable(Instruction* variable, + Function* function) { + // The variable needs to be removed from the global section, and placed in the + // header of the function. First step remove from the global list. + variable->RemoveFromList(); + std::unique_ptr var(variable); // Take ownership. + context()->ForgetUses(variable); + + // Update the storage class of the variable. + variable->SetInOperand(kVariableStorageClassInIdx, + {uint32_t(spv::StorageClass::Function)}); + + // Update the type as well. + uint32_t new_type_id = GetNewType(variable->type_id()); + if (new_type_id == 0) { + return false; + } + variable->SetResultType(new_type_id); + + // Place the variable at the start of the first basic block. + context()->AnalyzeUses(variable); + context()->set_instr_block(variable, &*function->begin()); + function->begin()->begin()->InsertBefore(std::move(var)); + + // Update uses where the type may have changed. + return UpdateUses(variable); +} + +uint32_t PrivateToLocalPass::GetNewType(uint32_t old_type_id) { + auto type_mgr = context()->get_type_mgr(); + Instruction* old_type_inst = get_def_use_mgr()->GetDef(old_type_id); + uint32_t pointee_type_id = + old_type_inst->GetSingleWordInOperand(kSpvTypePointerTypeIdInIdx); + uint32_t new_type_id = + type_mgr->FindPointerToType(pointee_type_id, spv::StorageClass::Function); + if (new_type_id != 0) { + context()->UpdateDefUse(context()->get_def_use_mgr()->GetDef(new_type_id)); + } + return new_type_id; +} + +bool PrivateToLocalPass::IsValidUse(const Instruction* inst) const { + // The cases in this switch have to match the cases in |UpdateUse|. + // If we don't know how to update it, it is not valid. + if (inst->GetCommonDebugOpcode() == CommonDebugInfoDebugGlobalVariable) { + return true; + } + switch (inst->opcode()) { + case spv::Op::OpLoad: + case spv::Op::OpStore: + case spv::Op::OpImageTexelPointer: // Treat like a load + return true; + case spv::Op::OpAccessChain: + return context()->get_def_use_mgr()->WhileEachUser( + inst, [this](const Instruction* user) { + if (!IsValidUse(user)) return false; + return true; + }); + case spv::Op::OpName: + return true; + default: + return spvOpcodeIsDecoration(inst->opcode()); + } +} + +bool PrivateToLocalPass::UpdateUse(Instruction* inst, Instruction* user) { + // The cases in this switch have to match the cases in |IsValidUse|. If we + // don't think it is valid, the optimization will not view the variable as a + // candidate, and therefore the use will not be updated. + if (inst->GetCommonDebugOpcode() == CommonDebugInfoDebugGlobalVariable) { + context()->get_debug_info_mgr()->ConvertDebugGlobalToLocalVariable(inst, + user); + return true; + } + switch (inst->opcode()) { + case spv::Op::OpLoad: + case spv::Op::OpStore: + case spv::Op::OpImageTexelPointer: // Treat like a load + // The type is fine because it is the type pointed to, and that does not + // change. + break; + case spv::Op::OpAccessChain: { + context()->ForgetUses(inst); + uint32_t new_type_id = GetNewType(inst->type_id()); + if (new_type_id == 0) { + return false; + } + inst->SetResultType(new_type_id); + context()->AnalyzeUses(inst); + + // Update uses where the type may have changed. + if (!UpdateUses(inst)) { + return false; + } + } break; + case spv::Op::OpName: + case spv::Op::OpEntryPoint: // entry points will be updated separately. + break; + default: + assert(spvOpcodeIsDecoration(inst->opcode()) && + "Do not know how to update the type for this instruction."); + break; + } + return true; +} + +bool PrivateToLocalPass::UpdateUses(Instruction* inst) { + uint32_t id = inst->result_id(); + std::vector uses; + context()->get_def_use_mgr()->ForEachUser( + id, [&uses](Instruction* use) { uses.push_back(use); }); + + for (Instruction* use : uses) { + if (!UpdateUse(use, inst)) { + return false; + } + } + return true; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/private_to_local_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/private_to_local_pass.h new file mode 100644 index 000000000000..e96a965e910f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/private_to_local_pass.h @@ -0,0 +1,73 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_PRIVATE_TO_LOCAL_PASS_H_ +#define SOURCE_OPT_PRIVATE_TO_LOCAL_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// This pass implements total redundancy elimination. This is the same as +// local redundancy elimination except it looks across basic block boundaries. +// An instruction, inst, is totally redundant if there is another instruction +// that dominates inst, and also computes the same value. +class PrivateToLocalPass : public Pass { + public: + const char* name() const override { return "private-to-local"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + // Moves |variable| from the private storage class to the function storage + // class of |function|. Returns false if the variable could not be moved. + bool MoveVariable(Instruction* variable, Function* function); + + // |inst| is an instruction declaring a variable. If that variable is + // referenced in a single function and all of uses are valid as defined by + // |IsValidUse|, then that function is returned. Otherwise, the return + // value is |nullptr|. + Function* FindLocalFunction(const Instruction& inst) const; + + // Returns true is |inst| is a valid use of a pointer. In this case, a + // valid use is one where the transformation is able to rewrite the type to + // match a change in storage class of the original variable. + bool IsValidUse(const Instruction* inst) const; + + // Given the result id of a pointer type, |old_type_id|, this function + // returns the id of a the same pointer type except the storage class has + // been changed to function. If the type does not already exist, it will be + // created. Returns 0 if the new type could not be found or generated. + uint32_t GetNewType(uint32_t old_type_id); + + // Updates |inst|, and any instruction dependent on |inst|, to reflect the + // change of the base pointer now pointing to the function storage class. + bool UpdateUse(Instruction* inst, Instruction* user); + bool UpdateUses(Instruction* inst); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_PRIVATE_TO_LOCAL_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/propagator.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/propagator.cpp new file mode 100644 index 000000000000..9cd6174cf6be --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/propagator.cpp @@ -0,0 +1,291 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/propagator.h" + +namespace spvtools { +namespace opt { + +void SSAPropagator::AddControlEdge(const Edge& edge) { + BasicBlock* dest_bb = edge.dest; + + // Refuse to add the exit block to the work list. + if (dest_bb == ctx_->cfg()->pseudo_exit_block()) { + return; + } + + // Try to mark the edge executable. If it was already in the set of + // executable edges, do nothing. + if (!MarkEdgeExecutable(edge)) { + return; + } + + // If the edge had not already been marked executable, add the destination + // basic block to the work list. + blocks_.push(dest_bb); +} + +void SSAPropagator::AddSSAEdges(Instruction* instr) { + // Ignore instructions that produce no result. + if (instr->result_id() == 0) { + return; + } + + get_def_use_mgr()->ForEachUser( + instr->result_id(), [this](Instruction* use_instr) { + // If the basic block for |use_instr| has not been simulated yet, do + // nothing. The instruction |use_instr| will be simulated next time the + // block is scheduled. + if (!BlockHasBeenSimulated(ctx_->get_instr_block(use_instr))) { + return; + } + + if (ShouldSimulateAgain(use_instr)) { + ssa_edge_uses_.push(use_instr); + } + }); +} + +bool SSAPropagator::IsPhiArgExecutable(Instruction* phi, uint32_t i) const { + BasicBlock* phi_bb = ctx_->get_instr_block(phi); + + uint32_t in_label_id = phi->GetSingleWordOperand(i + 1); + Instruction* in_label_instr = get_def_use_mgr()->GetDef(in_label_id); + BasicBlock* in_bb = ctx_->get_instr_block(in_label_instr); + + return IsEdgeExecutable(Edge(in_bb, phi_bb)); +} + +bool SSAPropagator::SetStatus(Instruction* inst, PropStatus status) { + bool has_old_status = false; + PropStatus old_status = kVarying; + if (HasStatus(inst)) { + has_old_status = true; + old_status = Status(inst); + } + + assert((!has_old_status || old_status <= status) && + "Invalid lattice transition"); + + bool status_changed = !has_old_status || (old_status != status); + if (status_changed) statuses_[inst] = status; + + return status_changed; +} + +bool SSAPropagator::Simulate(Instruction* instr) { + bool changed = false; + + // Don't bother visiting instructions that should not be simulated again. + if (!ShouldSimulateAgain(instr)) { + return changed; + } + + BasicBlock* dest_bb = nullptr; + PropStatus status = visit_fn_(instr, &dest_bb); + bool status_changed = SetStatus(instr, status); + + if (status == kVarying) { + // The statement produces a varying result, add it to the list of statements + // not to simulate anymore and add its SSA def-use edges for simulation. + DontSimulateAgain(instr); + if (status_changed) { + AddSSAEdges(instr); + } + + // If |instr| is a block terminator, add all the control edges out of its + // block. + if (instr->IsBlockTerminator()) { + BasicBlock* block = ctx_->get_instr_block(instr); + for (const auto& e : bb_succs_.at(block)) { + AddControlEdge(e); + } + } + return false; + } else if (status == kInteresting) { + // Add the SSA edges coming out of this instruction if the propagation + // status has changed. + if (status_changed) { + AddSSAEdges(instr); + } + + // If there are multiple outgoing control flow edges and we know which one + // will be taken, add the destination block to the CFG work list. + if (dest_bb) { + AddControlEdge(Edge(ctx_->get_instr_block(instr), dest_bb)); + } + changed = true; + } + + // At this point, we are dealing with instructions that are in status + // kInteresting or kNotInteresting. To decide whether this instruction should + // be simulated again, we examine its operands. If at least one operand O is + // defined at an instruction D that should be simulated again, then the output + // of D might affect |instr|, so we should simulate |instr| again. + bool has_operands_to_simulate = false; + if (instr->opcode() == spv::Op::OpPhi) { + // For Phi instructions, an operand causes the Phi to be simulated again if + // the operand comes from an edge that has not yet been traversed or if its + // definition should be simulated again. + for (uint32_t i = 2; i < instr->NumOperands(); i += 2) { + // Phi arguments come in pairs. Index 'i' contains the + // variable id, index 'i + 1' is the originating block id. + assert(i % 2 == 0 && i < instr->NumOperands() - 1 && + "malformed Phi arguments"); + + uint32_t arg_id = instr->GetSingleWordOperand(i); + Instruction* arg_def_instr = get_def_use_mgr()->GetDef(arg_id); + if (!IsPhiArgExecutable(instr, i) || ShouldSimulateAgain(arg_def_instr)) { + has_operands_to_simulate = true; + break; + } + } + } else { + // For regular instructions, check if the defining instruction of each + // operand needs to be simulated again. If so, then this instruction should + // also be simulated again. + has_operands_to_simulate = + !instr->WhileEachInId([this](const uint32_t* use) { + Instruction* def_instr = get_def_use_mgr()->GetDef(*use); + if (ShouldSimulateAgain(def_instr)) { + return false; + } + return true; + }); + } + + if (!has_operands_to_simulate) { + DontSimulateAgain(instr); + } + + return changed; +} + +bool SSAPropagator::Simulate(BasicBlock* block) { + if (block == ctx_->cfg()->pseudo_exit_block()) { + return false; + } + + // Always simulate Phi instructions, even if we have simulated this block + // before. We do this because Phi instructions receive their inputs from + // incoming edges. When those edges are marked executable, the corresponding + // operand can be simulated. + bool changed = false; + block->ForEachPhiInst( + [&changed, this](Instruction* instr) { changed |= Simulate(instr); }); + + // If this is the first time this block is being simulated, simulate every + // statement in it. + if (!BlockHasBeenSimulated(block)) { + block->ForEachInst([this, &changed](Instruction* instr) { + if (instr->opcode() != spv::Op::OpPhi) { + changed |= Simulate(instr); + } + }); + + MarkBlockSimulated(block); + + // If this block has exactly one successor, mark the edge to its successor + // as executable. + if (bb_succs_.at(block).size() == 1) { + AddControlEdge(bb_succs_.at(block).at(0)); + } + } + + return changed; +} + +void SSAPropagator::Initialize(Function* fn) { + // Compute predecessor and successor blocks for every block in |fn|'s CFG. + // TODO(dnovillo): Move this to CFG and always build them. Alternately, + // move it to IRContext and build CFG preds/succs on-demand. + bb_succs_[ctx_->cfg()->pseudo_entry_block()].push_back( + Edge(ctx_->cfg()->pseudo_entry_block(), fn->entry().get())); + + for (auto& block : *fn) { + const auto& const_block = block; + const_block.ForEachSuccessorLabel([this, &block](const uint32_t label_id) { + BasicBlock* succ_bb = + ctx_->get_instr_block(get_def_use_mgr()->GetDef(label_id)); + bb_succs_[&block].push_back(Edge(&block, succ_bb)); + bb_preds_[succ_bb].push_back(Edge(succ_bb, &block)); + }); + if (block.IsReturnOrAbort()) { + bb_succs_[&block].push_back( + Edge(&block, ctx_->cfg()->pseudo_exit_block())); + bb_preds_[ctx_->cfg()->pseudo_exit_block()].push_back( + Edge(ctx_->cfg()->pseudo_exit_block(), &block)); + } + } + + // Add the edges out of the entry block to seed the propagator. + const auto& entry_succs = bb_succs_[ctx_->cfg()->pseudo_entry_block()]; + for (const auto& e : entry_succs) { + AddControlEdge(e); + } +} + +bool SSAPropagator::Run(Function* fn) { + Initialize(fn); + + bool changed = false; + while (!blocks_.empty() || !ssa_edge_uses_.empty()) { + // Simulate all blocks first. Simulating blocks will add SSA edges to + // follow after all the blocks have been simulated. + if (!blocks_.empty()) { + auto block = blocks_.front(); + changed |= Simulate(block); + blocks_.pop(); + continue; + } + + // Simulate edges from the SSA queue. + if (!ssa_edge_uses_.empty()) { + Instruction* instr = ssa_edge_uses_.front(); + changed |= Simulate(instr); + ssa_edge_uses_.pop(); + } + } + +#ifndef NDEBUG + // Verify all visited values have settled. No value that has been simulated + // should end on not interesting. + fn->ForEachInst([this](Instruction* inst) { + assert( + (!HasStatus(inst) || Status(inst) != SSAPropagator::kNotInteresting) && + "Unsettled value"); + }); +#endif + + return changed; +} + +std::ostream& operator<<(std::ostream& str, + const SSAPropagator::PropStatus& status) { + switch (status) { + case SSAPropagator::kVarying: + str << "Varying"; + break; + case SSAPropagator::kInteresting: + str << "Interesting"; + break; + default: + str << "Not interesting"; + break; + } + return str; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/propagator.h b/thirdparty/glslang/External/spirv-tools/source/opt/propagator.h new file mode 100644 index 000000000000..71212c96929e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/propagator.h @@ -0,0 +1,317 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_PROPAGATOR_H_ +#define SOURCE_OPT_PROPAGATOR_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" + +namespace spvtools { +namespace opt { + +// Represents a CFG control edge. +struct Edge { + Edge(BasicBlock* b1, BasicBlock* b2) : source(b1), dest(b2) { + assert(source && "CFG edges cannot have a null source block."); + assert(dest && "CFG edges cannot have a null destination block."); + } + BasicBlock* source; + BasicBlock* dest; + bool operator<(const Edge& o) const { + return std::make_pair(source->id(), dest->id()) < + std::make_pair(o.source->id(), o.dest->id()); + } +}; + +// This class implements a generic value propagation algorithm based on the +// conditional constant propagation algorithm proposed in +// +// Constant propagation with conditional branches, +// Wegman and Zadeck, ACM TOPLAS 13(2):181-210. +// +// A Propagation Engine for GCC +// Diego Novillo, GCC Summit 2005 +// http://ols.fedoraproject.org/GCC/Reprints-2005/novillo-Reprint.pdf +// +// The purpose of this implementation is to act as a common framework for any +// transformation that needs to propagate values from statements producing new +// values to statements using those values. Simulation proceeds as follows: +// +// 1- Initially, all edges of the CFG are marked not executable and the CFG +// worklist is seeded with all the statements in the entry basic block. +// +// 2- Every instruction I is simulated by calling a pass-provided function +// |visit_fn|. This function is responsible for three things: +// +// (a) Keep a value table of interesting values. This table maps SSA IDs to +// their values. For instance, when implementing constant propagation, +// given a store operation 'OpStore %f %int_3', |visit_fn| should assign +// the value 3 to the table slot for %f. +// +// In general, |visit_fn| will need to use the value table to replace its +// operands, fold the result and decide whether a new value needs to be +// stored in the table. |visit_fn| should only create a new mapping in +// the value table if all the operands in the instruction are known and +// present in the value table. +// +// (b) Return a status indicator to direct the propagator logic. Once the +// instruction is simulated, the propagator needs to know whether this +// instruction produced something interesting. This is indicated via +// |visit_fn|'s return value: +// +// SSAPropagator::kNotInteresting: Instruction I produces nothing of +// interest and does not affect any of the work lists. The +// propagator will visit the statement again if any of its operands +// produce an interesting value in the future. +// +// |visit_fn| should always return this value when it is not sure +// whether the instruction will produce an interesting value in the +// future or not. For instance, for constant propagation, an OpIAdd +// instruction may produce a constant if its two operands are +// constant, but the first time we visit the instruction, we still +// may not have its operands in the value table. +// +// SSAPropagator::kVarying: The value produced by I cannot be determined +// at compile time. Further simulation of I is not required. The +// propagator will not visit this instruction again. Additionally, +// the propagator will add all the instructions at the end of SSA +// def-use edges to be simulated again. +// +// If I is a basic block terminator, it will mark all outgoing edges +// as executable so they are traversed one more time. Eventually +// the kVarying attribute will be spread out to all the data and +// control dependents for I. +// +// It is important for propagation to use kVarying as a bottom value +// for the propagation lattice. It should never be possible for an +// instruction to return kVarying once and kInteresting on a second +// visit. Otherwise, propagation would not stabilize. +// +// SSAPropagator::kInteresting: Instruction I produces a value that can +// be computed at compile time. In this case, |visit_fn| should +// create a new mapping between I's result ID and the produced +// value. Much like the kNotInteresting case, the propagator will +// visit this instruction again if any of its operands changes. +// This is useful when the statement changes from one interesting +// state to another. +// +// (c) For conditional branches, |visit_fn| may decide which edge to take out +// of I's basic block. For example, if the operand for an OpSwitch is +// known to take a specific constant value, |visit_fn| should figure out +// the destination basic block and pass it back by setting the second +// argument to |visit_fn|. +// +// At the end of propagation, values in the value table are guaranteed to be +// stable and can be replaced in the IR. +// +// 3- The propagator keeps two work queues. Instructions are only added to +// these queues if they produce an interesting or varying value. None of this +// should be handled by |visit_fn|. The propagator keeps track of this +// automatically (see SSAPropagator::Simulate for implementation). +// +// CFG blocks: contains the queue of blocks to be simulated. +// Blocks are added to this queue if their incoming edges are +// executable. +// +// SSA Edges: An SSA edge is a def-use edge between a value-producing +// instruction and its use instruction. The SSA edges list +// contains the statements at the end of a def-use edge that need +// to be re-visited when an instruction produces a kVarying or +// kInteresting result. +// +// 4- Simulation terminates when all work queues are drained. +// +// +// EXAMPLE: Basic constant store propagator. +// +// Suppose we want to propagate all constant assignments of the form "OpStore +// %id %cst" where "%id" is some variable and "%cst" an OpConstant. The +// following code builds a table |values| where every id that was assigned a +// constant value is mapped to the constant value it was assigned. +// +// auto ctx = BuildModule(...); +// std::map values; +// const auto visit_fn = [&ctx, &values](Instruction* instr, +// BasicBlock** dest_bb) { +// if (instr->opcode() == spv::Op::OpStore) { +// uint32_t rhs_id = instr->GetSingleWordOperand(1); +// Instruction* rhs_def = ctx->get_def_use_mgr()->GetDef(rhs_id); +// if (rhs_def->opcode() == spv::Op::OpConstant) { +// uint32_t val = rhs_def->GetSingleWordOperand(2); +// values[rhs_id] = val; +// return SSAPropagator::kInteresting; +// } +// } +// return SSAPropagator::kVarying; +// }; +// SSAPropagator propagator(ctx.get(), &cfg, visit_fn); +// propagator.Run(&fn); +// +// Given the code: +// +// %int_4 = OpConstant %int 4 +// %int_3 = OpConstant %int 3 +// %int_1 = OpConstant %int 1 +// OpStore %x %int_4 +// OpStore %y %int_3 +// OpStore %z %int_1 +// +// After SSAPropagator::Run returns, the |values| map will contain the entries: +// values[%x] = 4, values[%y] = 3, and, values[%z] = 1. +class SSAPropagator { + public: + // Lattice values used for propagation. See class documentation for + // a description. + enum PropStatus { kNotInteresting, kInteresting, kVarying }; + + using VisitFunction = std::function; + + SSAPropagator(IRContext* context, const VisitFunction& visit_fn) + : ctx_(context), visit_fn_(visit_fn) {} + + // Runs the propagator on function |fn|. Returns true if changes were made to + // the function. Otherwise, it returns false. + bool Run(Function* fn); + + // Returns true if the |i|th argument for |phi| comes through a CFG edge that + // has been marked executable. |i| should be an index value accepted by + // Instruction::GetSingleWordOperand. + bool IsPhiArgExecutable(Instruction* phi, uint32_t i) const; + + // Returns true if |inst| has a recorded status. This will be true once |inst| + // has been simulated once. + bool HasStatus(Instruction* inst) const { return statuses_.count(inst); } + + // Returns the current propagation status of |inst|. Assumes + // |HasStatus(inst)| returns true. + PropStatus Status(Instruction* inst) const { + return statuses_.find(inst)->second; + } + + // Records the propagation status |status| for |inst|. Returns true if the + // status for |inst| has changed or set was set for the first time. + bool SetStatus(Instruction* inst, PropStatus status); + + private: + // Initialize processing. + void Initialize(Function* fn); + + // Simulate the execution |block| by calling |visit_fn_| on every instruction + // in it. + bool Simulate(BasicBlock* block); + + // Simulate the execution of |instr| by replacing all the known values in + // every operand and determining whether the result is interesting for + // propagation. This invokes the callback function |visit_fn_| to determine + // the value computed by |instr|. + bool Simulate(Instruction* instr); + + // Returns true if |instr| should be simulated again. + bool ShouldSimulateAgain(Instruction* instr) const { + return do_not_simulate_.find(instr) == do_not_simulate_.end(); + } + + // Add |instr| to the set of instructions not to simulate again. + void DontSimulateAgain(Instruction* instr) { do_not_simulate_.insert(instr); } + + // Returns true if |block| has been simulated already. + bool BlockHasBeenSimulated(BasicBlock* block) const { + return simulated_blocks_.find(block) != simulated_blocks_.end(); + } + + // Marks block |block| as simulated. + void MarkBlockSimulated(BasicBlock* block) { + simulated_blocks_.insert(block); + } + + // Marks |edge| as executable. Returns false if the edge was already marked + // as executable. + bool MarkEdgeExecutable(const Edge& edge) { + return executable_edges_.insert(edge).second; + } + + // Returns true if |edge| has been marked as executable. + bool IsEdgeExecutable(const Edge& edge) const { + return executable_edges_.find(edge) != executable_edges_.end(); + } + + // Returns a pointer to the def-use manager for |ctx_|. + analysis::DefUseManager* get_def_use_mgr() const { + return ctx_->get_def_use_mgr(); + } + + // If the CFG edge |e| has not been executed, this function adds |e|'s + // destination block to the work list. + void AddControlEdge(const Edge& e); + + // Adds all the instructions that use the result of |instr| to the SSA edges + // work list. If |instr| produces no result id, this does nothing. + void AddSSAEdges(Instruction* instr); + + // IR context to use. + IRContext* ctx_; + + // Function that visits instructions during simulation. The output of this + // function is used to determine if the simulated instruction produced a value + // interesting for propagation. The function is responsible for keeping + // track of interesting values by storing them in some user-provided map. + VisitFunction visit_fn_; + + // SSA def-use edges to traverse. Each entry is a destination statement for an + // SSA def-use edge as returned by |def_use_manager_|. + std::queue ssa_edge_uses_; + + // Blocks to simulate. + std::queue blocks_; + + // Blocks simulated during propagation. + std::unordered_set simulated_blocks_; + + // Set of instructions that should not be simulated again because they have + // been found to be in the kVarying state. + std::unordered_set do_not_simulate_; + + // Map between a basic block and its predecessor edges. + // TODO(dnovillo): Move this to CFG and always build them. Alternately, + // move it to IRContext and build CFG preds/succs on-demand. + std::unordered_map> bb_preds_; + + // Map between a basic block and its successor edges. + // TODO(dnovillo): Move this to CFG and always build them. Alternately, + // move it to IRContext and build CFG preds/succs on-demand. + std::unordered_map> bb_succs_; + + // Set of executable CFG edges. + std::set executable_edges_; + + // Tracks instruction propagation status. + std::unordered_map statuses_; +}; + +std::ostream& operator<<(std::ostream& str, + const SSAPropagator::PropStatus& status); + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_PROPAGATOR_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/reduce_load_size.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/reduce_load_size.cpp new file mode 100644 index 000000000000..73a90f066b5b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/reduce_load_size.cpp @@ -0,0 +1,188 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/reduce_load_size.h" + +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/util/bit_vector.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kExtractCompositeIdInIdx = 0; +constexpr uint32_t kVariableStorageClassInIdx = 0; +constexpr uint32_t kLoadPointerInIdx = 0; +} // namespace + +Pass::Status ReduceLoadSize::Process() { + bool modified = false; + + for (auto& func : *get_module()) { + func.ForEachInst([&modified, this](Instruction* inst) { + if (inst->opcode() == spv::Op::OpCompositeExtract) { + if (ShouldReplaceExtract(inst)) { + modified |= ReplaceExtract(inst); + } + } + }); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool ReduceLoadSize::ReplaceExtract(Instruction* inst) { + assert(inst->opcode() == spv::Op::OpCompositeExtract && + "Wrong opcode. Should be OpCompositeExtract."); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + + uint32_t composite_id = + inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); + Instruction* composite_inst = def_use_mgr->GetDef(composite_id); + + if (composite_inst->opcode() != spv::Op::OpLoad) { + return false; + } + + analysis::Type* composite_type = type_mgr->GetType(composite_inst->type_id()); + if (composite_type->kind() == analysis::Type::kVector || + composite_type->kind() == analysis::Type::kMatrix) { + return false; + } + + Instruction* var = composite_inst->GetBaseAddress(); + if (var == nullptr || var->opcode() != spv::Op::OpVariable) { + return false; + } + + spv::StorageClass storage_class = static_cast( + var->GetSingleWordInOperand(kVariableStorageClassInIdx)); + switch (storage_class) { + case spv::StorageClass::Uniform: + case spv::StorageClass::UniformConstant: + case spv::StorageClass::Input: + break; + default: + return false; + } + + // Create a new access chain and load just after the old load. + // We cannot create the new access chain load in the position of the extract + // because the storage may have been written to in between. + InstructionBuilder ir_builder( + inst->context(), composite_inst, + IRContext::kAnalysisInstrToBlockMapping | IRContext::kAnalysisDefUse); + + uint32_t pointer_to_result_type_id = + type_mgr->FindPointerToType(inst->type_id(), storage_class); + assert(pointer_to_result_type_id != 0 && + "We did not find the pointer type that we need."); + + analysis::Integer int_type(32, false); + const analysis::Type* uint32_type = type_mgr->GetRegisteredType(&int_type); + std::vector ids; + for (uint32_t i = 1; i < inst->NumInOperands(); ++i) { + uint32_t index = inst->GetSingleWordInOperand(i); + const analysis::Constant* index_const = + const_mgr->GetConstant(uint32_type, {index}); + ids.push_back(const_mgr->GetDefiningInstruction(index_const)->result_id()); + } + + Instruction* new_access_chain = ir_builder.AddAccessChain( + pointer_to_result_type_id, + composite_inst->GetSingleWordInOperand(kLoadPointerInIdx), ids); + Instruction* new_load = + ir_builder.AddLoad(inst->type_id(), new_access_chain->result_id()); + + context()->ReplaceAllUsesWith(inst->result_id(), new_load->result_id()); + context()->KillInst(inst); + return true; +} + +bool ReduceLoadSize::ShouldReplaceExtract(Instruction* inst) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + Instruction* op_inst = def_use_mgr->GetDef( + inst->GetSingleWordInOperand(kExtractCompositeIdInIdx)); + + if (op_inst->opcode() != spv::Op::OpLoad) { + return false; + } + + auto cached_result = should_replace_cache_.find(op_inst->result_id()); + if (cached_result != should_replace_cache_.end()) { + return cached_result->second; + } + + bool all_elements_used = false; + std::set elements_used; + + all_elements_used = + !def_use_mgr->WhileEachUser(op_inst, [&elements_used](Instruction* use) { + if (use->IsCommonDebugInstr()) return true; + if (use->opcode() != spv::Op::OpCompositeExtract || + use->NumInOperands() == 1) { + return false; + } + elements_used.insert(use->GetSingleWordInOperand(1)); + return true; + }); + + bool should_replace = false; + if (all_elements_used) { + should_replace = false; + } else if (1.0 <= replacement_threshold_) { + should_replace = true; + } else { + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Type* load_type = type_mgr->GetType(op_inst->type_id()); + uint32_t total_size = 1; + switch (load_type->kind()) { + case analysis::Type::kArray: { + const analysis::Constant* size_const = + const_mgr->FindDeclaredConstant(load_type->AsArray()->LengthId()); + + if (size_const) { + assert(size_const->AsIntConstant()); + total_size = size_const->GetU32(); + } else { + // The size is spec constant, so it is unknown at this time. Assume + // it is very large. + total_size = UINT32_MAX; + } + } break; + case analysis::Type::kStruct: + total_size = static_cast( + load_type->AsStruct()->element_types().size()); + break; + default: + break; + } + double percent_used = static_cast(elements_used.size()) / + static_cast(total_size); + should_replace = (percent_used < replacement_threshold_); + } + + should_replace_cache_[op_inst->result_id()] = should_replace; + return should_replace; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/reduce_load_size.h b/thirdparty/glslang/External/spirv-tools/source/opt/reduce_load_size.h new file mode 100644 index 000000000000..b323845366af --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/reduce_load_size.h @@ -0,0 +1,73 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REDUCE_LOAD_SIZE_H_ +#define SOURCE_OPT_REDUCE_LOAD_SIZE_H_ + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class ReduceLoadSize : public Pass { + public: + explicit ReduceLoadSize(double replacement_threshold) + : replacement_threshold_(replacement_threshold) {} + + const char* name() const override { return "reduce-load-size"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Replaces |inst|, which must be an OpCompositeExtract instruction, with + // an OpAccessChain and a load if possible. This happens only if it is a load + // feeding |inst|. Returns true if the substitution happened. The position + // of the new instructions will be in the same place as the load feeding the + // extract. + bool ReplaceExtract(Instruction* inst); + + // Returns true if the OpCompositeExtract instruction |inst| should be replace + // or not. This is determined by looking at the load that feeds |inst| if + // it is a load. |should_replace_cache_| is used to cache the results based + // on the load feeding |inst|. + bool ShouldReplaceExtract(Instruction* inst); + + // Threshold to determine whether we have to replace the load or not. If the + // ratio of the used components of the load is less than the threshold, we + // replace the load. + double replacement_threshold_; + + // Maps the result id of an OpLoad instruction to the result of whether or + // not the OpCompositeExtract that use the id should be replaced. + std::unordered_map should_replace_cache_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REDUCE_LOAD_SIZE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/redundancy_elimination.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/redundancy_elimination.cpp new file mode 100644 index 000000000000..398225bb5d18 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/redundancy_elimination.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/redundancy_elimination.h" + +#include "source/opt/value_number_table.h" + +namespace spvtools { +namespace opt { + +Pass::Status RedundancyEliminationPass::Process() { + bool modified = false; + ValueNumberTable vnTable(context()); + + for (auto& func : *get_module()) { + if (func.IsDeclaration()) { + continue; + } + + // Build the dominator tree for this function. It is how the code is + // traversed. + DominatorTree& dom_tree = + context()->GetDominatorAnalysis(&func)->GetDomTree(); + + // Keeps track of all ids that contain a given value number. We keep + // track of multiple values because they could have the same value, but + // different decorations. + std::map value_to_ids; + + if (EliminateRedundanciesFrom(dom_tree.GetRoot(), vnTable, value_to_ids)) { + modified = true; + } + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool RedundancyEliminationPass::EliminateRedundanciesFrom( + DominatorTreeNode* bb, const ValueNumberTable& vnTable, + std::map value_to_ids) { + bool modified = EliminateRedundanciesInBB(bb->bb_, vnTable, &value_to_ids); + + for (auto dominated_bb : bb->children_) { + modified |= EliminateRedundanciesFrom(dominated_bb, vnTable, value_to_ids); + } + + return modified; +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/redundancy_elimination.h b/thirdparty/glslang/External/spirv-tools/source/opt/redundancy_elimination.h new file mode 100644 index 000000000000..40451f40e21c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/redundancy_elimination.h @@ -0,0 +1,56 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REDUNDANCY_ELIMINATION_H_ +#define SOURCE_OPT_REDUNDANCY_ELIMINATION_H_ + +#include + +#include "source/opt/ir_context.h" +#include "source/opt/local_redundancy_elimination.h" +#include "source/opt/pass.h" +#include "source/opt/value_number_table.h" + +namespace spvtools { +namespace opt { + +// This pass implements total redundancy elimination. This is the same as +// local redundancy elimination except it looks across basic block boundaries. +// An instruction, inst, is totally redundant if there is another instruction +// that dominates inst, and also computes the same value. +class RedundancyEliminationPass : public LocalRedundancyEliminationPass { + public: + const char* name() const override { return "redundancy-elimination"; } + Status Process() override; + + protected: + // Removes for all total redundancies in the function starting at |bb|. + // + // |vnTable| must have computed a value number for every result id defined + // in the function containing |bb|. + // + // |value_to_ids| is a map from value number to ids. If {vn, id} is in + // |value_to_ids| then vn is the value number of id, and the definition of id + // dominates |bb|. + // + // Returns true if at least one instruction is deleted. + bool EliminateRedundanciesFrom(DominatorTreeNode* bb, + const ValueNumberTable& vnTable, + std::map value_to_ids); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REDUNDANCY_ELIMINATION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/reflect.h b/thirdparty/glslang/External/spirv-tools/source/opt/reflect.h new file mode 100644 index 000000000000..ec7c2dd07565 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/reflect.h @@ -0,0 +1,63 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REFLECT_H_ +#define SOURCE_OPT_REFLECT_H_ + +#include "source/latest_version_spirv_header.h" +#include "source/opcode.h" + +namespace spvtools { +namespace opt { + +// Note that as SPIR-V evolves over time, new opcodes may appear. So the +// following functions tend to be outdated and should be updated when SPIR-V +// version bumps. + +inline bool IsDebug1Inst(spv::Op opcode) { + return (opcode >= spv::Op::OpSourceContinued && + opcode <= spv::Op::OpSourceExtension) || + opcode == spv::Op::OpString; +} +inline bool IsDebug2Inst(spv::Op opcode) { + return opcode == spv::Op::OpName || opcode == spv::Op::OpMemberName; +} +inline bool IsDebug3Inst(spv::Op opcode) { + return opcode == spv::Op::OpModuleProcessed; +} +inline bool IsOpLineInst(spv::Op opcode) { + return opcode == spv::Op::OpLine || opcode == spv::Op::OpNoLine; +} +inline bool IsAnnotationInst(spv::Op opcode) { + return (opcode >= spv::Op::OpDecorate && + opcode <= spv::Op::OpGroupMemberDecorate) || + opcode == spv::Op::OpDecorateId || + opcode == spv::Op::OpDecorateStringGOOGLE || + opcode == spv::Op::OpMemberDecorateStringGOOGLE; +} +inline bool IsTypeInst(spv::Op opcode) { + return spvOpcodeGeneratesType(opcode) || + opcode == spv::Op::OpTypeForwardPointer; +} +inline bool IsConstantInst(spv::Op opcode) { + return spvOpcodeIsConstant(opcode); +} +inline bool IsSpecConstantInst(spv::Op opcode) { + return spvOpcodeIsSpecConstant(opcode); +} + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REFLECT_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/register_pressure.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/register_pressure.cpp new file mode 100644 index 000000000000..34a8ba3e31f9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/register_pressure.cpp @@ -0,0 +1,582 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/register_pressure.h" + +#include +#include + +#include "source/opt/cfg.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/dominator_tree.h" +#include "source/opt/function.h" +#include "source/opt/ir_context.h" +#include "source/opt/iterator.h" + +namespace spvtools { +namespace opt { +namespace { +// Predicate for the FilterIterator to only consider instructions that are not +// phi instructions defined in the basic block |bb|. +class ExcludePhiDefinedInBlock { + public: + ExcludePhiDefinedInBlock(IRContext* context, const BasicBlock* bb) + : context_(context), bb_(bb) {} + + bool operator()(Instruction* insn) const { + return !(insn->opcode() == spv::Op::OpPhi && + context_->get_instr_block(insn) == bb_); + } + + private: + IRContext* context_; + const BasicBlock* bb_; +}; + +// Returns true if |insn| generates a SSA register that is likely to require a +// physical register. +bool CreatesRegisterUsage(Instruction* insn) { + if (!insn->HasResultId()) return false; + if (insn->opcode() == spv::Op::OpUndef) return false; + if (IsConstantInst(insn->opcode())) return false; + if (insn->opcode() == spv::Op::OpLabel) return false; + return true; +} + +// Compute the register liveness for each basic block of a function. This also +// fill-up some information about the pick register usage and a break down of +// register usage. This implements: "A non-iterative data-flow algorithm for +// computing liveness sets in strict ssa programs" from Boissinot et al. +class ComputeRegisterLiveness { + public: + ComputeRegisterLiveness(RegisterLiveness* reg_pressure, Function* f) + : reg_pressure_(reg_pressure), + context_(reg_pressure->GetContext()), + function_(f), + cfg_(*reg_pressure->GetContext()->cfg()), + def_use_manager_(*reg_pressure->GetContext()->get_def_use_mgr()), + dom_tree_( + reg_pressure->GetContext()->GetDominatorAnalysis(f)->GetDomTree()), + loop_desc_(*reg_pressure->GetContext()->GetLoopDescriptor(f)) {} + + // Computes the register liveness for |function_| and then estimate the + // register usage. The liveness algorithm works in 2 steps: + // - First, compute the liveness for each basic blocks, but will ignore any + // back-edge; + // - Second, walk loop forest to propagate registers crossing back-edges + // (add iterative values into the liveness set). + void Compute() { + for (BasicBlock& start_bb : *function_) { + if (reg_pressure_->Get(start_bb.id()) != nullptr) { + continue; + } + cfg_.ForEachBlockInPostOrder(&start_bb, [this](BasicBlock* bb) { + if (reg_pressure_->Get(bb->id()) == nullptr) { + ComputePartialLiveness(bb); + } + }); + } + DoLoopLivenessUnification(); + EvaluateRegisterRequirements(); + } + + private: + // Registers all SSA register used by successors of |bb| in their phi + // instructions. + void ComputePhiUses(const BasicBlock& bb, + RegisterLiveness::RegionRegisterLiveness::LiveSet* live) { + uint32_t bb_id = bb.id(); + bb.ForEachSuccessorLabel([live, bb_id, this](uint32_t sid) { + BasicBlock* succ_bb = cfg_.block(sid); + succ_bb->ForEachPhiInst([live, bb_id, this](const Instruction* phi) { + for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) { + if (phi->GetSingleWordInOperand(i + 1) == bb_id) { + Instruction* insn_op = + def_use_manager_.GetDef(phi->GetSingleWordInOperand(i)); + if (CreatesRegisterUsage(insn_op)) { + live->insert(insn_op); + break; + } + } + } + }); + }); + } + + // Computes register liveness for each basic blocks but ignores all + // back-edges. + void ComputePartialLiveness(BasicBlock* bb) { + assert(reg_pressure_->Get(bb) == nullptr && + "Basic block already processed"); + + RegisterLiveness::RegionRegisterLiveness* live_inout = + reg_pressure_->GetOrInsert(bb->id()); + ComputePhiUses(*bb, &live_inout->live_out_); + + const BasicBlock* cbb = bb; + cbb->ForEachSuccessorLabel([&live_inout, bb, this](uint32_t sid) { + // Skip back edges. + if (dom_tree_.Dominates(sid, bb->id())) { + return; + } + + BasicBlock* succ_bb = cfg_.block(sid); + RegisterLiveness::RegionRegisterLiveness* succ_live_inout = + reg_pressure_->Get(succ_bb); + assert(succ_live_inout && + "Successor liveness analysis was not performed"); + + ExcludePhiDefinedInBlock predicate(context_, succ_bb); + auto filter = + MakeFilterIteratorRange(succ_live_inout->live_in_.begin(), + succ_live_inout->live_in_.end(), predicate); + live_inout->live_out_.insert(filter.begin(), filter.end()); + }); + + live_inout->live_in_ = live_inout->live_out_; + for (Instruction& insn : make_range(bb->rbegin(), bb->rend())) { + if (insn.opcode() == spv::Op::OpPhi) { + live_inout->live_in_.insert(&insn); + break; + } + live_inout->live_in_.erase(&insn); + insn.ForEachInId([live_inout, this](uint32_t* id) { + Instruction* insn_op = def_use_manager_.GetDef(*id); + if (CreatesRegisterUsage(insn_op)) { + live_inout->live_in_.insert(insn_op); + } + }); + } + } + + // Propagates the register liveness information of each loop iterators. + void DoLoopLivenessUnification() { + for (const Loop* loop : *loop_desc_.GetPlaceholderRootLoop()) { + DoLoopLivenessUnification(*loop); + } + } + + // Propagates the register liveness information of loop iterators trough-out + // the loop body. + void DoLoopLivenessUnification(const Loop& loop) { + auto blocks_in_loop = MakeFilterIteratorRange( + loop.GetBlocks().begin(), loop.GetBlocks().end(), + [&loop, this](uint32_t bb_id) { + return bb_id != loop.GetHeaderBlock()->id() && + loop_desc_[bb_id] == &loop; + }); + + RegisterLiveness::RegionRegisterLiveness* header_live_inout = + reg_pressure_->Get(loop.GetHeaderBlock()); + assert(header_live_inout && + "Liveness analysis was not performed for the current block"); + + ExcludePhiDefinedInBlock predicate(context_, loop.GetHeaderBlock()); + auto live_loop = + MakeFilterIteratorRange(header_live_inout->live_in_.begin(), + header_live_inout->live_in_.end(), predicate); + + for (uint32_t bb_id : blocks_in_loop) { + BasicBlock* bb = cfg_.block(bb_id); + + RegisterLiveness::RegionRegisterLiveness* live_inout = + reg_pressure_->Get(bb); + live_inout->live_in_.insert(live_loop.begin(), live_loop.end()); + live_inout->live_out_.insert(live_loop.begin(), live_loop.end()); + } + + for (const Loop* inner_loop : loop) { + RegisterLiveness::RegionRegisterLiveness* live_inout = + reg_pressure_->Get(inner_loop->GetHeaderBlock()); + live_inout->live_in_.insert(live_loop.begin(), live_loop.end()); + live_inout->live_out_.insert(live_loop.begin(), live_loop.end()); + + DoLoopLivenessUnification(*inner_loop); + } + } + + // Get the number of required registers for this each basic block. + void EvaluateRegisterRequirements() { + for (BasicBlock& bb : *function_) { + RegisterLiveness::RegionRegisterLiveness* live_inout = + reg_pressure_->Get(bb.id()); + assert(live_inout != nullptr && "Basic block not processed"); + + size_t reg_count = live_inout->live_out_.size(); + for (Instruction* insn : live_inout->live_out_) { + live_inout->AddRegisterClass(insn); + } + live_inout->used_registers_ = reg_count; + + std::unordered_set die_in_block; + for (Instruction& insn : make_range(bb.rbegin(), bb.rend())) { + // If it is a phi instruction, the register pressure will not change + // anymore. + if (insn.opcode() == spv::Op::OpPhi) { + break; + } + + insn.ForEachInId( + [live_inout, &die_in_block, ®_count, this](uint32_t* id) { + Instruction* op_insn = def_use_manager_.GetDef(*id); + if (!CreatesRegisterUsage(op_insn) || + live_inout->live_out_.count(op_insn)) { + // already taken into account. + return; + } + if (!die_in_block.count(*id)) { + live_inout->AddRegisterClass(def_use_manager_.GetDef(*id)); + reg_count++; + die_in_block.insert(*id); + } + }); + live_inout->used_registers_ = + std::max(live_inout->used_registers_, reg_count); + if (CreatesRegisterUsage(&insn)) { + reg_count--; + } + } + } + } + + RegisterLiveness* reg_pressure_; + IRContext* context_; + Function* function_; + CFG& cfg_; + analysis::DefUseManager& def_use_manager_; + DominatorTree& dom_tree_; + LoopDescriptor& loop_desc_; +}; +} // namespace + +// Get the number of required registers for each basic block. +void RegisterLiveness::RegionRegisterLiveness::AddRegisterClass( + Instruction* insn) { + assert(CreatesRegisterUsage(insn) && "Instruction does not use a register"); + analysis::Type* type = + insn->context()->get_type_mgr()->GetType(insn->type_id()); + + RegisterLiveness::RegisterClass reg_class{type, false}; + + insn->context()->get_decoration_mgr()->WhileEachDecoration( + insn->result_id(), uint32_t(spv::Decoration::Uniform), + [®_class](const Instruction&) { + reg_class.is_uniform_ = true; + return false; + }); + + AddRegisterClass(reg_class); +} + +void RegisterLiveness::Analyze(Function* f) { + block_pressure_.clear(); + ComputeRegisterLiveness(this, f).Compute(); +} + +void RegisterLiveness::ComputeLoopRegisterPressure( + const Loop& loop, RegionRegisterLiveness* loop_reg_pressure) const { + loop_reg_pressure->Clear(); + + const RegionRegisterLiveness* header_live_inout = Get(loop.GetHeaderBlock()); + loop_reg_pressure->live_in_ = header_live_inout->live_in_; + + std::unordered_set exit_blocks; + loop.GetExitBlocks(&exit_blocks); + + for (uint32_t bb_id : exit_blocks) { + const RegionRegisterLiveness* live_inout = Get(bb_id); + loop_reg_pressure->live_out_.insert(live_inout->live_in_.begin(), + live_inout->live_in_.end()); + } + + std::unordered_set seen_insn; + for (Instruction* insn : loop_reg_pressure->live_out_) { + loop_reg_pressure->AddRegisterClass(insn); + seen_insn.insert(insn->result_id()); + } + for (Instruction* insn : loop_reg_pressure->live_in_) { + if (!seen_insn.count(insn->result_id())) { + continue; + } + loop_reg_pressure->AddRegisterClass(insn); + seen_insn.insert(insn->result_id()); + } + + loop_reg_pressure->used_registers_ = 0; + + for (uint32_t bb_id : loop.GetBlocks()) { + BasicBlock* bb = context_->cfg()->block(bb_id); + + const RegionRegisterLiveness* live_inout = Get(bb_id); + assert(live_inout != nullptr && "Basic block not processed"); + loop_reg_pressure->used_registers_ = std::max( + loop_reg_pressure->used_registers_, live_inout->used_registers_); + + for (Instruction& insn : *bb) { + if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || + seen_insn.count(insn.result_id())) { + continue; + } + loop_reg_pressure->AddRegisterClass(&insn); + } + } +} + +void RegisterLiveness::SimulateFusion( + const Loop& l1, const Loop& l2, RegionRegisterLiveness* sim_result) const { + sim_result->Clear(); + + // Compute the live-in state: + // sim_result.live_in = l1.live_in U l2.live_in + // This assumes that |l1| does not generated register that is live-out for + // |l1|. + const RegionRegisterLiveness* l1_header_live_inout = Get(l1.GetHeaderBlock()); + sim_result->live_in_ = l1_header_live_inout->live_in_; + + const RegionRegisterLiveness* l2_header_live_inout = Get(l2.GetHeaderBlock()); + sim_result->live_in_.insert(l2_header_live_inout->live_in_.begin(), + l2_header_live_inout->live_in_.end()); + + // The live-out set of the fused loop is the l2 live-out set. + std::unordered_set exit_blocks; + l2.GetExitBlocks(&exit_blocks); + + for (uint32_t bb_id : exit_blocks) { + const RegionRegisterLiveness* live_inout = Get(bb_id); + sim_result->live_out_.insert(live_inout->live_in_.begin(), + live_inout->live_in_.end()); + } + + // Compute the register usage information. + std::unordered_set seen_insn; + for (Instruction* insn : sim_result->live_out_) { + sim_result->AddRegisterClass(insn); + seen_insn.insert(insn->result_id()); + } + for (Instruction* insn : sim_result->live_in_) { + if (!seen_insn.count(insn->result_id())) { + continue; + } + sim_result->AddRegisterClass(insn); + seen_insn.insert(insn->result_id()); + } + + sim_result->used_registers_ = 0; + + // The loop fusion is injecting the l1 before the l2, the latch of l1 will be + // connected to the header of l2. + // To compute the register usage, we inject the loop live-in (union of l1 and + // l2 live-in header blocks) into the live in/out of each basic block of + // l1 to get the peak register usage. We then repeat the operation to for l2 + // basic blocks but in this case we inject the live-out of the latch of l1. + auto live_loop = MakeFilterIteratorRange( + sim_result->live_in_.begin(), sim_result->live_in_.end(), + [&l1, &l2](Instruction* insn) { + BasicBlock* bb = insn->context()->get_instr_block(insn); + return insn->HasResultId() && + !(insn->opcode() == spv::Op::OpPhi && + (bb == l1.GetHeaderBlock() || bb == l2.GetHeaderBlock())); + }); + + for (uint32_t bb_id : l1.GetBlocks()) { + BasicBlock* bb = context_->cfg()->block(bb_id); + + const RegionRegisterLiveness* live_inout_info = Get(bb_id); + assert(live_inout_info != nullptr && "Basic block not processed"); + RegionRegisterLiveness::LiveSet live_out = live_inout_info->live_out_; + live_out.insert(live_loop.begin(), live_loop.end()); + sim_result->used_registers_ = + std::max(sim_result->used_registers_, + live_inout_info->used_registers_ + live_out.size() - + live_inout_info->live_out_.size()); + + for (Instruction& insn : *bb) { + if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || + seen_insn.count(insn.result_id())) { + continue; + } + sim_result->AddRegisterClass(&insn); + } + } + + const RegionRegisterLiveness* l1_latch_live_inout_info = + Get(l1.GetLatchBlock()->id()); + assert(l1_latch_live_inout_info != nullptr && "Basic block not processed"); + RegionRegisterLiveness::LiveSet l1_latch_live_out = + l1_latch_live_inout_info->live_out_; + l1_latch_live_out.insert(live_loop.begin(), live_loop.end()); + + auto live_loop_l2 = + make_range(l1_latch_live_out.begin(), l1_latch_live_out.end()); + + for (uint32_t bb_id : l2.GetBlocks()) { + BasicBlock* bb = context_->cfg()->block(bb_id); + + const RegionRegisterLiveness* live_inout_info = Get(bb_id); + assert(live_inout_info != nullptr && "Basic block not processed"); + RegionRegisterLiveness::LiveSet live_out = live_inout_info->live_out_; + live_out.insert(live_loop_l2.begin(), live_loop_l2.end()); + sim_result->used_registers_ = + std::max(sim_result->used_registers_, + live_inout_info->used_registers_ + live_out.size() - + live_inout_info->live_out_.size()); + + for (Instruction& insn : *bb) { + if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || + seen_insn.count(insn.result_id())) { + continue; + } + sim_result->AddRegisterClass(&insn); + } + } +} + +void RegisterLiveness::SimulateFission( + const Loop& loop, const std::unordered_set& moved_inst, + const std::unordered_set& copied_inst, + RegionRegisterLiveness* l1_sim_result, + RegionRegisterLiveness* l2_sim_result) const { + l1_sim_result->Clear(); + l2_sim_result->Clear(); + + // Filter predicates: consider instructions that only belong to the first and + // second loop. + auto belong_to_loop1 = [&moved_inst, &copied_inst, &loop](Instruction* insn) { + return moved_inst.count(insn) || copied_inst.count(insn) || + !loop.IsInsideLoop(insn); + }; + auto belong_to_loop2 = [&moved_inst](Instruction* insn) { + return !moved_inst.count(insn); + }; + + const RegionRegisterLiveness* header_live_inout = Get(loop.GetHeaderBlock()); + // l1 live-in + { + auto live_loop = MakeFilterIteratorRange( + header_live_inout->live_in_.begin(), header_live_inout->live_in_.end(), + belong_to_loop1); + l1_sim_result->live_in_.insert(live_loop.begin(), live_loop.end()); + } + // l2 live-in + { + auto live_loop = MakeFilterIteratorRange( + header_live_inout->live_in_.begin(), header_live_inout->live_in_.end(), + belong_to_loop2); + l2_sim_result->live_in_.insert(live_loop.begin(), live_loop.end()); + } + + std::unordered_set exit_blocks; + loop.GetExitBlocks(&exit_blocks); + + // l2 live-out. + for (uint32_t bb_id : exit_blocks) { + const RegionRegisterLiveness* live_inout = Get(bb_id); + l2_sim_result->live_out_.insert(live_inout->live_in_.begin(), + live_inout->live_in_.end()); + } + // l1 live-out. + { + auto live_out = MakeFilterIteratorRange(l2_sim_result->live_out_.begin(), + l2_sim_result->live_out_.end(), + belong_to_loop1); + l1_sim_result->live_out_.insert(live_out.begin(), live_out.end()); + } + { + auto live_out = + MakeFilterIteratorRange(l2_sim_result->live_in_.begin(), + l2_sim_result->live_in_.end(), belong_to_loop1); + l1_sim_result->live_out_.insert(live_out.begin(), live_out.end()); + } + // Lives out of l1 are live out of l2 so are live in of l2 as well. + l2_sim_result->live_in_.insert(l1_sim_result->live_out_.begin(), + l1_sim_result->live_out_.end()); + + for (Instruction* insn : l1_sim_result->live_in_) { + l1_sim_result->AddRegisterClass(insn); + } + for (Instruction* insn : l2_sim_result->live_in_) { + l2_sim_result->AddRegisterClass(insn); + } + + l1_sim_result->used_registers_ = 0; + l2_sim_result->used_registers_ = 0; + + for (uint32_t bb_id : loop.GetBlocks()) { + BasicBlock* bb = context_->cfg()->block(bb_id); + + const RegisterLiveness::RegionRegisterLiveness* live_inout = Get(bb_id); + assert(live_inout != nullptr && "Basic block not processed"); + auto l1_block_live_out = + MakeFilterIteratorRange(live_inout->live_out_.begin(), + live_inout->live_out_.end(), belong_to_loop1); + auto l2_block_live_out = + MakeFilterIteratorRange(live_inout->live_out_.begin(), + live_inout->live_out_.end(), belong_to_loop2); + + size_t l1_reg_count = + std::distance(l1_block_live_out.begin(), l1_block_live_out.end()); + size_t l2_reg_count = + std::distance(l2_block_live_out.begin(), l2_block_live_out.end()); + + std::unordered_set die_in_block; + for (Instruction& insn : make_range(bb->rbegin(), bb->rend())) { + if (insn.opcode() == spv::Op::OpPhi) { + break; + } + + bool does_belong_to_loop1 = belong_to_loop1(&insn); + bool does_belong_to_loop2 = belong_to_loop2(&insn); + insn.ForEachInId([live_inout, &die_in_block, &l1_reg_count, &l2_reg_count, + does_belong_to_loop1, does_belong_to_loop2, + this](uint32_t* id) { + Instruction* op_insn = context_->get_def_use_mgr()->GetDef(*id); + if (!CreatesRegisterUsage(op_insn) || + live_inout->live_out_.count(op_insn)) { + // already taken into account. + return; + } + if (!die_in_block.count(*id)) { + if (does_belong_to_loop1) { + l1_reg_count++; + } + if (does_belong_to_loop2) { + l2_reg_count++; + } + die_in_block.insert(*id); + } + }); + l1_sim_result->used_registers_ = + std::max(l1_sim_result->used_registers_, l1_reg_count); + l2_sim_result->used_registers_ = + std::max(l2_sim_result->used_registers_, l2_reg_count); + if (CreatesRegisterUsage(&insn)) { + if (does_belong_to_loop1) { + if (!l1_sim_result->live_in_.count(&insn)) { + l1_sim_result->AddRegisterClass(&insn); + } + l1_reg_count--; + } + if (does_belong_to_loop2) { + if (!l2_sim_result->live_in_.count(&insn)) { + l2_sim_result->AddRegisterClass(&insn); + } + l2_reg_count--; + } + } + } + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/register_pressure.h b/thirdparty/glslang/External/spirv-tools/source/opt/register_pressure.h new file mode 100644 index 000000000000..cb3d2e2703b1 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/register_pressure.h @@ -0,0 +1,196 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REGISTER_PRESSURE_H_ +#define SOURCE_OPT_REGISTER_PRESSURE_H_ + +#include +#include +#include +#include + +#include "source/opt/function.h" +#include "source/opt/types.h" + +namespace spvtools { +namespace opt { + +class IRContext; +class Loop; +class LoopDescriptor; + +// Handles the register pressure of a function for different regions (function, +// loop, basic block). It also contains some utilities to foresee the register +// pressure following code transformations. +class RegisterLiveness { + public: + // Classification of SSA registers. + struct RegisterClass { + analysis::Type* type_; + bool is_uniform_; + + bool operator==(const RegisterClass& rhs) const { + return std::tie(type_, is_uniform_) == + std::tie(rhs.type_, rhs.is_uniform_); + } + }; + + struct RegionRegisterLiveness { + using LiveSet = std::unordered_set; + using RegClassSetTy = std::vector>; + + // SSA register live when entering the basic block. + LiveSet live_in_; + // SSA register live when exiting the basic block. + LiveSet live_out_; + + // Maximum number of required registers. + size_t used_registers_; + // Break down of the number of required registers per class of register. + RegClassSetTy registers_classes_; + + void Clear() { + live_out_.clear(); + live_in_.clear(); + used_registers_ = 0; + registers_classes_.clear(); + } + + void AddRegisterClass(const RegisterClass& reg_class) { + auto it = std::find_if( + registers_classes_.begin(), registers_classes_.end(), + [®_class](const std::pair& class_count) { + return class_count.first == reg_class; + }); + if (it != registers_classes_.end()) { + it->second++; + } else { + registers_classes_.emplace_back(std::move(reg_class), + static_cast(1)); + } + } + + void AddRegisterClass(Instruction* insn); + }; + + RegisterLiveness(IRContext* context, Function* f) : context_(context) { + Analyze(f); + } + + // Returns liveness and register information for the basic block |bb|. If no + // entry exist for the basic block, the function returns null. + const RegionRegisterLiveness* Get(const BasicBlock* bb) const { + return Get(bb->id()); + } + + // Returns liveness and register information for the basic block id |bb_id|. + // If no entry exist for the basic block, the function returns null. + const RegionRegisterLiveness* Get(uint32_t bb_id) const { + RegionRegisterLivenessMap::const_iterator it = block_pressure_.find(bb_id); + if (it != block_pressure_.end()) { + return &it->second; + } + return nullptr; + } + + IRContext* GetContext() const { return context_; } + + // Returns liveness and register information for the basic block |bb|. If no + // entry exist for the basic block, the function returns null. + RegionRegisterLiveness* Get(const BasicBlock* bb) { return Get(bb->id()); } + + // Returns liveness and register information for the basic block id |bb_id|. + // If no entry exist for the basic block, the function returns null. + RegionRegisterLiveness* Get(uint32_t bb_id) { + RegionRegisterLivenessMap::iterator it = block_pressure_.find(bb_id); + if (it != block_pressure_.end()) { + return &it->second; + } + return nullptr; + } + + // Returns liveness and register information for the basic block id |bb_id| or + // create a new empty entry if no entry already existed. + RegionRegisterLiveness* GetOrInsert(uint32_t bb_id) { + return &block_pressure_[bb_id]; + } + + // Compute the register pressure for the |loop| and store the result into + // |reg_pressure|. The live-in set corresponds to the live-in set of the + // header block, the live-out set of the loop corresponds to the union of the + // live-in sets of each exit basic block. + void ComputeLoopRegisterPressure(const Loop& loop, + RegionRegisterLiveness* reg_pressure) const; + + // Estimate the register pressure for the |l1| and |l2| as if they were making + // one unique loop. The result is stored into |simulation_result|. + void SimulateFusion(const Loop& l1, const Loop& l2, + RegionRegisterLiveness* simulation_result) const; + + // Estimate the register pressure of |loop| after it has been fissioned + // according to |moved_instructions| and |copied_instructions|. The function + // assumes that the fission creates a new loop before |loop|, moves any + // instructions present inside |moved_instructions| and copies any + // instructions present inside |copied_instructions| into this new loop. + // The set |loop1_sim_result| store the simulation result of the loop with the + // moved instructions. The set |loop2_sim_result| store the simulation result + // of the loop with the removed instructions. + void SimulateFission( + const Loop& loop, + const std::unordered_set& moved_instructions, + const std::unordered_set& copied_instructions, + RegionRegisterLiveness* loop1_sim_result, + RegionRegisterLiveness* loop2_sim_result) const; + + private: + using RegionRegisterLivenessMap = + std::unordered_map; + + IRContext* context_; + RegionRegisterLivenessMap block_pressure_; + + void Analyze(Function* f); +}; + +// Handles the register pressure of a function for different regions (function, +// loop, basic block). It also contains some utilities to foresee the register +// pressure following code transformations. +class LivenessAnalysis { + using LivenessAnalysisMap = + std::unordered_map; + + public: + LivenessAnalysis(IRContext* context) : context_(context) {} + + // Computes the liveness analysis for the function |f| and cache the result. + // If the analysis was performed for this function, then the cached analysis + // is returned. + const RegisterLiveness* Get(Function* f) { + LivenessAnalysisMap::iterator it = analysis_cache_.find(f); + if (it != analysis_cache_.end()) { + return &it->second; + } + return &analysis_cache_.emplace(f, RegisterLiveness{context_, f}) + .first->second; + } + + private: + IRContext* context_; + LivenessAnalysisMap analysis_cache_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REGISTER_PRESSURE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/relax_float_ops_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/relax_float_ops_pass.cpp new file mode 100644 index 000000000000..df925a2519d6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/relax_float_ops_pass.cpp @@ -0,0 +1,180 @@ +// Copyright (c) 2019 The Khronos Group Inc. +// Copyright (c) 2019 Valve Corporation +// Copyright (c) 2019 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "relax_float_ops_pass.h" + +#include "source/opt/ir_builder.h" + +namespace spvtools { +namespace opt { + +bool RelaxFloatOpsPass::IsRelaxable(Instruction* inst) { + return target_ops_core_f_rslt_.count(inst->opcode()) != 0 || + target_ops_core_f_opnd_.count(inst->opcode()) != 0 || + sample_ops_.count(inst->opcode()) != 0 || + (inst->opcode() == spv::Op::OpExtInst && + inst->GetSingleWordInOperand(0) == + context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && + target_ops_450_.count(inst->GetSingleWordInOperand(1)) != 0); +} + +bool RelaxFloatOpsPass::IsFloat32(Instruction* inst) { + uint32_t ty_id; + if (target_ops_core_f_opnd_.count(inst->opcode()) != 0) { + uint32_t opnd_id = inst->GetSingleWordInOperand(0); + Instruction* opnd_inst = get_def_use_mgr()->GetDef(opnd_id); + ty_id = opnd_inst->type_id(); + } else { + ty_id = inst->type_id(); + if (ty_id == 0) return false; + } + return IsFloat(ty_id, 32); +} + +bool RelaxFloatOpsPass::IsRelaxed(uint32_t r_id) { + for (auto r_inst : get_decoration_mgr()->GetDecorationsFor(r_id, false)) + if (r_inst->opcode() == spv::Op::OpDecorate && + spv::Decoration(r_inst->GetSingleWordInOperand(1)) == + spv::Decoration::RelaxedPrecision) + return true; + return false; +} + +bool RelaxFloatOpsPass::ProcessInst(Instruction* r_inst) { + uint32_t r_id = r_inst->result_id(); + if (r_id == 0) return false; + if (!IsFloat32(r_inst)) return false; + if (IsRelaxed(r_id)) return false; + if (!IsRelaxable(r_inst)) return false; + get_decoration_mgr()->AddDecoration( + r_id, uint32_t(spv::Decoration::RelaxedPrecision)); + return true; +} + +bool RelaxFloatOpsPass::ProcessFunction(Function* func) { + bool modified = false; + cfg()->ForEachBlockInReversePostOrder( + func->entry().get(), [&modified, this](BasicBlock* bb) { + for (auto ii = bb->begin(); ii != bb->end(); ++ii) + modified |= ProcessInst(&*ii); + }); + return modified; +} + +Pass::Status RelaxFloatOpsPass::ProcessImpl() { + Pass::ProcessFunction pfn = [this](Function* fp) { + return ProcessFunction(fp); + }; + bool modified = context()->ProcessReachableCallTree(pfn); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +Pass::Status RelaxFloatOpsPass::Process() { + Initialize(); + return ProcessImpl(); +} + +void RelaxFloatOpsPass::Initialize() { + target_ops_core_f_rslt_ = { + spv::Op::OpLoad, + spv::Op::OpPhi, + spv::Op::OpVectorExtractDynamic, + spv::Op::OpVectorInsertDynamic, + spv::Op::OpVectorShuffle, + spv::Op::OpCompositeExtract, + spv::Op::OpCompositeConstruct, + spv::Op::OpCompositeInsert, + spv::Op::OpCopyObject, + spv::Op::OpTranspose, + spv::Op::OpConvertSToF, + spv::Op::OpConvertUToF, + spv::Op::OpFConvert, + // spv::Op::OpQuantizeToF16, + spv::Op::OpFNegate, + spv::Op::OpFAdd, + spv::Op::OpFSub, + spv::Op::OpFMul, + spv::Op::OpFDiv, + spv::Op::OpFMod, + spv::Op::OpVectorTimesScalar, + spv::Op::OpMatrixTimesScalar, + spv::Op::OpVectorTimesMatrix, + spv::Op::OpMatrixTimesVector, + spv::Op::OpMatrixTimesMatrix, + spv::Op::OpOuterProduct, + spv::Op::OpDot, + spv::Op::OpSelect, + }; + target_ops_core_f_opnd_ = { + spv::Op::OpFOrdEqual, + spv::Op::OpFUnordEqual, + spv::Op::OpFOrdNotEqual, + spv::Op::OpFUnordNotEqual, + spv::Op::OpFOrdLessThan, + spv::Op::OpFUnordLessThan, + spv::Op::OpFOrdGreaterThan, + spv::Op::OpFUnordGreaterThan, + spv::Op::OpFOrdLessThanEqual, + spv::Op::OpFUnordLessThanEqual, + spv::Op::OpFOrdGreaterThanEqual, + spv::Op::OpFUnordGreaterThanEqual, + }; + target_ops_450_ = { + GLSLstd450Round, GLSLstd450RoundEven, GLSLstd450Trunc, GLSLstd450FAbs, + GLSLstd450FSign, GLSLstd450Floor, GLSLstd450Ceil, GLSLstd450Fract, + GLSLstd450Radians, GLSLstd450Degrees, GLSLstd450Sin, GLSLstd450Cos, + GLSLstd450Tan, GLSLstd450Asin, GLSLstd450Acos, GLSLstd450Atan, + GLSLstd450Sinh, GLSLstd450Cosh, GLSLstd450Tanh, GLSLstd450Asinh, + GLSLstd450Acosh, GLSLstd450Atanh, GLSLstd450Atan2, GLSLstd450Pow, + GLSLstd450Exp, GLSLstd450Log, GLSLstd450Exp2, GLSLstd450Log2, + GLSLstd450Sqrt, GLSLstd450InverseSqrt, GLSLstd450Determinant, + GLSLstd450MatrixInverse, + // TODO(greg-lunarg): GLSLstd450ModfStruct, + GLSLstd450FMin, GLSLstd450FMax, GLSLstd450FClamp, GLSLstd450FMix, + GLSLstd450Step, GLSLstd450SmoothStep, GLSLstd450Fma, + // TODO(greg-lunarg): GLSLstd450FrexpStruct, + GLSLstd450Ldexp, GLSLstd450Length, GLSLstd450Distance, GLSLstd450Cross, + GLSLstd450Normalize, GLSLstd450FaceForward, GLSLstd450Reflect, + GLSLstd450Refract, GLSLstd450NMin, GLSLstd450NMax, GLSLstd450NClamp}; + sample_ops_ = {spv::Op::OpImageSampleImplicitLod, + spv::Op::OpImageSampleExplicitLod, + spv::Op::OpImageSampleDrefImplicitLod, + spv::Op::OpImageSampleDrefExplicitLod, + spv::Op::OpImageSampleProjImplicitLod, + spv::Op::OpImageSampleProjExplicitLod, + spv::Op::OpImageSampleProjDrefImplicitLod, + spv::Op::OpImageSampleProjDrefExplicitLod, + spv::Op::OpImageFetch, + spv::Op::OpImageGather, + spv::Op::OpImageDrefGather, + spv::Op::OpImageRead, + spv::Op::OpImageSparseSampleImplicitLod, + spv::Op::OpImageSparseSampleExplicitLod, + spv::Op::OpImageSparseSampleDrefImplicitLod, + spv::Op::OpImageSparseSampleDrefExplicitLod, + spv::Op::OpImageSparseSampleProjImplicitLod, + spv::Op::OpImageSparseSampleProjExplicitLod, + spv::Op::OpImageSparseSampleProjDrefImplicitLod, + spv::Op::OpImageSparseSampleProjDrefExplicitLod, + spv::Op::OpImageSparseFetch, + spv::Op::OpImageSparseGather, + spv::Op::OpImageSparseDrefGather, + spv::Op::OpImageSparseTexelsResident, + spv::Op::OpImageSparseRead}; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/relax_float_ops_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/relax_float_ops_pass.h new file mode 100644 index 000000000000..9e4606f8db3f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/relax_float_ops_pass.h @@ -0,0 +1,86 @@ +// Copyright (c) 2019 Valve Corporation +// Copyright (c) 2019 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBSPIRV_OPT_RELAX_FLOAT_OPS_PASS_H_ +#define LIBSPIRV_OPT_RELAX_FLOAT_OPS_PASS_H_ + +#include "source/opt/ir_builder.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +class RelaxFloatOpsPass : public Pass { + public: + RelaxFloatOpsPass() : Pass() {} + + ~RelaxFloatOpsPass() override = default; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping; + } + + // See optimizer.hpp for pass user documentation. + Status Process() override; + + const char* name() const override { return "convert-to-half-pass"; } + + private: + // Return true if |inst| can have the RelaxedPrecision decoration applied + // to it. + bool IsRelaxable(Instruction* inst); + + // Return true if |inst| returns scalar, vector or matrix type with base + // float and width 32 + bool IsFloat32(Instruction* inst); + + // Return true if |r_id| is decorated with RelaxedPrecision + bool IsRelaxed(uint32_t r_id); + + // If |inst| is an instruction of float32-based type and is not decorated + // RelaxedPrecision, add such a decoration to the module. + bool ProcessInst(Instruction* inst); + + // Call ProcessInst on every instruction in |func|. + bool ProcessFunction(Function* func); + + Pass::Status ProcessImpl(); + + // Initialize state for converting to half + void Initialize(); + + struct hasher { + size_t operator()(const spv::Op& op) const noexcept { + return std::hash()(uint32_t(op)); + } + }; + + // Set of float result core operations to be processed + std::unordered_set target_ops_core_f_rslt_; + + // Set of float operand core operations to be processed + std::unordered_set target_ops_core_f_opnd_; + + // Set of 450 extension operations to be processed + std::unordered_set target_ops_450_; + + // Set of sample operations + std::unordered_set sample_ops_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // LIBSPIRV_OPT_RELAX_FLOAT_OPS_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/remove_dontinline_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/remove_dontinline_pass.cpp new file mode 100644 index 000000000000..3750bc1fe130 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/remove_dontinline_pass.cpp @@ -0,0 +1,50 @@ +// Copyright (c) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/remove_dontinline_pass.h" + +namespace spvtools { +namespace opt { + +Pass::Status RemoveDontInline::Process() { + bool modified = false; + modified = ClearDontInlineFunctionControl(); + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool RemoveDontInline::ClearDontInlineFunctionControl() { + bool modified = false; + for (auto& func : *get_module()) { + ClearDontInlineFunctionControl(&func); + } + return modified; +} + +bool RemoveDontInline::ClearDontInlineFunctionControl(Function* function) { + constexpr uint32_t kFunctionControlInOperandIdx = 0; + Instruction* function_inst = &function->DefInst(); + uint32_t function_control = + function_inst->GetSingleWordInOperand(kFunctionControlInOperandIdx); + + if ((function_control & uint32_t(spv::FunctionControlMask::DontInline)) == + 0) { + return false; + } + function_control &= ~uint32_t(spv::FunctionControlMask::DontInline); + function_inst->SetInOperand(kFunctionControlInOperandIdx, {function_control}); + return true; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/remove_dontinline_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/remove_dontinline_pass.h new file mode 100644 index 000000000000..162431991b64 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/remove_dontinline_pass.h @@ -0,0 +1,42 @@ +// Copyright (c) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REMOVE_DONTINLINE_PASS_H_ +#define SOURCE_OPT_REMOVE_DONTINLINE_PASS_H_ + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class RemoveDontInline : public Pass { + public: + const char* name() const override { return "remove-dont-inline"; } + Status Process() override; + + private: + // Clears the DontInline function control from every function in the module. + // Returns true of a change was made. + bool ClearDontInlineFunctionControl(); + + // Clears the DontInline function control from |function|. + // Returns true of a change was made. + bool ClearDontInlineFunctionControl(Function* function); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REMOVE_DONTINLINE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/remove_duplicates_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/remove_duplicates_pass.cpp new file mode 100644 index 000000000000..0df559b345ef --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/remove_duplicates_pass.cpp @@ -0,0 +1,210 @@ +// Copyright (c) 2017 Pierre Moreau +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/remove_duplicates_pass.h" + +#include +#include +#include +#include +#include + +#include "source/opcode.h" +#include "source/opt/decoration_manager.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +Pass::Status RemoveDuplicatesPass::Process() { + bool modified = RemoveDuplicateCapabilities(); + modified |= RemoveDuplicatesExtInstImports(); + modified |= RemoveDuplicateTypes(); + modified |= RemoveDuplicateDecorations(); + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +bool RemoveDuplicatesPass::RemoveDuplicateCapabilities() const { + bool modified = false; + + if (context()->capabilities().empty()) { + return modified; + } + + std::unordered_set capabilities; + for (auto* i = &*context()->capability_begin(); i;) { + auto res = capabilities.insert(i->GetSingleWordOperand(0u)); + + if (res.second) { + // Never seen before, keep it. + i = i->NextNode(); + } else { + // It's a duplicate, remove it. + i = context()->KillInst(i); + modified = true; + } + } + + return modified; +} + +bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports() const { + bool modified = false; + + if (context()->ext_inst_imports().empty()) { + return modified; + } + + std::unordered_map ext_inst_imports; + for (auto* i = &*context()->ext_inst_import_begin(); i;) { + auto res = ext_inst_imports.emplace(i->GetInOperand(0u).AsString(), + i->result_id()); + if (res.second) { + // Never seen before, keep it. + i = i->NextNode(); + } else { + // It's a duplicate, remove it. + context()->ReplaceAllUsesWith(i->result_id(), res.first->second); + i = context()->KillInst(i); + modified = true; + } + } + + return modified; +} + +bool RemoveDuplicatesPass::RemoveDuplicateTypes() const { + bool modified = false; + + if (context()->types_values().empty()) { + return modified; + } + + analysis::TypeManager type_manager(context()->consumer(), context()); + + std::vector visited_types; + std::vector visited_forward_pointers; + std::vector to_delete; + for (auto* i = &*context()->types_values_begin(); i; i = i->NextNode()) { + const bool is_i_forward_pointer = + i->opcode() == spv::Op::OpTypeForwardPointer; + + // We only care about types. + if (!spvOpcodeGeneratesType(i->opcode()) && !is_i_forward_pointer) { + continue; + } + + if (!is_i_forward_pointer) { + // Is the current type equal to one of the types we have already visited? + spv::Id id_to_keep = 0u; + analysis::Type* i_type = type_manager.GetType(i->result_id()); + assert(i_type); + // TODO(dneto0): Use a trie to avoid quadratic behaviour? Extract the + // ResultIdTrie from unify_const_pass.cpp for this. + for (auto j : visited_types) { + analysis::Type* j_type = type_manager.GetType(j->result_id()); + assert(j_type); + if (*i_type == *j_type) { + id_to_keep = j->result_id(); + break; + } + } + + if (id_to_keep == 0u) { + // This is a never seen before type, keep it around. + visited_types.emplace_back(i); + } else { + // The same type has already been seen before, remove this one. + context()->KillNamesAndDecorates(i->result_id()); + context()->ReplaceAllUsesWith(i->result_id(), id_to_keep); + modified = true; + to_delete.emplace_back(i); + } + } else { + analysis::ForwardPointer i_type( + i->GetSingleWordInOperand(0u), + (spv::StorageClass)i->GetSingleWordInOperand(1u)); + i_type.SetTargetPointer( + type_manager.GetType(i_type.target_id())->AsPointer()); + + // TODO(dneto0): Use a trie to avoid quadratic behaviour? Extract the + // ResultIdTrie from unify_const_pass.cpp for this. + const bool found_a_match = + std::find(std::begin(visited_forward_pointers), + std::end(visited_forward_pointers), + i_type) != std::end(visited_forward_pointers); + + if (!found_a_match) { + // This is a never seen before type, keep it around. + visited_forward_pointers.emplace_back(i_type); + } else { + // The same type has already been seen before, remove this one. + modified = true; + to_delete.emplace_back(i); + } + } + } + + for (auto i : to_delete) { + context()->KillInst(i); + } + + return modified; +} + +// TODO(pierremoreau): Duplicate decoration groups should be removed. For +// example, in +// OpDecorate %1 Constant +// %1 = OpDecorationGroup +// OpDecorate %2 Constant +// %2 = OpDecorationGroup +// OpGroupDecorate %1 %3 +// OpGroupDecorate %2 %4 +// group %2 could be removed. +bool RemoveDuplicatesPass::RemoveDuplicateDecorations() const { + bool modified = false; + + std::vector visited_decorations; + + analysis::DecorationManager decoration_manager(context()->module()); + for (auto* i = &*context()->annotation_begin(); i;) { + // Is the current decoration equal to one of the decorations we have + // already visited? + bool already_visited = false; + // TODO(dneto0): Use a trie to avoid quadratic behaviour? Extract the + // ResultIdTrie from unify_const_pass.cpp for this. + for (const Instruction* j : visited_decorations) { + if (decoration_manager.AreDecorationsTheSame(&*i, j, false)) { + already_visited = true; + break; + } + } + + if (!already_visited) { + // This is a never seen before decoration, keep it around. + visited_decorations.emplace_back(&*i); + i = i->NextNode(); + } else { + // The same decoration has already been seen before, remove this one. + modified = true; + i = context()->KillInst(i); + } + } + + return modified; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/remove_duplicates_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/remove_duplicates_pass.h new file mode 100644 index 000000000000..038caa8b9f24 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/remove_duplicates_pass.h @@ -0,0 +1,61 @@ +// Copyright (c) 2017 Pierre Moreau +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REMOVE_DUPLICATES_PASS_H_ +#define SOURCE_OPT_REMOVE_DUPLICATES_PASS_H_ + +#include +#include + +#include "source/opt/decoration_manager.h" +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +using IdDecorationsList = + std::unordered_map>; + +// See optimizer.hpp for documentation. +class RemoveDuplicatesPass : public Pass { + public: + const char* name() const override { return "remove-duplicates"; } + Status Process() override; + + private: + // Remove duplicate capabilities from the module + // + // Returns true if the module was modified, false otherwise. + bool RemoveDuplicateCapabilities() const; + // Remove duplicate extended instruction imports from the module + // + // Returns true if the module was modified, false otherwise. + bool RemoveDuplicatesExtInstImports() const; + // Remove duplicate types from the module + // + // Returns true if the module was modified, false otherwise. + bool RemoveDuplicateTypes() const; + // Remove duplicate decorations from the module + // + // Returns true if the module was modified, false otherwise. + bool RemoveDuplicateDecorations() const; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REMOVE_DUPLICATES_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/remove_unused_interface_variables_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/remove_unused_interface_variables_pass.cpp new file mode 100644 index 000000000000..d4df1b2efd9b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/remove_unused_interface_variables_pass.cpp @@ -0,0 +1,94 @@ +// Copyright (c) 2021 ZHOU He +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "remove_unused_interface_variables_pass.h" +#include "source/spirv_constant.h" +namespace spvtools { +namespace opt { + +class RemoveUnusedInterfaceVariablesContext { + RemoveUnusedInterfaceVariablesPass& parent_; + Instruction& entry_; + std::unordered_set used_variables_; + IRContext::ProcessFunction pfn_ = + std::bind(&RemoveUnusedInterfaceVariablesContext::processFunction, this, + std::placeholders::_1); + + bool processFunction(Function* func) { + for (const auto& basic_block : *func) + for (const auto& instruction : basic_block) + instruction.ForEachInId([&](const uint32_t* id) { + if (used_variables_.count(*id)) return; + auto* var = parent_.get_def_use_mgr()->GetDef(*id); + if (!var || var->opcode() != spv::Op::OpVariable) return; + auto storage_class = + spv::StorageClass(var->GetSingleWordInOperand(0)); + if (storage_class != spv::StorageClass::Function && + (parent_.get_module()->version() >= + SPV_SPIRV_VERSION_WORD(1, 4) || + storage_class == spv::StorageClass::Input || + storage_class == spv::StorageClass::Output)) + used_variables_.insert(*id); + }); + return false; + } + + public: + RemoveUnusedInterfaceVariablesContext( + RemoveUnusedInterfaceVariablesPass& parent, Instruction& entry) + : parent_(parent), entry_(entry) {} + + void CollectUsedVariables() { + std::queue roots; + roots.push(entry_.GetSingleWordInOperand(1)); + parent_.context()->ProcessCallTreeFromRoots(pfn_, &roots); + } + + bool ShouldModify() { + std::unordered_set old_variables; + for (int i = entry_.NumInOperands() - 1; i >= 3; --i) { + auto variable = entry_.GetInOperand(i).words[0]; + if (!used_variables_.count(variable)) return true; // It is unused. + if (old_variables.count(variable)) return true; // It is duplicate. + old_variables.insert(variable); + } + if (old_variables.size() != used_variables_.size()) // Missing IDs. + return true; + return false; + } + + void Modify() { + for (int i = entry_.NumInOperands() - 1; i >= 3; --i) + entry_.RemoveInOperand(i); + for (auto id : used_variables_) { + entry_.AddOperand(Operand(SPV_OPERAND_TYPE_ID, {id})); + } + } +}; + +RemoveUnusedInterfaceVariablesPass::Status +RemoveUnusedInterfaceVariablesPass::Process() { + bool modified = false; + for (auto& entry : get_module()->entry_points()) { + RemoveUnusedInterfaceVariablesContext context(*this, entry); + context.CollectUsedVariables(); + if (context.ShouldModify()) { + context.Modify(); + modified = true; + } + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/remove_unused_interface_variables_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/remove_unused_interface_variables_pass.h new file mode 100644 index 000000000000..a4cb1085abdc --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/remove_unused_interface_variables_pass.h @@ -0,0 +1,31 @@ +// Copyright (c) 2021 ZHOU He +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REMOVE_UNUSED_INTERFACE_VARIABLES_PASS_H_ +#define SOURCE_OPT_REMOVE_UNUSED_INTERFACE_VARIABLES_PASS_H_ + +#include "source/opt/pass.h" +namespace spvtools { +namespace opt { + +class RemoveUnusedInterfaceVariablesPass : public Pass { + const char* name() const override { + return "remove-unused-interface-variables-pass"; + } + Status Process() override; +}; +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REMOVE_UNUSED_INTERFACE_VARIABLES_PASS_H_ \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/replace_desc_array_access_using_var_index.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/replace_desc_array_access_using_var_index.cpp new file mode 100644 index 000000000000..59745e12deef --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/replace_desc_array_access_using_var_index.cpp @@ -0,0 +1,428 @@ +// Copyright (c) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/replace_desc_array_access_using_var_index.h" + +#include "source/opt/desc_sroa_util.h" +#include "source/opt/ir_builder.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kOpAccessChainInOperandIndexes = 1; +constexpr uint32_t kOpTypePointerInOperandType = 1; +constexpr uint32_t kOpTypeArrayInOperandType = 0; +constexpr uint32_t kOpTypeStructInOperandMember = 0; +IRContext::Analysis kAnalysisDefUseAndInstrToBlockMapping = + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping; + +uint32_t GetValueWithKeyExistenceCheck( + uint32_t key, const std::unordered_map& map) { + auto itr = map.find(key); + assert(itr != map.end() && "Key does not exist"); + return itr->second; +} + +} // namespace + +Pass::Status ReplaceDescArrayAccessUsingVarIndex::Process() { + Status status = Status::SuccessWithoutChange; + for (Instruction& var : context()->types_values()) { + if (descsroautil::IsDescriptorArray(context(), &var)) { + if (ReplaceVariableAccessesWithConstantElements(&var)) + status = Status::SuccessWithChange; + } + } + return status; +} + +bool ReplaceDescArrayAccessUsingVarIndex:: + ReplaceVariableAccessesWithConstantElements(Instruction* var) const { + std::vector work_list; + get_def_use_mgr()->ForEachUser(var, [&work_list](Instruction* use) { + switch (use->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + work_list.push_back(use); + break; + default: + break; + } + }); + + bool updated = false; + for (Instruction* access_chain : work_list) { + if (descsroautil::GetAccessChainIndexAsConst(context(), access_chain) == + nullptr) { + ReplaceAccessChain(var, access_chain); + updated = true; + } + } + // Note that we do not consider OpLoad and OpCompositeExtract because + // OpCompositeExtract always has constant literals for indices. + return updated; +} + +void ReplaceDescArrayAccessUsingVarIndex::ReplaceAccessChain( + Instruction* var, Instruction* access_chain) const { + uint32_t number_of_elements = + descsroautil::GetNumberOfElementsForArrayOrStruct(context(), var); + assert(number_of_elements != 0 && "Number of element is 0"); + if (number_of_elements == 1) { + UseConstIndexForAccessChain(access_chain, 0); + get_def_use_mgr()->AnalyzeInstUse(access_chain); + return; + } + ReplaceUsersOfAccessChain(access_chain, number_of_elements); +} + +void ReplaceDescArrayAccessUsingVarIndex::ReplaceUsersOfAccessChain( + Instruction* access_chain, uint32_t number_of_elements) const { + std::vector final_users; + CollectRecursiveUsersWithConcreteType(access_chain, &final_users); + for (auto* inst : final_users) { + std::deque insts_to_be_cloned = + CollectRequiredImageAndAccessInsts(inst); + ReplaceNonUniformAccessWithSwitchCase( + inst, access_chain, number_of_elements, insts_to_be_cloned); + } +} + +void ReplaceDescArrayAccessUsingVarIndex::CollectRecursiveUsersWithConcreteType( + Instruction* access_chain, std::vector* final_users) const { + std::queue work_list; + work_list.push(access_chain); + while (!work_list.empty()) { + auto* inst_from_work_list = work_list.front(); + work_list.pop(); + get_def_use_mgr()->ForEachUser( + inst_from_work_list, [this, final_users, &work_list](Instruction* use) { + // TODO: Support Boolean type as well. + if (!use->HasResultId() || IsConcreteType(use->type_id())) { + final_users->push_back(use); + } else { + work_list.push(use); + } + }); + } +} + +std::deque +ReplaceDescArrayAccessUsingVarIndex::CollectRequiredImageAndAccessInsts( + Instruction* user) const { + std::unordered_set seen_inst_ids; + std::queue work_list; + + auto decision_to_include_operand = [this, &seen_inst_ids, + &work_list](uint32_t* idp) { + if (!seen_inst_ids.insert(*idp).second) return; + Instruction* operand = get_def_use_mgr()->GetDef(*idp); + if (context()->get_instr_block(operand) != nullptr && + (HasImageOrImagePtrType(operand) || + operand->opcode() == spv::Op::OpAccessChain || + operand->opcode() == spv::Op::OpInBoundsAccessChain)) { + work_list.push(operand); + } + }; + + std::deque required_insts; + required_insts.push_front(user); + user->ForEachInId(decision_to_include_operand); + while (!work_list.empty()) { + auto* inst_from_work_list = work_list.front(); + work_list.pop(); + required_insts.push_front(inst_from_work_list); + inst_from_work_list->ForEachInId(decision_to_include_operand); + } + return required_insts; +} + +bool ReplaceDescArrayAccessUsingVarIndex::HasImageOrImagePtrType( + const Instruction* inst) const { + assert(inst != nullptr && inst->type_id() != 0 && "Invalid instruction"); + return IsImageOrImagePtrType(get_def_use_mgr()->GetDef(inst->type_id())); +} + +bool ReplaceDescArrayAccessUsingVarIndex::IsImageOrImagePtrType( + const Instruction* type_inst) const { + if (type_inst->opcode() == spv::Op::OpTypeImage || + type_inst->opcode() == spv::Op::OpTypeSampler || + type_inst->opcode() == spv::Op::OpTypeSampledImage) { + return true; + } + if (type_inst->opcode() == spv::Op::OpTypePointer) { + Instruction* pointee_type_inst = get_def_use_mgr()->GetDef( + type_inst->GetSingleWordInOperand(kOpTypePointerInOperandType)); + return IsImageOrImagePtrType(pointee_type_inst); + } + if (type_inst->opcode() == spv::Op::OpTypeArray) { + Instruction* element_type_inst = get_def_use_mgr()->GetDef( + type_inst->GetSingleWordInOperand(kOpTypeArrayInOperandType)); + return IsImageOrImagePtrType(element_type_inst); + } + if (type_inst->opcode() != spv::Op::OpTypeStruct) return false; + for (uint32_t in_operand_idx = kOpTypeStructInOperandMember; + in_operand_idx < type_inst->NumInOperands(); ++in_operand_idx) { + Instruction* member_type_inst = get_def_use_mgr()->GetDef( + type_inst->GetSingleWordInOperand(kOpTypeStructInOperandMember)); + if (IsImageOrImagePtrType(member_type_inst)) return true; + } + return false; +} + +bool ReplaceDescArrayAccessUsingVarIndex::IsConcreteType( + uint32_t type_id) const { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + if (type_inst->opcode() == spv::Op::OpTypeInt || + type_inst->opcode() == spv::Op::OpTypeFloat) { + return true; + } + if (type_inst->opcode() == spv::Op::OpTypeVector || + type_inst->opcode() == spv::Op::OpTypeMatrix || + type_inst->opcode() == spv::Op::OpTypeArray) { + return IsConcreteType(type_inst->GetSingleWordInOperand(0)); + } + if (type_inst->opcode() == spv::Op::OpTypeStruct) { + for (uint32_t i = 0; i < type_inst->NumInOperands(); ++i) { + if (!IsConcreteType(type_inst->GetSingleWordInOperand(i))) return false; + } + return true; + } + return false; +} + +BasicBlock* ReplaceDescArrayAccessUsingVarIndex::CreateCaseBlock( + Instruction* access_chain, uint32_t element_index, + const std::deque& insts_to_be_cloned, + uint32_t branch_target_id, + std::unordered_map* old_ids_to_new_ids) const { + auto* case_block = CreateNewBlock(); + AddConstElementAccessToCaseBlock(case_block, access_chain, element_index, + old_ids_to_new_ids); + CloneInstsToBlock(case_block, access_chain, insts_to_be_cloned, + old_ids_to_new_ids); + AddBranchToBlock(case_block, branch_target_id); + UseNewIdsInBlock(case_block, *old_ids_to_new_ids); + return case_block; +} + +void ReplaceDescArrayAccessUsingVarIndex::CloneInstsToBlock( + BasicBlock* block, Instruction* inst_to_skip_cloning, + const std::deque& insts_to_be_cloned, + std::unordered_map* old_ids_to_new_ids) const { + for (auto* inst_to_be_cloned : insts_to_be_cloned) { + if (inst_to_be_cloned == inst_to_skip_cloning) continue; + std::unique_ptr clone(inst_to_be_cloned->Clone(context())); + if (inst_to_be_cloned->HasResultId()) { + uint32_t new_id = context()->TakeNextId(); + clone->SetResultId(new_id); + (*old_ids_to_new_ids)[inst_to_be_cloned->result_id()] = new_id; + } + get_def_use_mgr()->AnalyzeInstDefUse(clone.get()); + context()->set_instr_block(clone.get(), block); + block->AddInstruction(std::move(clone)); + } +} + +void ReplaceDescArrayAccessUsingVarIndex::UseNewIdsInBlock( + BasicBlock* block, + const std::unordered_map& old_ids_to_new_ids) const { + for (auto block_itr = block->begin(); block_itr != block->end(); + ++block_itr) { + (&*block_itr)->ForEachInId([&old_ids_to_new_ids](uint32_t* idp) { + auto old_ids_to_new_ids_itr = old_ids_to_new_ids.find(*idp); + if (old_ids_to_new_ids_itr == old_ids_to_new_ids.end()) return; + *idp = old_ids_to_new_ids_itr->second; + }); + get_def_use_mgr()->AnalyzeInstUse(&*block_itr); + } +} + +void ReplaceDescArrayAccessUsingVarIndex::ReplaceNonUniformAccessWithSwitchCase( + Instruction* access_chain_final_user, Instruction* access_chain, + uint32_t number_of_elements, + const std::deque& insts_to_be_cloned) const { + auto* block = context()->get_instr_block(access_chain_final_user); + // If the instruction does not belong to a block (i.e. in the case of + // OpDecorate), no replacement is needed. + if (!block) return; + + // Create merge block and add terminator + auto* merge_block = SeparateInstructionsIntoNewBlock( + block, access_chain_final_user->NextNode()); + + auto* function = block->GetParent(); + + // Add case blocks + std::vector phi_operands; + std::vector case_block_ids; + for (uint32_t idx = 0; idx < number_of_elements; ++idx) { + std::unordered_map old_ids_to_new_ids_for_cloned_insts; + std::unique_ptr case_block(CreateCaseBlock( + access_chain, idx, insts_to_be_cloned, merge_block->id(), + &old_ids_to_new_ids_for_cloned_insts)); + case_block_ids.push_back(case_block->id()); + function->InsertBasicBlockBefore(std::move(case_block), merge_block); + + // Keep the operand for OpPhi + if (!access_chain_final_user->HasResultId()) continue; + uint32_t phi_operand = + GetValueWithKeyExistenceCheck(access_chain_final_user->result_id(), + old_ids_to_new_ids_for_cloned_insts); + phi_operands.push_back(phi_operand); + } + + // Create default block + std::unique_ptr default_block( + CreateDefaultBlock(access_chain_final_user->HasResultId(), &phi_operands, + merge_block->id())); + uint32_t default_block_id = default_block->id(); + function->InsertBasicBlockBefore(std::move(default_block), merge_block); + + // Create OpSwitch + uint32_t access_chain_index_var_id = + descsroautil::GetFirstIndexOfAccessChain(access_chain); + AddSwitchForAccessChain(block, access_chain_index_var_id, default_block_id, + merge_block->id(), case_block_ids); + + // Create phi instructions + if (!phi_operands.empty()) { + uint32_t phi_id = CreatePhiInstruction(merge_block, phi_operands, + case_block_ids, default_block_id); + context()->ReplaceAllUsesWith(access_chain_final_user->result_id(), phi_id); + } + + // Replace OpPhi incoming block operand that uses |block| with |merge_block| + ReplacePhiIncomingBlock(block->id(), merge_block->id()); +} + +BasicBlock* +ReplaceDescArrayAccessUsingVarIndex::SeparateInstructionsIntoNewBlock( + BasicBlock* block, Instruction* separation_begin_inst) const { + auto separation_begin = block->begin(); + while (separation_begin != block->end() && + &*separation_begin != separation_begin_inst) { + ++separation_begin; + } + return block->SplitBasicBlock(context(), context()->TakeNextId(), + separation_begin); +} + +BasicBlock* ReplaceDescArrayAccessUsingVarIndex::CreateNewBlock() const { + auto* new_block = new BasicBlock(std::unique_ptr(new Instruction( + context(), spv::Op::OpLabel, 0, context()->TakeNextId(), {}))); + get_def_use_mgr()->AnalyzeInstDefUse(new_block->GetLabelInst()); + context()->set_instr_block(new_block->GetLabelInst(), new_block); + return new_block; +} + +void ReplaceDescArrayAccessUsingVarIndex::UseConstIndexForAccessChain( + Instruction* access_chain, uint32_t const_element_idx) const { + uint32_t const_element_idx_id = + context()->get_constant_mgr()->GetUIntConstId(const_element_idx); + access_chain->SetInOperand(kOpAccessChainInOperandIndexes, + {const_element_idx_id}); +} + +void ReplaceDescArrayAccessUsingVarIndex::AddConstElementAccessToCaseBlock( + BasicBlock* case_block, Instruction* access_chain, + uint32_t const_element_idx, + std::unordered_map* old_ids_to_new_ids) const { + std::unique_ptr access_clone(access_chain->Clone(context())); + UseConstIndexForAccessChain(access_clone.get(), const_element_idx); + + uint32_t new_access_id = context()->TakeNextId(); + (*old_ids_to_new_ids)[access_clone->result_id()] = new_access_id; + access_clone->SetResultId(new_access_id); + get_def_use_mgr()->AnalyzeInstDefUse(access_clone.get()); + + context()->set_instr_block(access_clone.get(), case_block); + case_block->AddInstruction(std::move(access_clone)); +} + +void ReplaceDescArrayAccessUsingVarIndex::AddBranchToBlock( + BasicBlock* parent_block, uint32_t branch_destination) const { + InstructionBuilder builder{context(), parent_block, + kAnalysisDefUseAndInstrToBlockMapping}; + builder.AddBranch(branch_destination); +} + +BasicBlock* ReplaceDescArrayAccessUsingVarIndex::CreateDefaultBlock( + bool null_const_for_phi_is_needed, std::vector* phi_operands, + uint32_t merge_block_id) const { + auto* default_block = CreateNewBlock(); + AddBranchToBlock(default_block, merge_block_id); + if (!null_const_for_phi_is_needed) return default_block; + + // Create null value for OpPhi + Instruction* inst = context()->get_def_use_mgr()->GetDef((*phi_operands)[0]); + auto* null_const_inst = GetConstNull(inst->type_id()); + phi_operands->push_back(null_const_inst->result_id()); + return default_block; +} + +Instruction* ReplaceDescArrayAccessUsingVarIndex::GetConstNull( + uint32_t type_id) const { + assert(type_id != 0 && "Result type is expected"); + auto* type = context()->get_type_mgr()->GetType(type_id); + auto* null_const = context()->get_constant_mgr()->GetConstant(type, {}); + return context()->get_constant_mgr()->GetDefiningInstruction(null_const); +} + +void ReplaceDescArrayAccessUsingVarIndex::AddSwitchForAccessChain( + BasicBlock* parent_block, uint32_t access_chain_index_var_id, + uint32_t default_id, uint32_t merge_id, + const std::vector& case_block_ids) const { + InstructionBuilder builder{context(), parent_block, + kAnalysisDefUseAndInstrToBlockMapping}; + std::vector> cases; + for (uint32_t i = 0; i < static_cast(case_block_ids.size()); ++i) { + cases.emplace_back(Operand::OperandData{i}, case_block_ids[i]); + } + builder.AddSwitch(access_chain_index_var_id, default_id, cases, merge_id); +} + +uint32_t ReplaceDescArrayAccessUsingVarIndex::CreatePhiInstruction( + BasicBlock* parent_block, const std::vector& phi_operands, + const std::vector& case_block_ids, + uint32_t default_block_id) const { + std::vector incomings; + assert(case_block_ids.size() + 1 == phi_operands.size() && + "Number of Phi operands must be exactly 1 bigger than the one of case " + "blocks"); + for (size_t i = 0; i < case_block_ids.size(); ++i) { + incomings.push_back(phi_operands[i]); + incomings.push_back(case_block_ids[i]); + } + incomings.push_back(phi_operands.back()); + incomings.push_back(default_block_id); + + InstructionBuilder builder{context(), &*parent_block->begin(), + kAnalysisDefUseAndInstrToBlockMapping}; + uint32_t phi_result_type_id = + context()->get_def_use_mgr()->GetDef(phi_operands[0])->type_id(); + auto* phi = builder.AddPhi(phi_result_type_id, incomings); + return phi->result_id(); +} + +void ReplaceDescArrayAccessUsingVarIndex::ReplacePhiIncomingBlock( + uint32_t old_incoming_block_id, uint32_t new_incoming_block_id) const { + context()->ReplaceAllUsesWithPredicate( + old_incoming_block_id, new_incoming_block_id, + [](Instruction* use) { return use->opcode() == spv::Op::OpPhi; }); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/replace_desc_array_access_using_var_index.h b/thirdparty/glslang/External/spirv-tools/source/opt/replace_desc_array_access_using_var_index.h new file mode 100644 index 000000000000..51817c15f77e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/replace_desc_array_access_using_var_index.h @@ -0,0 +1,205 @@ +// Copyright (c) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REPLACE_DESC_VAR_INDEX_ACCESS_H_ +#define SOURCE_OPT_REPLACE_DESC_VAR_INDEX_ACCESS_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/function.h" +#include "source/opt/pass.h" +#include "source/opt/type_manager.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class ReplaceDescArrayAccessUsingVarIndex : public Pass { + public: + ReplaceDescArrayAccessUsingVarIndex() {} + + const char* name() const override { + return "replace-desc-array-access-using-var-index"; + } + + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Replaces all accesses to |var| using variable indices with constant + // elements of the array |var|. Creates switch-case statements to determine + // the value of the variable index for all the possible cases. Returns + // whether replacement is done or not. + bool ReplaceVariableAccessesWithConstantElements(Instruction* var) const; + + // Replaces the OpAccessChain or OpInBoundsAccessChain instruction |use| that + // uses the descriptor variable |var| with the OpAccessChain or + // OpInBoundsAccessChain instruction with a constant Indexes operand. + void ReplaceAccessChain(Instruction* var, Instruction* use) const; + + // Updates the first Indexes operand of the OpAccessChain or + // OpInBoundsAccessChain instruction |access_chain| to let it use a constant + // index |const_element_idx|. + void UseConstIndexForAccessChain(Instruction* access_chain, + uint32_t const_element_idx) const; + + // Replaces users of the OpAccessChain or OpInBoundsAccessChain instruction + // |access_chain| that accesses an array descriptor variable using variable + // indices with constant elements. |number_of_elements| is the number + // of array elements. + void ReplaceUsersOfAccessChain(Instruction* access_chain, + uint32_t number_of_elements) const; + + // Puts all the recursive users of |access_chain| with concrete result types + // or the ones without result it in |final_users|. + void CollectRecursiveUsersWithConcreteType( + Instruction* access_chain, std::vector* final_users) const; + + // Recursively collects the operands of |user| (and operands of the operands) + // whose result types are images/samplers (or pointers/arrays/ structs of + // them) and access chains instructions and returns them. The returned + // collection includes |user|. + std::deque CollectRequiredImageAndAccessInsts( + Instruction* user) const; + + // Returns whether result type of |inst| is an image/sampler/pointer of image + // or sampler or not. + bool HasImageOrImagePtrType(const Instruction* inst) const; + + // Returns whether |type_inst| is an image/sampler or pointer/array/struct of + // image or sampler or not. + bool IsImageOrImagePtrType(const Instruction* type_inst) const; + + // Returns whether the type with |type_id| is a concrete type or not. + bool IsConcreteType(uint32_t type_id) const; + + // Replaces the non-uniform access to a descriptor variable + // |access_chain_final_user| with OpSwitch instruction and case blocks. Each + // case block will contain a clone of |access_chain| and clones of + // |non_uniform_accesses_to_clone| that are recursively used by + // |access_chain_final_user|. The clone of |access_chain| (or + // OpInBoundsAccessChain) will have a constant index for its first index. The + // OpSwitch instruction will have the cases for the variable index of + // |access_chain| from 0 to |number_of_elements| - 1. + void ReplaceNonUniformAccessWithSwitchCase( + Instruction* access_chain_final_user, Instruction* access_chain, + uint32_t number_of_elements, + const std::deque& non_uniform_accesses_to_clone) const; + + // Creates and returns a new basic block that contains all instructions of + // |block| after |separation_begin_inst|. The new basic block is added to the + // function in this method. + BasicBlock* SeparateInstructionsIntoNewBlock( + BasicBlock* block, Instruction* separation_begin_inst) const; + + // Creates and returns a new block. + BasicBlock* CreateNewBlock() const; + + // Returns the first operand id of the OpAccessChain or OpInBoundsAccessChain + // instruction |access_chain|. + uint32_t GetFirstIndexOfAccessChain(Instruction* access_chain) const; + + // Adds a clone of the OpAccessChain or OpInBoundsAccessChain instruction + // |access_chain| to |case_block|. The clone of |access_chain| will use + // |const_element_idx| for its first index. |old_ids_to_new_ids| keeps the + // mapping from the result id of |access_chain| to the result of its clone. + void AddConstElementAccessToCaseBlock( + BasicBlock* case_block, Instruction* access_chain, + uint32_t const_element_idx, + std::unordered_map* old_ids_to_new_ids) const; + + // Clones all instructions in |insts_to_be_cloned| and put them to |block|. + // |old_ids_to_new_ids| keeps the mapping from the result id of each + // instruction of |insts_to_be_cloned| to the result of their clones. + void CloneInstsToBlock( + BasicBlock* block, Instruction* inst_to_skip_cloning, + const std::deque& insts_to_be_cloned, + std::unordered_map* old_ids_to_new_ids) const; + + // Adds OpBranch to |branch_destination| at the end of |parent_block|. + void AddBranchToBlock(BasicBlock* parent_block, + uint32_t branch_destination) const; + + // Replaces in-operands of all instructions in the basic block |block| using + // |old_ids_to_new_ids|. It conducts the replacement only if the in-operand + // id is a key of |old_ids_to_new_ids|. + void UseNewIdsInBlock( + BasicBlock* block, + const std::unordered_map& old_ids_to_new_ids) const; + + // Creates a case block for |element_index| case. It adds clones of + // |insts_to_be_cloned| and a clone of |access_chain| with |element_index| as + // its first index. The termination instruction of the created case block will + // be a branch to |branch_target_id|. Puts old ids to new ids map for the + // cloned instructions in |old_ids_to_new_ids|. + BasicBlock* CreateCaseBlock( + Instruction* access_chain, uint32_t element_index, + const std::deque& insts_to_be_cloned, + uint32_t branch_target_id, + std::unordered_map* old_ids_to_new_ids) const; + + // Creates a default block for switch-case statement that has only a single + // instruction OpBranch whose target is a basic block with |merge_block_id|. + // If |null_const_for_phi_is_needed| is true, gets or creates a default null + // constant value for a phi instruction whose operands are |phi_operands| and + // puts it in |phi_operands|. + BasicBlock* CreateDefaultBlock(bool null_const_for_phi_is_needed, + std::vector* phi_operands, + uint32_t merge_block_id) const; + + // Creates and adds an OpSwitch used for the selection of OpAccessChain whose + // first Indexes operand is |access_chain_index_var_id|. The OpSwitch will be + // added at the end of |parent_block|. It will jump to |default_id| for the + // default case and jumps to one of case blocks whose ids are |case_block_ids| + // if |access_chain_index_var_id| matches the case number. |merge_id| is the + // merge block id. + void AddSwitchForAccessChain( + BasicBlock* parent_block, uint32_t access_chain_index_var_id, + uint32_t default_id, uint32_t merge_id, + const std::vector& case_block_ids) const; + + // Creates a phi instruction with |phi_operands| as values and + // |case_block_ids| and |default_block_id| as incoming blocks. The size of + // |phi_operands| must be exactly 1 larger than the size of |case_block_ids|. + // The last element of |phi_operands| will be used for |default_block_id|. It + // adds the phi instruction to the beginning of |parent_block|. + uint32_t CreatePhiInstruction(BasicBlock* parent_block, + const std::vector& phi_operands, + const std::vector& case_block_ids, + uint32_t default_block_id) const; + + // Replaces the incoming block operand of OpPhi instructions with + // |new_incoming_block_id| if the incoming block operand is + // |old_incoming_block_id|. + void ReplacePhiIncomingBlock(uint32_t old_incoming_block_id, + uint32_t new_incoming_block_id) const; + + // Create an OpConstantNull instruction whose result type id is |type_id|. + Instruction* GetConstNull(uint32_t type_id) const; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REPLACE_DESC_VAR_INDEX_ACCESS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/replace_invalid_opc.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/replace_invalid_opc.cpp new file mode 100644 index 000000000000..1b97c0e84f95 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/replace_invalid_opc.cpp @@ -0,0 +1,219 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/replace_invalid_opc.h" + +#include +#include + +namespace spvtools { +namespace opt { + +Pass::Status ReplaceInvalidOpcodePass::Process() { + bool modified = false; + + if (context()->get_feature_mgr()->HasCapability(spv::Capability::Linkage)) { + return Status::SuccessWithoutChange; + } + + spv::ExecutionModel execution_model = GetExecutionModel(); + if (execution_model == spv::ExecutionModel::Kernel) { + // We do not handle kernels. + return Status::SuccessWithoutChange; + } + if (execution_model == spv::ExecutionModel::Max) { + // Mixed execution models for the entry points. This case is not currently + // handled. + return Status::SuccessWithoutChange; + } + + for (Function& func : *get_module()) { + modified |= RewriteFunction(&func, execution_model); + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +spv::ExecutionModel ReplaceInvalidOpcodePass::GetExecutionModel() { + spv::ExecutionModel result = spv::ExecutionModel::Max; + bool first = true; + for (Instruction& entry_point : get_module()->entry_points()) { + if (first) { + result = static_cast( + entry_point.GetSingleWordInOperand(0)); + first = false; + } else { + spv::ExecutionModel current_model = static_cast( + entry_point.GetSingleWordInOperand(0)); + if (current_model != result) { + result = spv::ExecutionModel::Max; + break; + } + } + } + return result; +} + +bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, + spv::ExecutionModel model) { + bool modified = false; + Instruction* last_line_dbg_inst = nullptr; + function->ForEachInst( + [model, &modified, &last_line_dbg_inst, this](Instruction* inst) { + // Track the debug information so we can have a meaningful message. + if (inst->opcode() == spv::Op::OpLabel || inst->IsNoLine()) { + last_line_dbg_inst = nullptr; + return; + } else if (inst->IsLine()) { + last_line_dbg_inst = inst; + return; + } + + bool replace = false; + if (model != spv::ExecutionModel::Fragment && + IsFragmentShaderOnlyInstruction(inst)) { + replace = true; + } + + if (model != spv::ExecutionModel::TessellationControl && + model != spv::ExecutionModel::GLCompute && + !context()->IsTargetEnvAtLeast(SPV_ENV_UNIVERSAL_1_3)) { + if (inst->opcode() == spv::Op::OpControlBarrier) { + assert(model != spv::ExecutionModel::Kernel && + "Expecting to be working on a shader module."); + replace = true; + } + } + + if (replace) { + modified = true; + if (last_line_dbg_inst == nullptr) { + ReplaceInstruction(inst, nullptr, 0, 0); + } else { + // Get the name of the source file. + uint32_t file_name_id = 0; + if (last_line_dbg_inst->opcode() == spv::Op::OpLine) { + file_name_id = last_line_dbg_inst->GetSingleWordInOperand(0); + } else { // Shader100::DebugLine + uint32_t debug_source_id = + last_line_dbg_inst->GetSingleWordInOperand(2); + Instruction* debug_source_inst = + context()->get_def_use_mgr()->GetDef(debug_source_id); + file_name_id = debug_source_inst->GetSingleWordInOperand(2); + } + Instruction* file_name = + context()->get_def_use_mgr()->GetDef(file_name_id); + const std::string source = file_name->GetInOperand(0).AsString(); + + // Get the line number and column number. + uint32_t line_number = + last_line_dbg_inst->GetSingleWordInOperand(1); + uint32_t col_number = last_line_dbg_inst->GetSingleWordInOperand(2); + + // Replace the instruction. + ReplaceInstruction(inst, source.c_str(), line_number, col_number); + } + } + }, + /* run_on_debug_line_insts = */ true); + return modified; +} + +bool ReplaceInvalidOpcodePass::IsFragmentShaderOnlyInstruction( + Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpDPdx: + case spv::Op::OpDPdy: + case spv::Op::OpFwidth: + case spv::Op::OpDPdxFine: + case spv::Op::OpDPdyFine: + case spv::Op::OpFwidthFine: + case spv::Op::OpDPdxCoarse: + case spv::Op::OpDPdyCoarse: + case spv::Op::OpFwidthCoarse: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageQueryLod: + // TODO: Teach |ReplaceInstruction| to handle block terminators. Then + // uncomment the OpKill case. + // case spv::Op::OpKill: + // case spv::Op::OpTerminateInstruction: + return true; + default: + return false; + } +} + +void ReplaceInvalidOpcodePass::ReplaceInstruction(Instruction* inst, + const char* source, + uint32_t line_number, + uint32_t column_number) { + if (inst->result_id() != 0) { + uint32_t const_id = GetSpecialConstant(inst->type_id()); + context()->KillNamesAndDecorates(inst); + context()->ReplaceAllUsesWith(inst->result_id(), const_id); + } + assert(!inst->IsBlockTerminator() && + "We cannot simply delete a block terminator. It must be replaced " + "with something."); + if (consumer()) { + std::string message = BuildWarningMessage(inst->opcode()); + consumer()(SPV_MSG_WARNING, source, {line_number, column_number, 0}, + message.c_str()); + } + context()->KillInst(inst); +} + +uint32_t ReplaceInvalidOpcodePass::GetSpecialConstant(uint32_t type_id) { + const analysis::Constant* special_const = nullptr; + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + + Instruction* type = context()->get_def_use_mgr()->GetDef(type_id); + if (type->opcode() == spv::Op::OpTypeVector) { + uint32_t component_const = + GetSpecialConstant(type->GetSingleWordInOperand(0)); + std::vector ids; + for (uint32_t i = 0; i < type->GetSingleWordInOperand(1); ++i) { + ids.push_back(component_const); + } + special_const = const_mgr->GetConstant(type_mgr->GetType(type_id), ids); + } else { + assert(type->opcode() == spv::Op::OpTypeInt || + type->opcode() == spv::Op::OpTypeFloat); + std::vector literal_words; + for (uint32_t i = 0; i < type->GetSingleWordInOperand(0); i += 32) { + literal_words.push_back(0xDEADBEEF); + } + special_const = + const_mgr->GetConstant(type_mgr->GetType(type_id), literal_words); + } + assert(special_const != nullptr); + return const_mgr->GetDefiningInstruction(special_const)->result_id(); +} + +std::string ReplaceInvalidOpcodePass::BuildWarningMessage(spv::Op opcode) { + spv_opcode_desc opcode_info; + context()->grammar().lookupOpcode(opcode, &opcode_info); + std::string message = "Removing "; + message += opcode_info->name; + message += " instruction because of incompatible execution model."; + return message; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/replace_invalid_opc.h b/thirdparty/glslang/External/spirv-tools/source/opt/replace_invalid_opc.h new file mode 100644 index 000000000000..3f0d16bba777 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/replace_invalid_opc.h @@ -0,0 +1,67 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_REPLACE_INVALID_OPC_H_ +#define SOURCE_OPT_REPLACE_INVALID_OPC_H_ + +#include + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// This pass will runs on shader modules only. It will replace the result of +// instructions that are valid for shader modules, but not the current shader +// stage, with a constant value. If the instruction does not have a return +// value, the instruction will simply be deleted. +class ReplaceInvalidOpcodePass : public Pass { + public: + const char* name() const override { return "replace-invalid-opcode"; } + Status Process() override; + + private: + // Returns the execution model that is used by every entry point in the + // module. If more than one execution model is used in the module, then the + // return value is spv::ExecutionModel::Max. + spv::ExecutionModel GetExecutionModel(); + + // Replaces all instructions in |function| that are invalid with execution + // model |mode|, but valid for another shader model, with a special constant + // value. See |GetSpecialConstant|. + bool RewriteFunction(Function* function, spv::ExecutionModel mode); + + // Returns true if |inst| is valid for fragment shaders only. + bool IsFragmentShaderOnlyInstruction(Instruction* inst); + + // Replaces all uses of the result of |inst|, if there is one, with the id of + // a special constant. Then |inst| is killed. |inst| cannot be a block + // terminator because the basic block will then become invalid. |inst| is no + // longer valid after calling this function. + void ReplaceInstruction(Instruction* inst, const char* source, + uint32_t line_number, uint32_t column_number); + + // Returns the id of a constant with type |type_id|. The type must be an + // integer, float, or vector. For scalar types, the hex representation of the + // constant will be the concatenation of 0xDEADBEEF with itself until the + // width of the type has been reached. For a vector, each element of the + // constant will be constructed the same way. + uint32_t GetSpecialConstant(uint32_t type_id); + std::string BuildWarningMessage(spv::Op opcode); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_REPLACE_INVALID_OPC_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis.cpp new file mode 100644 index 000000000000..26cc8b303a70 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis.cpp @@ -0,0 +1,987 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/scalar_analysis.h" + +#include +#include +#include + +#include "source/opt/ir_context.h" + +// Transforms a given scalar operation instruction into a DAG representation. +// +// 1. Take an instruction and traverse its operands until we reach a +// constant node or an instruction which we do not know how to compute the +// value, such as a load. +// +// 2. Create a new node for each instruction traversed and build the nodes for +// the in operands of that instruction as well. +// +// 3. Add the operand nodes as children of the first and hash the node. Use the +// hash to see if the node is already in the cache. We ensure the children are +// always in sorted order so that two nodes with the same children but inserted +// in a different order have the same hash and so that the overloaded operator== +// will return true. If the node is already in the cache return the cached +// version instead. +// +// 4. The created DAG can then be simplified by +// ScalarAnalysis::SimplifyExpression, implemented in +// scalar_analysis_simplification.cpp. See that file for further information on +// the simplification process. +// + +namespace spvtools { +namespace opt { + +uint32_t SENode::NumberOfNodes = 0; + +ScalarEvolutionAnalysis::ScalarEvolutionAnalysis(IRContext* context) + : context_(context), pretend_equal_{} { + // Create and cached the CantComputeNode. + cached_cant_compute_ = + GetCachedOrAdd(std::unique_ptr(new SECantCompute(this))); +} + +SENode* ScalarEvolutionAnalysis::CreateNegation(SENode* operand) { + // If operand is can't compute then the whole graph is can't compute. + if (operand->IsCantCompute()) return CreateCantComputeNode(); + + if (operand->GetType() == SENode::Constant) { + return CreateConstant(-operand->AsSEConstantNode()->FoldToSingleValue()); + } + std::unique_ptr negation_node{new SENegative(this)}; + negation_node->AddChild(operand); + return GetCachedOrAdd(std::move(negation_node)); +} + +SENode* ScalarEvolutionAnalysis::CreateConstant(int64_t integer) { + return GetCachedOrAdd( + std::unique_ptr(new SEConstantNode(this, integer))); +} + +SENode* ScalarEvolutionAnalysis::CreateRecurrentExpression( + const Loop* loop, SENode* offset, SENode* coefficient) { + assert(loop && "Recurrent add expressions must have a valid loop."); + + // If operands are can't compute then the whole graph is can't compute. + if (offset->IsCantCompute() || coefficient->IsCantCompute()) + return CreateCantComputeNode(); + + const Loop* loop_to_use = nullptr; + if (pretend_equal_[loop]) { + loop_to_use = pretend_equal_[loop]; + } else { + loop_to_use = loop; + } + + std::unique_ptr phi_node{ + new SERecurrentNode(this, loop_to_use)}; + phi_node->AddOffset(offset); + phi_node->AddCoefficient(coefficient); + + return GetCachedOrAdd(std::move(phi_node)); +} + +SENode* ScalarEvolutionAnalysis::AnalyzeMultiplyOp( + const Instruction* multiply) { + assert(multiply->opcode() == spv::Op::OpIMul && + "Multiply node did not come from a multiply instruction"); + analysis::DefUseManager* def_use = context_->get_def_use_mgr(); + + SENode* op1 = + AnalyzeInstruction(def_use->GetDef(multiply->GetSingleWordInOperand(0))); + SENode* op2 = + AnalyzeInstruction(def_use->GetDef(multiply->GetSingleWordInOperand(1))); + + return CreateMultiplyNode(op1, op2); +} + +SENode* ScalarEvolutionAnalysis::CreateMultiplyNode(SENode* operand_1, + SENode* operand_2) { + // If operands are can't compute then the whole graph is can't compute. + if (operand_1->IsCantCompute() || operand_2->IsCantCompute()) + return CreateCantComputeNode(); + + if (operand_1->GetType() == SENode::Constant && + operand_2->GetType() == SENode::Constant) { + return CreateConstant(operand_1->AsSEConstantNode()->FoldToSingleValue() * + operand_2->AsSEConstantNode()->FoldToSingleValue()); + } + + std::unique_ptr multiply_node{new SEMultiplyNode(this)}; + + multiply_node->AddChild(operand_1); + multiply_node->AddChild(operand_2); + + return GetCachedOrAdd(std::move(multiply_node)); +} + +SENode* ScalarEvolutionAnalysis::CreateSubtraction(SENode* operand_1, + SENode* operand_2) { + // Fold if both operands are constant. + if (operand_1->GetType() == SENode::Constant && + operand_2->GetType() == SENode::Constant) { + return CreateConstant(operand_1->AsSEConstantNode()->FoldToSingleValue() - + operand_2->AsSEConstantNode()->FoldToSingleValue()); + } + + return CreateAddNode(operand_1, CreateNegation(operand_2)); +} + +SENode* ScalarEvolutionAnalysis::CreateAddNode(SENode* operand_1, + SENode* operand_2) { + // Fold if both operands are constant and the |simplify| flag is true. + if (operand_1->GetType() == SENode::Constant && + operand_2->GetType() == SENode::Constant) { + return CreateConstant(operand_1->AsSEConstantNode()->FoldToSingleValue() + + operand_2->AsSEConstantNode()->FoldToSingleValue()); + } + + // If operands are can't compute then the whole graph is can't compute. + if (operand_1->IsCantCompute() || operand_2->IsCantCompute()) + return CreateCantComputeNode(); + + std::unique_ptr add_node{new SEAddNode(this)}; + + add_node->AddChild(operand_1); + add_node->AddChild(operand_2); + + return GetCachedOrAdd(std::move(add_node)); +} + +SENode* ScalarEvolutionAnalysis::AnalyzeInstruction(const Instruction* inst) { + auto itr = recurrent_node_map_.find(inst); + if (itr != recurrent_node_map_.end()) return itr->second; + + SENode* output = nullptr; + switch (inst->opcode()) { + case spv::Op::OpPhi: { + output = AnalyzePhiInstruction(inst); + break; + } + case spv::Op::OpConstant: + case spv::Op::OpConstantNull: { + output = AnalyzeConstant(inst); + break; + } + case spv::Op::OpISub: + case spv::Op::OpIAdd: { + output = AnalyzeAddOp(inst); + break; + } + case spv::Op::OpIMul: { + output = AnalyzeMultiplyOp(inst); + break; + } + default: { + output = CreateValueUnknownNode(inst); + break; + } + } + + return output; +} + +SENode* ScalarEvolutionAnalysis::AnalyzeConstant(const Instruction* inst) { + if (inst->opcode() == spv::Op::OpConstantNull) return CreateConstant(0); + + assert(inst->opcode() == spv::Op::OpConstant); + assert(inst->NumInOperands() == 1); + int64_t value = 0; + + // Look up the instruction in the constant manager. + const analysis::Constant* constant = + context_->get_constant_mgr()->FindDeclaredConstant(inst->result_id()); + + if (!constant) return CreateCantComputeNode(); + + const analysis::IntConstant* int_constant = constant->AsIntConstant(); + + // Exit out if it is a 64 bit integer. + if (!int_constant || int_constant->words().size() != 1) + return CreateCantComputeNode(); + + if (int_constant->type()->AsInteger()->IsSigned()) { + value = int_constant->GetS32BitValue(); + } else { + value = int_constant->GetU32BitValue(); + } + + return CreateConstant(value); +} + +// Handles both addition and subtraction. If the |sub| flag is set then the +// addition will be op1+(-op2) otherwise op1+op2. +SENode* ScalarEvolutionAnalysis::AnalyzeAddOp(const Instruction* inst) { + assert((inst->opcode() == spv::Op::OpIAdd || + inst->opcode() == spv::Op::OpISub) && + "Add node must be created from a OpIAdd or OpISub instruction"); + + analysis::DefUseManager* def_use = context_->get_def_use_mgr(); + + SENode* op1 = + AnalyzeInstruction(def_use->GetDef(inst->GetSingleWordInOperand(0))); + + SENode* op2 = + AnalyzeInstruction(def_use->GetDef(inst->GetSingleWordInOperand(1))); + + // To handle subtraction we wrap the second operand in a unary negation node. + if (inst->opcode() == spv::Op::OpISub) { + op2 = CreateNegation(op2); + } + + return CreateAddNode(op1, op2); +} + +SENode* ScalarEvolutionAnalysis::AnalyzePhiInstruction(const Instruction* phi) { + // The phi should only have two incoming value pairs. + if (phi->NumInOperands() != 4) { + return CreateCantComputeNode(); + } + + analysis::DefUseManager* def_use = context_->get_def_use_mgr(); + + // Get the basic block this instruction belongs to. + BasicBlock* basic_block = + context_->get_instr_block(const_cast(phi)); + + // And then the function that the basic blocks belongs to. + Function* function = basic_block->GetParent(); + + // Use the function to get the loop descriptor. + LoopDescriptor* loop_descriptor = context_->GetLoopDescriptor(function); + + // We only handle phis in loops at the moment. + if (!loop_descriptor) return CreateCantComputeNode(); + + // Get the innermost loop which this block belongs to. + Loop* loop = (*loop_descriptor)[basic_block->id()]; + + // If the loop doesn't exist or doesn't have a preheader or latch block, exit + // out. + if (!loop || !loop->GetLatchBlock() || !loop->GetPreHeaderBlock() || + loop->GetHeaderBlock() != basic_block) + return recurrent_node_map_[phi] = CreateCantComputeNode(); + + const Loop* loop_to_use = nullptr; + if (pretend_equal_[loop]) { + loop_to_use = pretend_equal_[loop]; + } else { + loop_to_use = loop; + } + std::unique_ptr phi_node{ + new SERecurrentNode(this, loop_to_use)}; + + // We add the node to this map to allow it to be returned before the node is + // fully built. This is needed as the subsequent call to AnalyzeInstruction + // could lead back to this |phi| instruction so we return the pointer + // immediately in AnalyzeInstruction to break the recursion. + recurrent_node_map_[phi] = phi_node.get(); + + // Traverse the operands of the instruction an create new nodes for each one. + for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) { + uint32_t value_id = phi->GetSingleWordInOperand(i); + uint32_t incoming_label_id = phi->GetSingleWordInOperand(i + 1); + + Instruction* value_inst = def_use->GetDef(value_id); + SENode* value_node = AnalyzeInstruction(value_inst); + + // If any operand is CantCompute then the whole graph is CantCompute. + if (value_node->IsCantCompute()) + return recurrent_node_map_[phi] = CreateCantComputeNode(); + + // If the value is coming from the preheader block then the value is the + // initial value of the phi. + if (incoming_label_id == loop->GetPreHeaderBlock()->id()) { + phi_node->AddOffset(value_node); + } else if (incoming_label_id == loop->GetLatchBlock()->id()) { + // Assumed to be in the form of step + phi. + if (value_node->GetType() != SENode::Add) + return recurrent_node_map_[phi] = CreateCantComputeNode(); + + SENode* step_node = nullptr; + SENode* phi_operand = nullptr; + SENode* operand_1 = value_node->GetChild(0); + SENode* operand_2 = value_node->GetChild(1); + + // Find which node is the step term. + if (!operand_1->AsSERecurrentNode()) + step_node = operand_1; + else if (!operand_2->AsSERecurrentNode()) + step_node = operand_2; + + // Find which node is the recurrent expression. + if (operand_1->AsSERecurrentNode()) + phi_operand = operand_1; + else if (operand_2->AsSERecurrentNode()) + phi_operand = operand_2; + + // If it is not in the form step + phi exit out. + if (!(step_node && phi_operand)) + return recurrent_node_map_[phi] = CreateCantComputeNode(); + + // If the phi operand is not the same phi node exit out. + if (phi_operand != phi_node.get()) + return recurrent_node_map_[phi] = CreateCantComputeNode(); + + if (!IsLoopInvariant(loop, step_node)) + return recurrent_node_map_[phi] = CreateCantComputeNode(); + + phi_node->AddCoefficient(step_node); + } + } + + // Once the node is fully built we update the map with the version from the + // cache (if it has already been added to the cache). + return recurrent_node_map_[phi] = GetCachedOrAdd(std::move(phi_node)); +} + +SENode* ScalarEvolutionAnalysis::CreateValueUnknownNode( + const Instruction* inst) { + std::unique_ptr load_node{ + new SEValueUnknown(this, inst->result_id())}; + return GetCachedOrAdd(std::move(load_node)); +} + +SENode* ScalarEvolutionAnalysis::CreateCantComputeNode() { + return cached_cant_compute_; +} + +// Add the created node into the cache of nodes. If it already exists return it. +SENode* ScalarEvolutionAnalysis::GetCachedOrAdd( + std::unique_ptr prospective_node) { + auto itr = node_cache_.find(prospective_node); + if (itr != node_cache_.end()) { + return (*itr).get(); + } + + SENode* raw_ptr_to_node = prospective_node.get(); + node_cache_.insert(std::move(prospective_node)); + return raw_ptr_to_node; +} + +bool ScalarEvolutionAnalysis::IsLoopInvariant(const Loop* loop, + const SENode* node) const { + for (auto itr = node->graph_cbegin(); itr != node->graph_cend(); ++itr) { + if (const SERecurrentNode* rec = itr->AsSERecurrentNode()) { + const BasicBlock* header = rec->GetLoop()->GetHeaderBlock(); + + // If the loop which the recurrent expression belongs to is either |loop + // or a nested loop inside |loop| then we assume it is variant. + if (loop->IsInsideLoop(header)) { + return false; + } + } else if (const SEValueUnknown* unknown = itr->AsSEValueUnknown()) { + // If the instruction is inside the loop we conservatively assume it is + // loop variant. + if (loop->IsInsideLoop(unknown->ResultId())) return false; + } + } + + return true; +} + +SENode* ScalarEvolutionAnalysis::GetCoefficientFromRecurrentTerm( + SENode* node, const Loop* loop) { + // Traverse the DAG to find the recurrent expression belonging to |loop|. + for (auto itr = node->graph_begin(); itr != node->graph_end(); ++itr) { + SERecurrentNode* rec = itr->AsSERecurrentNode(); + if (rec && rec->GetLoop() == loop) { + return rec->GetCoefficient(); + } + } + return CreateConstant(0); +} + +SENode* ScalarEvolutionAnalysis::UpdateChildNode(SENode* parent, + SENode* old_child, + SENode* new_child) { + // Only handles add. + if (parent->GetType() != SENode::Add) return parent; + + std::vector new_children; + for (SENode* child : *parent) { + if (child == old_child) { + new_children.push_back(new_child); + } else { + new_children.push_back(child); + } + } + + std::unique_ptr add_node{new SEAddNode(this)}; + for (SENode* child : new_children) { + add_node->AddChild(child); + } + + return SimplifyExpression(GetCachedOrAdd(std::move(add_node))); +} + +// Rebuild the |node| eliminating, if it exists, the recurrent term which +// belongs to the |loop|. +SENode* ScalarEvolutionAnalysis::BuildGraphWithoutRecurrentTerm( + SENode* node, const Loop* loop) { + // If the node is already a recurrent expression belonging to loop then just + // return the offset. + SERecurrentNode* recurrent = node->AsSERecurrentNode(); + if (recurrent) { + if (recurrent->GetLoop() == loop) { + return recurrent->GetOffset(); + } else { + return node; + } + } + + std::vector new_children; + // Otherwise find the recurrent node in the children of this node. + for (auto itr : *node) { + recurrent = itr->AsSERecurrentNode(); + if (recurrent && recurrent->GetLoop() == loop) { + new_children.push_back(recurrent->GetOffset()); + } else { + new_children.push_back(itr); + } + } + + std::unique_ptr add_node{new SEAddNode(this)}; + for (SENode* child : new_children) { + add_node->AddChild(child); + } + + return SimplifyExpression(GetCachedOrAdd(std::move(add_node))); +} + +// Return the recurrent term belonging to |loop| if it appears in the graph +// starting at |node| or null if it doesn't. +SERecurrentNode* ScalarEvolutionAnalysis::GetRecurrentTerm(SENode* node, + const Loop* loop) { + for (auto itr = node->graph_begin(); itr != node->graph_end(); ++itr) { + SERecurrentNode* rec = itr->AsSERecurrentNode(); + if (rec && rec->GetLoop() == loop) { + return rec; + } + } + return nullptr; +} +std::string SENode::AsString() const { + switch (GetType()) { + case Constant: + return "Constant"; + case RecurrentAddExpr: + return "RecurrentAddExpr"; + case Add: + return "Add"; + case Negative: + return "Negative"; + case Multiply: + return "Multiply"; + case ValueUnknown: + return "Value Unknown"; + case CanNotCompute: + return "Can not compute"; + } + return "NULL"; +} + +bool SENode::operator==(const SENode& other) const { + if (GetType() != other.GetType()) return false; + + if (other.GetChildren().size() != children_.size()) return false; + + const SERecurrentNode* this_as_recurrent = AsSERecurrentNode(); + + // Check the children are the same, for SERecurrentNodes we need to check the + // offset and coefficient manually as the child vector is sorted by ids so the + // offset/coefficient information is lost. + if (!this_as_recurrent) { + for (size_t index = 0; index < children_.size(); ++index) { + if (other.GetChildren()[index] != children_[index]) return false; + } + } else { + const SERecurrentNode* other_as_recurrent = other.AsSERecurrentNode(); + + // We've already checked the types are the same, this should not fail if + // this->AsSERecurrentNode() succeeded. + assert(other_as_recurrent); + + if (this_as_recurrent->GetCoefficient() != + other_as_recurrent->GetCoefficient()) + return false; + + if (this_as_recurrent->GetOffset() != other_as_recurrent->GetOffset()) + return false; + + if (this_as_recurrent->GetLoop() != other_as_recurrent->GetLoop()) + return false; + } + + // If we're dealing with a value unknown node check both nodes were created by + // the same instruction. + if (GetType() == SENode::ValueUnknown) { + if (AsSEValueUnknown()->ResultId() != + other.AsSEValueUnknown()->ResultId()) { + return false; + } + } + + if (AsSEConstantNode()) { + if (AsSEConstantNode()->FoldToSingleValue() != + other.AsSEConstantNode()->FoldToSingleValue()) + return false; + } + + return true; +} + +bool SENode::operator!=(const SENode& other) const { return !(*this == other); } + +namespace { +// Helper functions to insert 32/64 bit values into the 32 bit hash string. This +// allows us to add pointers to the string by reinterpreting the pointers as +// uintptr_t. PushToString will deduce the type, call sizeof on it and use +// that size to call into the correct PushToStringImpl functor depending on +// whether it is 32 or 64 bit. + +template +struct PushToStringImpl; + +template +struct PushToStringImpl { + void operator()(T id, std::u32string* str) { + str->push_back(static_cast(id >> 32)); + str->push_back(static_cast(id)); + } +}; + +template +struct PushToStringImpl { + void operator()(T id, std::u32string* str) { + str->push_back(static_cast(id)); + } +}; + +template +void PushToString(T id, std::u32string* str) { + PushToStringImpl{}(id, str); +} + +} // namespace + +// Implements the hashing of SENodes. +size_t SENodeHash::operator()(const SENode* node) const { + // Concatenate the terms into a string which we can hash. + std::u32string hash_string{}; + + // Hashing the type as a string is safer than hashing the enum as the enum is + // very likely to collide with constants. + for (char ch : node->AsString()) { + hash_string.push_back(static_cast(ch)); + } + + // We just ignore the literal value unless it is a constant. + if (node->GetType() == SENode::Constant) + PushToString(node->AsSEConstantNode()->FoldToSingleValue(), &hash_string); + + const SERecurrentNode* recurrent = node->AsSERecurrentNode(); + + // If we're dealing with a recurrent expression hash the loop as well so that + // nested inductions like i=0,i++ and j=0,j++ correspond to different nodes. + if (recurrent) { + PushToString(reinterpret_cast(recurrent->GetLoop()), + &hash_string); + + // Recurrent expressions can't be hashed using the normal method as the + // order of coefficient and offset matters to the hash. + PushToString(reinterpret_cast(recurrent->GetCoefficient()), + &hash_string); + PushToString(reinterpret_cast(recurrent->GetOffset()), + &hash_string); + + return std::hash{}(hash_string); + } + + // Hash the result id of the original instruction which created this node if + // it is a value unknown node. + if (node->GetType() == SENode::ValueUnknown) { + PushToString(node->AsSEValueUnknown()->ResultId(), &hash_string); + } + + // Hash the pointers of the child nodes, each SENode has a unique pointer + // associated with it. + const std::vector& children = node->GetChildren(); + for (const SENode* child : children) { + PushToString(reinterpret_cast(child), &hash_string); + } + + return std::hash{}(hash_string); +} + +// This overload is the actual overload used by the node_cache_ set. +size_t SENodeHash::operator()(const std::unique_ptr& node) const { + return this->operator()(node.get()); +} + +void SENode::DumpDot(std::ostream& out, bool recurse) const { + size_t unique_id = std::hash{}(this); + out << unique_id << " [label=\"" << AsString() << " "; + if (GetType() == SENode::Constant) { + out << "\nwith value: " << this->AsSEConstantNode()->FoldToSingleValue(); + } + out << "\"]\n"; + for (const SENode* child : children_) { + size_t child_unique_id = std::hash{}(child); + out << unique_id << " -> " << child_unique_id << " \n"; + if (recurse) child->DumpDot(out, true); + } +} + +namespace { +class IsGreaterThanZero { + public: + explicit IsGreaterThanZero(IRContext* context) : context_(context) {} + + // Determine if the value of |node| is always strictly greater than zero if + // |or_equal_zero| is false or greater or equal to zero if |or_equal_zero| is + // true. It returns true is the evaluation was able to conclude something, in + // which case the result is stored in |result|. + // The algorithm work by going through all the nodes and determine the + // sign of each of them. + bool Eval(const SENode* node, bool or_equal_zero, bool* result) { + *result = false; + switch (Visit(node)) { + case Signedness::kPositiveOrNegative: { + return false; + } + case Signedness::kStrictlyNegative: { + *result = false; + break; + } + case Signedness::kNegative: { + if (!or_equal_zero) { + return false; + } + *result = false; + break; + } + case Signedness::kStrictlyPositive: { + *result = true; + break; + } + case Signedness::kPositive: { + if (!or_equal_zero) { + return false; + } + *result = true; + break; + } + } + return true; + } + + private: + enum class Signedness { + kPositiveOrNegative, // Yield a value positive or negative. + kStrictlyNegative, // Yield a value strictly less than 0. + kNegative, // Yield a value less or equal to 0. + kStrictlyPositive, // Yield a value strictly greater than 0. + kPositive // Yield a value greater or equal to 0. + }; + + // Combine the signedness according to arithmetic rules of a given operator. + using Combiner = std::function; + + // Returns a functor to interpret the signedness of 2 expressions as if they + // were added. + Combiner GetAddCombiner() const { + return [](Signedness lhs, Signedness rhs) { + switch (lhs) { + case Signedness::kPositiveOrNegative: + break; + case Signedness::kStrictlyNegative: + if (rhs == Signedness::kStrictlyNegative || + rhs == Signedness::kNegative) + return lhs; + break; + case Signedness::kNegative: { + if (rhs == Signedness::kStrictlyNegative) + return Signedness::kStrictlyNegative; + if (rhs == Signedness::kNegative) return Signedness::kNegative; + break; + } + case Signedness::kStrictlyPositive: { + if (rhs == Signedness::kStrictlyPositive || + rhs == Signedness::kPositive) { + return Signedness::kStrictlyPositive; + } + break; + } + case Signedness::kPositive: { + if (rhs == Signedness::kStrictlyPositive) + return Signedness::kStrictlyPositive; + if (rhs == Signedness::kPositive) return Signedness::kPositive; + break; + } + } + return Signedness::kPositiveOrNegative; + }; + } + + // Returns a functor to interpret the signedness of 2 expressions as if they + // were multiplied. + Combiner GetMulCombiner() const { + return [](Signedness lhs, Signedness rhs) { + switch (lhs) { + case Signedness::kPositiveOrNegative: + break; + case Signedness::kStrictlyNegative: { + switch (rhs) { + case Signedness::kPositiveOrNegative: { + break; + } + case Signedness::kStrictlyNegative: { + return Signedness::kStrictlyPositive; + } + case Signedness::kNegative: { + return Signedness::kPositive; + } + case Signedness::kStrictlyPositive: { + return Signedness::kStrictlyNegative; + } + case Signedness::kPositive: { + return Signedness::kNegative; + } + } + break; + } + case Signedness::kNegative: { + switch (rhs) { + case Signedness::kPositiveOrNegative: { + break; + } + case Signedness::kStrictlyNegative: + case Signedness::kNegative: { + return Signedness::kPositive; + } + case Signedness::kStrictlyPositive: + case Signedness::kPositive: { + return Signedness::kNegative; + } + } + break; + } + case Signedness::kStrictlyPositive: { + return rhs; + } + case Signedness::kPositive: { + switch (rhs) { + case Signedness::kPositiveOrNegative: { + break; + } + case Signedness::kStrictlyNegative: + case Signedness::kNegative: { + return Signedness::kNegative; + } + case Signedness::kStrictlyPositive: + case Signedness::kPositive: { + return Signedness::kPositive; + } + } + break; + } + } + return Signedness::kPositiveOrNegative; + }; + } + + Signedness Visit(const SENode* node) { + switch (node->GetType()) { + case SENode::Constant: + return Visit(node->AsSEConstantNode()); + break; + case SENode::RecurrentAddExpr: + return Visit(node->AsSERecurrentNode()); + break; + case SENode::Negative: + return Visit(node->AsSENegative()); + break; + case SENode::CanNotCompute: + return Visit(node->AsSECantCompute()); + break; + case SENode::ValueUnknown: + return Visit(node->AsSEValueUnknown()); + break; + case SENode::Add: + return VisitExpr(node, GetAddCombiner()); + break; + case SENode::Multiply: + return VisitExpr(node, GetMulCombiner()); + break; + } + return Signedness::kPositiveOrNegative; + } + + // Returns the signedness of a constant |node|. + Signedness Visit(const SEConstantNode* node) { + if (0 == node->FoldToSingleValue()) return Signedness::kPositive; + if (0 < node->FoldToSingleValue()) return Signedness::kStrictlyPositive; + if (0 > node->FoldToSingleValue()) return Signedness::kStrictlyNegative; + return Signedness::kPositiveOrNegative; + } + + // Returns the signedness of an unknown |node| based on its type. + Signedness Visit(const SEValueUnknown* node) { + Instruction* insn = context_->get_def_use_mgr()->GetDef(node->ResultId()); + analysis::Type* type = context_->get_type_mgr()->GetType(insn->type_id()); + assert(type && "Can't retrieve a type for the instruction"); + analysis::Integer* int_type = type->AsInteger(); + assert(type && "Can't retrieve an integer type for the instruction"); + return int_type->IsSigned() ? Signedness::kPositiveOrNegative + : Signedness::kPositive; + } + + // Returns the signedness of a recurring expression. + Signedness Visit(const SERecurrentNode* node) { + Signedness coeff_sign = Visit(node->GetCoefficient()); + // SERecurrentNode represent an affine expression in the range [0, + // loop_bound], so the result cannot be strictly positive or negative. + switch (coeff_sign) { + default: + break; + case Signedness::kStrictlyNegative: + coeff_sign = Signedness::kNegative; + break; + case Signedness::kStrictlyPositive: + coeff_sign = Signedness::kPositive; + break; + } + return GetAddCombiner()(coeff_sign, Visit(node->GetOffset())); + } + + // Returns the signedness of a negation |node|. + Signedness Visit(const SENegative* node) { + switch (Visit(*node->begin())) { + case Signedness::kPositiveOrNegative: { + return Signedness::kPositiveOrNegative; + } + case Signedness::kStrictlyNegative: { + return Signedness::kStrictlyPositive; + } + case Signedness::kNegative: { + return Signedness::kPositive; + } + case Signedness::kStrictlyPositive: { + return Signedness::kStrictlyNegative; + } + case Signedness::kPositive: { + return Signedness::kNegative; + } + } + return Signedness::kPositiveOrNegative; + } + + Signedness Visit(const SECantCompute*) { + return Signedness::kPositiveOrNegative; + } + + // Returns the signedness of a binary expression by using the combiner + // |reduce|. + Signedness VisitExpr( + const SENode* node, + std::function reduce) { + Signedness result = Visit(*node->begin()); + for (const SENode* operand : make_range(++node->begin(), node->end())) { + if (result == Signedness::kPositiveOrNegative) { + return Signedness::kPositiveOrNegative; + } + result = reduce(result, Visit(operand)); + } + return result; + } + + IRContext* context_; +}; +} // namespace + +bool ScalarEvolutionAnalysis::IsAlwaysGreaterThanZero(SENode* node, + bool* is_gt_zero) const { + return IsGreaterThanZero(context_).Eval(node, false, is_gt_zero); +} + +bool ScalarEvolutionAnalysis::IsAlwaysGreaterOrEqualToZero( + SENode* node, bool* is_ge_zero) const { + return IsGreaterThanZero(context_).Eval(node, true, is_ge_zero); +} + +namespace { + +// Remove |node| from the |mul| chain (of the form A * ... * |node| * ... * Z), +// if |node| is not in the chain, returns the original chain. +SENode* RemoveOneNodeFromMultiplyChain(SEMultiplyNode* mul, + const SENode* node) { + SENode* lhs = mul->GetChildren()[0]; + SENode* rhs = mul->GetChildren()[1]; + if (lhs == node) { + return rhs; + } + if (rhs == node) { + return lhs; + } + if (lhs->AsSEMultiplyNode()) { + SENode* res = RemoveOneNodeFromMultiplyChain(lhs->AsSEMultiplyNode(), node); + if (res != lhs) + return mul->GetParentAnalysis()->CreateMultiplyNode(res, rhs); + } + if (rhs->AsSEMultiplyNode()) { + SENode* res = RemoveOneNodeFromMultiplyChain(rhs->AsSEMultiplyNode(), node); + if (res != rhs) + return mul->GetParentAnalysis()->CreateMultiplyNode(res, rhs); + } + + return mul; +} +} // namespace + +std::pair SExpression::operator/( + SExpression rhs_wrapper) const { + SENode* lhs = node_; + SENode* rhs = rhs_wrapper.node_; + // Check for division by 0. + if (rhs->AsSEConstantNode() && + !rhs->AsSEConstantNode()->FoldToSingleValue()) { + return {scev_->CreateCantComputeNode(), 0}; + } + + // Trivial case. + if (lhs->AsSEConstantNode() && rhs->AsSEConstantNode()) { + int64_t lhs_value = lhs->AsSEConstantNode()->FoldToSingleValue(); + int64_t rhs_value = rhs->AsSEConstantNode()->FoldToSingleValue(); + return {scev_->CreateConstant(lhs_value / rhs_value), + lhs_value % rhs_value}; + } + + // look for a "c U / U" pattern. + if (lhs->AsSEMultiplyNode()) { + assert(lhs->GetChildren().size() == 2 && + "More than 2 operand for a multiply node."); + SENode* res = RemoveOneNodeFromMultiplyChain(lhs->AsSEMultiplyNode(), rhs); + if (res != lhs) { + return {res, 0}; + } + } + + return {scev_->CreateCantComputeNode(), 0}; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis.h b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis.h new file mode 100644 index 000000000000..fb6d631f5650 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis.h @@ -0,0 +1,314 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_SCALAR_ANALYSIS_H_ +#define SOURCE_OPT_SCALAR_ANALYSIS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/instruction.h" +#include "source/opt/scalar_analysis_nodes.h" + +namespace spvtools { +namespace opt { + +class IRContext; +class Loop; + +// Manager for the Scalar Evolution analysis. Creates and maintains a DAG of +// scalar operations generated from analysing the use def graph from incoming +// instructions. Each node is hashed as it is added so like node (for instance, +// two induction variables i=0,i++ and j=0,j++) become the same node. After +// creating a DAG with AnalyzeInstruction it can the be simplified into a more +// usable form with SimplifyExpression. +class ScalarEvolutionAnalysis { + public: + explicit ScalarEvolutionAnalysis(IRContext* context); + + // Create a unary negative node on |operand|. + SENode* CreateNegation(SENode* operand); + + // Creates a subtraction between the two operands by adding |operand_1| to the + // negation of |operand_2|. + SENode* CreateSubtraction(SENode* operand_1, SENode* operand_2); + + // Create an addition node between two operands. The |simplify| when set will + // allow the function to return an SEConstant instead of an addition if the + // two input operands are also constant. + SENode* CreateAddNode(SENode* operand_1, SENode* operand_2); + + // Create a multiply node between two operands. + SENode* CreateMultiplyNode(SENode* operand_1, SENode* operand_2); + + // Create a node representing a constant integer. + SENode* CreateConstant(int64_t integer); + + // Create a value unknown node, such as a load. + SENode* CreateValueUnknownNode(const Instruction* inst); + + // Create a CantComputeNode. Used to exit out of analysis. + SENode* CreateCantComputeNode(); + + // Create a new recurrent node with |offset| and |coefficient|, with respect + // to |loop|. + SENode* CreateRecurrentExpression(const Loop* loop, SENode* offset, + SENode* coefficient); + + // Construct the DAG by traversing use def chain of |inst|. + SENode* AnalyzeInstruction(const Instruction* inst); + + // Simplify the |node| by grouping like terms or if contains a recurrent + // expression, rewrite the graph so the whole DAG (from |node| down) is in + // terms of that recurrent expression. + // + // For example. + // Induction variable i=0, i++ would produce Rec(0,1) so i+1 could be + // transformed into Rec(1,1). + // + // X+X*2+Y-Y+34-17 would be transformed into 3*X + 17, where X and Y are + // ValueUnknown nodes (such as a load instruction). + SENode* SimplifyExpression(SENode* node); + + // Add |prospective_node| into the cache and return a raw pointer to it. If + // |prospective_node| is already in the cache just return the raw pointer. + SENode* GetCachedOrAdd(std::unique_ptr prospective_node); + + // Checks that the graph starting from |node| is invariant to the |loop|. + bool IsLoopInvariant(const Loop* loop, const SENode* node) const; + + // Sets |is_gt_zero| to true if |node| represent a value always strictly + // greater than 0. The result of |is_gt_zero| is valid only if the function + // returns true. + bool IsAlwaysGreaterThanZero(SENode* node, bool* is_gt_zero) const; + + // Sets |is_ge_zero| to true if |node| represent a value greater or equals to + // 0. The result of |is_ge_zero| is valid only if the function returns true. + bool IsAlwaysGreaterOrEqualToZero(SENode* node, bool* is_ge_zero) const; + + // Find the recurrent term belonging to |loop| in the graph starting from + // |node| and return the coefficient of that recurrent term. Constant zero + // will be returned if no recurrent could be found. |node| should be in + // simplest form. + SENode* GetCoefficientFromRecurrentTerm(SENode* node, const Loop* loop); + + // Return a rebuilt graph starting from |node| with the recurrent expression + // belonging to |loop| being zeroed out. Returned node will be simplified. + SENode* BuildGraphWithoutRecurrentTerm(SENode* node, const Loop* loop); + + // Return the recurrent term belonging to |loop| if it appears in the graph + // starting at |node| or null if it doesn't. + SERecurrentNode* GetRecurrentTerm(SENode* node, const Loop* loop); + + SENode* UpdateChildNode(SENode* parent, SENode* child, SENode* new_child); + + // The loops in |loop_pair| will be considered the same when constructing + // SERecurrentNode objects. This enables analysing dependencies that will be + // created during loop fusion. + void AddLoopsToPretendAreTheSame( + const std::pair& loop_pair) { + pretend_equal_[std::get<1>(loop_pair)] = std::get<0>(loop_pair); + } + + private: + SENode* AnalyzeConstant(const Instruction* inst); + + // Handles both addition and subtraction. If the |instruction| is OpISub + // then the resulting node will be op1+(-op2) otherwise if it is OpIAdd then + // the result will be op1+op2. |instruction| must be OpIAdd or OpISub. + SENode* AnalyzeAddOp(const Instruction* instruction); + + SENode* AnalyzeMultiplyOp(const Instruction* multiply); + + SENode* AnalyzePhiInstruction(const Instruction* phi); + + IRContext* context_; + + // A map of instructions to SENodes. This is used to track recurrent + // expressions as they are added when analyzing instructions. Recurrent + // expressions come from phi nodes which by nature can include recursion so we + // check if nodes have already been built when analyzing instructions. + std::map recurrent_node_map_; + + // On creation we create and cache the CantCompute node so we not need to + // perform a needless create step. + SENode* cached_cant_compute_; + + // Helper functor to allow two unique_ptr to nodes to be compare. Only + // needed + // for the unordered_set implementation. + struct NodePointersEquality { + bool operator()(const std::unique_ptr& lhs, + const std::unique_ptr& rhs) const { + return *lhs == *rhs; + } + }; + + // Cache of nodes. All pointers to the nodes are references to the memory + // managed by they set. + std::unordered_set, SENodeHash, NodePointersEquality> + node_cache_; + + // Loops that should be considered the same for performing analysis for loop + // fusion. + std::map pretend_equal_; +}; + +// Wrapping class to manipulate SENode pointer using + - * / operators. +class SExpression { + public: + // Implicit on purpose ! + SExpression(SENode* node) + : node_(node->GetParentAnalysis()->SimplifyExpression(node)), + scev_(node->GetParentAnalysis()) {} + + inline operator SENode*() const { return node_; } + inline SENode* operator->() const { return node_; } + const SENode& operator*() const { return *node_; } + + inline ScalarEvolutionAnalysis* GetScalarEvolutionAnalysis() const { + return scev_; + } + + inline SExpression operator+(SENode* rhs) const; + template ::value, int>::type = 0> + inline SExpression operator+(T integer) const; + inline SExpression operator+(SExpression rhs) const; + + inline SExpression operator-() const; + inline SExpression operator-(SENode* rhs) const; + template ::value, int>::type = 0> + inline SExpression operator-(T integer) const; + inline SExpression operator-(SExpression rhs) const; + + inline SExpression operator*(SENode* rhs) const; + template ::value, int>::type = 0> + inline SExpression operator*(T integer) const; + inline SExpression operator*(SExpression rhs) const; + + template ::value, int>::type = 0> + inline std::pair operator/(T integer) const; + // Try to perform a division. Returns the pair . If it fails to simplify it, the function returns a + // CanNotCompute node. + std::pair operator/(SExpression rhs) const; + + private: + SENode* node_; + ScalarEvolutionAnalysis* scev_; +}; + +inline SExpression SExpression::operator+(SENode* rhs) const { + return scev_->CreateAddNode(node_, rhs); +} + +template ::value, int>::type> +inline SExpression SExpression::operator+(T integer) const { + return *this + scev_->CreateConstant(integer); +} + +inline SExpression SExpression::operator+(SExpression rhs) const { + return *this + rhs.node_; +} + +inline SExpression SExpression::operator-() const { + return scev_->CreateNegation(node_); +} + +inline SExpression SExpression::operator-(SENode* rhs) const { + return *this + scev_->CreateNegation(rhs); +} + +template ::value, int>::type> +inline SExpression SExpression::operator-(T integer) const { + return *this - scev_->CreateConstant(integer); +} + +inline SExpression SExpression::operator-(SExpression rhs) const { + return *this - rhs.node_; +} + +inline SExpression SExpression::operator*(SENode* rhs) const { + return scev_->CreateMultiplyNode(node_, rhs); +} + +template ::value, int>::type> +inline SExpression SExpression::operator*(T integer) const { + return *this * scev_->CreateConstant(integer); +} + +inline SExpression SExpression::operator*(SExpression rhs) const { + return *this * rhs.node_; +} + +template ::value, int>::type> +inline std::pair SExpression::operator/(T integer) const { + return *this / scev_->CreateConstant(integer); +} + +template ::value, int>::type> +inline SExpression operator+(T lhs, SExpression rhs) { + return rhs + lhs; +} +inline SExpression operator+(SENode* lhs, SExpression rhs) { return rhs + lhs; } + +template ::value, int>::type> +inline SExpression operator-(T lhs, SExpression rhs) { + // NOLINTNEXTLINE(whitespace/braces) + return SExpression{rhs.GetScalarEvolutionAnalysis()->CreateConstant(lhs)} - + rhs; +} +inline SExpression operator-(SENode* lhs, SExpression rhs) { + // NOLINTNEXTLINE(whitespace/braces) + return SExpression{lhs} - rhs; +} + +template ::value, int>::type> +inline SExpression operator*(T lhs, SExpression rhs) { + return rhs * lhs; +} +inline SExpression operator*(SENode* lhs, SExpression rhs) { return rhs * lhs; } + +template ::value, int>::type> +inline std::pair operator/(T lhs, SExpression rhs) { + // NOLINTNEXTLINE(whitespace/braces) + return SExpression{rhs.GetScalarEvolutionAnalysis()->CreateConstant(lhs)} / + rhs; +} +inline std::pair operator/(SENode* lhs, SExpression rhs) { + // NOLINTNEXTLINE(whitespace/braces) + return SExpression{lhs} / rhs; +} + +} // namespace opt +} // namespace spvtools +#endif // SOURCE_OPT_SCALAR_ANALYSIS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis_nodes.h b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis_nodes.h new file mode 100644 index 000000000000..91ce446f3d1c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis_nodes.h @@ -0,0 +1,347 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASI, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_SCALAR_ANALYSIS_NODES_H_ +#define SOURCE_OPT_SCALAR_ANALYSIS_NODES_H_ + +#include +#include +#include +#include + +#include "source/opt/tree_iterator.h" + +namespace spvtools { +namespace opt { + +class Loop; +class ScalarEvolutionAnalysis; +class SEConstantNode; +class SERecurrentNode; +class SEAddNode; +class SEMultiplyNode; +class SENegative; +class SEValueUnknown; +class SECantCompute; + +// Abstract class representing a node in the scalar evolution DAG. Each node +// contains a vector of pointers to its children and each subclass of SENode +// implements GetType and an As method to allow casting. SENodes can be hashed +// using the SENodeHash functor. The vector of children is sorted when a node is +// added. This is important as it allows the hash of X+Y to be the same as Y+X. +class SENode { + public: + enum SENodeType { + Constant, + RecurrentAddExpr, + Add, + Multiply, + Negative, + ValueUnknown, + CanNotCompute + }; + + using ChildContainerType = std::vector; + + explicit SENode(ScalarEvolutionAnalysis* parent_analysis) + : parent_analysis_(parent_analysis), unique_id_(++NumberOfNodes) {} + + virtual SENodeType GetType() const = 0; + + virtual ~SENode() {} + + virtual inline void AddChild(SENode* child) { + // If this is a constant node, assert. + if (AsSEConstantNode()) { + assert(false && "Trying to add a child node to a constant!"); + } + + // Find the first point in the vector where |child| is greater than the node + // currently in the vector. + auto find_first_less_than = [child](const SENode* node) { + return child->unique_id_ <= node->unique_id_; + }; + + auto position = std::find_if_not(children_.begin(), children_.end(), + find_first_less_than); + // Children are sorted so the hashing and equality operator will be the same + // for a node with the same children. X+Y should be the same as Y+X. + children_.insert(position, child); + } + + // Get the type as an std::string. This is used to represent the node in the + // dot output and is used to hash the type as well. + std::string AsString() const; + + // Dump the SENode and its immediate children, if |recurse| is true then it + // will recurse through all children to print the DAG starting from this node + // as a root. + void DumpDot(std::ostream& out, bool recurse = false) const; + + // Checks if two nodes are the same by hashing them. + bool operator==(const SENode& other) const; + + // Checks if two nodes are not the same by comparing the hashes. + bool operator!=(const SENode& other) const; + + // Return the child node at |index|. + inline SENode* GetChild(size_t index) { return children_[index]; } + inline const SENode* GetChild(size_t index) const { return children_[index]; } + + // Iterator to iterate over the child nodes. + using iterator = ChildContainerType::iterator; + using const_iterator = ChildContainerType::const_iterator; + + // Iterate over immediate child nodes. + iterator begin() { return children_.begin(); } + iterator end() { return children_.end(); } + + // Constant overloads for iterating over immediate child nodes. + const_iterator begin() const { return children_.cbegin(); } + const_iterator end() const { return children_.cend(); } + const_iterator cbegin() { return children_.cbegin(); } + const_iterator cend() { return children_.cend(); } + + // Collect all the recurrent nodes in this SENode + std::vector CollectRecurrentNodes() { + std::vector recurrent_nodes{}; + + if (auto recurrent_node = AsSERecurrentNode()) { + recurrent_nodes.push_back(recurrent_node); + } + + for (auto child : GetChildren()) { + auto child_recurrent_nodes = child->CollectRecurrentNodes(); + recurrent_nodes.insert(recurrent_nodes.end(), + child_recurrent_nodes.begin(), + child_recurrent_nodes.end()); + } + + return recurrent_nodes; + } + + // Collect all the value unknown nodes in this SENode + std::vector CollectValueUnknownNodes() { + std::vector value_unknown_nodes{}; + + if (auto value_unknown_node = AsSEValueUnknown()) { + value_unknown_nodes.push_back(value_unknown_node); + } + + for (auto child : GetChildren()) { + auto child_value_unknown_nodes = child->CollectValueUnknownNodes(); + value_unknown_nodes.insert(value_unknown_nodes.end(), + child_value_unknown_nodes.begin(), + child_value_unknown_nodes.end()); + } + + return value_unknown_nodes; + } + + // Iterator to iterate over the entire DAG. Even though we are using the tree + // iterator it should still be safe to iterate over. However, nodes with + // multiple parents will be visited multiple times, unlike in a tree. + using dag_iterator = TreeDFIterator; + using const_dag_iterator = TreeDFIterator; + + // Iterate over all child nodes in the graph. + dag_iterator graph_begin() { return dag_iterator(this); } + dag_iterator graph_end() { return dag_iterator(); } + const_dag_iterator graph_begin() const { return graph_cbegin(); } + const_dag_iterator graph_end() const { return graph_cend(); } + const_dag_iterator graph_cbegin() const { return const_dag_iterator(this); } + const_dag_iterator graph_cend() const { return const_dag_iterator(); } + + // Return the vector of immediate children. + const ChildContainerType& GetChildren() const { return children_; } + ChildContainerType& GetChildren() { return children_; } + + // Return true if this node is a can't compute node. + bool IsCantCompute() const { return GetType() == CanNotCompute; } + +// Implements a casting method for each type. +// clang-format off +#define DeclareCastMethod(target) \ + virtual target* As##target() { return nullptr; } \ + virtual const target* As##target() const { return nullptr; } + DeclareCastMethod(SEConstantNode) + DeclareCastMethod(SERecurrentNode) + DeclareCastMethod(SEAddNode) + DeclareCastMethod(SEMultiplyNode) + DeclareCastMethod(SENegative) + DeclareCastMethod(SEValueUnknown) + DeclareCastMethod(SECantCompute) +#undef DeclareCastMethod + + // Get the analysis which has this node in its cache. + inline ScalarEvolutionAnalysis* GetParentAnalysis() const { + return parent_analysis_; + } + + protected: + ChildContainerType children_; + + ScalarEvolutionAnalysis* parent_analysis_; + + // The unique id of this node, assigned on creation by incrementing the static + // node count. + uint32_t unique_id_; + + // The number of nodes created. + static uint32_t NumberOfNodes; +}; +// clang-format on + +// Function object to handle the hashing of SENodes. Hashing algorithm hashes +// the type (as a string), the literal value of any constants, and the child +// pointers which are assumed to be unique. +struct SENodeHash { + size_t operator()(const std::unique_ptr& node) const; + size_t operator()(const SENode* node) const; +}; + +// A node representing a constant integer. +class SEConstantNode : public SENode { + public: + SEConstantNode(ScalarEvolutionAnalysis* parent_analysis, int64_t value) + : SENode(parent_analysis), literal_value_(value) {} + + SENodeType GetType() const final { return Constant; } + + int64_t FoldToSingleValue() const { return literal_value_; } + + SEConstantNode* AsSEConstantNode() override { return this; } + const SEConstantNode* AsSEConstantNode() const override { return this; } + + inline void AddChild(SENode*) final { + assert(false && "Attempting to add a child to a constant node!"); + } + + protected: + int64_t literal_value_; +}; + +// A node representing a recurrent expression in the code. A recurrent +// expression is an expression whose value can be expressed as a linear +// expression of the loop iterations. Such as an induction variable. The actual +// value of a recurrent expression is coefficent_ * iteration + offset_, hence +// an induction variable i=0, i++ becomes a recurrent expression with an offset +// of zero and a coefficient of one. +class SERecurrentNode : public SENode { + public: + SERecurrentNode(ScalarEvolutionAnalysis* parent_analysis, const Loop* loop) + : SENode(parent_analysis), loop_(loop) {} + + SENodeType GetType() const final { return RecurrentAddExpr; } + + inline void AddCoefficient(SENode* child) { + coefficient_ = child; + SENode::AddChild(child); + } + + inline void AddOffset(SENode* child) { + offset_ = child; + SENode::AddChild(child); + } + + inline const SENode* GetCoefficient() const { return coefficient_; } + inline SENode* GetCoefficient() { return coefficient_; } + + inline const SENode* GetOffset() const { return offset_; } + inline SENode* GetOffset() { return offset_; } + + // Return the loop which this recurrent expression is recurring within. + const Loop* GetLoop() const { return loop_; } + + SERecurrentNode* AsSERecurrentNode() override { return this; } + const SERecurrentNode* AsSERecurrentNode() const override { return this; } + + private: + SENode* coefficient_; + SENode* offset_; + const Loop* loop_; +}; + +// A node representing an addition operation between child nodes. +class SEAddNode : public SENode { + public: + explicit SEAddNode(ScalarEvolutionAnalysis* parent_analysis) + : SENode(parent_analysis) {} + + SENodeType GetType() const final { return Add; } + + SEAddNode* AsSEAddNode() override { return this; } + const SEAddNode* AsSEAddNode() const override { return this; } +}; + +// A node representing a multiply operation between child nodes. +class SEMultiplyNode : public SENode { + public: + explicit SEMultiplyNode(ScalarEvolutionAnalysis* parent_analysis) + : SENode(parent_analysis) {} + + SENodeType GetType() const final { return Multiply; } + + SEMultiplyNode* AsSEMultiplyNode() override { return this; } + const SEMultiplyNode* AsSEMultiplyNode() const override { return this; } +}; + +// A node representing a unary negative operation. +class SENegative : public SENode { + public: + explicit SENegative(ScalarEvolutionAnalysis* parent_analysis) + : SENode(parent_analysis) {} + + SENodeType GetType() const final { return Negative; } + + SENegative* AsSENegative() override { return this; } + const SENegative* AsSENegative() const override { return this; } +}; + +// A node representing a value which we do not know the value of, such as a load +// instruction. +class SEValueUnknown : public SENode { + public: + // SEValueUnknowns must come from an instruction |unique_id| is the unique id + // of that instruction. This is so we cancompare value unknowns and have a + // unique value unknown for each instruction. + SEValueUnknown(ScalarEvolutionAnalysis* parent_analysis, uint32_t result_id) + : SENode(parent_analysis), result_id_(result_id) {} + + SENodeType GetType() const final { return ValueUnknown; } + + SEValueUnknown* AsSEValueUnknown() override { return this; } + const SEValueUnknown* AsSEValueUnknown() const override { return this; } + + inline uint32_t ResultId() const { return result_id_; } + + private: + uint32_t result_id_; +}; + +// A node which we cannot reason about at all. +class SECantCompute : public SENode { + public: + explicit SECantCompute(ScalarEvolutionAnalysis* parent_analysis) + : SENode(parent_analysis) {} + + SENodeType GetType() const final { return CanNotCompute; } + + SECantCompute* AsSECantCompute() override { return this; } + const SECantCompute* AsSECantCompute() const override { return this; } +}; + +} // namespace opt +} // namespace spvtools +#endif // SOURCE_OPT_SCALAR_ANALYSIS_NODES_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis_simplification.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis_simplification.cpp new file mode 100644 index 000000000000..3c0947cdae63 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_analysis_simplification.cpp @@ -0,0 +1,538 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include + +#include "source/opt/scalar_analysis.h" + +// Simplifies scalar analysis DAGs. +// +// 1. Given a node passed to SimplifyExpression we first simplify the graph by +// calling SimplifyPolynomial. This groups like nodes following basic arithmetic +// rules, so multiple adds of the same load instruction could be grouped into a +// single multiply of that instruction. SimplifyPolynomial will traverse the DAG +// and build up an accumulator buffer for each class of instruction it finds. +// For example take the loop: +// for (i=0, i accumulators_; +}; + +// From a |multiply| build up the accumulator objects. +bool SENodeSimplifyImpl::AccumulatorsFromMultiply(SENode* multiply, + bool negation) { + if (multiply->GetChildren().size() != 2 || + multiply->GetType() != SENode::Multiply) + return false; + + SENode* operand_1 = multiply->GetChild(0); + SENode* operand_2 = multiply->GetChild(1); + + SENode* value_unknown = nullptr; + SENode* constant = nullptr; + + // Work out which operand is the unknown value. + if (operand_1->GetType() == SENode::ValueUnknown || + operand_1->GetType() == SENode::RecurrentAddExpr) + value_unknown = operand_1; + else if (operand_2->GetType() == SENode::ValueUnknown || + operand_2->GetType() == SENode::RecurrentAddExpr) + value_unknown = operand_2; + + // Work out which operand is the constant coefficient. + if (operand_1->GetType() == SENode::Constant) + constant = operand_1; + else if (operand_2->GetType() == SENode::Constant) + constant = operand_2; + + // If the expression is not a variable multiplied by a constant coefficient, + // exit out. + if (!(value_unknown && constant)) { + return false; + } + + int64_t sign = negation ? -1 : 1; + + auto iterator = accumulators_.find(value_unknown); + int64_t new_value = constant->AsSEConstantNode()->FoldToSingleValue() * sign; + // Add the result of the multiplication to the accumulators. + if (iterator != accumulators_.end()) { + (*iterator).second += new_value; + } else { + accumulators_.insert({value_unknown, new_value}); + } + + return true; +} + +SENode* SENodeSimplifyImpl::Simplify() { + // We only handle graphs with an addition, multiplication, or negation, at the + // root. + if (node_->GetType() != SENode::Add && node_->GetType() != SENode::Multiply && + node_->GetType() != SENode::Negative) + return node_; + + SENode* simplified_polynomial = SimplifyPolynomial(); + + SERecurrentNode* recurrent_expr = nullptr; + node_ = simplified_polynomial; + + // Fold recurrent expressions which are with respect to the same loop into a + // single recurrent expression. + simplified_polynomial = FoldRecurrentAddExpressions(simplified_polynomial); + + simplified_polynomial = + EliminateZeroCoefficientRecurrents(simplified_polynomial); + + // Traverse the immediate children of the new node to find the recurrent + // expression. If there is more than one there is nothing further we can do. + for (SENode* child : simplified_polynomial->GetChildren()) { + if (child->GetType() == SENode::RecurrentAddExpr) { + recurrent_expr = child->AsSERecurrentNode(); + } + } + + // We need to count the number of unique recurrent expressions in the DAG to + // ensure there is only one. + for (auto child_iterator = simplified_polynomial->graph_begin(); + child_iterator != simplified_polynomial->graph_end(); ++child_iterator) { + if (child_iterator->GetType() == SENode::RecurrentAddExpr && + recurrent_expr != child_iterator->AsSERecurrentNode()) { + return simplified_polynomial; + } + } + + if (recurrent_expr) { + return SimplifyRecurrentAddExpression(recurrent_expr); + } + + return simplified_polynomial; +} + +// Traverse the graph to build up the accumulator objects. +void SENodeSimplifyImpl::GatherAccumulatorsFromChildNodes(SENode* new_node, + SENode* child, + bool negation) { + int32_t sign = negation ? -1 : 1; + + if (child->GetType() == SENode::Constant) { + // Collect all the constants and add them together. + constant_accumulator_ += + child->AsSEConstantNode()->FoldToSingleValue() * sign; + + } else if (child->GetType() == SENode::ValueUnknown || + child->GetType() == SENode::RecurrentAddExpr) { + // To rebuild the graph of X+X+X*2 into 4*X we count the occurrences of X + // and create a new node of count*X after. X can either be a ValueUnknown or + // a RecurrentAddExpr. The count for each X is stored in the accumulators_ + // map. + + auto iterator = accumulators_.find(child); + // If we've encountered this term before add to the accumulator for it. + if (iterator == accumulators_.end()) + accumulators_.insert({child, sign}); + else + iterator->second += sign; + + } else if (child->GetType() == SENode::Multiply) { + if (!AccumulatorsFromMultiply(child, negation)) { + new_node->AddChild(child); + } + + } else if (child->GetType() == SENode::Add) { + for (SENode* next_child : *child) { + GatherAccumulatorsFromChildNodes(new_node, next_child, negation); + } + + } else if (child->GetType() == SENode::Negative) { + SENode* negated_node = child->GetChild(0); + GatherAccumulatorsFromChildNodes(new_node, negated_node, !negation); + } else { + // If we can't work out how to fold the expression just add it back into + // the graph. + new_node->AddChild(child); + } +} + +SERecurrentNode* SENodeSimplifyImpl::UpdateCoefficient( + SERecurrentNode* recurrent, int64_t coefficient_update) const { + std::unique_ptr new_recurrent_node{new SERecurrentNode( + recurrent->GetParentAnalysis(), recurrent->GetLoop())}; + + SENode* new_coefficient = analysis_.CreateMultiplyNode( + recurrent->GetCoefficient(), + analysis_.CreateConstant(coefficient_update)); + + // See if the node can be simplified. + SENode* simplified = analysis_.SimplifyExpression(new_coefficient); + if (simplified->GetType() != SENode::CanNotCompute) + new_coefficient = simplified; + + if (coefficient_update < 0) { + new_recurrent_node->AddOffset( + analysis_.CreateNegation(recurrent->GetOffset())); + } else { + new_recurrent_node->AddOffset(recurrent->GetOffset()); + } + + new_recurrent_node->AddCoefficient(new_coefficient); + + return analysis_.GetCachedOrAdd(std::move(new_recurrent_node)) + ->AsSERecurrentNode(); +} + +// Simplify all the terms in the polynomial function. +SENode* SENodeSimplifyImpl::SimplifyPolynomial() { + std::unique_ptr new_add{new SEAddNode(node_->GetParentAnalysis())}; + + // Traverse the graph and gather the accumulators from it. + GatherAccumulatorsFromChildNodes(new_add.get(), node_, false); + + // Fold all the constants into a single constant node. + if (constant_accumulator_ != 0) { + new_add->AddChild(analysis_.CreateConstant(constant_accumulator_)); + } + + for (auto& pair : accumulators_) { + SENode* term = pair.first; + int64_t count = pair.second; + + // We can eliminate the term completely. + if (count == 0) continue; + + if (count == 1) { + new_add->AddChild(term); + } else if (count == -1 && term->GetType() != SENode::RecurrentAddExpr) { + // If the count is -1 we can just add a negative version of that node, + // unless it is a recurrent expression as we would rather the negative + // goes on the recurrent expressions children. This makes it easier to + // work with in other places. + new_add->AddChild(analysis_.CreateNegation(term)); + } else { + // Output value unknown terms as count*term and output recurrent + // expression terms as rec(offset, coefficient + count) offset and + // coefficient are the same as in the original expression. + if (term->GetType() == SENode::ValueUnknown) { + SENode* count_as_constant = analysis_.CreateConstant(count); + new_add->AddChild( + analysis_.CreateMultiplyNode(count_as_constant, term)); + } else { + assert(term->GetType() == SENode::RecurrentAddExpr && + "We only handle value unknowns or recurrent expressions"); + + // Create a new recurrent expression by adding the count to the + // coefficient of the old one. + new_add->AddChild(UpdateCoefficient(term->AsSERecurrentNode(), count)); + } + } + } + + // If there is only one term in the addition left just return that term. + if (new_add->GetChildren().size() == 1) { + return new_add->GetChild(0); + } + + // If there are no terms left in the addition just return 0. + if (new_add->GetChildren().size() == 0) { + return analysis_.CreateConstant(0); + } + + return analysis_.GetCachedOrAdd(std::move(new_add)); +} + +SENode* SENodeSimplifyImpl::FoldRecurrentAddExpressions(SENode* root) { + std::unique_ptr new_node{new SEAddNode(&analysis_)}; + + // A mapping of loops to the list of recurrent expressions which are with + // respect to those loops. + std::map>> + loops_to_recurrent{}; + + bool has_multiple_same_loop_recurrent_terms = false; + + for (SENode* child : *root) { + bool negation = false; + + if (child->GetType() == SENode::Negative) { + child = child->GetChild(0); + negation = true; + } + + if (child->GetType() == SENode::RecurrentAddExpr) { + const Loop* loop = child->AsSERecurrentNode()->GetLoop(); + + SERecurrentNode* rec = child->AsSERecurrentNode(); + if (loops_to_recurrent.find(loop) == loops_to_recurrent.end()) { + loops_to_recurrent[loop] = {std::make_pair(rec, negation)}; + } else { + loops_to_recurrent[loop].push_back(std::make_pair(rec, negation)); + has_multiple_same_loop_recurrent_terms = true; + } + } else { + new_node->AddChild(child); + } + } + + if (!has_multiple_same_loop_recurrent_terms) return root; + + for (auto pair : loops_to_recurrent) { + std::vector>& recurrent_expressions = + pair.second; + const Loop* loop = pair.first; + + std::unique_ptr new_coefficient{new SEAddNode(&analysis_)}; + std::unique_ptr new_offset{new SEAddNode(&analysis_)}; + + for (auto node_pair : recurrent_expressions) { + SERecurrentNode* node = node_pair.first; + bool negative = node_pair.second; + + if (!negative) { + new_coefficient->AddChild(node->GetCoefficient()); + new_offset->AddChild(node->GetOffset()); + } else { + new_coefficient->AddChild( + analysis_.CreateNegation(node->GetCoefficient())); + new_offset->AddChild(analysis_.CreateNegation(node->GetOffset())); + } + } + + std::unique_ptr new_recurrent{ + new SERecurrentNode(&analysis_, loop)}; + + SENode* new_coefficient_simplified = + analysis_.SimplifyExpression(new_coefficient.get()); + + SENode* new_offset_simplified = + analysis_.SimplifyExpression(new_offset.get()); + + if (new_coefficient_simplified->GetType() == SENode::Constant && + new_coefficient_simplified->AsSEConstantNode()->FoldToSingleValue() == + 0) { + return new_offset_simplified; + } + + new_recurrent->AddCoefficient(new_coefficient_simplified); + new_recurrent->AddOffset(new_offset_simplified); + + new_node->AddChild(analysis_.GetCachedOrAdd(std::move(new_recurrent))); + } + + // If we only have one child in the add just return that. + if (new_node->GetChildren().size() == 1) { + return new_node->GetChild(0); + } + + return analysis_.GetCachedOrAdd(std::move(new_node)); +} + +SENode* SENodeSimplifyImpl::EliminateZeroCoefficientRecurrents(SENode* node) { + if (node->GetType() != SENode::Add) return node; + + bool has_change = false; + + std::vector new_children{}; + for (SENode* child : *node) { + if (child->GetType() == SENode::RecurrentAddExpr) { + SENode* coefficient = child->AsSERecurrentNode()->GetCoefficient(); + // If coefficient is zero then we can eliminate the recurrent expression + // entirely and just return the offset as the recurrent expression is + // representing the equation coefficient*iterations + offset. + if (coefficient->GetType() == SENode::Constant && + coefficient->AsSEConstantNode()->FoldToSingleValue() == 0) { + new_children.push_back(child->AsSERecurrentNode()->GetOffset()); + has_change = true; + } else { + new_children.push_back(child); + } + } else { + new_children.push_back(child); + } + } + + if (!has_change) return node; + + std::unique_ptr new_add{new SEAddNode(node_->GetParentAnalysis())}; + + for (SENode* child : new_children) { + new_add->AddChild(child); + } + + return analysis_.GetCachedOrAdd(std::move(new_add)); +} + +SENode* SENodeSimplifyImpl::SimplifyRecurrentAddExpression( + SERecurrentNode* recurrent_expr) { + const std::vector& children = node_->GetChildren(); + + std::unique_ptr recurrent_node{new SERecurrentNode( + recurrent_expr->GetParentAnalysis(), recurrent_expr->GetLoop())}; + + // Create and simplify the new offset node. + std::unique_ptr new_offset{ + new SEAddNode(recurrent_expr->GetParentAnalysis())}; + new_offset->AddChild(recurrent_expr->GetOffset()); + + for (SENode* child : children) { + if (child->GetType() != SENode::RecurrentAddExpr) { + new_offset->AddChild(child); + } + } + + // Simplify the new offset. + SENode* simplified_child = analysis_.SimplifyExpression(new_offset.get()); + + // If the child can be simplified, add the simplified form otherwise, add it + // via the usual caching mechanism. + if (simplified_child->GetType() != SENode::CanNotCompute) { + recurrent_node->AddOffset(simplified_child); + } else { + recurrent_expr->AddOffset(analysis_.GetCachedOrAdd(std::move(new_offset))); + } + + recurrent_node->AddCoefficient(recurrent_expr->GetCoefficient()); + + return analysis_.GetCachedOrAdd(std::move(recurrent_node)); +} + +/* + * Scalar Analysis simplification public methods. + */ + +SENode* ScalarEvolutionAnalysis::SimplifyExpression(SENode* node) { + SENodeSimplifyImpl impl{this, node}; + + return impl.Simplify(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/scalar_replacement_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_replacement_pass.cpp new file mode 100644 index 000000000000..38c8aeccc61d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_replacement_pass.cpp @@ -0,0 +1,1013 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/scalar_replacement_pass.h" + +#include +#include +#include +#include + +#include "source/extensions.h" +#include "source/opt/reflect.h" +#include "source/opt/types.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kDebugValueOperandValueIndex = 5; +constexpr uint32_t kDebugValueOperandExpressionIndex = 6; +constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; +} // namespace + +Pass::Status ScalarReplacementPass::Process() { + Status status = Status::SuccessWithoutChange; + for (auto& f : *get_module()) { + if (f.IsDeclaration()) { + continue; + } + + Status functionStatus = ProcessFunction(&f); + if (functionStatus == Status::Failure) + return functionStatus; + else if (functionStatus == Status::SuccessWithChange) + status = functionStatus; + } + + return status; +} + +Pass::Status ScalarReplacementPass::ProcessFunction(Function* function) { + std::queue worklist; + BasicBlock& entry = *function->begin(); + for (auto iter = entry.begin(); iter != entry.end(); ++iter) { + // Function storage class OpVariables must appear as the first instructions + // of the entry block. + if (iter->opcode() != spv::Op::OpVariable) break; + + Instruction* varInst = &*iter; + if (CanReplaceVariable(varInst)) { + worklist.push(varInst); + } + } + + Status status = Status::SuccessWithoutChange; + while (!worklist.empty()) { + Instruction* varInst = worklist.front(); + worklist.pop(); + + Status var_status = ReplaceVariable(varInst, &worklist); + if (var_status == Status::Failure) + return var_status; + else if (var_status == Status::SuccessWithChange) + status = var_status; + } + + return status; +} + +Pass::Status ScalarReplacementPass::ReplaceVariable( + Instruction* inst, std::queue* worklist) { + std::vector replacements; + if (!CreateReplacementVariables(inst, &replacements)) { + return Status::Failure; + } + + std::vector dead; + bool replaced_all_uses = get_def_use_mgr()->WhileEachUser( + inst, [this, &replacements, &dead](Instruction* user) { + if (user->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { + if (ReplaceWholeDebugDeclare(user, replacements)) { + dead.push_back(user); + return true; + } + return false; + } + if (user->GetCommonDebugOpcode() == CommonDebugInfoDebugValue) { + if (ReplaceWholeDebugValue(user, replacements)) { + dead.push_back(user); + return true; + } + return false; + } + if (!IsAnnotationInst(user->opcode())) { + switch (user->opcode()) { + case spv::Op::OpLoad: + if (ReplaceWholeLoad(user, replacements)) { + dead.push_back(user); + } else { + return false; + } + break; + case spv::Op::OpStore: + if (ReplaceWholeStore(user, replacements)) { + dead.push_back(user); + } else { + return false; + } + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + if (ReplaceAccessChain(user, replacements)) + dead.push_back(user); + else + return false; + break; + case spv::Op::OpName: + case spv::Op::OpMemberName: + break; + default: + assert(false && "Unexpected opcode"); + break; + } + } + return true; + }); + + if (replaced_all_uses) { + dead.push_back(inst); + } else { + return Status::Failure; + } + + // If there are no dead instructions to clean up, return with no changes. + if (dead.empty()) return Status::SuccessWithoutChange; + + // Clean up some dead code. + while (!dead.empty()) { + Instruction* toKill = dead.back(); + dead.pop_back(); + context()->KillInst(toKill); + } + + // Attempt to further scalarize. + for (auto var : replacements) { + if (var->opcode() == spv::Op::OpVariable) { + if (get_def_use_mgr()->NumUsers(var) == 0) { + context()->KillInst(var); + } else if (CanReplaceVariable(var)) { + worklist->push(var); + } + } + } + + return Status::SuccessWithChange; +} + +bool ScalarReplacementPass::ReplaceWholeDebugDeclare( + Instruction* dbg_decl, const std::vector& replacements) { + // Insert Deref operation to the front of the operation list of |dbg_decl|. + Instruction* dbg_expr = context()->get_def_use_mgr()->GetDef( + dbg_decl->GetSingleWordOperand(kDebugValueOperandExpressionIndex)); + auto* deref_expr = + context()->get_debug_info_mgr()->DerefDebugExpression(dbg_expr); + + // Add DebugValue instruction with Indexes operand and Deref operation. + int32_t idx = 0; + for (const auto* var : replacements) { + Instruction* insert_before = var->NextNode(); + while (insert_before->opcode() == spv::Op::OpVariable) + insert_before = insert_before->NextNode(); + assert(insert_before != nullptr && "unexpected end of list"); + Instruction* added_dbg_value = + context()->get_debug_info_mgr()->AddDebugValueForDecl( + dbg_decl, /*value_id=*/var->result_id(), + /*insert_before=*/insert_before, /*scope_and_line=*/dbg_decl); + + if (added_dbg_value == nullptr) return false; + added_dbg_value->AddOperand( + {SPV_OPERAND_TYPE_ID, + {context()->get_constant_mgr()->GetSIntConstId(idx)}}); + added_dbg_value->SetOperand(kDebugValueOperandExpressionIndex, + {deref_expr->result_id()}); + if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) { + context()->get_def_use_mgr()->AnalyzeInstUse(added_dbg_value); + } + ++idx; + } + return true; +} + +bool ScalarReplacementPass::ReplaceWholeDebugValue( + Instruction* dbg_value, const std::vector& replacements) { + int32_t idx = 0; + BasicBlock* block = context()->get_instr_block(dbg_value); + for (auto var : replacements) { + // Clone the DebugValue. + std::unique_ptr new_dbg_value(dbg_value->Clone(context())); + uint32_t new_id = TakeNextId(); + if (new_id == 0) return false; + new_dbg_value->SetResultId(new_id); + // Update 'Value' operand to the |replacements|. + new_dbg_value->SetOperand(kDebugValueOperandValueIndex, {var->result_id()}); + // Append 'Indexes' operand. + new_dbg_value->AddOperand( + {SPV_OPERAND_TYPE_ID, + {context()->get_constant_mgr()->GetSIntConstId(idx)}}); + // Insert the new DebugValue to the basic block. + auto* added_instr = dbg_value->InsertBefore(std::move(new_dbg_value)); + get_def_use_mgr()->AnalyzeInstDefUse(added_instr); + context()->set_instr_block(added_instr, block); + ++idx; + } + return true; +} + +bool ScalarReplacementPass::ReplaceWholeLoad( + Instruction* load, const std::vector& replacements) { + // Replaces the load of the entire composite with a load from each replacement + // variable followed by a composite construction. + BasicBlock* block = context()->get_instr_block(load); + std::vector loads; + loads.reserve(replacements.size()); + BasicBlock::iterator where(load); + for (auto var : replacements) { + // Create a load of each replacement variable. + if (var->opcode() != spv::Op::OpVariable) { + loads.push_back(var); + continue; + } + + Instruction* type = GetStorageType(var); + uint32_t loadId = TakeNextId(); + if (loadId == 0) { + return false; + } + std::unique_ptr newLoad( + new Instruction(context(), spv::Op::OpLoad, type->result_id(), loadId, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); + // Copy memory access attributes which start at index 1. Index 0 is the + // pointer to load. + for (uint32_t i = 1; i < load->NumInOperands(); ++i) { + Operand copy(load->GetInOperand(i)); + newLoad->AddOperand(std::move(copy)); + } + where = where.InsertBefore(std::move(newLoad)); + get_def_use_mgr()->AnalyzeInstDefUse(&*where); + context()->set_instr_block(&*where, block); + where->UpdateDebugInfoFrom(load); + loads.push_back(&*where); + } + + // Construct a new composite. + uint32_t compositeId = TakeNextId(); + if (compositeId == 0) { + return false; + } + where = load; + std::unique_ptr compositeConstruct( + new Instruction(context(), spv::Op::OpCompositeConstruct, load->type_id(), + compositeId, {})); + for (auto l : loads) { + Operand op(SPV_OPERAND_TYPE_ID, + std::initializer_list{l->result_id()}); + compositeConstruct->AddOperand(std::move(op)); + } + where = where.InsertBefore(std::move(compositeConstruct)); + get_def_use_mgr()->AnalyzeInstDefUse(&*where); + where->UpdateDebugInfoFrom(load); + context()->set_instr_block(&*where, block); + context()->ReplaceAllUsesWith(load->result_id(), compositeId); + return true; +} + +bool ScalarReplacementPass::ReplaceWholeStore( + Instruction* store, const std::vector& replacements) { + // Replaces a store to the whole composite with a series of extract and stores + // to each element. + uint32_t storeInput = store->GetSingleWordInOperand(1u); + BasicBlock* block = context()->get_instr_block(store); + BasicBlock::iterator where(store); + uint32_t elementIndex = 0; + for (auto var : replacements) { + // Create the extract. + if (var->opcode() != spv::Op::OpVariable) { + elementIndex++; + continue; + } + + Instruction* type = GetStorageType(var); + uint32_t extractId = TakeNextId(); + if (extractId == 0) { + return false; + } + std::unique_ptr extract(new Instruction( + context(), spv::Op::OpCompositeExtract, type->result_id(), extractId, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {storeInput}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {elementIndex++}}})); + auto iter = where.InsertBefore(std::move(extract)); + iter->UpdateDebugInfoFrom(store); + get_def_use_mgr()->AnalyzeInstDefUse(&*iter); + context()->set_instr_block(&*iter, block); + + // Create the store. + std::unique_ptr newStore( + new Instruction(context(), spv::Op::OpStore, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}, + {SPV_OPERAND_TYPE_ID, {extractId}}})); + // Copy memory access attributes which start at index 2. Index 0 is the + // pointer and index 1 is the data. + for (uint32_t i = 2; i < store->NumInOperands(); ++i) { + Operand copy(store->GetInOperand(i)); + newStore->AddOperand(std::move(copy)); + } + iter = where.InsertBefore(std::move(newStore)); + iter->UpdateDebugInfoFrom(store); + get_def_use_mgr()->AnalyzeInstDefUse(&*iter); + context()->set_instr_block(&*iter, block); + } + return true; +} + +bool ScalarReplacementPass::ReplaceAccessChain( + Instruction* chain, const std::vector& replacements) { + // Replaces the access chain with either another access chain (with one fewer + // indexes) or a direct use of the replacement variable. + uint32_t indexId = chain->GetSingleWordInOperand(1u); + const Instruction* index = get_def_use_mgr()->GetDef(indexId); + int64_t indexValue = context() + ->get_constant_mgr() + ->GetConstantFromInst(index) + ->GetSignExtendedValue(); + if (indexValue < 0 || + indexValue >= static_cast(replacements.size())) { + // Out of bounds access, this is illegal IR. Notice that OpAccessChain + // indexing is 0-based, so we should also reject index == size-of-array. + return false; + } else { + const Instruction* var = replacements[static_cast(indexValue)]; + if (chain->NumInOperands() > 2) { + // Replace input access chain with another access chain. + BasicBlock::iterator chainIter(chain); + uint32_t replacementId = TakeNextId(); + if (replacementId == 0) { + return false; + } + std::unique_ptr replacementChain(new Instruction( + context(), chain->opcode(), chain->type_id(), replacementId, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); + // Add the remaining indexes. + for (uint32_t i = 2; i < chain->NumInOperands(); ++i) { + Operand copy(chain->GetInOperand(i)); + replacementChain->AddOperand(std::move(copy)); + } + replacementChain->UpdateDebugInfoFrom(chain); + auto iter = chainIter.InsertBefore(std::move(replacementChain)); + get_def_use_mgr()->AnalyzeInstDefUse(&*iter); + context()->set_instr_block(&*iter, context()->get_instr_block(chain)); + context()->ReplaceAllUsesWith(chain->result_id(), replacementId); + } else { + // Replace with a use of the variable. + context()->ReplaceAllUsesWith(chain->result_id(), var->result_id()); + } + } + + return true; +} + +bool ScalarReplacementPass::CreateReplacementVariables( + Instruction* inst, std::vector* replacements) { + Instruction* type = GetStorageType(inst); + + std::unique_ptr> components_used = + GetUsedComponents(inst); + + uint32_t elem = 0; + switch (type->opcode()) { + case spv::Op::OpTypeStruct: + type->ForEachInOperand( + [this, inst, &elem, replacements, &components_used](uint32_t* id) { + if (!components_used || components_used->count(elem)) { + CreateVariable(*id, inst, elem, replacements); + } else { + replacements->push_back(GetUndef(*id)); + } + elem++; + }); + break; + case spv::Op::OpTypeArray: + for (uint32_t i = 0; i != GetArrayLength(type); ++i) { + if (!components_used || components_used->count(i)) { + CreateVariable(type->GetSingleWordInOperand(0u), inst, i, + replacements); + } else { + uint32_t element_type_id = type->GetSingleWordInOperand(0); + replacements->push_back(GetUndef(element_type_id)); + } + } + break; + + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: + for (uint32_t i = 0; i != GetNumElements(type); ++i) { + CreateVariable(type->GetSingleWordInOperand(0u), inst, i, replacements); + } + break; + + default: + assert(false && "Unexpected type."); + break; + } + + TransferAnnotations(inst, replacements); + return std::find(replacements->begin(), replacements->end(), nullptr) == + replacements->end(); +} + +Instruction* ScalarReplacementPass::GetUndef(uint32_t type_id) { + return get_def_use_mgr()->GetDef(Type2Undef(type_id)); +} + +void ScalarReplacementPass::TransferAnnotations( + const Instruction* source, std::vector* replacements) { + // Only transfer invariant and restrict decorations on the variable. There are + // no type or member decorations that are necessary to transfer. + for (auto inst : + get_decoration_mgr()->GetDecorationsFor(source->result_id(), false)) { + assert(inst->opcode() == spv::Op::OpDecorate); + auto decoration = spv::Decoration(inst->GetSingleWordInOperand(1u)); + if (decoration == spv::Decoration::Invariant || + decoration == spv::Decoration::Restrict) { + for (auto var : *replacements) { + if (var == nullptr) { + continue; + } + + std::unique_ptr annotation(new Instruction( + context(), spv::Op::OpDecorate, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}, + {SPV_OPERAND_TYPE_DECORATION, {uint32_t(decoration)}}})); + for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { + Operand copy(inst->GetInOperand(i)); + annotation->AddOperand(std::move(copy)); + } + context()->AddAnnotationInst(std::move(annotation)); + get_def_use_mgr()->AnalyzeInstUse(&*--context()->annotation_end()); + } + } + } +} + +void ScalarReplacementPass::CreateVariable( + uint32_t type_id, Instruction* var_inst, uint32_t index, + std::vector* replacements) { + uint32_t ptr_id = GetOrCreatePointerType(type_id); + uint32_t id = TakeNextId(); + + if (id == 0) { + replacements->push_back(nullptr); + } + + std::unique_ptr variable( + new Instruction(context(), spv::Op::OpVariable, ptr_id, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(spv::StorageClass::Function)}}})); + + BasicBlock* block = context()->get_instr_block(var_inst); + block->begin().InsertBefore(std::move(variable)); + Instruction* inst = &*block->begin(); + + // If varInst was initialized, make sure to initialize its replacement. + GetOrCreateInitialValue(var_inst, index, inst); + get_def_use_mgr()->AnalyzeInstDefUse(inst); + context()->set_instr_block(inst, block); + + CopyDecorationsToVariable(var_inst, inst, index); + inst->UpdateDebugInfoFrom(var_inst); + + replacements->push_back(inst); +} + +uint32_t ScalarReplacementPass::GetOrCreatePointerType(uint32_t id) { + auto iter = pointee_to_pointer_.find(id); + if (iter != pointee_to_pointer_.end()) return iter->second; + + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + uint32_t ptr_type_id = + type_mgr->FindPointerToType(id, spv::StorageClass::Function); + pointee_to_pointer_[id] = ptr_type_id; + return ptr_type_id; +} + +void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, + uint32_t index, + Instruction* newVar) { + assert(source->opcode() == spv::Op::OpVariable); + if (source->NumInOperands() < 2) return; + + uint32_t initId = source->GetSingleWordInOperand(1u); + uint32_t storageId = GetStorageType(newVar)->result_id(); + Instruction* init = get_def_use_mgr()->GetDef(initId); + uint32_t newInitId = 0; + // TODO(dnovillo): Refactor this with constant propagation. + if (init->opcode() == spv::Op::OpConstantNull) { + // Initialize to appropriate NULL. + auto iter = type_to_null_.find(storageId); + if (iter == type_to_null_.end()) { + newInitId = TakeNextId(); + type_to_null_[storageId] = newInitId; + context()->AddGlobalValue( + MakeUnique(context(), spv::Op::OpConstantNull, storageId, + newInitId, std::initializer_list{})); + Instruction* newNull = &*--context()->types_values_end(); + get_def_use_mgr()->AnalyzeInstDefUse(newNull); + } else { + newInitId = iter->second; + } + } else if (IsSpecConstantInst(init->opcode())) { + // Create a new constant extract. + newInitId = TakeNextId(); + context()->AddGlobalValue(MakeUnique( + context(), spv::Op::OpSpecConstantOp, storageId, newInitId, + std::initializer_list{ + {SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, + {uint32_t(spv::Op::OpCompositeExtract)}}, + {SPV_OPERAND_TYPE_ID, {init->result_id()}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {index}}})); + Instruction* newSpecConst = &*--context()->types_values_end(); + get_def_use_mgr()->AnalyzeInstDefUse(newSpecConst); + } else if (init->opcode() == spv::Op::OpConstantComposite) { + // Get the appropriate index constant. + newInitId = init->GetSingleWordInOperand(index); + Instruction* element = get_def_use_mgr()->GetDef(newInitId); + if (element->opcode() == spv::Op::OpUndef) { + // Undef is not a valid initializer for a variable. + newInitId = 0; + } + } else { + assert(false); + } + + if (newInitId != 0) { + newVar->AddOperand({SPV_OPERAND_TYPE_ID, {newInitId}}); + } +} + +uint64_t ScalarReplacementPass::GetArrayLength( + const Instruction* arrayType) const { + assert(arrayType->opcode() == spv::Op::OpTypeArray); + const Instruction* length = + get_def_use_mgr()->GetDef(arrayType->GetSingleWordInOperand(1u)); + return context() + ->get_constant_mgr() + ->GetConstantFromInst(length) + ->GetZeroExtendedValue(); +} + +uint64_t ScalarReplacementPass::GetNumElements(const Instruction* type) const { + assert(type->opcode() == spv::Op::OpTypeVector || + type->opcode() == spv::Op::OpTypeMatrix); + const Operand& op = type->GetInOperand(1u); + assert(op.words.size() <= 2); + uint64_t len = 0; + for (size_t i = 0; i != op.words.size(); ++i) { + len |= (static_cast(op.words[i]) << (32ull * i)); + } + return len; +} + +bool ScalarReplacementPass::IsSpecConstant(uint32_t id) const { + const Instruction* inst = get_def_use_mgr()->GetDef(id); + assert(inst); + return spvOpcodeIsSpecConstant(inst->opcode()); +} + +Instruction* ScalarReplacementPass::GetStorageType( + const Instruction* inst) const { + assert(inst->opcode() == spv::Op::OpVariable); + + uint32_t ptrTypeId = inst->type_id(); + uint32_t typeId = + get_def_use_mgr()->GetDef(ptrTypeId)->GetSingleWordInOperand(1u); + return get_def_use_mgr()->GetDef(typeId); +} + +bool ScalarReplacementPass::CanReplaceVariable( + const Instruction* varInst) const { + assert(varInst->opcode() == spv::Op::OpVariable); + + // Can only replace function scope variables. + if (spv::StorageClass(varInst->GetSingleWordInOperand(0u)) != + spv::StorageClass::Function) { + return false; + } + + if (!CheckTypeAnnotations(get_def_use_mgr()->GetDef(varInst->type_id()))) { + return false; + } + + const Instruction* typeInst = GetStorageType(varInst); + if (!CheckType(typeInst)) { + return false; + } + + if (!CheckAnnotations(varInst)) { + return false; + } + + if (!CheckUses(varInst)) { + return false; + } + + return true; +} + +bool ScalarReplacementPass::CheckType(const Instruction* typeInst) const { + if (!CheckTypeAnnotations(typeInst)) { + return false; + } + + switch (typeInst->opcode()) { + case spv::Op::OpTypeStruct: + // Don't bother with empty structs or very large structs. + if (typeInst->NumInOperands() == 0 || + IsLargerThanSizeLimit(typeInst->NumInOperands())) { + return false; + } + return true; + case spv::Op::OpTypeArray: + if (IsSpecConstant(typeInst->GetSingleWordInOperand(1u))) { + return false; + } + if (IsLargerThanSizeLimit(GetArrayLength(typeInst))) { + return false; + } + return true; + // TODO(alanbaker): Develop some heuristics for when this should be + // re-enabled. + //// Specifically including matrix and vector in an attempt to reduce the + //// number of vector registers required. + // case spv::Op::OpTypeMatrix: + // case spv::Op::OpTypeVector: + // if (IsLargerThanSizeLimit(GetNumElements(typeInst))) return false; + // return true; + + case spv::Op::OpTypeRuntimeArray: + default: + return false; + } +} + +bool ScalarReplacementPass::CheckTypeAnnotations( + const Instruction* typeInst) const { + for (auto inst : + get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) { + uint32_t decoration; + if (inst->opcode() == spv::Op::OpDecorate) { + decoration = inst->GetSingleWordInOperand(1u); + } else { + assert(inst->opcode() == spv::Op::OpMemberDecorate); + decoration = inst->GetSingleWordInOperand(2u); + } + + switch (spv::Decoration(decoration)) { + case spv::Decoration::RowMajor: + case spv::Decoration::ColMajor: + case spv::Decoration::ArrayStride: + case spv::Decoration::MatrixStride: + case spv::Decoration::CPacked: + case spv::Decoration::Invariant: + case spv::Decoration::Restrict: + case spv::Decoration::Offset: + case spv::Decoration::Alignment: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffset: + case spv::Decoration::RelaxedPrecision: + case spv::Decoration::AliasedPointer: + case spv::Decoration::RestrictPointer: + break; + default: + return false; + } + } + + return true; +} + +bool ScalarReplacementPass::CheckAnnotations(const Instruction* varInst) const { + for (auto inst : + get_decoration_mgr()->GetDecorationsFor(varInst->result_id(), false)) { + assert(inst->opcode() == spv::Op::OpDecorate); + auto decoration = spv::Decoration(inst->GetSingleWordInOperand(1u)); + switch (decoration) { + case spv::Decoration::Invariant: + case spv::Decoration::Restrict: + case spv::Decoration::Alignment: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffset: + case spv::Decoration::AliasedPointer: + case spv::Decoration::RestrictPointer: + break; + default: + return false; + } + } + + return true; +} + +bool ScalarReplacementPass::CheckUses(const Instruction* inst) const { + VariableStats stats = {0, 0}; + bool ok = CheckUses(inst, &stats); + + // TODO(alanbaker/greg-lunarg): Add some meaningful heuristics about when + // SRoA is costly, such as when the structure has many (unaccessed?) + // members. + + return ok; +} + +bool ScalarReplacementPass::CheckUses(const Instruction* inst, + VariableStats* stats) const { + uint64_t max_legal_index = GetMaxLegalIndex(inst); + + bool ok = true; + get_def_use_mgr()->ForEachUse(inst, [this, max_legal_index, stats, &ok]( + const Instruction* user, + uint32_t index) { + if (user->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare || + user->GetCommonDebugOpcode() == CommonDebugInfoDebugValue) { + // TODO: include num_partial_accesses if it uses Fragment operation or + // DebugValue has Indexes operand. + stats->num_full_accesses++; + return; + } + + // Annotations are check as a group separately. + if (!IsAnnotationInst(user->opcode())) { + switch (user->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + if (index == 2u && user->NumInOperands() > 1) { + uint32_t id = user->GetSingleWordInOperand(1u); + const Instruction* opInst = get_def_use_mgr()->GetDef(id); + const auto* constant = + context()->get_constant_mgr()->GetConstantFromInst(opInst); + if (!constant) { + ok = false; + } else if (constant->GetZeroExtendedValue() >= max_legal_index) { + ok = false; + } else { + if (!CheckUsesRelaxed(user)) ok = false; + } + stats->num_partial_accesses++; + } else { + ok = false; + } + break; + case spv::Op::OpLoad: + if (!CheckLoad(user, index)) ok = false; + stats->num_full_accesses++; + break; + case spv::Op::OpStore: + if (!CheckStore(user, index)) ok = false; + stats->num_full_accesses++; + break; + case spv::Op::OpName: + case spv::Op::OpMemberName: + break; + default: + ok = false; + break; + } + } + }); + + return ok; +} + +bool ScalarReplacementPass::CheckUsesRelaxed(const Instruction* inst) const { + bool ok = true; + get_def_use_mgr()->ForEachUse( + inst, [this, &ok](const Instruction* user, uint32_t index) { + switch (user->opcode()) { + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + if (index != 2u) { + ok = false; + } else { + if (!CheckUsesRelaxed(user)) ok = false; + } + break; + case spv::Op::OpLoad: + if (!CheckLoad(user, index)) ok = false; + break; + case spv::Op::OpStore: + if (!CheckStore(user, index)) ok = false; + break; + case spv::Op::OpImageTexelPointer: + if (!CheckImageTexelPointer(index)) ok = false; + break; + case spv::Op::OpExtInst: + if (user->GetCommonDebugOpcode() != CommonDebugInfoDebugDeclare || + !CheckDebugDeclare(index)) + ok = false; + break; + default: + ok = false; + break; + } + }); + + return ok; +} + +bool ScalarReplacementPass::CheckImageTexelPointer(uint32_t index) const { + return index == 2u; +} + +bool ScalarReplacementPass::CheckLoad(const Instruction* inst, + uint32_t index) const { + if (index != 2u) return false; + if (inst->NumInOperands() >= 2 && + inst->GetSingleWordInOperand(1u) & + uint32_t(spv::MemoryAccessMask::Volatile)) + return false; + return true; +} + +bool ScalarReplacementPass::CheckStore(const Instruction* inst, + uint32_t index) const { + if (index != 0u) return false; + if (inst->NumInOperands() >= 3 && + inst->GetSingleWordInOperand(2u) & + uint32_t(spv::MemoryAccessMask::Volatile)) + return false; + return true; +} + +bool ScalarReplacementPass::CheckDebugDeclare(uint32_t index) const { + if (index != kDebugDeclareOperandVariableIndex) return false; + return true; +} + +bool ScalarReplacementPass::IsLargerThanSizeLimit(uint64_t length) const { + if (max_num_elements_ == 0) { + return false; + } + return length > max_num_elements_; +} + +std::unique_ptr> +ScalarReplacementPass::GetUsedComponents(Instruction* inst) { + std::unique_ptr> result( + new std::unordered_set()); + + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + + def_use_mgr->WhileEachUser(inst, [&result, def_use_mgr, + this](Instruction* use) { + switch (use->opcode()) { + case spv::Op::OpLoad: { + // Look for extract from the load. + std::vector t; + if (def_use_mgr->WhileEachUser(use, [&t](Instruction* use2) { + if (use2->opcode() != spv::Op::OpCompositeExtract || + use2->NumInOperands() <= 1) { + return false; + } + t.push_back(use2->GetSingleWordInOperand(1)); + return true; + })) { + result->insert(t.begin(), t.end()); + return true; + } else { + result.reset(nullptr); + return false; + } + } + case spv::Op::OpName: + case spv::Op::OpMemberName: + case spv::Op::OpStore: + // No components are used. + return true; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: { + // Add the first index it if is a constant. + // TODO: Could be improved by checking if the address is used in a load. + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + uint32_t index_id = use->GetSingleWordInOperand(1); + const analysis::Constant* index_const = + const_mgr->FindDeclaredConstant(index_id); + if (index_const) { + result->insert(index_const->GetSignExtendedValue()); + return true; + } else { + // Could be any element. Assuming all are used. + result.reset(nullptr); + return false; + } + } + default: + // We do not know what is happening. Have to assume the worst. + result.reset(nullptr); + return false; + } + }); + + return result; +} + +uint64_t ScalarReplacementPass::GetMaxLegalIndex( + const Instruction* var_inst) const { + assert(var_inst->opcode() == spv::Op::OpVariable && + "|var_inst| must be a variable instruction."); + Instruction* type = GetStorageType(var_inst); + switch (type->opcode()) { + case spv::Op::OpTypeStruct: + return type->NumInOperands(); + case spv::Op::OpTypeArray: + return GetArrayLength(type); + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: + return GetNumElements(type); + default: + return 0; + } + return 0; +} + +void ScalarReplacementPass::CopyDecorationsToVariable(Instruction* from, + Instruction* to, + uint32_t member_index) { + CopyPointerDecorationsToVariable(from, to); + CopyNecessaryMemberDecorationsToVariable(from, to, member_index); +} + +void ScalarReplacementPass::CopyPointerDecorationsToVariable(Instruction* from, + Instruction* to) { + // The RestrictPointer and AliasedPointer decorations are copied to all + // members even if the new variable does not contain a pointer. It does + // not hurt to do so. + for (auto dec_inst : + get_decoration_mgr()->GetDecorationsFor(from->result_id(), false)) { + uint32_t decoration; + decoration = dec_inst->GetSingleWordInOperand(1u); + switch (spv::Decoration(decoration)) { + case spv::Decoration::AliasedPointer: + case spv::Decoration::RestrictPointer: { + std::unique_ptr new_dec_inst(dec_inst->Clone(context())); + new_dec_inst->SetInOperand(0, {to->result_id()}); + context()->AddAnnotationInst(std::move(new_dec_inst)); + } break; + default: + break; + } + } +} + +void ScalarReplacementPass::CopyNecessaryMemberDecorationsToVariable( + Instruction* from, Instruction* to, uint32_t member_index) { + Instruction* type_inst = GetStorageType(from); + for (auto dec_inst : + get_decoration_mgr()->GetDecorationsFor(type_inst->result_id(), false)) { + uint32_t decoration; + if (dec_inst->opcode() == spv::Op::OpMemberDecorate) { + if (dec_inst->GetSingleWordInOperand(1) != member_index) { + continue; + } + + decoration = dec_inst->GetSingleWordInOperand(2u); + switch (spv::Decoration(decoration)) { + case spv::Decoration::ArrayStride: + case spv::Decoration::Alignment: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffset: + case spv::Decoration::MaxByteOffsetId: + case spv::Decoration::RelaxedPrecision: { + std::unique_ptr new_dec_inst( + new Instruction(context(), spv::Op::OpDecorate, 0, 0, {})); + new_dec_inst->AddOperand( + Operand(SPV_OPERAND_TYPE_ID, {to->result_id()})); + for (uint32_t i = 2; i < dec_inst->NumInOperandWords(); ++i) { + new_dec_inst->AddOperand(Operand(dec_inst->GetInOperand(i))); + } + context()->AddAnnotationInst(std::move(new_dec_inst)); + } break; + default: + break; + } + } + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/scalar_replacement_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_replacement_pass.h new file mode 100644 index 000000000000..c73ecfd98ba5 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/scalar_replacement_pass.h @@ -0,0 +1,294 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_SCALAR_REPLACEMENT_PASS_H_ +#define SOURCE_OPT_SCALAR_REPLACEMENT_PASS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/opt/function.h" +#include "source/opt/mem_pass.h" +#include "source/opt/type_manager.h" + +namespace spvtools { +namespace opt { + +// Documented in optimizer.hpp +class ScalarReplacementPass : public MemPass { + private: + static constexpr uint32_t kDefaultLimit = 100; + + public: + ScalarReplacementPass(uint32_t limit = kDefaultLimit) + : max_num_elements_(limit) { + const auto num_to_write = snprintf( + name_, sizeof(name_), "scalar-replacement=%u", max_num_elements_); + assert(size_t(num_to_write) < sizeof(name_)); + (void)num_to_write; // Mark as unused + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + // ClusterFuzz/OSS-Fuzz is likely to yield examples with very large arrays. + // This can cause timeouts and memouts during fuzzing that + // are not classed as bugs. To avoid this noise, we set the + // max_num_elements_ to a smaller value for fuzzing. + max_num_elements_ = + (max_num_elements_ > 0 && max_num_elements_ < 100 ? max_num_elements_ + : 100); +#endif + } + + const char* name() const override { return name_; } + + // Attempts to scalarize all appropriate function scope variables. Returns + // SuccessWithChange if any change is made. + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Small container for tracking statistics about variables. + // + // TODO(alanbaker): Develop some useful heuristics to tune this pass. + struct VariableStats { + uint32_t num_partial_accesses; + uint32_t num_full_accesses; + }; + + // Attempts to scalarize all appropriate function scope variables in + // |function|. Returns SuccessWithChange if any changes are mode. + Status ProcessFunction(Function* function); + + // Returns true if |varInst| can be scalarized. + // + // Examines the use chain of |varInst| to verify all uses are valid for + // scalarization. + bool CanReplaceVariable(const Instruction* varInst) const; + + // Returns true if |typeInst| is an acceptable type to scalarize. + // + // Allows all aggregate types except runtime arrays. Additionally, checks the + // that the number of elements that would be scalarized is within bounds. + bool CheckType(const Instruction* typeInst) const; + + // Returns true if all the decorations for |varInst| are acceptable for + // scalarization. + bool CheckAnnotations(const Instruction* varInst) const; + + // Returns true if all the decorations for |typeInst| are acceptable for + // scalarization. + bool CheckTypeAnnotations(const Instruction* typeInst) const; + + // Returns true if the uses of |inst| are acceptable for scalarization. + // + // Recursively checks all the uses of |inst|. For |inst| specifically, only + // allows spv::Op::OpAccessChain, spv::Op::OpInBoundsAccessChain, + // spv::Op::OpLoad and spv::Op::OpStore. Access chains must have the first + // index be a compile-time constant. Subsequent uses of access chains + // (including other access chains) are checked in a more relaxed manner. + bool CheckUses(const Instruction* inst) const; + + // Helper function for the above |CheckUses|. + // + // This version tracks some stats about the current OpVariable. These stats + // are used to drive heuristics about when to scalarize. + bool CheckUses(const Instruction* inst, VariableStats* stats) const; + + // Relaxed helper function for |CheckUses|. + bool CheckUsesRelaxed(const Instruction* inst) const; + + // Transfers appropriate decorations from |source| to |replacements|. + void TransferAnnotations(const Instruction* source, + std::vector* replacements); + + // Scalarizes |inst| and updates its uses. + // + // |inst| must be an OpVariable. It is replaced with an OpVariable for each + // for element of the composite type. Uses of |inst| are updated as + // appropriate. If the replacement variables are themselves scalarizable, they + // get added to |worklist| for further processing. If any replacement + // variable ends up with no uses it is erased. Returns + // - Status::SuccessWithoutChange if the variable could not be replaced. + // - Status::SuccessWithChange if it made replacements. + // - Status::Failure if it couldn't create replacement variables. + Pass::Status ReplaceVariable(Instruction* inst, + std::queue* worklist); + + // Returns the underlying storage type for |inst|. + // + // |inst| must be an OpVariable. Returns the type that is pointed to by + // |inst|. + Instruction* GetStorageType(const Instruction* inst) const; + + // Returns true if the load can be scalarized. + // + // |inst| must be an OpLoad. Returns true if |index| is the pointer operand of + // |inst| and the load is not from volatile memory. + bool CheckLoad(const Instruction* inst, uint32_t index) const; + + // Returns true if the store can be scalarized. + // + // |inst| must be an OpStore. Returns true if |index| is the pointer operand + // of |inst| and the store is not to volatile memory. + bool CheckStore(const Instruction* inst, uint32_t index) const; + + // Returns true if the DebugDeclare can be scalarized at |index|. + bool CheckDebugDeclare(uint32_t index) const; + + // Returns true if |index| is the pointer operand of an OpImageTexelPointer + // instruction. + bool CheckImageTexelPointer(uint32_t index) const; + + // Creates a variable of type |typeId| from the |index|'th element of + // |varInst|. The new variable is added to |replacements|. If the variable + // could not be created, then |nullptr| is appended to |replacements|. + void CreateVariable(uint32_t typeId, Instruction* varInst, uint32_t index, + std::vector* replacements); + + // Populates |replacements| with a new OpVariable for each element of |inst|. + // Returns true if the replacement variables were successfully created. + // + // |inst| must be an OpVariable of a composite type. New variables are + // initialized the same as the corresponding index in |inst|. |replacements| + // will contain a variable for each element of the composite with matching + // indexes (i.e. the 0'th element of |inst| is the 0'th entry of + // |replacements|). + bool CreateReplacementVariables(Instruction* inst, + std::vector* replacements); + + // Returns the array length for |arrayInst|. + uint64_t GetArrayLength(const Instruction* arrayInst) const; + + // Returns the number of elements in |type|. + // + // |type| must be a vector or matrix type. + uint64_t GetNumElements(const Instruction* type) const; + + // Returns true if |id| is a specialization constant. + // + // |id| must be registered definition. + bool IsSpecConstant(uint32_t id) const; + + // Returns an id for a pointer to |id|. + uint32_t GetOrCreatePointerType(uint32_t id); + + // Creates the initial value for the |index| element of |source| in |newVar|. + // + // If there is an initial value for |source| for element |index|, it is + // appended as an operand on |newVar|. If the initial value is OpUndef, no + // initial value is added to |newVar|. + void GetOrCreateInitialValue(Instruction* source, uint32_t index, + Instruction* newVar); + + // Replaces the load to the entire composite. + // + // Generates a load for each replacement variable and then creates a new + // composite by combining all of the loads. + // + // |load| must be a load. Returns true if successful. + bool ReplaceWholeLoad(Instruction* load, + const std::vector& replacements); + + // Replaces the store to the entire composite. + // + // Generates a composite extract and store for each element in the scalarized + // variable from the original store data input. Returns true if successful. + bool ReplaceWholeStore(Instruction* store, + const std::vector& replacements); + + // Replaces the DebugDeclare to the entire composite. + // + // Generates a DebugValue with Deref operation for each element in the + // scalarized variable from the original DebugDeclare. Returns true if + // successful. + bool ReplaceWholeDebugDeclare(Instruction* dbg_decl, + const std::vector& replacements); + + // Replaces the DebugValue to the entire composite. + // + // Generates a DebugValue for each element in the scalarized variable from + // the original DebugValue. Returns true if successful. + bool ReplaceWholeDebugValue(Instruction* dbg_value, + const std::vector& replacements); + + // Replaces an access chain to the composite variable with either a direct use + // of the appropriate replacement variable or another access chain with the + // replacement variable as the base and one fewer indexes. Returns true if + // successful. + bool ReplaceAccessChain(Instruction* chain, + const std::vector& replacements); + + // Returns a set containing the which components of the result of |inst| are + // potentially used. If the return value is |nullptr|, then every components + // is possibly used. + std::unique_ptr> GetUsedComponents( + Instruction* inst); + + // Returns an instruction defining an undefined value type |type_id|. + Instruction* GetUndef(uint32_t type_id); + + // Maps storage type to a pointer type enclosing that type. + std::unordered_map pointee_to_pointer_; + + // Maps type id to OpConstantNull for that type. + std::unordered_map type_to_null_; + + // Returns the number of elements in the variable |var_inst|. + uint64_t GetMaxLegalIndex(const Instruction* var_inst) const; + + // Returns true if |length| is larger than limit on the size of the variable + // that we will be willing to split. + bool IsLargerThanSizeLimit(uint64_t length) const; + + // Copies all relevant decorations from `from` to `to`. This includes + // decorations applied to the variable, and to the members of the type. + // It is assumed that `to` is a variable that is intended to replace the + // `member_index`th member of `from`. + void CopyDecorationsToVariable(Instruction* from, Instruction* to, + uint32_t member_index); + + // Copies pointer related decoration from `from` to `to` if they exist. + void CopyPointerDecorationsToVariable(Instruction* from, Instruction* to); + + // Copies decorations that are needed from the `member_index` of `from` to + // `to, if there was one. + void CopyNecessaryMemberDecorationsToVariable(Instruction* from, + Instruction* to, + uint32_t member_index); + + // Limit on the number of members in an object that will be replaced. + // 0 means there is no limit. + uint32_t max_num_elements_; + + // This has to be big enough to fit "scalar-replacement=" followed by a + // uint32_t number written in decimal (so 10 digits), and then a + // terminating nul. + char name_[30]; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_SCALAR_REPLACEMENT_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/set_spec_constant_default_value_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/set_spec_constant_default_value_pass.cpp new file mode 100644 index 000000000000..d2aa9b1da2ee --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/set_spec_constant_default_value_pass.cpp @@ -0,0 +1,390 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/set_spec_constant_default_value_pass.h" + +#include +#include +#include +#include +#include + +#include "source/opt/def_use_manager.h" +#include "source/opt/types.h" +#include "source/util/make_unique.h" +#include "source/util/parse_number.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace opt { +namespace { +using utils::EncodeNumberStatus; +using utils::NumberType; +using utils::ParseAndEncodeNumber; +using utils::ParseNumber; + +// Given a numeric value in a null-terminated c string and the expected type of +// the value, parses the string and encodes it in a vector of words. If the +// value is a scalar integer or floating point value, encodes the value in +// SPIR-V encoding format. If the value is 'false' or 'true', returns a vector +// with single word with value 0 or 1 respectively. Returns the vector +// containing the encoded value on success. Otherwise returns an empty vector. +std::vector ParseDefaultValueStr(const char* text, + const analysis::Type* type) { + std::vector result; + if (!strcmp(text, "true") && type->AsBool()) { + result.push_back(1u); + } else if (!strcmp(text, "false") && type->AsBool()) { + result.push_back(0u); + } else { + NumberType number_type = {32, SPV_NUMBER_UNSIGNED_INT}; + if (const auto* IT = type->AsInteger()) { + number_type.bitwidth = IT->width(); + number_type.kind = + IT->IsSigned() ? SPV_NUMBER_SIGNED_INT : SPV_NUMBER_UNSIGNED_INT; + } else if (const auto* FT = type->AsFloat()) { + number_type.bitwidth = FT->width(); + number_type.kind = SPV_NUMBER_FLOATING; + } else { + // Does not handle types other then boolean, integer or float. Returns + // empty vector. + result.clear(); + return result; + } + EncodeNumberStatus rc = ParseAndEncodeNumber( + text, number_type, [&result](uint32_t word) { result.push_back(word); }, + nullptr); + // Clear the result vector on failure. + if (rc != EncodeNumberStatus::kSuccess) { + result.clear(); + } + } + return result; +} + +// Given a bit pattern and a type, checks if the bit pattern is compatible +// with the type. If so, returns the bit pattern, otherwise returns an empty +// bit pattern. If the given bit pattern is empty, returns an empty bit +// pattern. If the given type represents a SPIR-V Boolean type, the bit pattern +// to be returned is determined with the following standard: +// If any words in the input bit pattern are non zero, returns a bit pattern +// with 0x1, which represents a 'true'. +// If all words in the bit pattern are zero, returns a bit pattern with 0x0, +// which represents a 'false'. +// For integer and floating point types narrower than 32 bits, the upper bits +// in the input bit pattern are ignored. Instead the upper bits are set +// according to SPIR-V literal requirements: sign extend a signed integer, and +// otherwise set the upper bits to zero. +std::vector ParseDefaultValueBitPattern( + const std::vector& input_bit_pattern, + const analysis::Type* type) { + std::vector result; + if (type->AsBool()) { + if (std::any_of(input_bit_pattern.begin(), input_bit_pattern.end(), + [](uint32_t i) { return i != 0; })) { + result.push_back(1u); + } else { + result.push_back(0u); + } + return result; + } else if (const auto* IT = type->AsInteger()) { + const auto width = IT->width(); + assert(width > 0); + const auto adjusted_width = std::max(32u, width); + if (adjusted_width == input_bit_pattern.size() * sizeof(uint32_t) * 8) { + result = std::vector(input_bit_pattern); + if (width < 32) { + const uint32_t high_active_bit = (1u << width) >> 1; + if (IT->IsSigned() && (high_active_bit & result[0])) { + // Sign extend. This overwrites the sign bit again, but that's ok. + result[0] = result[0] | ~(high_active_bit - 1); + } else { + // Upper bits must be zero. + result[0] = result[0] & ((1u << width) - 1); + } + } + return result; + } + } else if (const auto* FT = type->AsFloat()) { + const auto width = FT->width(); + const auto adjusted_width = std::max(32u, width); + if (adjusted_width == input_bit_pattern.size() * sizeof(uint32_t) * 8) { + result = std::vector(input_bit_pattern); + if (width < 32) { + // Upper bits must be zero. + result[0] = result[0] & ((1u << width) - 1); + } + return result; + } + } + result.clear(); + return result; +} + +// Returns true if the given instruction's result id could have a SpecId +// decoration. +bool CanHaveSpecIdDecoration(const Instruction& inst) { + switch (inst.opcode()) { + case spv::Op::OpSpecConstant: + case spv::Op::OpSpecConstantFalse: + case spv::Op::OpSpecConstantTrue: + return true; + default: + return false; + } +} + +// Given a decoration group defining instruction that is decorated with SpecId +// decoration, finds the spec constant defining instruction which is the real +// target of the SpecId decoration. Returns the spec constant defining +// instruction if such an instruction is found, otherwise returns a nullptr. +Instruction* GetSpecIdTargetFromDecorationGroup( + const Instruction& decoration_group_defining_inst, + analysis::DefUseManager* def_use_mgr) { + // Find the OpGroupDecorate instruction which consumes the given decoration + // group. Note that the given decoration group has SpecId decoration, which + // is unique for different spec constants. So the decoration group cannot be + // consumed by different OpGroupDecorate instructions. Therefore we only need + // the first OpGroupDecoration instruction that uses the given decoration + // group. + Instruction* group_decorate_inst = nullptr; + if (def_use_mgr->WhileEachUser(&decoration_group_defining_inst, + [&group_decorate_inst](Instruction* user) { + if (user->opcode() == + spv::Op::OpGroupDecorate) { + group_decorate_inst = user; + return false; + } + return true; + })) + return nullptr; + + // Scan through the target ids of the OpGroupDecorate instruction. There + // should be only one spec constant target consumes the SpecId decoration. + // If multiple target ids are presented in the OpGroupDecorate instruction, + // they must be the same one that defined by an eligible spec constant + // instruction. If the OpGroupDecorate instruction has different target ids + // or a target id is not defined by an eligible spec cosntant instruction, + // returns a nullptr. + Instruction* target_inst = nullptr; + for (uint32_t i = 1; i < group_decorate_inst->NumInOperands(); i++) { + // All the operands of a OpGroupDecorate instruction should be of type + // SPV_OPERAND_TYPE_ID. + uint32_t candidate_id = group_decorate_inst->GetSingleWordInOperand(i); + Instruction* candidate_inst = def_use_mgr->GetDef(candidate_id); + + if (!candidate_inst) { + continue; + } + + if (!target_inst) { + // If the spec constant target has not been found yet, check if the + // candidate instruction is the target. + if (CanHaveSpecIdDecoration(*candidate_inst)) { + target_inst = candidate_inst; + } else { + // Spec id decoration should not be applied on other instructions. + // TODO(qining): Emit an error message in the invalid case once the + // error handling is done. + return nullptr; + } + } else { + // If the spec constant target has been found, check if the candidate + // instruction is the same one as the target. The module is invalid if + // the candidate instruction is different with the found target. + // TODO(qining): Emit an error messaage in the invalid case once the + // error handling is done. + if (candidate_inst != target_inst) return nullptr; + } + } + return target_inst; +} +} // namespace + +Pass::Status SetSpecConstantDefaultValuePass::Process() { + // The operand index of decoration target in an OpDecorate instruction. + constexpr uint32_t kTargetIdOperandIndex = 0; + // The operand index of the decoration literal in an OpDecorate instruction. + constexpr uint32_t kDecorationOperandIndex = 1; + // The operand index of Spec id literal value in an OpDecorate SpecId + // instruction. + constexpr uint32_t kSpecIdLiteralOperandIndex = 2; + // The number of operands in an OpDecorate SpecId instruction. + constexpr uint32_t kOpDecorateSpecIdNumOperands = 3; + // The in-operand index of the default value in a OpSpecConstant instruction. + constexpr uint32_t kOpSpecConstantLiteralInOperandIndex = 0; + + bool modified = false; + // Scan through all the annotation instructions to find 'OpDecorate SpecId' + // instructions. Then extract the decoration target of those instructions. + // The decoration targets should be spec constant defining instructions with + // opcode: OpSpecConstant{|True|False}. The spec id of those spec constants + // will be used to look up their new default values in the mapping from + // spec id to new default value strings. Once a new default value string + // is found for a spec id, the string will be parsed according to the target + // spec constant type. The parsed value will be used to replace the original + // default value of the target spec constant. + for (Instruction& inst : context()->annotations()) { + // Only process 'OpDecorate SpecId' instructions + if (inst.opcode() != spv::Op::OpDecorate) continue; + if (inst.NumOperands() != kOpDecorateSpecIdNumOperands) continue; + if (inst.GetSingleWordInOperand(kDecorationOperandIndex) != + uint32_t(spv::Decoration::SpecId)) { + continue; + } + + // 'inst' is an OpDecorate SpecId instruction. + uint32_t spec_id = inst.GetSingleWordOperand(kSpecIdLiteralOperandIndex); + uint32_t target_id = inst.GetSingleWordOperand(kTargetIdOperandIndex); + + // Find the spec constant defining instruction. Note that the + // target_id might be a decoration group id. + Instruction* spec_inst = nullptr; + if (Instruction* target_inst = get_def_use_mgr()->GetDef(target_id)) { + if (target_inst->opcode() == spv::Op::OpDecorationGroup) { + spec_inst = + GetSpecIdTargetFromDecorationGroup(*target_inst, get_def_use_mgr()); + } else { + spec_inst = target_inst; + } + } else { + continue; + } + if (!spec_inst) continue; + + // Get the default value bit pattern for this spec id. + std::vector bit_pattern; + + if (spec_id_to_value_str_.size() != 0) { + // Search for the new string-form default value for this spec id. + auto iter = spec_id_to_value_str_.find(spec_id); + if (iter == spec_id_to_value_str_.end()) { + continue; + } + + // Gets the string of the default value and parses it to bit pattern + // with the type of the spec constant. + const std::string& default_value_str = iter->second; + bit_pattern = ParseDefaultValueStr( + default_value_str.c_str(), + context()->get_type_mgr()->GetType(spec_inst->type_id())); + + } else { + // Search for the new bit-pattern-form default value for this spec id. + auto iter = spec_id_to_value_bit_pattern_.find(spec_id); + if (iter == spec_id_to_value_bit_pattern_.end()) { + continue; + } + + // Gets the bit-pattern of the default value from the map directly. + bit_pattern = ParseDefaultValueBitPattern( + iter->second, + context()->get_type_mgr()->GetType(spec_inst->type_id())); + } + + if (bit_pattern.empty()) continue; + + // Update the operand bit patterns of the spec constant defining + // instruction. + switch (spec_inst->opcode()) { + case spv::Op::OpSpecConstant: + // If the new value is the same with the original value, no + // need to do anything. Otherwise update the operand words. + if (spec_inst->GetInOperand(kOpSpecConstantLiteralInOperandIndex) + .words != bit_pattern) { + spec_inst->SetInOperand(kOpSpecConstantLiteralInOperandIndex, + std::move(bit_pattern)); + modified = true; + } + break; + case spv::Op::OpSpecConstantTrue: + // If the new value is also 'true', no need to change anything. + // Otherwise, set the opcode to OpSpecConstantFalse; + if (!static_cast(bit_pattern.front())) { + spec_inst->SetOpcode(spv::Op::OpSpecConstantFalse); + modified = true; + } + break; + case spv::Op::OpSpecConstantFalse: + // If the new value is also 'false', no need to change anything. + // Otherwise, set the opcode to OpSpecConstantTrue; + if (static_cast(bit_pattern.front())) { + spec_inst->SetOpcode(spv::Op::OpSpecConstantTrue); + modified = true; + } + break; + default: + break; + } + // No need to update the DefUse manager, as this pass does not change any + // ids. + } + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +// Returns true if the given char is ':', '\0' or considered as blank space +// (i.e.: '\n', '\r', '\v', '\t', '\f' and ' '). +bool IsSeparator(char ch) { + return std::strchr(":\0", ch) || std::isspace(ch) != 0; +} + +std::unique_ptr +SetSpecConstantDefaultValuePass::ParseDefaultValuesString(const char* str) { + if (!str) return nullptr; + + auto spec_id_to_value = MakeUnique(); + + // The parsing loop, break when points to the end. + while (*str) { + // Find the spec id. + while (std::isspace(*str)) str++; // skip leading spaces. + const char* entry_begin = str; + while (!IsSeparator(*str)) str++; + const char* entry_end = str; + std::string spec_id_str(entry_begin, entry_end - entry_begin); + uint32_t spec_id = 0; + if (!ParseNumber(spec_id_str.c_str(), &spec_id)) { + // The spec id is not a valid uint32 number. + return nullptr; + } + auto iter = spec_id_to_value->find(spec_id); + if (iter != spec_id_to_value->end()) { + // Same spec id has been defined before + return nullptr; + } + // Find the ':', spaces between the spec id and the ':' are not allowed. + if (*str++ != ':') { + // ':' not found + return nullptr; + } + // Find the value string + const char* val_begin = str; + while (!IsSeparator(*str)) str++; + const char* val_end = str; + if (val_end == val_begin) { + // Value string is empty. + return nullptr; + } + // Update the mapping with spec id and value string. + (*spec_id_to_value)[spec_id] = std::string(val_begin, val_end - val_begin); + + // Skip trailing spaces. + while (std::isspace(*str)) str++; + } + + return spec_id_to_value; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/set_spec_constant_default_value_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/set_spec_constant_default_value_pass.h new file mode 100644 index 000000000000..8bd1787cc266 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/set_spec_constant_default_value_pass.h @@ -0,0 +1,114 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_SET_SPEC_CONSTANT_DEFAULT_VALUE_PASS_H_ +#define SOURCE_OPT_SET_SPEC_CONSTANT_DEFAULT_VALUE_PASS_H_ + +#include +#include +#include +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class SetSpecConstantDefaultValuePass : public Pass { + public: + using SpecIdToValueStrMap = std::unordered_map; + using SpecIdToValueBitPatternMap = + std::unordered_map>; + using SpecIdToInstMap = std::unordered_map; + + // Constructs a pass instance with a map from spec ids to default values + // in the form of string. + explicit SetSpecConstantDefaultValuePass( + const SpecIdToValueStrMap& default_values) + : spec_id_to_value_str_(default_values), + spec_id_to_value_bit_pattern_() {} + explicit SetSpecConstantDefaultValuePass(SpecIdToValueStrMap&& default_values) + : spec_id_to_value_str_(std::move(default_values)), + spec_id_to_value_bit_pattern_() {} + + // Constructs a pass instance with a map from spec ids to default values in + // the form of bit pattern. + explicit SetSpecConstantDefaultValuePass( + const SpecIdToValueBitPatternMap& default_values) + : spec_id_to_value_str_(), + spec_id_to_value_bit_pattern_(default_values) {} + explicit SetSpecConstantDefaultValuePass( + SpecIdToValueBitPatternMap&& default_values) + : spec_id_to_value_str_(), + spec_id_to_value_bit_pattern_(std::move(default_values)) {} + + const char* name() const override { return "set-spec-const-default-value"; } + Status Process() override; + + // Parses the given null-terminated C string to get a mapping from Spec Id to + // default value strings. Returns a unique pointer of the mapping from spec + // ids to spec constant default value strings built from the given |str| on + // success. Returns a nullptr if the given string is not valid for building + // the mapping. + // A valid string for building the mapping should follow the rule below: + // + // ": : ..." + // Example: + // "200:0x11 201:3.14 202:1.4728" + // + // Entries are separated with blank spaces (i.e.:' ', '\n', '\r', '\t', + // '\f', '\v'). Each entry corresponds to a Spec Id and default value pair. + // Multiple spaces between, before or after entries are allowed. However, + // spaces are not allowed within spec id or the default value string because + // spaces are always considered as delimiter to separate entries. + // + // In each entry, the spec id and value string is separated by ':'. Missing + // ':' in any entry is invalid. And it is invalid to have blank spaces in + // between the spec id and ':' or the default value and ':'. + // + // : specifies the spec id value. + // The text must represent a valid uint32_t number. + // Hex format with '0x' prefix is allowed. + // Empty is not allowed. + // One spec id value can only be defined once, multiple default values + // defined for the same spec id is not allowed. Spec ids with same value + // but different formats (e.g. 0x100 and 256) are considered the same. + // + // : the default value string. + // Spaces before and after default value text is allowed. + // Spaces within the text is not allowed. + // Empty is not allowed. + static std::unique_ptr ParseDefaultValuesString( + const char* str); + + private: + // The mappings from spec ids to default values. Two maps are defined here, + // each to be used for one specific form of the default values. Only one of + // them will be populated in practice. + + // The mapping from spec ids to their string-form default values to be set. + const SpecIdToValueStrMap spec_id_to_value_str_; + // The mapping from spec ids to their bitpattern-form default values to be + // set. + const SpecIdToValueBitPatternMap spec_id_to_value_bit_pattern_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_SET_SPEC_CONSTANT_DEFAULT_VALUE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/simplification_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/simplification_pass.cpp new file mode 100644 index 000000000000..f8ffc03c20b8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/simplification_pass.cpp @@ -0,0 +1,168 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/simplification_pass.h" + +#include +#include + +#include "source/opt/fold.h" + +namespace spvtools { +namespace opt { + +Pass::Status SimplificationPass::Process() { + bool modified = false; + + for (Function& function : *get_module()) { + modified |= SimplifyFunction(&function); + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +void SimplificationPass::AddNewOperands( + Instruction* folded_inst, std::unordered_set* inst_seen, + std::vector* work_list) { + analysis::DefUseManager* def_use_mgr = get_def_use_mgr(); + folded_inst->ForEachInId( + [&inst_seen, &def_use_mgr, &work_list](uint32_t* iid) { + Instruction* iid_inst = def_use_mgr->GetDef(*iid); + if (!inst_seen->insert(iid_inst).second) return; + work_list->push_back(iid_inst); + }); +} + +bool SimplificationPass::SimplifyFunction(Function* function) { + if (function->IsDeclaration()) { + return false; + } + + bool modified = false; + // Phase 1: Traverse all instructions in dominance order. + // The second phase will only be on the instructions whose inputs have changed + // after being processed during phase 1. Since OpPhi instructions are the + // only instructions whose inputs do not necessarily dominate the use, we keep + // track of the OpPhi instructions already seen, and add them to the work list + // for phase 2 when needed. + std::vector work_list; + std::unordered_set process_phis; + std::unordered_set inst_to_kill; + std::unordered_set in_work_list; + std::unordered_set inst_seen; + const InstructionFolder& folder = context()->get_instruction_folder(); + + cfg()->ForEachBlockInReversePostOrder( + function->entry().get(), + [&modified, &process_phis, &work_list, &in_work_list, &inst_to_kill, + &folder, &inst_seen, this](BasicBlock* bb) { + for (Instruction* inst = &*bb->begin(); inst; inst = inst->NextNode()) { + inst_seen.insert(inst); + if (inst->opcode() == spv::Op::OpPhi) { + process_phis.insert(inst); + } + + bool is_foldable_copy = + inst->opcode() == spv::Op::OpCopyObject && + context()->get_decoration_mgr()->HaveSubsetOfDecorations( + inst->result_id(), inst->GetSingleWordInOperand(0)); + + if (is_foldable_copy || folder.FoldInstruction(inst)) { + modified = true; + context()->AnalyzeUses(inst); + get_def_use_mgr()->ForEachUser(inst, [&work_list, &process_phis, + &in_work_list]( + Instruction* use) { + if (process_phis.count(use) && in_work_list.insert(use).second) { + work_list.push_back(use); + } + }); + + AddNewOperands(inst, &inst_seen, &work_list); + + if (inst->opcode() == spv::Op::OpCopyObject) { + context()->ReplaceAllUsesWithPredicate( + inst->result_id(), inst->GetSingleWordInOperand(0), + [](Instruction* user) { + const auto opcode = user->opcode(); + if (!spvOpcodeIsDebug(opcode) && + !spvOpcodeIsDecoration(opcode)) { + return true; + } + return false; + }); + inst_to_kill.insert(inst); + in_work_list.insert(inst); + } else if (inst->opcode() == spv::Op::OpNop) { + inst_to_kill.insert(inst); + in_work_list.insert(inst); + } + } + } + }); + + // Phase 2: process the instructions in the work list until all of the work is + // done. This time we add all users to the work list because phase 1 + // has already finished. + for (size_t i = 0; i < work_list.size(); ++i) { + Instruction* inst = work_list[i]; + in_work_list.erase(inst); + inst_seen.insert(inst); + + bool is_foldable_copy = + inst->opcode() == spv::Op::OpCopyObject && + context()->get_decoration_mgr()->HaveSubsetOfDecorations( + inst->result_id(), inst->GetSingleWordInOperand(0)); + + if (is_foldable_copy || folder.FoldInstruction(inst)) { + modified = true; + context()->AnalyzeUses(inst); + get_def_use_mgr()->ForEachUser( + inst, [&work_list, &in_work_list](Instruction* use) { + if (!use->IsDecoration() && use->opcode() != spv::Op::OpName && + in_work_list.insert(use).second) { + work_list.push_back(use); + } + }); + + AddNewOperands(inst, &inst_seen, &work_list); + + if (inst->opcode() == spv::Op::OpCopyObject) { + context()->ReplaceAllUsesWithPredicate( + inst->result_id(), inst->GetSingleWordInOperand(0), + [](Instruction* user) { + const auto opcode = user->opcode(); + if (!spvOpcodeIsDebug(opcode) && !spvOpcodeIsDecoration(opcode)) { + return true; + } + return false; + }); + inst_to_kill.insert(inst); + in_work_list.insert(inst); + } else if (inst->opcode() == spv::Op::OpNop) { + inst_to_kill.insert(inst); + in_work_list.insert(inst); + } + } + } + + // Phase 3: Kill instructions we know are no longer needed. + for (Instruction* inst : inst_to_kill) { + context()->KillInst(inst); + } + + return modified; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/simplification_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/simplification_pass.h new file mode 100644 index 000000000000..149874b0944c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/simplification_pass.h @@ -0,0 +1,58 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_SIMPLIFICATION_PASS_H_ +#define SOURCE_OPT_SIMPLIFICATION_PASS_H_ + +#include "source/opt/function.h" +#include "source/opt/ir_context.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class SimplificationPass : public Pass { + public: + const char* name() const override { return "simplify-instructions"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | + IRContext::kAnalysisTypes; + } + + private: + // Returns true if the module was changed. The simplifier is called on every + // instruction in |function| until nothing else in the function can be + // simplified. + bool SimplifyFunction(Function* function); + + // FactorAddMul can create |folded_inst| Mul of new Add. If Mul, push any Add + // operand not in |seen_inst| into |worklist|. This is heavily restricted to + // improve compile time but can be expanded for future simplifications which + // simiarly create new operations. + void AddNewOperands(Instruction* folded_inst, + std::unordered_set* inst_seen, + std::vector* work_list); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_SIMPLIFICATION_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/spread_volatile_semantics.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/spread_volatile_semantics.cpp new file mode 100644 index 000000000000..e552ba5e7611 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/spread_volatile_semantics.cpp @@ -0,0 +1,300 @@ +// Copyright (c) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/spread_volatile_semantics.h" + +#include "source/opt/decoration_manager.h" +#include "source/spirv_constant.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kOpDecorateInOperandBuiltinDecoration = 2u; +constexpr uint32_t kOpLoadInOperandMemoryOperands = 1u; +constexpr uint32_t kOpEntryPointInOperandEntryPoint = 1u; +constexpr uint32_t kOpEntryPointInOperandInterface = 3u; + +bool HasBuiltinDecoration(analysis::DecorationManager* decoration_manager, + uint32_t var_id, uint32_t built_in) { + return decoration_manager->FindDecoration( + var_id, uint32_t(spv::Decoration::BuiltIn), + [built_in](const Instruction& inst) { + return built_in == inst.GetSingleWordInOperand( + kOpDecorateInOperandBuiltinDecoration); + }); +} + +bool IsBuiltInForRayTracingVolatileSemantics(spv::BuiltIn built_in) { + switch (built_in) { + case spv::BuiltIn::SMIDNV: + case spv::BuiltIn::WarpIDNV: + case spv::BuiltIn::SubgroupSize: + case spv::BuiltIn::SubgroupLocalInvocationId: + case spv::BuiltIn::SubgroupEqMask: + case spv::BuiltIn::SubgroupGeMask: + case spv::BuiltIn::SubgroupGtMask: + case spv::BuiltIn::SubgroupLeMask: + case spv::BuiltIn::SubgroupLtMask: + return true; + default: + return false; + } +} + +bool HasBuiltinForRayTracingVolatileSemantics( + analysis::DecorationManager* decoration_manager, uint32_t var_id) { + return decoration_manager->FindDecoration( + var_id, uint32_t(spv::Decoration::BuiltIn), [](const Instruction& inst) { + spv::BuiltIn built_in = spv::BuiltIn( + inst.GetSingleWordInOperand(kOpDecorateInOperandBuiltinDecoration)); + return IsBuiltInForRayTracingVolatileSemantics(built_in); + }); +} + +bool HasVolatileDecoration(analysis::DecorationManager* decoration_manager, + uint32_t var_id) { + return decoration_manager->HasDecoration(var_id, + uint32_t(spv::Decoration::Volatile)); +} + +} // namespace + +Pass::Status SpreadVolatileSemantics::Process() { + if (HasNoExecutionModel()) { + return Status::SuccessWithoutChange; + } + const bool is_vk_memory_model_enabled = + context()->get_feature_mgr()->HasCapability( + spv::Capability::VulkanMemoryModel); + CollectTargetsForVolatileSemantics(is_vk_memory_model_enabled); + + // If VulkanMemoryModel capability is not enabled, we have to set Volatile + // decoration for interface variables instead of setting Volatile for load + // instructions. If an interface (or pointers to it) is used by two load + // instructions in two entry points and one must be volatile while another + // is not, we have to report an error for the conflict. + if (!is_vk_memory_model_enabled && + HasInterfaceInConflictOfVolatileSemantics()) { + return Status::Failure; + } + + return SpreadVolatileSemanticsToVariables(is_vk_memory_model_enabled); +} + +Pass::Status SpreadVolatileSemantics::SpreadVolatileSemanticsToVariables( + const bool is_vk_memory_model_enabled) { + Status status = Status::SuccessWithoutChange; + for (Instruction& var : context()->types_values()) { + auto entry_function_ids = + EntryFunctionsToSpreadVolatileSemanticsForVar(var.result_id()); + if (entry_function_ids.empty()) { + continue; + } + + if (is_vk_memory_model_enabled) { + SetVolatileForLoadsInEntries(&var, entry_function_ids); + } else { + DecorateVarWithVolatile(&var); + } + status = Status::SuccessWithChange; + } + return status; +} + +bool SpreadVolatileSemantics::IsTargetUsedByNonVolatileLoadInEntryPoint( + uint32_t var_id, Instruction* entry_point) { + uint32_t entry_function_id = + entry_point->GetSingleWordInOperand(kOpEntryPointInOperandEntryPoint); + std::unordered_set funcs; + context()->CollectCallTreeFromRoots(entry_function_id, &funcs); + return !VisitLoadsOfPointersToVariableInEntries( + var_id, + [](Instruction* load) { + // If it has a load without volatile memory operand, finish traversal + // and return false. + if (load->NumInOperands() <= kOpLoadInOperandMemoryOperands) { + return false; + } + uint32_t memory_operands = + load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); + return (memory_operands & uint32_t(spv::MemoryAccessMask::Volatile)) != + 0; + }, + funcs); +} + +bool SpreadVolatileSemantics::HasInterfaceInConflictOfVolatileSemantics() { + for (Instruction& entry_point : get_module()->entry_points()) { + spv::ExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); + for (uint32_t operand_index = kOpEntryPointInOperandInterface; + operand_index < entry_point.NumInOperands(); ++operand_index) { + uint32_t var_id = entry_point.GetSingleWordInOperand(operand_index); + if (!EntryFunctionsToSpreadVolatileSemanticsForVar(var_id).empty() && + !IsTargetForVolatileSemantics(var_id, execution_model) && + IsTargetUsedByNonVolatileLoadInEntryPoint(var_id, &entry_point)) { + Instruction* inst = context()->get_def_use_mgr()->GetDef(var_id); + context()->EmitErrorMessage( + "Variable is a target for Volatile semantics for an entry point, " + "but it is not for another entry point", + inst); + return true; + } + } + } + return false; +} + +void SpreadVolatileSemantics::MarkVolatileSemanticsForVariable( + uint32_t var_id, Instruction* entry_point) { + uint32_t entry_function_id = + entry_point->GetSingleWordInOperand(kOpEntryPointInOperandEntryPoint); + auto itr = var_ids_to_entry_fn_for_volatile_semantics_.find(var_id); + if (itr == var_ids_to_entry_fn_for_volatile_semantics_.end()) { + var_ids_to_entry_fn_for_volatile_semantics_[var_id] = {entry_function_id}; + return; + } + itr->second.insert(entry_function_id); +} + +void SpreadVolatileSemantics::CollectTargetsForVolatileSemantics( + const bool is_vk_memory_model_enabled) { + for (Instruction& entry_point : get_module()->entry_points()) { + spv::ExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); + for (uint32_t operand_index = kOpEntryPointInOperandInterface; + operand_index < entry_point.NumInOperands(); ++operand_index) { + uint32_t var_id = entry_point.GetSingleWordInOperand(operand_index); + if (!IsTargetForVolatileSemantics(var_id, execution_model)) { + continue; + } + if (is_vk_memory_model_enabled || + IsTargetUsedByNonVolatileLoadInEntryPoint(var_id, &entry_point)) { + MarkVolatileSemanticsForVariable(var_id, &entry_point); + } + } + } +} + +void SpreadVolatileSemantics::DecorateVarWithVolatile(Instruction* var) { + analysis::DecorationManager* decoration_manager = + context()->get_decoration_mgr(); + uint32_t var_id = var->result_id(); + if (HasVolatileDecoration(decoration_manager, var_id)) { + return; + } + get_decoration_mgr()->AddDecoration( + spv::Op::OpDecorate, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {var_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {uint32_t(spv::Decoration::Volatile)}}}); +} + +bool SpreadVolatileSemantics::VisitLoadsOfPointersToVariableInEntries( + uint32_t var_id, const std::function& handle_load, + const std::unordered_set& function_ids) { + std::vector worklist({var_id}); + auto* def_use_mgr = context()->get_def_use_mgr(); + while (!worklist.empty()) { + uint32_t ptr_id = worklist.back(); + worklist.pop_back(); + bool finish_traversal = !def_use_mgr->WhileEachUser( + ptr_id, [this, &worklist, &ptr_id, handle_load, + &function_ids](Instruction* user) { + BasicBlock* block = context()->get_instr_block(user); + if (block == nullptr || + function_ids.find(block->GetParent()->result_id()) == + function_ids.end()) { + return true; + } + + if (user->opcode() == spv::Op::OpAccessChain || + user->opcode() == spv::Op::OpInBoundsAccessChain || + user->opcode() == spv::Op::OpPtrAccessChain || + user->opcode() == spv::Op::OpInBoundsPtrAccessChain || + user->opcode() == spv::Op::OpCopyObject) { + if (ptr_id == user->GetSingleWordInOperand(0)) + worklist.push_back(user->result_id()); + return true; + } + + if (user->opcode() != spv::Op::OpLoad) { + return true; + } + + return handle_load(user); + }); + if (finish_traversal) return false; + } + return true; +} + +void SpreadVolatileSemantics::SetVolatileForLoadsInEntries( + Instruction* var, const std::unordered_set& entry_function_ids) { + // Set Volatile memory operand for all load instructions if they do not have + // it. + for (auto entry_id : entry_function_ids) { + std::unordered_set funcs; + context()->CollectCallTreeFromRoots(entry_id, &funcs); + VisitLoadsOfPointersToVariableInEntries( + var->result_id(), + [](Instruction* load) { + if (load->NumInOperands() <= kOpLoadInOperandMemoryOperands) { + load->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, + {uint32_t(spv::MemoryAccessMask::Volatile)}}); + return true; + } + uint32_t memory_operands = + load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); + memory_operands |= uint32_t(spv::MemoryAccessMask::Volatile); + load->SetInOperand(kOpLoadInOperandMemoryOperands, {memory_operands}); + return true; + }, + funcs); + } +} + +bool SpreadVolatileSemantics::IsTargetForVolatileSemantics( + uint32_t var_id, spv::ExecutionModel execution_model) { + analysis::DecorationManager* decoration_manager = + context()->get_decoration_mgr(); + if (execution_model == spv::ExecutionModel::Fragment) { + return get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 6) && + HasBuiltinDecoration(decoration_manager, var_id, + uint32_t(spv::BuiltIn::HelperInvocation)); + } + + if (execution_model == spv::ExecutionModel::IntersectionKHR || + execution_model == spv::ExecutionModel::IntersectionNV) { + if (HasBuiltinDecoration(decoration_manager, var_id, + uint32_t(spv::BuiltIn::RayTmaxKHR))) { + return true; + } + } + + switch (execution_model) { + case spv::ExecutionModel::RayGenerationKHR: + case spv::ExecutionModel::ClosestHitKHR: + case spv::ExecutionModel::MissKHR: + case spv::ExecutionModel::CallableKHR: + case spv::ExecutionModel::IntersectionKHR: + return HasBuiltinForRayTracingVolatileSemantics(decoration_manager, + var_id); + default: + return false; + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/spread_volatile_semantics.h b/thirdparty/glslang/External/spirv-tools/source/opt/spread_volatile_semantics.h new file mode 100644 index 000000000000..4cbb526feda6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/spread_volatile_semantics.h @@ -0,0 +1,117 @@ +// Copyright (c) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_SPREAD_VOLATILE_SEMANTICS_H_ +#define SOURCE_OPT_SPREAD_VOLATILE_SEMANTICS_H_ + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class SpreadVolatileSemantics : public Pass { + public: + SpreadVolatileSemantics() {} + + const char* name() const override { return "spread-volatile-semantics"; } + + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisDecorations | + IRContext::kAnalysisInstrToBlockMapping; + } + + private: + // Returns true if it does not have an execution model. Linkage shaders do not + // have an execution model. + bool HasNoExecutionModel() { + return get_module()->entry_points().empty() && + context()->get_feature_mgr()->HasCapability( + spv::Capability::Linkage); + } + + // Iterates interface variables and spreads the Volatile semantics if it has + // load instructions for the Volatile semantics. + Pass::Status SpreadVolatileSemanticsToVariables( + const bool is_vk_memory_model_enabled); + + // Returns whether |var_id| is the result id of a target builtin variable for + // the volatile semantics for |execution_model| based on the Vulkan spec + // VUID-StandaloneSpirv-VulkanMemoryModel-04678 or + // VUID-StandaloneSpirv-VulkanMemoryModel-04679. + bool IsTargetForVolatileSemantics(uint32_t var_id, + spv::ExecutionModel execution_model); + + // Collects interface variables that need the volatile semantics. + // |is_vk_memory_model_enabled| is true if VulkanMemoryModel capability is + // enabled. + void CollectTargetsForVolatileSemantics( + const bool is_vk_memory_model_enabled); + + // Reports an error if an interface variable is used by two entry points and + // it needs the Volatile decoration for one but not for another. Returns true + // if the error must be reported. + bool HasInterfaceInConflictOfVolatileSemantics(); + + // Returns whether the variable whose result is |var_id| is used by a + // non-volatile load or a pointer to it is used by a non-volatile load in + // |entry_point| or not. + bool IsTargetUsedByNonVolatileLoadInEntryPoint(uint32_t var_id, + Instruction* entry_point); + + // Visits load instructions of pointers to variable whose result id is + // |var_id| if the load instructions are in reachable functions from entry + // points. |handle_load| is a function to do some actions for the load + // instructions. Finishes the traversal and returns false if |handle_load| + // returns false for a load instruction. Otherwise, returns true after running + // |handle_load| for all the load instructions. + bool VisitLoadsOfPointersToVariableInEntries( + uint32_t var_id, const std::function& handle_load, + const std::unordered_set& function_ids); + + // Sets Memory Operands of OpLoad instructions that load |var| or pointers + // of |var| as Volatile if the function id of the OpLoad instruction is + // included in |entry_function_ids|. + void SetVolatileForLoadsInEntries( + Instruction* var, const std::unordered_set& entry_function_ids); + + // Adds OpDecorate Volatile for |var| if it does not exist. + void DecorateVarWithVolatile(Instruction* var); + + // Returns a set of entry function ids to spread the volatile semantics for + // the variable with the result id |var_id|. + std::unordered_set EntryFunctionsToSpreadVolatileSemanticsForVar( + uint32_t var_id) { + auto itr = var_ids_to_entry_fn_for_volatile_semantics_.find(var_id); + if (itr == var_ids_to_entry_fn_for_volatile_semantics_.end()) return {}; + return itr->second; + } + + // Specifies that we have to spread the volatile semantics for the + // variable with the result id |var_id| for the entry point |entry_point|. + void MarkVolatileSemanticsForVariable(uint32_t var_id, + Instruction* entry_point); + + // Result ids of variables to entry function ids for the volatile semantics + // spread. + std::unordered_map> + var_ids_to_entry_fn_for_volatile_semantics_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_SPREAD_VOLATILE_SEMANTICS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/spv-amd-shader-ballot.insts.inc b/thirdparty/glslang/External/spirv-tools/source/opt/spv-amd-shader-ballot.insts.inc new file mode 100644 index 000000000000..c3b4aa09b8b8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/spv-amd-shader-ballot.insts.inc @@ -0,0 +1,8 @@ + + +static const spv_ext_inst_desc_t spv_amd_shader_ballot_entries[] = { + {"SwizzleInvocationsAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SwizzleInvocationsMaskedAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"WriteInvocationAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"MbcntAMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ssa_rewrite_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/ssa_rewrite_pass.cpp new file mode 100644 index 000000000000..3eb4ec3f8e68 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ssa_rewrite_pass.cpp @@ -0,0 +1,708 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file implements the SSA rewriting algorithm proposed in +// +// Simple and Efficient Construction of Static Single Assignment Form. +// Braun M., Buchwald S., Hack S., Leißa R., Mallon C., Zwinkau A. (2013) +// In: Jhala R., De Bosschere K. (eds) +// Compiler Construction. CC 2013. +// Lecture Notes in Computer Science, vol 7791. +// Springer, Berlin, Heidelberg +// +// https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6 +// +// In contrast to common eager algorithms based on dominance and dominance +// frontier information, this algorithm works backwards from load operations. +// +// When a target variable is loaded, it queries the variable's reaching +// definition. If the reaching definition is unknown at the current location, +// it searches backwards in the CFG, inserting Phi instructions at join points +// in the CFG along the way until it finds the desired store instruction. +// +// The algorithm avoids repeated lookups using memoization. +// +// For reducible CFGs, which are a superset of the structured CFGs in SPIRV, +// this algorithm is proven to produce minimal SSA. That is, it inserts the +// minimal number of Phi instructions required to ensure the SSA property, but +// some Phi instructions may be dead +// (https://en.wikipedia.org/wiki/Static_single_assignment_form). + +#include "source/opt/ssa_rewrite_pass.h" + +#include +#include + +#include "source/opcode.h" +#include "source/opt/cfg.h" +#include "source/opt/mem_pass.h" +#include "source/opt/types.h" + +// Debug logging (0: Off, 1-N: Verbosity level). Replace this with the +// implementation done for +// https://github.com/KhronosGroup/SPIRV-Tools/issues/1351 +// #define SSA_REWRITE_DEBUGGING_LEVEL 3 + +#ifdef SSA_REWRITE_DEBUGGING_LEVEL +#include +#else +#define SSA_REWRITE_DEBUGGING_LEVEL 0 +#endif + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kStoreValIdInIdx = 1; +constexpr uint32_t kVariableInitIdInIdx = 1; +} // namespace + +std::string SSARewriter::PhiCandidate::PrettyPrint(const CFG* cfg) const { + std::ostringstream str; + str << "%" << result_id_ << " = Phi[%" << var_id_ << ", BB %" << bb_->id() + << "]("; + if (phi_args_.size() > 0) { + uint32_t arg_ix = 0; + for (uint32_t pred_label : cfg->preds(bb_->id())) { + uint32_t arg_id = phi_args_[arg_ix++]; + str << "[%" << arg_id << ", bb(%" << pred_label << ")] "; + } + } + str << ")"; + if (copy_of_ != 0) { + str << " [COPY OF " << copy_of_ << "]"; + } + str << ((is_complete_) ? " [COMPLETE]" : " [INCOMPLETE]"); + + return str.str(); +} + +SSARewriter::PhiCandidate& SSARewriter::CreatePhiCandidate(uint32_t var_id, + BasicBlock* bb) { + // TODO(1841): Handle id overflow. + uint32_t phi_result_id = pass_->context()->TakeNextId(); + auto result = phi_candidates_.emplace( + phi_result_id, PhiCandidate(var_id, phi_result_id, bb)); + PhiCandidate& phi_candidate = result.first->second; + return phi_candidate; +} + +void SSARewriter::ReplacePhiUsersWith(const PhiCandidate& phi_to_remove, + uint32_t repl_id) { + for (uint32_t user_id : phi_to_remove.users()) { + PhiCandidate* user_phi = GetPhiCandidate(user_id); + BasicBlock* bb = pass_->context()->get_instr_block(user_id); + if (user_phi) { + // If the user is a Phi candidate, replace all arguments that refer to + // |phi_to_remove.result_id()| with |repl_id|. + for (uint32_t& arg : user_phi->phi_args()) { + if (arg == phi_to_remove.result_id()) { + arg = repl_id; + } + } + } else if (bb->id() == user_id) { + // The phi candidate is the definition of the variable at basic block + // |bb|. We must change this to the replacement. + WriteVariable(phi_to_remove.var_id(), bb, repl_id); + } else { + // For regular loads, traverse the |load_replacement_| table looking for + // instances of |phi_to_remove|. + for (auto& it : load_replacement_) { + if (it.second == phi_to_remove.result_id()) { + it.second = repl_id; + } + } + } + } +} + +uint32_t SSARewriter::TryRemoveTrivialPhi(PhiCandidate* phi_candidate) { + uint32_t same_id = 0; + for (uint32_t arg_id : phi_candidate->phi_args()) { + if (arg_id == same_id || arg_id == phi_candidate->result_id()) { + // This is a self-reference operand or a reference to the same value ID. + continue; + } + if (same_id != 0) { + // This Phi candidate merges at least two values. Therefore, it is not + // trivial. + assert(phi_candidate->copy_of() == 0 && + "Phi candidate transitioning from copy to non-copy."); + return phi_candidate->result_id(); + } + same_id = arg_id; + } + + // The previous logic has determined that this Phi candidate |phi_candidate| + // is trivial. It is essentially the copy operation phi_candidate->phi_result + // = Phi(same, same, same, ...). Since it is not necessary, we can re-route + // all the users of |phi_candidate->phi_result| to all its users, and remove + // |phi_candidate|. + + // Mark the Phi candidate as a trivial copy of |same_id|, so it won't be + // generated. + phi_candidate->MarkCopyOf(same_id); + + assert(same_id != 0 && "Completed Phis cannot have %0 in their arguments"); + + // Since |phi_candidate| always produces |same_id|, replace all the users of + // |phi_candidate| with |same_id|. + ReplacePhiUsersWith(*phi_candidate, same_id); + + return same_id; +} + +uint32_t SSARewriter::AddPhiOperands(PhiCandidate* phi_candidate) { + assert(phi_candidate->phi_args().size() == 0 && + "Phi candidate already has arguments"); + + bool found_0_arg = false; + for (uint32_t pred : pass_->cfg()->preds(phi_candidate->bb()->id())) { + BasicBlock* pred_bb = pass_->cfg()->block(pred); + + // If |pred_bb| is not sealed, use %0 to indicate that + // |phi_candidate| needs to be completed after the whole CFG has + // been processed. + // + // Note that we cannot call GetReachingDef() in these cases + // because this would generate an empty Phi candidate in + // |pred_bb|. When |pred_bb| is later processed, a new definition + // for |phi_candidate->var_id_| will be lost because + // |phi_candidate| will still be reached by the empty Phi. + // + // Consider: + // + // BB %23: + // %38 = Phi[%i](%int_0[%1], %39[%25]) + // + // ... + // + // BB %25: [Starts unsealed] + // %39 = Phi[%i]() + // %34 = ... + // OpStore %i %34 -> Currdef(%i) at %25 is %34 + // OpBranch %23 + // + // When we first create the Phi in %38, we add an operandless Phi in + // %39 to hold the unknown reaching def for %i. + // + // But then, when we go to complete %39 at the end. The reaching def + // for %i in %25's predecessor is %38 itself. So we miss the fact + // that %25 has a def for %i that should be used. + // + // By making the argument %0, we make |phi_candidate| incomplete, + // which will cause it to be completed after the whole CFG has + // been scanned. + uint32_t arg_id = IsBlockSealed(pred_bb) + ? GetReachingDef(phi_candidate->var_id(), pred_bb) + : 0; + phi_candidate->phi_args().push_back(arg_id); + + if (arg_id == 0) { + found_0_arg = true; + } else { + // If this argument is another Phi candidate, add |phi_candidate| to the + // list of users for the defining Phi. + PhiCandidate* defining_phi = GetPhiCandidate(arg_id); + if (defining_phi && defining_phi != phi_candidate) { + defining_phi->AddUser(phi_candidate->result_id()); + } + } + } + + // If we could not fill-in all the arguments of this Phi, mark it incomplete + // so it gets completed after the whole CFG has been processed. + if (found_0_arg) { + phi_candidate->MarkIncomplete(); + incomplete_phis_.push(phi_candidate); + return phi_candidate->result_id(); + } + + // Try to remove |phi_candidate|, if it's trivial. + uint32_t repl_id = TryRemoveTrivialPhi(phi_candidate); + if (repl_id == phi_candidate->result_id()) { + // |phi_candidate| is complete and not trivial. Add it to the + // list of Phi candidates to generate. + phi_candidate->MarkComplete(); + phis_to_generate_.push_back(phi_candidate); + } + + return repl_id; +} + +uint32_t SSARewriter::GetValueAtBlock(uint32_t var_id, BasicBlock* bb) { + assert(bb != nullptr); + const auto& bb_it = defs_at_block_.find(bb); + if (bb_it != defs_at_block_.end()) { + const auto& current_defs = bb_it->second; + const auto& var_it = current_defs.find(var_id); + if (var_it != current_defs.end()) { + return var_it->second; + } + } + return 0; +} + +uint32_t SSARewriter::GetReachingDef(uint32_t var_id, BasicBlock* bb) { + // If |var_id| has a definition in |bb|, return it. + uint32_t val_id = GetValueAtBlock(var_id, bb); + if (val_id != 0) return val_id; + + // Otherwise, look up the value for |var_id| in |bb|'s predecessors. + auto& predecessors = pass_->cfg()->preds(bb->id()); + if (predecessors.size() == 1) { + // If |bb| has exactly one predecessor, we look for |var_id|'s definition + // there. + val_id = GetReachingDef(var_id, pass_->cfg()->block(predecessors[0])); + } else if (predecessors.size() > 1) { + // If there is more than one predecessor, this is a join block which may + // require a Phi instruction. This will act as |var_id|'s current + // definition to break potential cycles. + PhiCandidate& phi_candidate = CreatePhiCandidate(var_id, bb); + + // Set the value for |bb| to avoid an infinite recursion. + WriteVariable(var_id, bb, phi_candidate.result_id()); + val_id = AddPhiOperands(&phi_candidate); + } + + // If we could not find a store for this variable in the path from the root + // of the CFG, the variable is not defined, so we use undef. + if (val_id == 0) { + val_id = pass_->GetUndefVal(var_id); + if (val_id == 0) { + return 0; + } + } + + WriteVariable(var_id, bb, val_id); + + return val_id; +} + +void SSARewriter::SealBlock(BasicBlock* bb) { + auto result = sealed_blocks_.insert(bb); + (void)result; + assert(result.second == true && + "Tried to seal the same basic block more than once."); +} + +void SSARewriter::ProcessStore(Instruction* inst, BasicBlock* bb) { + auto opcode = inst->opcode(); + assert((opcode == spv::Op::OpStore || opcode == spv::Op::OpVariable) && + "Expecting a store or a variable definition instruction."); + + uint32_t var_id = 0; + uint32_t val_id = 0; + if (opcode == spv::Op::OpStore) { + (void)pass_->GetPtr(inst, &var_id); + val_id = inst->GetSingleWordInOperand(kStoreValIdInIdx); + } else if (inst->NumInOperands() >= 2) { + var_id = inst->result_id(); + val_id = inst->GetSingleWordInOperand(kVariableInitIdInIdx); + } + if (pass_->IsTargetVar(var_id)) { + WriteVariable(var_id, bb, val_id); + pass_->context()->get_debug_info_mgr()->AddDebugValueForVariable( + inst, var_id, val_id, inst); + +#if SSA_REWRITE_DEBUGGING_LEVEL > 1 + std::cerr << "\tFound store '%" << var_id << " = %" << val_id << "': " + << inst->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) + << "\n"; +#endif + } +} + +bool SSARewriter::ProcessLoad(Instruction* inst, BasicBlock* bb) { + // Get the pointer that we are using to load from. + uint32_t var_id = 0; + (void)pass_->GetPtr(inst, &var_id); + + // Get the immediate reaching definition for |var_id|. + // + // In the presence of variable pointers, the reaching definition may be + // another pointer. For example, the following fragment: + // + // %2 = OpVariable %_ptr_Input_float Input + // %11 = OpVariable %_ptr_Function__ptr_Input_float Function + // OpStore %11 %2 + // %12 = OpLoad %_ptr_Input_float %11 + // %13 = OpLoad %float %12 + // + // corresponds to the pseudo-code: + // + // layout(location = 0) in flat float *%2 + // float %13; + // float *%12; + // float **%11; + // *%11 = %2; + // %12 = *%11; + // %13 = *%12; + // + // which ultimately, should correspond to: + // + // %13 = *%2; + // + // During rewriting, the pointer %12 is found to be replaceable by %2 (i.e., + // load_replacement_[12] is 2). However, when processing the load + // %13 = *%12, the type of %12's reaching definition is another float + // pointer (%2), instead of a float value. + // + // When this happens, we need to continue looking up the reaching definition + // chain until we get to a float value or a non-target var (i.e. a variable + // that cannot be SSA replaced, like %2 in this case since it is a function + // argument). + analysis::DefUseManager* def_use_mgr = pass_->context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = pass_->context()->get_type_mgr(); + analysis::Type* load_type = type_mgr->GetType(inst->type_id()); + uint32_t val_id = 0; + bool found_reaching_def = false; + while (!found_reaching_def) { + if (!pass_->IsTargetVar(var_id)) { + // If the variable we are loading from is not an SSA target (globals, + // function parameters), do nothing. + return true; + } + + val_id = GetReachingDef(var_id, bb); + if (val_id == 0) { + return false; + } + + // If the reaching definition is a pointer type different than the type of + // the instruction we are analyzing, then it must be a reference to another + // pointer (otherwise, this would be invalid SPIRV). We continue + // de-referencing it by making |val_id| be |var_id|. + // + // NOTE: if there is no reaching definition instruction, it means |val_id| + // is an undef. + Instruction* reaching_def_inst = def_use_mgr->GetDef(val_id); + if (reaching_def_inst && + !type_mgr->GetType(reaching_def_inst->type_id())->IsSame(load_type)) { + var_id = val_id; + } else { + found_reaching_def = true; + } + } + + // Schedule a replacement for the result of this load instruction with + // |val_id|. After all the rewriting decisions are made, every use of + // this load will be replaced with |val_id|. + uint32_t load_id = inst->result_id(); + assert(load_replacement_.count(load_id) == 0); + load_replacement_[load_id] = val_id; + PhiCandidate* defining_phi = GetPhiCandidate(val_id); + if (defining_phi) { + defining_phi->AddUser(load_id); + } + +#if SSA_REWRITE_DEBUGGING_LEVEL > 1 + std::cerr << "\tFound load: " + << inst->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) + << " (replacement for %" << load_id << " is %" << val_id << ")\n"; +#endif + + return true; +} + +void SSARewriter::PrintPhiCandidates() const { + std::cerr << "\nPhi candidates:\n"; + for (const auto& phi_it : phi_candidates_) { + std::cerr << "\tBB %" << phi_it.second.bb()->id() << ": " + << phi_it.second.PrettyPrint(pass_->cfg()) << "\n"; + } + std::cerr << "\n"; +} + +void SSARewriter::PrintReplacementTable() const { + std::cerr << "\nLoad replacement table\n"; + for (const auto& it : load_replacement_) { + std::cerr << "\t%" << it.first << " -> %" << it.second << "\n"; + } + std::cerr << "\n"; +} + +bool SSARewriter::GenerateSSAReplacements(BasicBlock* bb) { +#if SSA_REWRITE_DEBUGGING_LEVEL > 1 + std::cerr << "Generating SSA replacements for block: " << bb->id() << "\n"; + std::cerr << bb->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) + << "\n"; +#endif + + for (auto& inst : *bb) { + auto opcode = inst.opcode(); + if (opcode == spv::Op::OpStore || opcode == spv::Op::OpVariable) { + ProcessStore(&inst, bb); + } else if (inst.opcode() == spv::Op::OpLoad) { + if (!ProcessLoad(&inst, bb)) { + return false; + } + } + } + + // Seal |bb|. This means that all the stores in it have been scanned and + // it's ready to feed them into its successors. + SealBlock(bb); + +#if SSA_REWRITE_DEBUGGING_LEVEL > 1 + PrintPhiCandidates(); + PrintReplacementTable(); + std::cerr << "\n\n"; +#endif + return true; +} + +uint32_t SSARewriter::GetReplacement(std::pair repl) { + uint32_t val_id = repl.second; + auto it = load_replacement_.find(val_id); + while (it != load_replacement_.end()) { + val_id = it->second; + it = load_replacement_.find(val_id); + } + return val_id; +} + +uint32_t SSARewriter::GetPhiArgument(const PhiCandidate* phi_candidate, + uint32_t ix) { + assert(phi_candidate->IsReady() && + "Tried to get the final argument from an incomplete/trivial Phi"); + + uint32_t arg_id = phi_candidate->phi_args()[ix]; + while (arg_id != 0) { + PhiCandidate* phi_user = GetPhiCandidate(arg_id); + if (phi_user == nullptr || phi_user->IsReady()) { + // If the argument is not a Phi or it's a Phi candidate ready to be + // emitted, return it. + return arg_id; + } + arg_id = phi_user->copy_of(); + } + + assert(false && + "No Phi candidates in the copy-of chain are ready to be generated"); + + return 0; +} + +bool SSARewriter::ApplyReplacements() { + bool modified = false; + +#if SSA_REWRITE_DEBUGGING_LEVEL > 2 + std::cerr << "\n\nApplying replacement decisions to IR\n\n"; + PrintPhiCandidates(); + PrintReplacementTable(); + std::cerr << "\n\n"; +#endif + + // Add Phi instructions from completed Phi candidates. + std::vector generated_phis; + for (const PhiCandidate* phi_candidate : phis_to_generate_) { +#if SSA_REWRITE_DEBUGGING_LEVEL > 2 + std::cerr << "Phi candidate: " << phi_candidate->PrettyPrint(pass_->cfg()) + << "\n"; +#endif + + assert(phi_candidate->is_complete() && + "Tried to instantiate a Phi instruction from an incomplete Phi " + "candidate"); + + auto* local_var = pass_->get_def_use_mgr()->GetDef(phi_candidate->var_id()); + + // Build the vector of operands for the new OpPhi instruction. + uint32_t type_id = pass_->GetPointeeTypeId(local_var); + std::vector phi_operands; + uint32_t arg_ix = 0; + std::unordered_map already_seen; + for (uint32_t pred_label : pass_->cfg()->preds(phi_candidate->bb()->id())) { + uint32_t op_val_id = GetPhiArgument(phi_candidate, arg_ix++); + if (already_seen.count(pred_label) == 0) { + phi_operands.push_back( + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {op_val_id}}); + phi_operands.push_back( + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {pred_label}}); + already_seen[pred_label] = op_val_id; + } else { + // It is possible that there are two edges from the same parent block. + // Since the OpPhi can have only one entry for each parent, we have to + // make sure the two edges are consistent with each other. + assert(already_seen[pred_label] == op_val_id && + "Inconsistent value for duplicate edges."); + } + } + + // Generate a new OpPhi instruction and insert it in its basic + // block. + std::unique_ptr phi_inst( + new Instruction(pass_->context(), spv::Op::OpPhi, type_id, + phi_candidate->result_id(), phi_operands)); + generated_phis.push_back(phi_inst.get()); + pass_->get_def_use_mgr()->AnalyzeInstDef(&*phi_inst); + pass_->context()->set_instr_block(&*phi_inst, phi_candidate->bb()); + auto insert_it = phi_candidate->bb()->begin(); + insert_it = insert_it.InsertBefore(std::move(phi_inst)); + pass_->context()->get_decoration_mgr()->CloneDecorations( + phi_candidate->var_id(), phi_candidate->result_id(), + {spv::Decoration::RelaxedPrecision}); + + // Add DebugValue for the new OpPhi instruction. + insert_it->SetDebugScope(local_var->GetDebugScope()); + pass_->context()->get_debug_info_mgr()->AddDebugValueForVariable( + &*insert_it, phi_candidate->var_id(), phi_candidate->result_id(), + &*insert_it); + + modified = true; + } + + // Scan uses for all inserted Phi instructions. Do this separately from the + // registration of the Phi instruction itself to avoid trying to analyze + // uses of Phi instructions that have not been registered yet. + for (Instruction* phi_inst : generated_phis) { + pass_->get_def_use_mgr()->AnalyzeInstUse(&*phi_inst); + } + +#if SSA_REWRITE_DEBUGGING_LEVEL > 1 + std::cerr << "\n\nReplacing the result of load instructions with the " + "corresponding SSA id\n\n"; +#endif + + // Apply replacements from the load replacement table. + for (auto& repl : load_replacement_) { + uint32_t load_id = repl.first; + uint32_t val_id = GetReplacement(repl); + Instruction* load_inst = + pass_->context()->get_def_use_mgr()->GetDef(load_id); + +#if SSA_REWRITE_DEBUGGING_LEVEL > 2 + std::cerr << "\t" + << load_inst->PrettyPrint( + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) + << " (%" << load_id << " -> %" << val_id << ")\n"; +#endif + + // Remove the load instruction and replace all the uses of this load's + // result with |val_id|. Kill any names or decorates using the load's + // result before replacing to prevent incorrect replacement in those + // instructions. + pass_->context()->KillNamesAndDecorates(load_id); + pass_->context()->ReplaceAllUsesWith(load_id, val_id); + pass_->context()->KillInst(load_inst); + modified = true; + } + + return modified; +} + +void SSARewriter::FinalizePhiCandidate(PhiCandidate* phi_candidate) { + assert(phi_candidate->phi_args().size() > 0 && + "Phi candidate should have arguments"); + + uint32_t ix = 0; + for (uint32_t pred : pass_->cfg()->preds(phi_candidate->bb()->id())) { + BasicBlock* pred_bb = pass_->cfg()->block(pred); + uint32_t& arg_id = phi_candidate->phi_args()[ix++]; + if (arg_id == 0) { + // If |pred_bb| is still not sealed, it means it's unreachable. In this + // case, we just use Undef as an argument. + arg_id = IsBlockSealed(pred_bb) + ? GetReachingDef(phi_candidate->var_id(), pred_bb) + : pass_->GetUndefVal(phi_candidate->var_id()); + } + } + + // This candidate is now completed. + phi_candidate->MarkComplete(); + + // If |phi_candidate| is not trivial, add it to the list of Phis to + // generate. + if (TryRemoveTrivialPhi(phi_candidate) == phi_candidate->result_id()) { + // If we could not remove |phi_candidate|, it means that it is complete + // and not trivial. Add it to the list of Phis to generate. + assert(!phi_candidate->copy_of() && "A completed Phi cannot be trivial."); + phis_to_generate_.push_back(phi_candidate); + } +} + +void SSARewriter::FinalizePhiCandidates() { +#if SSA_REWRITE_DEBUGGING_LEVEL > 1 + std::cerr << "Finalizing Phi candidates:\n\n"; + PrintPhiCandidates(); + std::cerr << "\n"; +#endif + + // Now, complete the collected candidates. + while (incomplete_phis_.size() > 0) { + PhiCandidate* phi_candidate = incomplete_phis_.front(); + incomplete_phis_.pop(); + FinalizePhiCandidate(phi_candidate); + } +} + +Pass::Status SSARewriter::RewriteFunctionIntoSSA(Function* fp) { +#if SSA_REWRITE_DEBUGGING_LEVEL > 0 + std::cerr << "Function before SSA rewrite:\n" + << fp->PrettyPrint(0) << "\n\n\n"; +#endif + + // Collect variables that can be converted into SSA IDs. + pass_->CollectTargetVars(fp); + + // Generate all the SSA replacements and Phi candidates. This will + // generate incomplete and trivial Phis. + bool succeeded = pass_->cfg()->WhileEachBlockInReversePostOrder( + fp->entry().get(), [this](BasicBlock* bb) { + if (!GenerateSSAReplacements(bb)) { + return false; + } + return true; + }); + + if (!succeeded) { + return Pass::Status::Failure; + } + + // Remove trivial Phis and add arguments to incomplete Phis. + FinalizePhiCandidates(); + + // Finally, apply all the replacements in the IR. + bool modified = ApplyReplacements(); + +#if SSA_REWRITE_DEBUGGING_LEVEL > 0 + std::cerr << "\n\n\nFunction after SSA rewrite:\n" + << fp->PrettyPrint(0) << "\n"; +#endif + + return modified ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +Pass::Status SSARewritePass::Process() { + Status status = Status::SuccessWithoutChange; + for (auto& fn : *get_module()) { + if (fn.IsDeclaration()) { + continue; + } + status = + CombineStatus(status, SSARewriter(this).RewriteFunctionIntoSSA(&fn)); + // Kill DebugDeclares for target variables. + for (auto var_id : seen_target_vars_) { + context()->get_debug_info_mgr()->KillDebugDeclares(var_id); + } + if (status == Status::Failure) { + break; + } + } + return status; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/ssa_rewrite_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/ssa_rewrite_pass.h new file mode 100644 index 000000000000..2470f85f6bce --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/ssa_rewrite_pass.h @@ -0,0 +1,306 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_SSA_REWRITE_PASS_H_ +#define SOURCE_OPT_SSA_REWRITE_PASS_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/opt/basic_block.h" +#include "source/opt/ir_context.h" +#include "source/opt/mem_pass.h" + +namespace spvtools { +namespace opt { + +// Utility class for passes that need to rewrite a function into SSA. This +// converts load/store operations on function-local variables into SSA IDs, +// which allows them to be the target of optimizing transformations. +// +// Store and load operations to these variables are converted into +// operations on SSA IDs. Phi instructions are added when needed. See the +// SSA construction paper for algorithmic details +// (https://link.springer.com/chapter/10.1007/978-3-642-37051-9_6) +class SSARewriter { + public: + SSARewriter(MemPass* pass) : pass_(pass) {} + + // Rewrites SSA-target variables in function |fp| into SSA. This is the + // entry point for the SSA rewrite algorithm. SSA-target variables are + // locally defined variables that meet the criteria set by IsSSATargetVar. + // + // Returns whether the function was modified or not, and whether or not the + // rewrite was successful. + Pass::Status RewriteFunctionIntoSSA(Function* fp); + + private: + class PhiCandidate { + public: + explicit PhiCandidate(uint32_t var, uint32_t result, BasicBlock* block) + : var_id_(var), + result_id_(result), + bb_(block), + phi_args_(), + copy_of_(0), + is_complete_(false), + users_() {} + + uint32_t var_id() const { return var_id_; } + uint32_t result_id() const { return result_id_; } + BasicBlock* bb() const { return bb_; } + std::vector& phi_args() { return phi_args_; } + const std::vector& phi_args() const { return phi_args_; } + uint32_t copy_of() const { return copy_of_; } + bool is_complete() const { return is_complete_; } + std::vector& users() { return users_; } + const std::vector& users() const { return users_; } + + // Marks this phi candidate as a trivial copy of |orig_id|. + void MarkCopyOf(uint32_t orig_id) { copy_of_ = orig_id; } + + // Marks this phi candidate as incomplete. + void MarkIncomplete() { is_complete_ = false; } + + // Marks this phi candidate as complete. + void MarkComplete() { is_complete_ = true; } + + // Returns true if this Phi candidate is ready to be emitted. + bool IsReady() const { return is_complete() && copy_of() == 0; } + + // Pretty prints this Phi candidate into a string and returns it. |cfg| is + // needed to lookup basic block predecessors. + std::string PrettyPrint(const CFG* cfg) const; + + // Registers |operand_id| as a user of this Phi candidate. + void AddUser(uint32_t operand_id) { users_.push_back(operand_id); } + + private: + // Variable ID that this Phi is merging. + uint32_t var_id_; + + // SSA ID generated by this Phi (i.e., this is the result ID of the eventual + // Phi instruction). + uint32_t result_id_; + + // Basic block to hold this Phi. + BasicBlock* bb_; + + // Vector of operands for every predecessor block of |bb|. This vector is + // organized so that the Ith slot contains the argument coming from the Ith + // predecessor of |bb|. + std::vector phi_args_; + + // If this Phi is a trivial copy of another Phi, this is the ID of the + // original. If this is 0, it means that this is not a trivial Phi. + uint32_t copy_of_; + + // False, if this Phi candidate has no arguments or at least one argument is + // %0. + bool is_complete_; + + // List of all users for this Phi instruction. Each element is the result ID + // of the load instruction replaced by this Phi, or the result ID of a Phi + // candidate that has this Phi in its list of operands. + std::vector users_; + }; + + // Type used to keep track of store operations in each basic block. + typedef std::unordered_map> + BlockDefsMap; + + // Generates all the SSA rewriting decisions for basic block |bb|. This + // populates the Phi candidate table (|phi_candidate_|) and the load + // replacement table (|load_replacement_). Returns true if successful. + bool GenerateSSAReplacements(BasicBlock* bb); + + // Seals block |bb|. Sealing a basic block means |bb| and all its + // predecessors of |bb| have been scanned for loads/stores. + void SealBlock(BasicBlock* bb); + + // Returns true if |bb| has been sealed. + bool IsBlockSealed(BasicBlock* bb) { return sealed_blocks_.count(bb) != 0; } + + // Returns the Phi candidate with result ID |id| if it exists in the table + // |phi_candidates_|. If no such Phi candidate exists, it returns nullptr. + PhiCandidate* GetPhiCandidate(uint32_t id) { + auto it = phi_candidates_.find(id); + return (it != phi_candidates_.end()) ? &it->second : nullptr; + } + + // Replaces all the users of Phi candidate |phi_cand| to be users of + // |repl_id|. + void ReplacePhiUsersWith(const PhiCandidate& phi_cand, uint32_t repl_id); + + // Returns the value ID that should replace the load ID in the given + // replacement pair |repl|. The replacement is a pair (|load_id|, |val_id|). + // If |val_id| is itself replaced by another value in the table, this function + // will look the replacement for |val_id| until it finds one that is not + // itself replaced. For instance, given: + // + // %34 = OpLoad %float %f1 + // OpStore %t %34 + // %36 = OpLoad %float %t + // + // Assume that %f1 is reached by a Phi candidate %42, the load + // replacement table will have the following entries: + // + // %34 -> %42 + // %36 -> %34 + // + // So, when looking for the replacement for %36, we should not use + // %34. Rather, we should use %42. To do this, the chain of + // replacements must be followed until we reach an element that has + // no replacement. + uint32_t GetReplacement(std::pair repl); + + // Returns the argument at index |ix| from |phi_candidate|. If argument |ix| + // comes from a trivial Phi, it follows the copy-of chain from that trivial + // Phi until it finds the original Phi candidate. + // + // This is only valid after all Phi candidates have been completed. It can + // only be called when generating the IR for these Phis. + uint32_t GetPhiArgument(const PhiCandidate* phi_candidate, uint32_t ix); + + // Applies all the SSA replacement decisions. This replaces loads/stores to + // SSA target variables with their corresponding SSA IDs, and inserts Phi + // instructions for them. + bool ApplyReplacements(); + + // Registers a definition for variable |var_id| in basic block |bb| with + // value |val_id|. + void WriteVariable(uint32_t var_id, BasicBlock* bb, uint32_t val_id) { + defs_at_block_[bb][var_id] = val_id; + if (auto* pc = GetPhiCandidate(val_id)) { + pc->AddUser(bb->id()); + } + } + + // Returns the value of |var_id| at |bb| if |defs_at_block_| contains it. + // Otherwise, returns 0. + uint32_t GetValueAtBlock(uint32_t var_id, BasicBlock* bb); + + // Processes the store operation |inst| in basic block |bb|. This extracts + // the variable ID being stored into, determines whether the variable is an + // SSA-target variable, and, if it is, it stores its value in the + // |defs_at_block_| map. + void ProcessStore(Instruction* inst, BasicBlock* bb); + + // Processes the load operation |inst| in basic block |bb|. This extracts + // the variable ID being stored into, determines whether the variable is an + // SSA-target variable, and, if it is, it reads its reaching definition by + // calling |GetReachingDef|. Returns true if successful. + bool ProcessLoad(Instruction* inst, BasicBlock* bb); + + // Reads the current definition for variable |var_id| in basic block |bb|. + // If |var_id| is not defined in block |bb| it walks up the predecessors of + // |bb|, creating new Phi candidates along the way, if needed. + // + // It returns the value for |var_id| from the RHS of the current reaching + // definition for |var_id|. + uint32_t GetReachingDef(uint32_t var_id, BasicBlock* bb); + + // Adds arguments to |phi_candidate| by getting the reaching definition of + // |phi_candidate|'s variable on each of the predecessors of its basic + // block. After populating the argument list, it determines whether all its + // arguments are the same. If so, it returns the ID of the argument that + // this Phi copies. + uint32_t AddPhiOperands(PhiCandidate* phi_candidate); + + // Creates a Phi candidate instruction for variable |var_id| in basic block + // |bb|. + // + // Since the rewriting algorithm may remove Phi candidates when it finds + // them to be trivial, we avoid the expense of creating actual Phi + // instructions by keeping a pool of Phi candidates (|phi_candidates_|) + // during rewriting. + // + // Once the candidate Phi is created, it returns its ID. + PhiCandidate& CreatePhiCandidate(uint32_t var_id, BasicBlock* bb); + + // Attempts to remove a trivial Phi candidate |phi_cand|. Trivial Phis are + // those that only reference themselves and one other value |val| any number + // of times. This will try to remove any other Phis that become trivial + // after |phi_cand| is removed. + // + // If |phi_cand| is trivial, it returns the SSA ID for the value that should + // replace it. Otherwise, it returns the SSA ID for |phi_cand|. + uint32_t TryRemoveTrivialPhi(PhiCandidate* phi_cand); + + // Finalizes |phi_candidate| by replacing every argument that is still %0 + // with its reaching definition. + void FinalizePhiCandidate(PhiCandidate* phi_candidate); + + // Finalizes processing of Phi candidates. Once the whole function has been + // scanned for loads and stores, the CFG will still have some incomplete and + // trivial Phis. This will add missing arguments and remove trivial Phi + // candidates. + void FinalizePhiCandidates(); + + // Prints the table of Phi candidates to std::cerr. + void PrintPhiCandidates() const; + + // Prints the load replacement table to std::cerr. + void PrintReplacementTable() const; + + // Map holding the value of every SSA-target variable at every basic block + // where the variable is stored. defs_at_block_[block][var_id] = val_id + // means that there is a store or Phi instruction for variable |var_id| at + // basic block |block| with value |val_id|. + BlockDefsMap defs_at_block_; + + // Map, indexed by Phi ID, holding all the Phi candidates created during SSA + // rewriting. |phi_candidates_[id]| returns the Phi candidate whose result + // is |id|. + std::unordered_map phi_candidates_; + + // Queue of incomplete Phi candidates. These are Phi candidates created at + // unsealed blocks. They need to be completed before they are instantiated + // in ApplyReplacements. + std::queue incomplete_phis_; + + // List of completed Phi candidates. These are the only candidates that + // will become real Phi instructions. + std::vector phis_to_generate_; + + // SSA replacement table. This maps variable IDs, resulting from a load + // operation, to the value IDs that will replace them after SSA rewriting. + // After all the rewriting decisions are made, a final scan through the IR + // is done to replace all uses of the original load ID with the value ID. + std::unordered_map load_replacement_; + + // Set of blocks that have been sealed already. + std::unordered_set sealed_blocks_; + + // Memory pass requesting the SSA rewriter. + MemPass* pass_; +}; + +class SSARewritePass : public MemPass { + public: + SSARewritePass() = default; + + const char* name() const override { return "ssa-rewrite"; } + Status Process() override; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_SSA_REWRITE_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/strength_reduction_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/strength_reduction_pass.cpp new file mode 100644 index 000000000000..16a7869ec5ab --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/strength_reduction_pass.cpp @@ -0,0 +1,194 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/strength_reduction_pass.h" + +#include +#include +#include +#include + +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/log.h" +#include "source/opt/reflect.h" + +namespace spvtools { +namespace opt { +namespace { +// Count the number of trailing zeros in the binary representation of +// |constVal|. +uint32_t CountTrailingZeros(uint32_t constVal) { + // Faster if we use the hardware count trailing zeros instruction. + // If not available, we could create a table. + uint32_t shiftAmount = 0; + while ((constVal & 1) == 0) { + ++shiftAmount; + constVal = (constVal >> 1); + } + return shiftAmount; +} + +// Return true if |val| is a power of 2. +bool IsPowerOf2(uint32_t val) { + // The idea is that the & will clear out the least + // significant 1 bit. If it is a power of 2, then + // there is exactly 1 bit set, and the value becomes 0. + if (val == 0) return false; + return ((val - 1) & val) == 0; +} + +} // namespace + +Pass::Status StrengthReductionPass::Process() { + // Initialize the member variables on a per module basis. + bool modified = false; + int32_type_id_ = 0; + uint32_type_id_ = 0; + std::memset(constant_ids_, 0, sizeof(constant_ids_)); + + FindIntTypesAndConstants(); + modified = ScanFunctions(); + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool StrengthReductionPass::ReplaceMultiplyByPowerOf2( + BasicBlock::iterator* inst) { + assert((*inst)->opcode() == spv::Op::OpIMul && + "Only works for multiplication of integers."); + bool modified = false; + + // Currently only works on 32-bit integers. + if ((*inst)->type_id() != int32_type_id_ && + (*inst)->type_id() != uint32_type_id_) { + return modified; + } + + // Check the operands for a constant that is a power of 2. + for (int i = 0; i < 2; i++) { + uint32_t opId = (*inst)->GetSingleWordInOperand(i); + Instruction* opInst = get_def_use_mgr()->GetDef(opId); + if (opInst->opcode() == spv::Op::OpConstant) { + // We found a constant operand. + uint32_t constVal = opInst->GetSingleWordOperand(2); + + if (IsPowerOf2(constVal)) { + modified = true; + uint32_t shiftAmount = CountTrailingZeros(constVal); + uint32_t shiftConstResultId = GetConstantId(shiftAmount); + + // Create the new instruction. + uint32_t newResultId = TakeNextId(); + std::vector newOperands; + newOperands.push_back((*inst)->GetInOperand(1 - i)); + Operand shiftOperand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {shiftConstResultId}); + newOperands.push_back(shiftOperand); + std::unique_ptr newInstruction( + new Instruction(context(), spv::Op::OpShiftLeftLogical, + (*inst)->type_id(), newResultId, newOperands)); + + // Insert the new instruction and update the data structures. + (*inst) = (*inst).InsertBefore(std::move(newInstruction)); + get_def_use_mgr()->AnalyzeInstDefUse(&*(*inst)); + ++(*inst); + context()->ReplaceAllUsesWith((*inst)->result_id(), newResultId); + + // Remove the old instruction. + Instruction* inst_to_delete = &*(*inst); + --(*inst); + context()->KillInst(inst_to_delete); + + // We do not want to replace the instruction twice if both operands + // are constants that are a power of 2. So we break here. + break; + } + } + } + + return modified; +} + +void StrengthReductionPass::FindIntTypesAndConstants() { + analysis::Integer int32(32, true); + int32_type_id_ = context()->get_type_mgr()->GetId(&int32); + analysis::Integer uint32(32, false); + uint32_type_id_ = context()->get_type_mgr()->GetId(&uint32); + for (auto iter = get_module()->types_values_begin(); + iter != get_module()->types_values_end(); ++iter) { + switch (iter->opcode()) { + case spv::Op::OpConstant: + if (iter->type_id() == uint32_type_id_) { + uint32_t value = iter->GetSingleWordOperand(2); + if (value <= 32) constant_ids_[value] = iter->result_id(); + } + break; + default: + break; + } + } +} + +uint32_t StrengthReductionPass::GetConstantId(uint32_t val) { + assert(val <= 32 && + "This function does not handle constants larger than 32."); + + if (constant_ids_[val] == 0) { + if (uint32_type_id_ == 0) { + analysis::Integer uint(32, false); + uint32_type_id_ = context()->get_type_mgr()->GetTypeInstruction(&uint); + } + + // Construct the constant. + uint32_t resultId = TakeNextId(); + Operand constant(spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {val}); + std::unique_ptr newConstant(new Instruction( + context(), spv::Op::OpConstant, uint32_type_id_, resultId, {constant})); + get_module()->AddGlobalValue(std::move(newConstant)); + + // Notify the DefUseManager about this constant. + auto constantIter = --get_module()->types_values_end(); + get_def_use_mgr()->AnalyzeInstDef(&*constantIter); + + // Store the result id for next time. + constant_ids_[val] = resultId; + } + + return constant_ids_[val]; +} + +bool StrengthReductionPass::ScanFunctions() { + // I did not use |ForEachInst| in the module because the function that acts on + // the instruction gets a pointer to the instruction. We cannot use that to + // insert a new instruction. I want an iterator. + bool modified = false; + for (auto& func : *get_module()) { + for (auto& bb : func) { + for (auto inst = bb.begin(); inst != bb.end(); ++inst) { + switch (inst->opcode()) { + case spv::Op::OpIMul: + if (ReplaceMultiplyByPowerOf2(&inst)) modified = true; + break; + default: + break; + } + } + } + } + return modified; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/strength_reduction_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/strength_reduction_pass.h new file mode 100644 index 000000000000..1cbbbcc6d0af --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/strength_reduction_pass.h @@ -0,0 +1,65 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_STRENGTH_REDUCTION_PASS_H_ +#define SOURCE_OPT_STRENGTH_REDUCTION_PASS_H_ + +#include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class StrengthReductionPass : public Pass { + public: + const char* name() const override { return "strength-reduction"; } + Status Process() override; + + private: + // Replaces multiple by power of 2 with an equivalent bit shift. + // Returns true if something changed. + bool ReplaceMultiplyByPowerOf2(BasicBlock::iterator*); + + // Scan the types and constants in the module looking for the integer + // types that we are + // interested in. The shift operation needs a small unsigned integer. We + // need to find + // them or create them. We do not want duplicates. + void FindIntTypesAndConstants(); + + // Get the id for the given constant. If it does not exist, it will be + // created. The parameter must be between 0 and 32 inclusive. + uint32_t GetConstantId(uint32_t); + + // Replaces certain instructions in function bodies with presumably cheaper + // ones. Returns true if something changed. + bool ScanFunctions(); + + // Type ids for the types of interest, or 0 if they do not exist. + uint32_t int32_type_id_; + uint32_t uint32_type_id_; + + // constant_ids[i] is the id for unsigned integer constant i. + // We set the limit at 32 because a bit shift of a 32-bit integer does not + // need a value larger than 32. + uint32_t constant_ids_[33]; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_STRENGTH_REDUCTION_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/strip_debug_info_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/strip_debug_info_pass.cpp new file mode 100644 index 000000000000..f81bced52c86 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/strip_debug_info_pass.cpp @@ -0,0 +1,111 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/strip_debug_info_pass.h" +#include "source/opt/ir_context.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { + +Pass::Status StripDebugInfoPass::Process() { + bool uses_non_semantic_info = false; + for (auto& inst : context()->module()->extensions()) { + const std::string ext_name = inst.GetInOperand(0).AsString(); + if (ext_name == "SPV_KHR_non_semantic_info") { + uses_non_semantic_info = true; + } + } + + std::vector to_kill; + + // if we use non-semantic info, it may reference OpString. Do a more + // expensive pass checking the uses of the OpString to see if any are + // OpExtInst on a non-semantic instruction set. If we're not using the + // extension then we can do a simpler pass and kill all debug1 instructions + if (uses_non_semantic_info) { + for (auto& inst : context()->module()->debugs1()) { + switch (inst.opcode()) { + case spv::Op::OpString: { + analysis::DefUseManager* def_use = context()->get_def_use_mgr(); + + // see if this string is used anywhere by a non-semantic instruction + bool no_nonsemantic_use = + def_use->WhileEachUser(&inst, [def_use](Instruction* use) { + if (use->opcode() == spv::Op::OpExtInst) { + auto ext_inst_set = + def_use->GetDef(use->GetSingleWordInOperand(0u)); + const std::string extension_name = + ext_inst_set->GetInOperand(0).AsString(); + if (spvtools::utils::starts_with(extension_name, + "NonSemantic.")) { + // found a non-semantic use, return false as we cannot + // remove this OpString + return false; + } + } + + // other instructions can't be a non-semantic use + return true; + }); + + if (no_nonsemantic_use) to_kill.push_back(&inst); + + break; + } + + default: + to_kill.push_back(&inst); + break; + } + } + } else { + for (auto& dbg : context()->debugs1()) to_kill.push_back(&dbg); + } + + for (auto& dbg : context()->debugs2()) to_kill.push_back(&dbg); + for (auto& dbg : context()->debugs3()) to_kill.push_back(&dbg); + for (auto& dbg : context()->ext_inst_debuginfo()) to_kill.push_back(&dbg); + + // OpName must come first, since they may refer to other debug instructions. + // If they are after the instructions that refer to, then they will be killed + // when that instruction is killed, which will lead to a double kill. + std::sort(to_kill.begin(), to_kill.end(), + [](Instruction* lhs, Instruction* rhs) -> bool { + if (lhs->opcode() == spv::Op::OpName && + rhs->opcode() != spv::Op::OpName) + return true; + return false; + }); + + bool modified = !to_kill.empty(); + + for (auto* inst : to_kill) context()->KillInst(inst); + + // clear OpLine information + context()->module()->ForEachInst([&modified](Instruction* inst) { + modified |= !inst->dbg_line_insts().empty(); + inst->dbg_line_insts().clear(); + }); + + if (!get_module()->trailing_dbg_line_info().empty()) { + modified = true; + get_module()->trailing_dbg_line_info().clear(); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/strip_debug_info_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/strip_debug_info_pass.h new file mode 100644 index 000000000000..47a2cd4090bd --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/strip_debug_info_pass.h @@ -0,0 +1,35 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_STRIP_DEBUG_INFO_PASS_H_ +#define SOURCE_OPT_STRIP_DEBUG_INFO_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class StripDebugInfoPass : public Pass { + public: + const char* name() const override { return "strip-debug"; } + Status Process() override; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_STRIP_DEBUG_INFO_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp new file mode 100644 index 000000000000..3886835ad7e1 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp @@ -0,0 +1,118 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/strip_nonsemantic_info_pass.h" + +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { + +Pass::Status StripNonSemanticInfoPass::Process() { + bool modified = false; + + std::vector to_remove; + + bool other_uses_for_decorate_string = false; + for (auto& inst : context()->module()->annotations()) { + switch (inst.opcode()) { + case spv::Op::OpDecorateStringGOOGLE: + if (spv::Decoration(inst.GetSingleWordInOperand(1)) == + spv::Decoration::HlslSemanticGOOGLE || + spv::Decoration(inst.GetSingleWordInOperand(1)) == + spv::Decoration::UserTypeGOOGLE) { + to_remove.push_back(&inst); + } else { + other_uses_for_decorate_string = true; + } + break; + + case spv::Op::OpMemberDecorateStringGOOGLE: + if (spv::Decoration(inst.GetSingleWordInOperand(2)) == + spv::Decoration::HlslSemanticGOOGLE || + spv::Decoration(inst.GetSingleWordInOperand(2)) == + spv::Decoration::UserTypeGOOGLE) { + to_remove.push_back(&inst); + } else { + other_uses_for_decorate_string = true; + } + break; + + case spv::Op::OpDecorateId: + if (spv::Decoration(inst.GetSingleWordInOperand(1)) == + spv::Decoration::HlslCounterBufferGOOGLE) { + to_remove.push_back(&inst); + } + break; + + default: + break; + } + } + + for (auto& inst : context()->module()->extensions()) { + const std::string ext_name = inst.GetInOperand(0).AsString(); + if (ext_name == "SPV_GOOGLE_hlsl_functionality1") { + to_remove.push_back(&inst); + } else if (ext_name == "SPV_GOOGLE_user_type") { + to_remove.push_back(&inst); + } else if (!other_uses_for_decorate_string && + ext_name == "SPV_GOOGLE_decorate_string") { + to_remove.push_back(&inst); + } else if (ext_name == "SPV_KHR_non_semantic_info") { + to_remove.push_back(&inst); + } + } + + // remove any extended inst imports that are non semantic + std::unordered_set non_semantic_sets; + for (auto& inst : context()->module()->ext_inst_imports()) { + assert(inst.opcode() == spv::Op::OpExtInstImport && + "Expecting an import of an extension's instruction set."); + const std::string extension_name = inst.GetInOperand(0).AsString(); + if (spvtools::utils::starts_with(extension_name, "NonSemantic.")) { + non_semantic_sets.insert(inst.result_id()); + to_remove.push_back(&inst); + } + } + + // if we removed some non-semantic sets, then iterate over the instructions in + // the module to remove any OpExtInst that referenced those sets + if (!non_semantic_sets.empty()) { + context()->module()->ForEachInst( + [&non_semantic_sets, &to_remove](Instruction* inst) { + if (inst->opcode() == spv::Op::OpExtInst) { + if (non_semantic_sets.find(inst->GetSingleWordInOperand(0)) != + non_semantic_sets.end()) { + to_remove.push_back(inst); + } + } + }, + true); + } + + for (auto* inst : to_remove) { + modified = true; + context()->KillInst(inst); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/strip_nonsemantic_info_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/strip_nonsemantic_info_pass.h new file mode 100644 index 000000000000..ff4e2e1ddfac --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/strip_nonsemantic_info_pass.h @@ -0,0 +1,44 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_STRIP_NONSEMANTIC_INFO_PASS_H_ +#define SOURCE_OPT_STRIP_NONSEMANTIC_INFO_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class StripNonSemanticInfoPass : public Pass { + public: + const char* name() const override { return "strip-nonsemantic"; } + Status Process() override; + + // Return the mask of preserved Analyses. + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | + IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_STRIP_NONSEMANTIC_INFO_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/struct_cfg_analysis.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/struct_cfg_analysis.cpp new file mode 100644 index 000000000000..290b4bf45d68 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/struct_cfg_analysis.cpp @@ -0,0 +1,249 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/struct_cfg_analysis.h" + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kMergeNodeIndex = 0; +constexpr uint32_t kContinueNodeIndex = 1; +} // namespace + +StructuredCFGAnalysis::StructuredCFGAnalysis(IRContext* ctx) : context_(ctx) { + // If this is not a shader, there are no merge instructions, and not + // structured CFG to analyze. + if (!context_->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { + return; + } + + for (auto& func : *context_->module()) { + AddBlocksInFunction(&func); + } +} + +void StructuredCFGAnalysis::AddBlocksInFunction(Function* func) { + if (func->begin() == func->end()) return; + + std::list order; + context_->cfg()->ComputeStructuredOrder(func, &*func->begin(), &order); + + struct TraversalInfo { + ConstructInfo cinfo; + uint32_t merge_node; + uint32_t continue_node; + }; + + // Set up a stack to keep track of currently active constructs. + std::vector state; + state.emplace_back(); + state[0].cinfo.containing_construct = 0; + state[0].cinfo.containing_loop = 0; + state[0].cinfo.containing_switch = 0; + state[0].cinfo.in_continue = false; + state[0].merge_node = 0; + state[0].continue_node = 0; + + for (BasicBlock* block : order) { + if (context_->cfg()->IsPseudoEntryBlock(block) || + context_->cfg()->IsPseudoExitBlock(block)) { + continue; + } + + if (block->id() == state.back().merge_node) { + state.pop_back(); + } + + // This works because the structured order is designed to keep the blocks in + // the continue construct between the continue header and the merge node. + if (block->id() == state.back().continue_node) { + state.back().cinfo.in_continue = true; + } + + bb_to_construct_.emplace(std::make_pair(block->id(), state.back().cinfo)); + + if (Instruction* merge_inst = block->GetMergeInst()) { + TraversalInfo new_state; + new_state.merge_node = + merge_inst->GetSingleWordInOperand(kMergeNodeIndex); + new_state.cinfo.containing_construct = block->id(); + + if (merge_inst->opcode() == spv::Op::OpLoopMerge) { + new_state.cinfo.containing_loop = block->id(); + new_state.cinfo.containing_switch = 0; + new_state.continue_node = + merge_inst->GetSingleWordInOperand(kContinueNodeIndex); + if (block->id() == new_state.continue_node) { + new_state.cinfo.in_continue = true; + bb_to_construct_[block->id()].in_continue = true; + } else { + new_state.cinfo.in_continue = false; + } + } else { + new_state.cinfo.containing_loop = state.back().cinfo.containing_loop; + new_state.cinfo.in_continue = state.back().cinfo.in_continue; + new_state.continue_node = state.back().continue_node; + + if (merge_inst->NextNode()->opcode() == spv::Op::OpSwitch) { + new_state.cinfo.containing_switch = block->id(); + } else { + new_state.cinfo.containing_switch = + state.back().cinfo.containing_switch; + } + } + + state.emplace_back(new_state); + merge_blocks_.Set(new_state.merge_node); + } + } +} + +uint32_t StructuredCFGAnalysis::ContainingConstruct(Instruction* inst) { + uint32_t bb = context_->get_instr_block(inst)->id(); + return ContainingConstruct(bb); +} + +uint32_t StructuredCFGAnalysis::MergeBlock(uint32_t bb_id) { + uint32_t header_id = ContainingConstruct(bb_id); + if (header_id == 0) { + return 0; + } + + BasicBlock* header = context_->cfg()->block(header_id); + Instruction* merge_inst = header->GetMergeInst(); + return merge_inst->GetSingleWordInOperand(kMergeNodeIndex); +} + +uint32_t StructuredCFGAnalysis::NestingDepth(uint32_t bb_id) { + uint32_t result = 0; + + // Find the merge block of the current merge construct as long as the block is + // inside a merge construct, exiting one for each iteration. + for (uint32_t merge_block_id = MergeBlock(bb_id); merge_block_id != 0; + merge_block_id = MergeBlock(merge_block_id)) { + result++; + } + + return result; +} + +uint32_t StructuredCFGAnalysis::LoopMergeBlock(uint32_t bb_id) { + uint32_t header_id = ContainingLoop(bb_id); + if (header_id == 0) { + return 0; + } + + BasicBlock* header = context_->cfg()->block(header_id); + Instruction* merge_inst = header->GetMergeInst(); + return merge_inst->GetSingleWordInOperand(kMergeNodeIndex); +} + +uint32_t StructuredCFGAnalysis::LoopContinueBlock(uint32_t bb_id) { + uint32_t header_id = ContainingLoop(bb_id); + if (header_id == 0) { + return 0; + } + + BasicBlock* header = context_->cfg()->block(header_id); + Instruction* merge_inst = header->GetMergeInst(); + return merge_inst->GetSingleWordInOperand(kContinueNodeIndex); +} + +uint32_t StructuredCFGAnalysis::LoopNestingDepth(uint32_t bb_id) { + uint32_t result = 0; + + // Find the merge block of the current loop as long as the block is inside a + // loop, exiting a loop for each iteration. + for (uint32_t merge_block_id = LoopMergeBlock(bb_id); merge_block_id != 0; + merge_block_id = LoopMergeBlock(merge_block_id)) { + result++; + } + + return result; +} + +uint32_t StructuredCFGAnalysis::SwitchMergeBlock(uint32_t bb_id) { + uint32_t header_id = ContainingSwitch(bb_id); + if (header_id == 0) { + return 0; + } + + BasicBlock* header = context_->cfg()->block(header_id); + Instruction* merge_inst = header->GetMergeInst(); + return merge_inst->GetSingleWordInOperand(kMergeNodeIndex); +} + +bool StructuredCFGAnalysis::IsContinueBlock(uint32_t bb_id) { + assert(bb_id != 0); + return LoopContinueBlock(bb_id) == bb_id; +} + +bool StructuredCFGAnalysis::IsInContainingLoopsContinueConstruct( + uint32_t bb_id) { + auto it = bb_to_construct_.find(bb_id); + if (it == bb_to_construct_.end()) { + return false; + } + return it->second.in_continue; +} + +bool StructuredCFGAnalysis::IsInContinueConstruct(uint32_t bb_id) { + while (bb_id != 0) { + if (IsInContainingLoopsContinueConstruct(bb_id)) { + return true; + } + bb_id = ContainingLoop(bb_id); + } + return false; +} + +bool StructuredCFGAnalysis::IsMergeBlock(uint32_t bb_id) { + return merge_blocks_.Get(bb_id); +} + +std::unordered_set +StructuredCFGAnalysis::FindFuncsCalledFromContinue() { + std::unordered_set called_from_continue; + std::queue funcs_to_process; + + // First collect the functions that are called directly from a continue + // construct. + for (Function& func : *context_->module()) { + for (auto& bb : func) { + if (IsInContainingLoopsContinueConstruct(bb.id())) { + for (const Instruction& inst : bb) { + if (inst.opcode() == spv::Op::OpFunctionCall) { + funcs_to_process.push(inst.GetSingleWordInOperand(0)); + } + } + } + } + } + + // Now collect all of the functions that are indirectly called as well. + while (!funcs_to_process.empty()) { + uint32_t func_id = funcs_to_process.front(); + funcs_to_process.pop(); + Function* func = context_->GetFunction(func_id); + if (called_from_continue.insert(func_id).second) { + context_->AddCalls(func, &funcs_to_process); + } + } + return called_from_continue; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/struct_cfg_analysis.h b/thirdparty/glslang/External/spirv-tools/source/opt/struct_cfg_analysis.h new file mode 100644 index 000000000000..9436b4fb0ea8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/struct_cfg_analysis.h @@ -0,0 +1,160 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_STRUCT_CFG_ANALYSIS_H_ +#define SOURCE_OPT_STRUCT_CFG_ANALYSIS_H_ + +#include +#include + +#include "source/opt/function.h" +#include "source/util/bit_vector.h" + +namespace spvtools { +namespace opt { + +class IRContext; + +// An analysis that, for each basic block, finds the constructs in which it is +// contained, so we can easily get headers and merge nodes. +class StructuredCFGAnalysis { + public: + explicit StructuredCFGAnalysis(IRContext* ctx); + + // Returns the id of the header of the innermost merge construct + // that contains |bb_id|. Returns |0| if |bb_id| is not contained in any + // merge construct. + uint32_t ContainingConstruct(uint32_t bb_id) { + auto it = bb_to_construct_.find(bb_id); + if (it == bb_to_construct_.end()) { + return 0; + } + return it->second.containing_construct; + } + + // Returns the id of the header of the innermost merge construct + // that contains |inst|. Returns |0| if |inst| is not contained in any + // merge construct. + uint32_t ContainingConstruct(Instruction* inst); + + // Returns the id of the merge block of the innermost merge construct + // that contains |bb_id|. Returns |0| if |bb_id| is not contained in any + // merge construct. + uint32_t MergeBlock(uint32_t bb_id); + + // Returns the nesting depth of the given block, i.e. the number of merge + // constructs containing it. Headers and merge blocks are not considered part + // of the corresponding merge constructs. + uint32_t NestingDepth(uint32_t block_id); + + // Returns the id of the header of the innermost loop construct + // that contains |bb_id|. Return |0| if |bb_id| is not contained in any loop + // construct. + uint32_t ContainingLoop(uint32_t bb_id) { + auto it = bb_to_construct_.find(bb_id); + if (it == bb_to_construct_.end()) { + return 0; + } + return it->second.containing_loop; + } + + // Returns the id of the merge block of the innermost loop construct + // that contains |bb_id|. Return |0| if |bb_id| is not contained in any loop + // construct. + uint32_t LoopMergeBlock(uint32_t bb_id); + + // Returns the id of the continue block of the innermost loop construct + // that contains |bb_id|. Return |0| if |bb_id| is not contained in any loop + // construct. + uint32_t LoopContinueBlock(uint32_t bb_id); + + // Returns the loop nesting depth of |bb_id| within its function, i.e. the + // number of loop constructs in which |bb_id| is contained. As per other + // functions in StructuredCFGAnalysis, a loop header is not regarded as being + // part of the loop that it heads, so that e.g. the nesting depth of an + // outer-most loop header is 0. + uint32_t LoopNestingDepth(uint32_t bb_id); + + // Returns the id of the header of the innermost switch construct + // that contains |bb_id| as long as there is no intervening loop. Returns |0| + // if no such construct exists. + uint32_t ContainingSwitch(uint32_t bb_id) { + auto it = bb_to_construct_.find(bb_id); + if (it == bb_to_construct_.end()) { + return 0; + } + return it->second.containing_switch; + } + // Returns the id of the merge block of the innermost switch construct + // that contains |bb_id| as long as there is no intervening loop. Return |0| + // if no such block exists. + uint32_t SwitchMergeBlock(uint32_t bb_id); + + // Returns true if |bb_id| is the continue block for a loop. + bool IsContinueBlock(uint32_t bb_id); + + // Returns true if |bb_id| is in the continue construct for its inner most + // containing loop. + bool IsInContainingLoopsContinueConstruct(uint32_t bb_id); + + // Returns true if |bb_id| is in the continue construct for any loop in its + // function. + bool IsInContinueConstruct(uint32_t bb_id); + + // Return true if |bb_id| is the merge block for a construct. + bool IsMergeBlock(uint32_t bb_id); + + // Returns the set of function ids that are called directly or indirectly from + // a continue construct. + std::unordered_set FindFuncsCalledFromContinue(); + + private: + // Struct used to hold the information for a basic block. + // |containing_construct| is the header for the innermost containing + // construct, or 0 if no such construct exists. It could be a selection + // construct or a loop construct. + // + // |containing_loop| is the innermost containing loop construct, or 0 if the + // basic bloc is not in a loop. If the basic block is in a selection + // construct that is contained in a loop construct, then these two values will + // not be the same. + // + // |containing_switch| is the innermost contain selection construct with an + // |OpSwitch| for the branch, as long as there is not intervening loop. This + // is used to identify the selection construct from which it can break. + // + // |in_continue| is true of the block is in the continue construct for its + // innermost containing loop. + struct ConstructInfo { + uint32_t containing_construct; + uint32_t containing_loop; + uint32_t containing_switch; + bool in_continue; + }; + + // Populates |bb_to_construct_| with the innermost containing merge and loop + // constructs for each basic block in |func|. + void AddBlocksInFunction(Function* func); + + IRContext* context_; + + // A map from a basic block to the headers of its inner most containing + // constructs. + std::unordered_map bb_to_construct_; + utils::BitVector merge_blocks_; +}; + +} // namespace opt +} // namespace spvtools +#endif // SOURCE_OPT_STRUCT_CFG_ANALYSIS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/switch_descriptorset_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/switch_descriptorset_pass.cpp new file mode 100644 index 000000000000..f07c917579f9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/switch_descriptorset_pass.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2023 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/switch_descriptorset_pass.h" + +#include "source/opt/ir_builder.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { + +Pass::Status SwitchDescriptorSetPass::Process() { + Status status = Status::SuccessWithoutChange; + auto* deco_mgr = context()->get_decoration_mgr(); + + for (Instruction& var : context()->types_values()) { + if (var.opcode() != spv::Op::OpVariable) { + continue; + } + auto decos = deco_mgr->GetDecorationsFor(var.result_id(), false); + for (const auto& deco : decos) { + spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u)); + if (d == spv::Decoration::DescriptorSet && + deco->GetSingleWordInOperand(2u) == ds_from_) { + deco->SetInOperand(2u, {ds_to_}); + status = Status::SuccessWithChange; + break; + } + } + } + return status; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/switch_descriptorset_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/switch_descriptorset_pass.h new file mode 100644 index 000000000000..2084e9cda154 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/switch_descriptorset_pass.h @@ -0,0 +1,52 @@ +// Copyright (c) 2023 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class SwitchDescriptorSetPass : public Pass { + public: + SwitchDescriptorSetPass(uint32_t ds_from, uint32_t ds_to) + : ds_from_(ds_from), ds_to_(ds_to) {} + + const char* name() const override { return "switch-descriptorset"; } + + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + // this pass preserves everything except decorations + uint32_t mask = ((IRContext::kAnalysisEnd << 1) - 1); + mask &= ~static_cast(IRContext::kAnalysisDecorations); + return static_cast(mask); + } + + private: + uint32_t ds_from_; + uint32_t ds_to_; +}; + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/tree_iterator.h b/thirdparty/glslang/External/spirv-tools/source/opt/tree_iterator.h new file mode 100644 index 000000000000..05f42bc5bd09 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/tree_iterator.h @@ -0,0 +1,246 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_TREE_ITERATOR_H_ +#define SOURCE_OPT_TREE_ITERATOR_H_ + +#include +#include +#include + +namespace spvtools { +namespace opt { + +// Helper class to iterate over a tree in a depth first order. +// The class assumes the data structure is a tree, tree node type implements a +// forward iterator. +// At each step, the iterator holds the pointer to the current node and state of +// the walk. +// The state is recorded by stacking the iteration position of the node +// children. To move to the next node, the iterator: +// - Looks at the top of the stack; +// - Sets the node behind the iterator as the current node; +// - Increments the iterator if it has more children to visit, pops otherwise; +// - If the current node has children, the children iterator is pushed into the +// stack. +template +class TreeDFIterator { + static_assert(!std::is_pointer::value && + !std::is_reference::value, + "NodeTy should be a class"); + // Type alias to keep track of the const qualifier. + using NodeIterator = + typename std::conditional::value, + typename NodeTy::const_iterator, + typename NodeTy::iterator>::type; + + // Type alias to keep track of the const qualifier. + using NodePtr = NodeTy*; + + public: + // Standard iterator interface. + using reference = NodeTy&; + using value_type = NodeTy; + + explicit inline TreeDFIterator(NodePtr top_node) : current_(top_node) { + if (current_ && current_->begin() != current_->end()) + parent_iterators_.emplace(make_pair(current_, current_->begin())); + } + + // end() iterator. + inline TreeDFIterator() : TreeDFIterator(nullptr) {} + + bool operator==(const TreeDFIterator& x) const { + return current_ == x.current_; + } + + bool operator!=(const TreeDFIterator& x) const { return !(*this == x); } + + reference operator*() const { return *current_; } + + NodePtr operator->() const { return current_; } + + TreeDFIterator& operator++() { + MoveToNextNode(); + return *this; + } + + TreeDFIterator operator++(int) { + TreeDFIterator tmp = *this; + ++*this; + return tmp; + } + + private: + // Moves the iterator to the next node in the tree. + // If we are at the end, do nothing, otherwise + // if our current node has children, use the children iterator and push the + // current node into the stack. + // If we reach the end of the local iterator, pop it. + inline void MoveToNextNode() { + if (!current_) return; + if (parent_iterators_.empty()) { + current_ = nullptr; + return; + } + std::pair& next_it = parent_iterators_.top(); + // Set the new node. + current_ = *next_it.second; + // Update the iterator for the next child. + ++next_it.second; + // If we finished with node, pop it. + if (next_it.first->end() == next_it.second) parent_iterators_.pop(); + // If our current node is not a leaf, store the iteration state for later. + if (current_->begin() != current_->end()) + parent_iterators_.emplace(make_pair(current_, current_->begin())); + } + + // The current node of the tree. + NodePtr current_; + // State of the tree walk: each pair contains the parent node (which has been + // already visited) and the iterator of the next children to visit. + // When all the children has been visited, we pop the entry, get the next + // child and push back the pair if the children iterator is not end(). + std::stack> parent_iterators_; +}; + +// Helper class to iterate over a tree in a depth first post-order. +// The class assumes the data structure is a tree, tree node type implements a +// forward iterator. +// At each step, the iterator holds the pointer to the current node and state of +// the walk. +// The state is recorded by stacking the iteration position of the node +// children. To move to the next node, the iterator: +// - Looks at the top of the stack; +// - If the children iterator has reach the end, then the node become the +// current one and we pop the stack; +// - Otherwise, we save the child and increment the iterator; +// - We walk the child sub-tree until we find a leaf, stacking all non-leaves +// states (pair of node pointer and child iterator) as we walk it. +template +class PostOrderTreeDFIterator { + static_assert(!std::is_pointer::value && + !std::is_reference::value, + "NodeTy should be a class"); + // Type alias to keep track of the const qualifier. + using NodeIterator = + typename std::conditional::value, + typename NodeTy::const_iterator, + typename NodeTy::iterator>::type; + + // Type alias to keep track of the const qualifier. + using NodePtr = NodeTy*; + + public: + // Standard iterator interface. + using reference = NodeTy&; + using value_type = NodeTy; + + static inline PostOrderTreeDFIterator begin(NodePtr top_node) { + return PostOrderTreeDFIterator(top_node); + } + + static inline PostOrderTreeDFIterator end(NodePtr sentinel_node) { + return PostOrderTreeDFIterator(sentinel_node, false); + } + + bool operator==(const PostOrderTreeDFIterator& x) const { + return current_ == x.current_; + } + + bool operator!=(const PostOrderTreeDFIterator& x) const { + return !(*this == x); + } + + reference operator*() const { return *current_; } + + NodePtr operator->() const { return current_; } + + PostOrderTreeDFIterator& operator++() { + MoveToNextNode(); + return *this; + } + + PostOrderTreeDFIterator operator++(int) { + PostOrderTreeDFIterator tmp = *this; + ++*this; + return tmp; + } + + private: + explicit inline PostOrderTreeDFIterator(NodePtr top_node) + : current_(top_node) { + if (current_) WalkToLeaf(); + } + + // Constructor for the "end()" iterator. + // |end_sentinel| is the value that acts as end value (can be null). The bool + // parameters is to distinguish from the start() Ctor. + inline PostOrderTreeDFIterator(NodePtr sentinel_node, bool) + : current_(sentinel_node) {} + + // Moves the iterator to the next node in the tree. + // If we are at the end, do nothing, otherwise + // if our current node has children, use the children iterator and push the + // current node into the stack. + // If we reach the end of the local iterator, pop it. + inline void MoveToNextNode() { + if (!current_) return; + if (parent_iterators_.empty()) { + current_ = nullptr; + return; + } + std::pair& next_it = parent_iterators_.top(); + // If we visited all children, the current node is the top of the stack. + if (next_it.second == next_it.first->end()) { + // Set the new node. + current_ = next_it.first; + parent_iterators_.pop(); + return; + } + // We have more children to visit, set the current node to the first child + // and dive to leaf. + current_ = *next_it.second; + // Update the iterator for the next child (avoid unneeded pop). + ++next_it.second; + WalkToLeaf(); + } + + // Moves the iterator to the next node in the tree. + // If we are at the end, do nothing, otherwise + // if our current node has children, use the children iterator and push the + // current node into the stack. + // If we reach the end of the local iterator, pop it. + inline void WalkToLeaf() { + while (current_->begin() != current_->end()) { + NodeIterator next = ++current_->begin(); + parent_iterators_.emplace(make_pair(current_, next)); + // Set the first child as the new node. + current_ = *current_->begin(); + } + } + + // The current node of the tree. + NodePtr current_; + // State of the tree walk: each pair contains the parent node and the iterator + // of the next children to visit. + // When all the children has been visited, we pop the first entry and the + // parent node become the current node. + std::stack> parent_iterators_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_TREE_ITERATOR_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/trim_capabilities_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/trim_capabilities_pass.cpp new file mode 100644 index 000000000000..24f9e4670e7c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/trim_capabilities_pass.cpp @@ -0,0 +1,649 @@ +// Copyright (c) 2023 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/trim_capabilities_pass.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/enum_set.h" +#include "source/enum_string_mapping.h" +#include "source/opt/ir_context.h" +#include "source/opt/reflect.h" +#include "source/spirv_target_env.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { + +namespace { +constexpr uint32_t kOpTypeFloatSizeIndex = 0; +constexpr uint32_t kOpTypePointerStorageClassIndex = 0; +constexpr uint32_t kTypeArrayTypeIndex = 0; +constexpr uint32_t kOpTypeScalarBitWidthIndex = 0; +constexpr uint32_t kTypePointerTypeIdInIndex = 1; +constexpr uint32_t kOpTypeIntSizeIndex = 0; +constexpr uint32_t kOpTypeImageDimIndex = 1; +constexpr uint32_t kOpTypeImageArrayedIndex = kOpTypeImageDimIndex + 2; +constexpr uint32_t kOpTypeImageMSIndex = kOpTypeImageArrayedIndex + 1; +constexpr uint32_t kOpTypeImageSampledIndex = kOpTypeImageMSIndex + 1; +constexpr uint32_t kOpTypeImageFormatIndex = kOpTypeImageSampledIndex + 1; +constexpr uint32_t kOpImageReadImageIndex = 0; +constexpr uint32_t kOpImageSparseReadImageIndex = 0; + +// DFS visit of the type defined by `instruction`. +// If `condition` is true, children of the current node are visited. +// If `condition` is false, the children of the current node are ignored. +template +static void DFSWhile(const Instruction* instruction, UnaryPredicate condition) { + std::stack instructions_to_visit; + instructions_to_visit.push(instruction->result_id()); + const auto* def_use_mgr = instruction->context()->get_def_use_mgr(); + + while (!instructions_to_visit.empty()) { + const Instruction* item = def_use_mgr->GetDef(instructions_to_visit.top()); + instructions_to_visit.pop(); + + if (!condition(item)) { + continue; + } + + if (item->opcode() == spv::Op::OpTypePointer) { + instructions_to_visit.push( + item->GetSingleWordInOperand(kTypePointerTypeIdInIndex)); + continue; + } + + if (item->opcode() == spv::Op::OpTypeMatrix || + item->opcode() == spv::Op::OpTypeVector || + item->opcode() == spv::Op::OpTypeArray || + item->opcode() == spv::Op::OpTypeRuntimeArray) { + instructions_to_visit.push( + item->GetSingleWordInOperand(kTypeArrayTypeIndex)); + continue; + } + + if (item->opcode() == spv::Op::OpTypeStruct) { + item->ForEachInOperand([&instructions_to_visit](const uint32_t* op_id) { + instructions_to_visit.push(*op_id); + }); + continue; + } + } +} + +// Walks the type defined by `instruction` (OpType* only). +// Returns `true` if any call to `predicate` with the type/subtype returns true. +template +static bool AnyTypeOf(const Instruction* instruction, + UnaryPredicate predicate) { + assert(IsTypeInst(instruction->opcode()) && + "AnyTypeOf called with a non-type instruction."); + + bool found_one = false; + DFSWhile(instruction, [&found_one, predicate](const Instruction* node) { + if (found_one || predicate(node)) { + found_one = true; + return false; + } + + return true; + }); + return found_one; +} + +static bool is16bitType(const Instruction* instruction) { + if (instruction->opcode() != spv::Op::OpTypeInt && + instruction->opcode() != spv::Op::OpTypeFloat) { + return false; + } + + return instruction->GetSingleWordInOperand(kOpTypeScalarBitWidthIndex) == 16; +} + +static bool Has16BitCapability(const FeatureManager* feature_manager) { + const CapabilitySet& capabilities = feature_manager->GetCapabilities(); + return capabilities.contains(spv::Capability::Float16) || + capabilities.contains(spv::Capability::Int16); +} + +} // namespace + +// ============== Begin opcode handler implementations. ======================= +// +// Adding support for a new capability should only require adding a new handler, +// and updating the +// kSupportedCapabilities/kUntouchableCapabilities/kFordiddenCapabilities lists. +// +// Handler names follow the following convention: +// Handler__() + +static std::optional Handler_OpTypeFloat_Float16( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypeFloat && + "This handler only support OpTypeFloat opcodes."); + + const uint32_t size = + instruction->GetSingleWordInOperand(kOpTypeFloatSizeIndex); + return size == 16 ? std::optional(spv::Capability::Float16) : std::nullopt; +} + +static std::optional Handler_OpTypeFloat_Float64( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypeFloat && + "This handler only support OpTypeFloat opcodes."); + + const uint32_t size = + instruction->GetSingleWordInOperand(kOpTypeFloatSizeIndex); + return size == 64 ? std::optional(spv::Capability::Float64) : std::nullopt; +} + +static std::optional +Handler_OpTypePointer_StorageInputOutput16(const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypePointer && + "This handler only support OpTypePointer opcodes."); + + // This capability is only required if the variable has an Input/Output + // storage class. + spv::StorageClass storage_class = spv::StorageClass( + instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex)); + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + return std::nullopt; + } + + if (!Has16BitCapability(instruction->context()->get_feature_mgr())) { + return std::nullopt; + } + + return AnyTypeOf(instruction, is16bitType) + ? std::optional(spv::Capability::StorageInputOutput16) + : std::nullopt; +} + +static std::optional +Handler_OpTypePointer_StoragePushConstant16(const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypePointer && + "This handler only support OpTypePointer opcodes."); + + // This capability is only required if the variable has a PushConstant storage + // class. + spv::StorageClass storage_class = spv::StorageClass( + instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex)); + if (storage_class != spv::StorageClass::PushConstant) { + return std::nullopt; + } + + if (!Has16BitCapability(instruction->context()->get_feature_mgr())) { + return std::nullopt; + } + + return AnyTypeOf(instruction, is16bitType) + ? std::optional(spv::Capability::StoragePushConstant16) + : std::nullopt; +} + +static std::optional +Handler_OpTypePointer_StorageUniformBufferBlock16( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypePointer && + "This handler only support OpTypePointer opcodes."); + + // This capability is only required if the variable has a Uniform storage + // class. + spv::StorageClass storage_class = spv::StorageClass( + instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex)); + if (storage_class != spv::StorageClass::Uniform) { + return std::nullopt; + } + + if (!Has16BitCapability(instruction->context()->get_feature_mgr())) { + return std::nullopt; + } + + const auto* decoration_mgr = instruction->context()->get_decoration_mgr(); + const bool matchesCondition = + AnyTypeOf(instruction, [decoration_mgr](const Instruction* item) { + if (!decoration_mgr->HasDecoration(item->result_id(), + spv::Decoration::BufferBlock)) { + return false; + } + + return AnyTypeOf(item, is16bitType); + }); + + return matchesCondition + ? std::optional(spv::Capability::StorageUniformBufferBlock16) + : std::nullopt; +} + +static std::optional Handler_OpTypePointer_StorageUniform16( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypePointer && + "This handler only support OpTypePointer opcodes."); + + // This capability is only required if the variable has a Uniform storage + // class. + spv::StorageClass storage_class = spv::StorageClass( + instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex)); + if (storage_class != spv::StorageClass::Uniform) { + return std::nullopt; + } + + const auto* feature_manager = instruction->context()->get_feature_mgr(); + if (!Has16BitCapability(feature_manager)) { + return std::nullopt; + } + + const bool hasBufferBlockCapability = + feature_manager->GetCapabilities().contains( + spv::Capability::StorageUniformBufferBlock16); + const auto* decoration_mgr = instruction->context()->get_decoration_mgr(); + bool found16bitType = false; + + DFSWhile(instruction, [decoration_mgr, hasBufferBlockCapability, + &found16bitType](const Instruction* item) { + if (found16bitType) { + return false; + } + + if (hasBufferBlockCapability && + decoration_mgr->HasDecoration(item->result_id(), + spv::Decoration::BufferBlock)) { + return false; + } + + if (is16bitType(item)) { + found16bitType = true; + return false; + } + + return true; + }); + + return found16bitType ? std::optional(spv::Capability::StorageUniform16) + : std::nullopt; +} + +static std::optional Handler_OpTypeInt_Int16( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypeInt && + "This handler only support OpTypeInt opcodes."); + + const uint32_t size = + instruction->GetSingleWordInOperand(kOpTypeIntSizeIndex); + return size == 16 ? std::optional(spv::Capability::Int16) : std::nullopt; +} + +static std::optional Handler_OpTypeInt_Int64( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypeInt && + "This handler only support OpTypeInt opcodes."); + + const uint32_t size = + instruction->GetSingleWordInOperand(kOpTypeIntSizeIndex); + return size == 64 ? std::optional(spv::Capability::Int64) : std::nullopt; +} + +static std::optional Handler_OpTypeImage_ImageMSArray( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpTypeImage && + "This handler only support OpTypeImage opcodes."); + + const uint32_t arrayed = + instruction->GetSingleWordInOperand(kOpTypeImageArrayedIndex); + const uint32_t ms = instruction->GetSingleWordInOperand(kOpTypeImageMSIndex); + const uint32_t sampled = + instruction->GetSingleWordInOperand(kOpTypeImageSampledIndex); + + return arrayed == 1 && sampled == 2 && ms == 1 + ? std::optional(spv::Capability::ImageMSArray) + : std::nullopt; +} + +static std::optional +Handler_OpImageRead_StorageImageReadWithoutFormat( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpImageRead && + "This handler only support OpImageRead opcodes."); + const auto* def_use_mgr = instruction->context()->get_def_use_mgr(); + + const uint32_t image_index = + instruction->GetSingleWordInOperand(kOpImageReadImageIndex); + const uint32_t type_index = def_use_mgr->GetDef(image_index)->type_id(); + const Instruction* type = def_use_mgr->GetDef(type_index); + const uint32_t dim = type->GetSingleWordInOperand(kOpTypeImageDimIndex); + const uint32_t format = type->GetSingleWordInOperand(kOpTypeImageFormatIndex); + + const bool is_unknown = spv::ImageFormat(format) == spv::ImageFormat::Unknown; + const bool requires_capability_for_unknown = + spv::Dim(dim) != spv::Dim::SubpassData; + return is_unknown && requires_capability_for_unknown + ? std::optional(spv::Capability::StorageImageReadWithoutFormat) + : std::nullopt; +} + +static std::optional +Handler_OpImageSparseRead_StorageImageReadWithoutFormat( + const Instruction* instruction) { + assert(instruction->opcode() == spv::Op::OpImageSparseRead && + "This handler only support OpImageSparseRead opcodes."); + const auto* def_use_mgr = instruction->context()->get_def_use_mgr(); + + const uint32_t image_index = + instruction->GetSingleWordInOperand(kOpImageSparseReadImageIndex); + const uint32_t type_index = def_use_mgr->GetDef(image_index)->type_id(); + const Instruction* type = def_use_mgr->GetDef(type_index); + const uint32_t format = type->GetSingleWordInOperand(kOpTypeImageFormatIndex); + + return spv::ImageFormat(format) == spv::ImageFormat::Unknown + ? std::optional(spv::Capability::StorageImageReadWithoutFormat) + : std::nullopt; +} + +// Opcode of interest to determine capabilities requirements. +constexpr std::array, 12> kOpcodeHandlers{{ + // clang-format off + {spv::Op::OpImageRead, Handler_OpImageRead_StorageImageReadWithoutFormat}, + {spv::Op::OpImageSparseRead, Handler_OpImageSparseRead_StorageImageReadWithoutFormat}, + {spv::Op::OpTypeFloat, Handler_OpTypeFloat_Float16 }, + {spv::Op::OpTypeFloat, Handler_OpTypeFloat_Float64 }, + {spv::Op::OpTypeImage, Handler_OpTypeImage_ImageMSArray}, + {spv::Op::OpTypeInt, Handler_OpTypeInt_Int16 }, + {spv::Op::OpTypeInt, Handler_OpTypeInt_Int64 }, + {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageInputOutput16}, + {spv::Op::OpTypePointer, Handler_OpTypePointer_StoragePushConstant16}, + {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniform16}, + {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniform16}, + {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniformBufferBlock16}, + // clang-format on +}}; + +// ============== End opcode handler implementations. ======================= + +namespace { +ExtensionSet getExtensionsRelatedTo(const CapabilitySet& capabilities, + const AssemblyGrammar& grammar) { + ExtensionSet output; + const spv_operand_desc_t* desc = nullptr; + for (auto capability : capabilities) { + if (SPV_SUCCESS != grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, + static_cast(capability), + &desc)) { + continue; + } + + for (uint32_t i = 0; i < desc->numExtensions; ++i) { + output.insert(desc->extensions[i]); + } + } + + return output; +} +} // namespace + +TrimCapabilitiesPass::TrimCapabilitiesPass() + : supportedCapabilities_( + TrimCapabilitiesPass::kSupportedCapabilities.cbegin(), + TrimCapabilitiesPass::kSupportedCapabilities.cend()), + forbiddenCapabilities_( + TrimCapabilitiesPass::kForbiddenCapabilities.cbegin(), + TrimCapabilitiesPass::kForbiddenCapabilities.cend()), + untouchableCapabilities_( + TrimCapabilitiesPass::kUntouchableCapabilities.cbegin(), + TrimCapabilitiesPass::kUntouchableCapabilities.cend()), + opcodeHandlers_(kOpcodeHandlers.cbegin(), kOpcodeHandlers.cend()) {} + +void TrimCapabilitiesPass::addInstructionRequirementsForOpcode( + spv::Op opcode, CapabilitySet* capabilities, + ExtensionSet* extensions) const { + // Ignoring OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT + // because they have three possible capabilities, only one of which is needed + if (opcode == spv::Op::OpBeginInvocationInterlockEXT || + opcode == spv::Op::OpEndInvocationInterlockEXT) { + return; + } + + const spv_opcode_desc_t* desc = {}; + auto result = context()->grammar().lookupOpcode(opcode, &desc); + if (result != SPV_SUCCESS) { + return; + } + + addSupportedCapabilitiesToSet(desc, capabilities); + addSupportedExtensionsToSet(desc, extensions); +} + +void TrimCapabilitiesPass::addInstructionRequirementsForOperand( + const Operand& operand, CapabilitySet* capabilities, + ExtensionSet* extensions) const { + // No supported capability relies on a 2+-word operand. + if (operand.words.size() != 1) { + return; + } + + // No supported capability relies on a literal string operand or an ID. + if (operand.type == SPV_OPERAND_TYPE_LITERAL_STRING || + operand.type == SPV_OPERAND_TYPE_ID || + operand.type == SPV_OPERAND_TYPE_RESULT_ID) { + return; + } + + // If the Vulkan memory model is declared and any instruction uses Device + // scope, the VulkanMemoryModelDeviceScope capability must be declared. This + // rule cannot be covered by the grammar, so must be checked explicitly. + if (operand.type == SPV_OPERAND_TYPE_SCOPE_ID) { + const Instruction* memory_model = context()->GetMemoryModel(); + if (memory_model && memory_model->GetSingleWordInOperand(1u) == + uint32_t(spv::MemoryModel::Vulkan)) { + capabilities->insert(spv::Capability::VulkanMemoryModelDeviceScope); + } + } + + // case 1: Operand is a single value, can directly lookup. + if (!spvOperandIsConcreteMask(operand.type)) { + const spv_operand_desc_t* desc = {}; + auto result = context()->grammar().lookupOperand(operand.type, + operand.words[0], &desc); + if (result != SPV_SUCCESS) { + return; + } + addSupportedCapabilitiesToSet(desc, capabilities); + addSupportedExtensionsToSet(desc, extensions); + return; + } + + // case 2: operand can be a bitmask, we need to decompose the lookup. + for (uint32_t i = 0; i < 32; i++) { + const uint32_t mask = (1 << i) & operand.words[0]; + if (!mask) { + continue; + } + + const spv_operand_desc_t* desc = {}; + auto result = context()->grammar().lookupOperand(operand.type, mask, &desc); + if (result != SPV_SUCCESS) { + continue; + } + + addSupportedCapabilitiesToSet(desc, capabilities); + addSupportedExtensionsToSet(desc, extensions); + } +} + +void TrimCapabilitiesPass::addInstructionRequirements( + Instruction* instruction, CapabilitySet* capabilities, + ExtensionSet* extensions) const { + // Ignoring OpCapability and OpExtension instructions. + if (instruction->opcode() == spv::Op::OpCapability || + instruction->opcode() == spv::Op::OpExtension) { + return; + } + + addInstructionRequirementsForOpcode(instruction->opcode(), capabilities, + extensions); + + // Second case: one of the opcode operand is gated by a capability. + const uint32_t operandCount = instruction->NumOperands(); + for (uint32_t i = 0; i < operandCount; i++) { + addInstructionRequirementsForOperand(instruction->GetOperand(i), + capabilities, extensions); + } + + // Last case: some complex logic needs to be run to determine capabilities. + auto[begin, end] = opcodeHandlers_.equal_range(instruction->opcode()); + for (auto it = begin; it != end; it++) { + const OpcodeHandler handler = it->second; + auto result = handler(instruction); + if (!result.has_value()) { + continue; + } + + capabilities->insert(*result); + } +} + +void TrimCapabilitiesPass::AddExtensionsForOperand( + const spv_operand_type_t type, const uint32_t value, + ExtensionSet* extensions) const { + const spv_operand_desc_t* desc = nullptr; + spv_result_t result = context()->grammar().lookupOperand(type, value, &desc); + if (result != SPV_SUCCESS) { + return; + } + addSupportedExtensionsToSet(desc, extensions); +} + +std::pair +TrimCapabilitiesPass::DetermineRequiredCapabilitiesAndExtensions() const { + CapabilitySet required_capabilities; + ExtensionSet required_extensions; + + get_module()->ForEachInst([&](Instruction* instruction) { + addInstructionRequirements(instruction, &required_capabilities, + &required_extensions); + }); + + for (auto capability : required_capabilities) { + AddExtensionsForOperand(SPV_OPERAND_TYPE_CAPABILITY, + static_cast(capability), + &required_extensions); + } + +#if !defined(NDEBUG) + // Debug only. We check the outputted required capabilities against the + // supported capabilities list. The supported capabilities list is useful for + // API users to quickly determine if they can use the pass or not. But this + // list has to remain up-to-date with the pass code. If we can detect a + // capability as required, but it's not listed, it means the list is + // out-of-sync. This method is not ideal, but should cover most cases. + { + for (auto capability : required_capabilities) { + assert(supportedCapabilities_.contains(capability) && + "Module is using a capability that is not listed as supported."); + } + } +#endif + + return std::make_pair(std::move(required_capabilities), + std::move(required_extensions)); +} + +Pass::Status TrimCapabilitiesPass::TrimUnrequiredCapabilities( + const CapabilitySet& required_capabilities) const { + const FeatureManager* feature_manager = context()->get_feature_mgr(); + CapabilitySet capabilities_to_trim; + for (auto capability : feature_manager->GetCapabilities()) { + // Some capabilities cannot be safely removed. Leaving them untouched. + if (untouchableCapabilities_.contains(capability)) { + continue; + } + + // If the capability is unsupported, don't trim it. + if (!supportedCapabilities_.contains(capability)) { + continue; + } + + if (required_capabilities.contains(capability)) { + continue; + } + + capabilities_to_trim.insert(capability); + } + + for (auto capability : capabilities_to_trim) { + context()->RemoveCapability(capability); + } + + return capabilities_to_trim.size() == 0 ? Pass::Status::SuccessWithoutChange + : Pass::Status::SuccessWithChange; +} + +Pass::Status TrimCapabilitiesPass::TrimUnrequiredExtensions( + const ExtensionSet& required_extensions) const { + const auto supported_extensions = + getExtensionsRelatedTo(supportedCapabilities_, context()->grammar()); + + bool modified_module = false; + for (auto extension : supported_extensions) { + if (required_extensions.contains(extension)) { + continue; + } + + if (context()->RemoveExtension(extension)) { + modified_module = true; + } + } + + return modified_module ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +bool TrimCapabilitiesPass::HasForbiddenCapabilities() const { + // EnumSet.HasAnyOf returns `true` if the given set is empty. + if (forbiddenCapabilities_.size() == 0) { + return false; + } + + const auto& capabilities = context()->get_feature_mgr()->GetCapabilities(); + return capabilities.HasAnyOf(forbiddenCapabilities_); +} + +Pass::Status TrimCapabilitiesPass::Process() { + if (HasForbiddenCapabilities()) { + return Status::SuccessWithoutChange; + } + + auto[required_capabilities, required_extensions] = + DetermineRequiredCapabilitiesAndExtensions(); + + Pass::Status capStatus = TrimUnrequiredCapabilities(required_capabilities); + Pass::Status extStatus = TrimUnrequiredExtensions(required_extensions); + + return capStatus == Pass::Status::SuccessWithChange || + extStatus == Pass::Status::SuccessWithChange + ? Pass::Status::SuccessWithChange + : Pass::Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/trim_capabilities_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/trim_capabilities_pass.h new file mode 100644 index 000000000000..3a8460f3b235 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/trim_capabilities_pass.h @@ -0,0 +1,204 @@ +// Copyright (c) 2023 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_TRIM_CAPABILITIES_PASS_H_ +#define SOURCE_OPT_TRIM_CAPABILITIES_PASS_H_ + +#include +#include +#include +#include +#include +#include + +#include "source/enum_set.h" +#include "source/extensions.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" +#include "source/spirv_target_env.h" + +namespace spvtools { +namespace opt { + +// This is required for NDK build. The unordered_set/unordered_map +// implementation don't work with class enums. +struct ClassEnumHash { + std::size_t operator()(spv::Capability value) const { + using StoringType = typename std::underlying_type_t; + return std::hash{}(static_cast(value)); + } + + std::size_t operator()(spv::Op value) const { + using StoringType = typename std::underlying_type_t; + return std::hash{}(static_cast(value)); + } +}; + +// An opcode handler is a function which, given an instruction, returns either +// the required capability, or nothing. +// Each handler checks one case for a capability requirement. +// +// Example: +// - `OpTypeImage` can have operand `A` operand which requires capability 1 +// - `OpTypeImage` can also have operand `B` which requires capability 2. +// -> We have 2 handlers: `Handler_OpTypeImage_1` and +// `Handler_OpTypeImage_2`. +using OpcodeHandler = + std::optional (*)(const Instruction* instruction); + +// This pass tried to remove superfluous capabilities declared in the module. +// - If all the capabilities listed by an extension are removed, the extension +// is also trimmed. +// - If the module countains any capability listed in `kForbiddenCapabilities`, +// the module is left untouched. +// - No capabilities listed in `kUntouchableCapabilities` are trimmed, even when +// not used. +// - Only capabilitied listed in `kSupportedCapabilities` are supported. +// - If the module contains unsupported capabilities, results might be +// incorrect. +class TrimCapabilitiesPass : public Pass { + private: + // All the capabilities supported by this optimization pass. If your module + // contains unsupported instruction, the pass could yield bad results. + static constexpr std::array kSupportedCapabilities{ + // clang-format off + spv::Capability::ComputeDerivativeGroupLinearNV, + spv::Capability::ComputeDerivativeGroupQuadsNV, + spv::Capability::Float16, + spv::Capability::Float64, + spv::Capability::FragmentShaderPixelInterlockEXT, + spv::Capability::FragmentShaderSampleInterlockEXT, + spv::Capability::FragmentShaderShadingRateInterlockEXT, + spv::Capability::Groups, + spv::Capability::ImageMSArray, + spv::Capability::Int16, + spv::Capability::Int64, + spv::Capability::Linkage, + spv::Capability::MinLod, + spv::Capability::PhysicalStorageBufferAddresses, + spv::Capability::RayQueryKHR, + spv::Capability::RayTracingKHR, + spv::Capability::RayTraversalPrimitiveCullingKHR, + spv::Capability::Shader, + spv::Capability::ShaderClockKHR, + spv::Capability::StorageImageReadWithoutFormat, + spv::Capability::StorageInputOutput16, + spv::Capability::StoragePushConstant16, + spv::Capability::StorageUniform16, + spv::Capability::StorageUniformBufferBlock16, + spv::Capability::VulkanMemoryModelDeviceScope + // clang-format on + }; + + // Those capabilities disable all transformation of the module. + static constexpr std::array kForbiddenCapabilities{ + spv::Capability::Linkage, + }; + + // Those capabilities are never removed from a module because we cannot + // guess from the SPIR-V only if they are required or not. + static constexpr std::array kUntouchableCapabilities{ + spv::Capability::Shader, + }; + + public: + TrimCapabilitiesPass(); + TrimCapabilitiesPass(const TrimCapabilitiesPass&) = delete; + TrimCapabilitiesPass(TrimCapabilitiesPass&&) = delete; + + private: + // Inserts every capability listed by `descriptor` this pass supports into + // `output`. Expects a Descriptor like `spv_opcode_desc_t` or + // `spv_operand_desc_t`. + template + inline void addSupportedCapabilitiesToSet(const Descriptor* const descriptor, + CapabilitySet* output) const { + const uint32_t capabilityCount = descriptor->numCapabilities; + for (uint32_t i = 0; i < capabilityCount; ++i) { + const auto capability = descriptor->capabilities[i]; + if (supportedCapabilities_.contains(capability)) { + output->insert(capability); + } + } + } + + // Inserts every extension listed by `descriptor` required by the module into + // `output`. Expects a Descriptor like `spv_opcode_desc_t` or + // `spv_operand_desc_t`. + template + inline void addSupportedExtensionsToSet(const Descriptor* const descriptor, + ExtensionSet* output) const { + if (descriptor->minVersion <= + spvVersionForTargetEnv(context()->GetTargetEnv())) { + return; + } + output->insert(descriptor->extensions, + descriptor->extensions + descriptor->numExtensions); + } + + void addInstructionRequirementsForOpcode(spv::Op opcode, + CapabilitySet* capabilities, + ExtensionSet* extensions) const; + void addInstructionRequirementsForOperand(const Operand& operand, + CapabilitySet* capabilities, + ExtensionSet* extensions) const; + + // Given an `instruction`, determines the capabilities it requires, and output + // them in `capabilities`. The returned capabilities form a subset of + // kSupportedCapabilities. + void addInstructionRequirements(Instruction* instruction, + CapabilitySet* capabilities, + ExtensionSet* extensions) const; + + // Given an operand `type` and `value`, adds the extensions it would require + // to `extensions`. + void AddExtensionsForOperand(const spv_operand_type_t type, + const uint32_t value, + ExtensionSet* extensions) const; + + // Returns the list of required capabilities and extensions for the module. + // The returned capabilities form a subset of kSupportedCapabilities. + std::pair + DetermineRequiredCapabilitiesAndExtensions() const; + + // Trims capabilities not listed in `required_capabilities` if possible. + // Returns whether or not the module was modified. + Pass::Status TrimUnrequiredCapabilities( + const CapabilitySet& required_capabilities) const; + + // Trims extensions not listed in `required_extensions` if supported by this + // pass. An extensions is considered supported as soon as one capability this + // pass support requires it. + Pass::Status TrimUnrequiredExtensions( + const ExtensionSet& required_extensions) const; + + // Returns if the analyzed module contains any forbidden capability. + bool HasForbiddenCapabilities() const; + + public: + const char* name() const override { return "trim-capabilities"; } + Status Process() override; + + private: + const CapabilitySet supportedCapabilities_; + const CapabilitySet forbiddenCapabilities_; + const CapabilitySet untouchableCapabilities_; + const std::unordered_multimap + opcodeHandlers_; +}; + +} // namespace opt +} // namespace spvtools +#endif // SOURCE_OPT_TRIM_CAPABILITIES_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/type_manager.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/type_manager.cpp new file mode 100644 index 000000000000..ae320772df1e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/type_manager.cpp @@ -0,0 +1,1086 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/type_manager.h" + +#include +#include +#include +#include + +#include "source/opt/ir_context.h" +#include "source/opt/log.h" +#include "source/opt/reflect.h" +#include "source/util/make_unique.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { +namespace analysis { +namespace { +constexpr int kSpvTypePointerStorageClass = 1; +constexpr int kSpvTypePointerTypeIdInIdx = 2; +} // namespace + +TypeManager::TypeManager(const MessageConsumer& consumer, IRContext* c) + : consumer_(consumer), context_(c) { + AnalyzeTypes(*c->module()); +} + +Type* TypeManager::GetType(uint32_t id) const { + auto iter = id_to_type_.find(id); + if (iter != id_to_type_.end()) return (*iter).second; + iter = id_to_incomplete_type_.find(id); + if (iter != id_to_incomplete_type_.end()) return (*iter).second; + return nullptr; +} + +std::pair> TypeManager::GetTypeAndPointerType( + uint32_t id, spv::StorageClass sc) const { + Type* type = GetType(id); + if (type) { + return std::make_pair(type, MakeUnique(type, sc)); + } else { + return std::make_pair(type, std::unique_ptr()); + } +} + +uint32_t TypeManager::GetId(const Type* type) const { + auto iter = type_to_id_.find(type); + if (iter != type_to_id_.end()) { + return (*iter).second; + } + return 0; +} + +void TypeManager::AnalyzeTypes(const Module& module) { + // First pass through the constants, as some will be needed when traversing + // the types in the next pass. + for (const auto* inst : module.GetConstants()) { + id_to_constant_inst_[inst->result_id()] = inst; + } + + // Then pass through the types. Any types that reference a forward pointer + // (directly or indirectly) are incomplete, and are added to incomplete types. + for (const auto* inst : module.GetTypes()) { + RecordIfTypeDefinition(*inst); + } + + if (incomplete_types_.empty()) { + return; + } + + // Get the real pointer definition for all of the forward pointers. + for (auto& type : incomplete_types_) { + if (type.type()->kind() == Type::kForwardPointer) { + auto* t = GetType(type.id()); + assert(t); + auto* p = t->AsPointer(); + assert(p); + type.type()->AsForwardPointer()->SetTargetPointer(p); + } + } + + // Replaces the references to the forward pointers in the incomplete types. + for (auto& type : incomplete_types_) { + ReplaceForwardPointers(type.type()); + } + + // Delete the forward pointers now that they are not referenced anymore. + for (auto& type : incomplete_types_) { + if (type.type()->kind() == Type::kForwardPointer) { + type.ResetType(nullptr); + } + } + + // Compare the complete types looking for types that are the same. If there + // are two types that are the same, then replace one with the other. + // Continue until we reach a fixed point. + bool restart = true; + while (restart) { + restart = false; + for (auto it1 = incomplete_types_.begin(); it1 != incomplete_types_.end(); + ++it1) { + uint32_t id1 = it1->id(); + Type* type1 = it1->type(); + if (!type1) { + continue; + } + + for (auto it2 = it1 + 1; it2 != incomplete_types_.end(); ++it2) { + uint32_t id2 = it2->id(); + (void)(id2 + id1); + Type* type2 = it2->type(); + if (!type2) { + continue; + } + + if (type1->IsSame(type2)) { + ReplaceType(type1, type2); + it2->ResetType(nullptr); + id_to_incomplete_type_[it2->id()] = type1; + restart = true; + } + } + } + } + + // Add the remaining incomplete types to the type pool. + for (auto& type : incomplete_types_) { + if (type.type() && !type.type()->AsForwardPointer()) { + std::vector decorations = + context()->get_decoration_mgr()->GetDecorationsFor(type.id(), true); + for (auto dec : decorations) { + AttachDecoration(*dec, type.type()); + } + auto pair = type_pool_.insert(type.ReleaseType()); + id_to_type_[type.id()] = pair.first->get(); + type_to_id_[pair.first->get()] = type.id(); + id_to_incomplete_type_.erase(type.id()); + } + } + + // Add a mapping for any ids that whose original type was replaced by an + // equivalent type. + for (auto& type : id_to_incomplete_type_) { + id_to_type_[type.first] = type.second; + } + +#ifndef NDEBUG + // Check if the type pool contains two types that are the same. This + // is an indication that the hashing and comparison are wrong. It + // will cause a problem if the type pool gets resized and everything + // is rehashed. + for (auto& i : type_pool_) { + for (auto& j : type_pool_) { + Type* ti = i.get(); + Type* tj = j.get(); + assert((ti == tj || !ti->IsSame(tj)) && + "Type pool contains two types that are the same."); + } + } +#endif +} + +void TypeManager::RemoveId(uint32_t id) { + auto iter = id_to_type_.find(id); + if (iter == id_to_type_.end()) return; + + auto& type = iter->second; + if (!type->IsUniqueType()) { + auto tIter = type_to_id_.find(type); + if (tIter != type_to_id_.end() && tIter->second == id) { + // |type| currently maps to |id|. + // Search for an equivalent type to re-map. + bool found = false; + for (auto& pair : id_to_type_) { + if (pair.first != id && *pair.second == *type) { + // Equivalent ambiguous type, re-map type. + type_to_id_.erase(type); + type_to_id_[pair.second] = pair.first; + found = true; + break; + } + } + // No equivalent ambiguous type, remove mapping. + if (!found) type_to_id_.erase(tIter); + } + } else { + // Unique type, so just erase the entry. + type_to_id_.erase(type); + } + + // Erase the entry for |id|. + id_to_type_.erase(iter); +} + +uint32_t TypeManager::GetTypeInstruction(const Type* type) { + uint32_t id = GetId(type); + if (id != 0) return id; + + std::unique_ptr typeInst; + // TODO(1841): Handle id overflow. + id = context()->TakeNextId(); + if (id == 0) { + return 0; + } + + RegisterType(id, *type); + switch (type->kind()) { +#define DefineParameterlessCase(kind) \ + case Type::k##kind: \ + typeInst = MakeUnique(context(), spv::Op::OpType##kind, 0, \ + id, std::initializer_list{}); \ + break + DefineParameterlessCase(Void); + DefineParameterlessCase(Bool); + DefineParameterlessCase(Sampler); + DefineParameterlessCase(Event); + DefineParameterlessCase(DeviceEvent); + DefineParameterlessCase(ReserveId); + DefineParameterlessCase(Queue); + DefineParameterlessCase(PipeStorage); + DefineParameterlessCase(NamedBarrier); + DefineParameterlessCase(AccelerationStructureNV); + DefineParameterlessCase(RayQueryKHR); + DefineParameterlessCase(HitObjectNV); +#undef DefineParameterlessCase + case Type::kInteger: + typeInst = MakeUnique( + context(), spv::Op::OpTypeInt, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {type->AsInteger()->width()}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, + {(type->AsInteger()->IsSigned() ? 1u : 0u)}}}); + break; + case Type::kFloat: + typeInst = MakeUnique( + context(), spv::Op::OpTypeFloat, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {type->AsFloat()->width()}}}); + break; + case Type::kVector: { + uint32_t subtype = GetTypeInstruction(type->AsVector()->element_type()); + if (subtype == 0) { + return 0; + } + typeInst = + MakeUnique(context(), spv::Op::OpTypeVector, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {subtype}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, + {type->AsVector()->element_count()}}}); + break; + } + case Type::kMatrix: { + uint32_t subtype = GetTypeInstruction(type->AsMatrix()->element_type()); + if (subtype == 0) { + return 0; + } + typeInst = + MakeUnique(context(), spv::Op::OpTypeMatrix, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {subtype}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, + {type->AsMatrix()->element_count()}}}); + break; + } + case Type::kImage: { + const Image* image = type->AsImage(); + uint32_t subtype = GetTypeInstruction(image->sampled_type()); + if (subtype == 0) { + return 0; + } + typeInst = MakeUnique( + context(), spv::Op::OpTypeImage, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {subtype}}, + {SPV_OPERAND_TYPE_DIMENSIONALITY, + {static_cast(image->dim())}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {image->depth()}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, + {(image->is_arrayed() ? 1u : 0u)}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, + {(image->is_multisampled() ? 1u : 0u)}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {image->sampled()}}, + {SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, + {static_cast(image->format())}}, + {SPV_OPERAND_TYPE_ACCESS_QUALIFIER, + {static_cast(image->access_qualifier())}}}); + break; + } + case Type::kSampledImage: { + uint32_t subtype = + GetTypeInstruction(type->AsSampledImage()->image_type()); + if (subtype == 0) { + return 0; + } + typeInst = MakeUnique( + context(), spv::Op::OpTypeSampledImage, 0, id, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {subtype}}}); + break; + } + case Type::kArray: { + uint32_t subtype = GetTypeInstruction(type->AsArray()->element_type()); + if (subtype == 0) { + return 0; + } + typeInst = MakeUnique( + context(), spv::Op::OpTypeArray, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {subtype}}, + {SPV_OPERAND_TYPE_ID, {type->AsArray()->LengthId()}}}); + break; + } + case Type::kRuntimeArray: { + uint32_t subtype = + GetTypeInstruction(type->AsRuntimeArray()->element_type()); + if (subtype == 0) { + return 0; + } + typeInst = MakeUnique( + context(), spv::Op::OpTypeRuntimeArray, 0, id, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {subtype}}}); + break; + } + case Type::kStruct: { + std::vector ops; + const Struct* structTy = type->AsStruct(); + for (auto ty : structTy->element_types()) { + uint32_t member_type_id = GetTypeInstruction(ty); + if (member_type_id == 0) { + return 0; + } + ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {member_type_id})); + } + typeInst = + MakeUnique(context(), spv::Op::OpTypeStruct, 0, id, ops); + break; + } + case Type::kOpaque: { + const Opaque* opaque = type->AsOpaque(); + // Convert to null-terminated packed UTF-8 string. + std::vector words = spvtools::utils::MakeVector(opaque->name()); + typeInst = MakeUnique( + context(), spv::Op::OpTypeOpaque, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_LITERAL_STRING, words}}); + break; + } + case Type::kPointer: { + const Pointer* pointer = type->AsPointer(); + uint32_t subtype = GetTypeInstruction(pointer->pointee_type()); + if (subtype == 0) { + return 0; + } + typeInst = MakeUnique( + context(), spv::Op::OpTypePointer, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, + {static_cast(pointer->storage_class())}}, + {SPV_OPERAND_TYPE_ID, {subtype}}}); + break; + } + case Type::kFunction: { + std::vector ops; + const Function* function = type->AsFunction(); + uint32_t return_type_id = GetTypeInstruction(function->return_type()); + if (return_type_id == 0) { + return 0; + } + ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {return_type_id})); + for (auto ty : function->param_types()) { + uint32_t paramater_type_id = GetTypeInstruction(ty); + if (paramater_type_id == 0) { + return 0; + } + ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {paramater_type_id})); + } + typeInst = MakeUnique(context(), spv::Op::OpTypeFunction, 0, + id, ops); + break; + } + case Type::kPipe: + typeInst = MakeUnique( + context(), spv::Op::OpTypePipe, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ACCESS_QUALIFIER, + {static_cast(type->AsPipe()->access_qualifier())}}}); + break; + case Type::kForwardPointer: + typeInst = MakeUnique( + context(), spv::Op::OpTypeForwardPointer, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {type->AsForwardPointer()->target_id()}}, + {SPV_OPERAND_TYPE_STORAGE_CLASS, + {static_cast( + type->AsForwardPointer()->storage_class())}}}); + break; + case Type::kCooperativeMatrixNV: { + auto coop_mat = type->AsCooperativeMatrixNV(); + uint32_t const component_type = + GetTypeInstruction(coop_mat->component_type()); + if (component_type == 0) { + return 0; + } + typeInst = MakeUnique( + context(), spv::Op::OpTypeCooperativeMatrixNV, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {component_type}}, + {SPV_OPERAND_TYPE_SCOPE_ID, {coop_mat->scope_id()}}, + {SPV_OPERAND_TYPE_ID, {coop_mat->rows_id()}}, + {SPV_OPERAND_TYPE_ID, {coop_mat->columns_id()}}}); + break; + } + case Type::kCooperativeMatrixKHR: { + auto coop_mat = type->AsCooperativeMatrixKHR(); + uint32_t const component_type = + GetTypeInstruction(coop_mat->component_type()); + if (component_type == 0) { + return 0; + } + typeInst = MakeUnique( + context(), spv::Op::OpTypeCooperativeMatrixKHR, 0, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {component_type}}, + {SPV_OPERAND_TYPE_SCOPE_ID, {coop_mat->scope_id()}}, + {SPV_OPERAND_TYPE_ID, {coop_mat->rows_id()}}, + {SPV_OPERAND_TYPE_ID, {coop_mat->columns_id()}}, + {SPV_OPERAND_TYPE_ID, {coop_mat->use_id()}}}); + break; + } + default: + assert(false && "Unexpected type"); + break; + } + context()->AddType(std::move(typeInst)); + context()->AnalyzeDefUse(&*--context()->types_values_end()); + AttachDecorations(id, type); + return id; +} + +uint32_t TypeManager::FindPointerToType(uint32_t type_id, + spv::StorageClass storage_class) { + Type* pointeeTy = GetType(type_id); + Pointer pointerTy(pointeeTy, storage_class); + if (pointeeTy->IsUniqueType()) { + // Non-ambiguous type. Get the pointer type through the type manager. + return GetTypeInstruction(&pointerTy); + } + + // Ambiguous type, do a linear search. + Module::inst_iterator type_itr = context()->module()->types_values_begin(); + for (; type_itr != context()->module()->types_values_end(); ++type_itr) { + const Instruction* type_inst = &*type_itr; + if (type_inst->opcode() == spv::Op::OpTypePointer && + type_inst->GetSingleWordOperand(kSpvTypePointerTypeIdInIdx) == + type_id && + spv::StorageClass(type_inst->GetSingleWordOperand( + kSpvTypePointerStorageClass)) == storage_class) + return type_inst->result_id(); + } + + // Must create the pointer type. + // TODO(1841): Handle id overflow. + uint32_t resultId = context()->TakeNextId(); + std::unique_ptr type_inst( + new Instruction(context(), spv::Op::OpTypePointer, 0, resultId, + {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, + {uint32_t(storage_class)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_id}}})); + context()->AddType(std::move(type_inst)); + context()->get_type_mgr()->RegisterType(resultId, pointerTy); + return resultId; +} + +void TypeManager::AttachDecorations(uint32_t id, const Type* type) { + for (auto vec : type->decorations()) { + CreateDecoration(id, vec); + } + if (const Struct* structTy = type->AsStruct()) { + for (auto pair : structTy->element_decorations()) { + uint32_t element = pair.first; + for (auto vec : pair.second) { + CreateDecoration(id, vec, /* is_member */ true, element); + } + } + } +} + +void TypeManager::CreateDecoration(uint32_t target, + const std::vector& decoration, + bool is_member, uint32_t element) { + std::vector ops; + ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {target})); + if (is_member) { + ops.push_back(Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {element})); + } + ops.push_back(Operand(SPV_OPERAND_TYPE_DECORATION, {decoration[0]})); + for (size_t i = 1; i < decoration.size(); ++i) { + ops.push_back(Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration[i]})); + } + context()->AddAnnotationInst(MakeUnique( + context(), (is_member ? spv::Op::OpMemberDecorate : spv::Op::OpDecorate), + 0, 0, ops)); + Instruction* inst = &*--context()->annotation_end(); + context()->get_def_use_mgr()->AnalyzeInstUse(inst); +} + +Type* TypeManager::RebuildType(const Type& type) { + // The comparison and hash on the type pool will avoid inserting the rebuilt + // type if an equivalent type already exists. The rebuilt type will be deleted + // when it goes out of scope at the end of the function in that case. Repeated + // insertions of the same Type will, at most, keep one corresponding object in + // the type pool. + std::unique_ptr rebuilt_ty; + switch (type.kind()) { +#define DefineNoSubtypeCase(kind) \ + case Type::k##kind: \ + rebuilt_ty.reset(type.Clone().release()); \ + return type_pool_.insert(std::move(rebuilt_ty)).first->get() + + DefineNoSubtypeCase(Void); + DefineNoSubtypeCase(Bool); + DefineNoSubtypeCase(Integer); + DefineNoSubtypeCase(Float); + DefineNoSubtypeCase(Sampler); + DefineNoSubtypeCase(Opaque); + DefineNoSubtypeCase(Event); + DefineNoSubtypeCase(DeviceEvent); + DefineNoSubtypeCase(ReserveId); + DefineNoSubtypeCase(Queue); + DefineNoSubtypeCase(Pipe); + DefineNoSubtypeCase(PipeStorage); + DefineNoSubtypeCase(NamedBarrier); + DefineNoSubtypeCase(AccelerationStructureNV); + DefineNoSubtypeCase(RayQueryKHR); + DefineNoSubtypeCase(HitObjectNV); +#undef DefineNoSubtypeCase + case Type::kVector: { + const Vector* vec_ty = type.AsVector(); + const Type* ele_ty = vec_ty->element_type(); + rebuilt_ty = + MakeUnique(RebuildType(*ele_ty), vec_ty->element_count()); + break; + } + case Type::kMatrix: { + const Matrix* mat_ty = type.AsMatrix(); + const Type* ele_ty = mat_ty->element_type(); + rebuilt_ty = + MakeUnique(RebuildType(*ele_ty), mat_ty->element_count()); + break; + } + case Type::kImage: { + const Image* image_ty = type.AsImage(); + const Type* ele_ty = image_ty->sampled_type(); + rebuilt_ty = + MakeUnique(RebuildType(*ele_ty), image_ty->dim(), + image_ty->depth(), image_ty->is_arrayed(), + image_ty->is_multisampled(), image_ty->sampled(), + image_ty->format(), image_ty->access_qualifier()); + break; + } + case Type::kSampledImage: { + const SampledImage* image_ty = type.AsSampledImage(); + const Type* ele_ty = image_ty->image_type(); + rebuilt_ty = MakeUnique(RebuildType(*ele_ty)); + break; + } + case Type::kArray: { + const Array* array_ty = type.AsArray(); + rebuilt_ty = + MakeUnique(array_ty->element_type(), array_ty->length_info()); + break; + } + case Type::kRuntimeArray: { + const RuntimeArray* array_ty = type.AsRuntimeArray(); + const Type* ele_ty = array_ty->element_type(); + rebuilt_ty = MakeUnique(RebuildType(*ele_ty)); + break; + } + case Type::kStruct: { + const Struct* struct_ty = type.AsStruct(); + std::vector subtypes; + subtypes.reserve(struct_ty->element_types().size()); + for (const auto* ele_ty : struct_ty->element_types()) { + subtypes.push_back(RebuildType(*ele_ty)); + } + rebuilt_ty = MakeUnique(subtypes); + Struct* rebuilt_struct = rebuilt_ty->AsStruct(); + for (auto pair : struct_ty->element_decorations()) { + uint32_t index = pair.first; + for (const auto& dec : pair.second) { + // Explicit copy intended. + std::vector copy(dec); + rebuilt_struct->AddMemberDecoration(index, std::move(copy)); + } + } + break; + } + case Type::kPointer: { + const Pointer* pointer_ty = type.AsPointer(); + const Type* ele_ty = pointer_ty->pointee_type(); + rebuilt_ty = MakeUnique(RebuildType(*ele_ty), + pointer_ty->storage_class()); + break; + } + case Type::kFunction: { + const Function* function_ty = type.AsFunction(); + const Type* ret_ty = function_ty->return_type(); + std::vector param_types; + param_types.reserve(function_ty->param_types().size()); + for (const auto* param_ty : function_ty->param_types()) { + param_types.push_back(RebuildType(*param_ty)); + } + rebuilt_ty = MakeUnique(RebuildType(*ret_ty), param_types); + break; + } + case Type::kForwardPointer: { + const ForwardPointer* forward_ptr_ty = type.AsForwardPointer(); + rebuilt_ty = MakeUnique(forward_ptr_ty->target_id(), + forward_ptr_ty->storage_class()); + const Pointer* target_ptr = forward_ptr_ty->target_pointer(); + if (target_ptr) { + rebuilt_ty->AsForwardPointer()->SetTargetPointer( + RebuildType(*target_ptr)->AsPointer()); + } + break; + } + case Type::kCooperativeMatrixNV: { + const CooperativeMatrixNV* cm_type = type.AsCooperativeMatrixNV(); + const Type* component_type = cm_type->component_type(); + rebuilt_ty = MakeUnique( + RebuildType(*component_type), cm_type->scope_id(), cm_type->rows_id(), + cm_type->columns_id()); + break; + } + case Type::kCooperativeMatrixKHR: { + const CooperativeMatrixKHR* cm_type = type.AsCooperativeMatrixKHR(); + const Type* component_type = cm_type->component_type(); + rebuilt_ty = MakeUnique( + RebuildType(*component_type), cm_type->scope_id(), cm_type->rows_id(), + cm_type->columns_id(), cm_type->use_id()); + break; + } + default: + assert(false && "Unhandled type"); + return nullptr; + } + for (const auto& dec : type.decorations()) { + // Explicit copy intended. + std::vector copy(dec); + rebuilt_ty->AddDecoration(std::move(copy)); + } + + return type_pool_.insert(std::move(rebuilt_ty)).first->get(); +} + +void TypeManager::RegisterType(uint32_t id, const Type& type) { + // Rebuild |type| so it and all its constituent types are owned by the type + // pool. + Type* rebuilt = RebuildType(type); + assert(rebuilt->IsSame(&type)); + id_to_type_[id] = rebuilt; + if (GetId(rebuilt) == 0) { + type_to_id_[rebuilt] = id; + } +} + +Type* TypeManager::GetRegisteredType(const Type* type) { + uint32_t id = GetTypeInstruction(type); + if (id == 0) { + return nullptr; + } + return GetType(id); +} + +Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { + if (!IsTypeInst(inst.opcode())) return nullptr; + + Type* type = nullptr; + switch (inst.opcode()) { + case spv::Op::OpTypeVoid: + type = new Void(); + break; + case spv::Op::OpTypeBool: + type = new Bool(); + break; + case spv::Op::OpTypeInt: + type = new Integer(inst.GetSingleWordInOperand(0), + inst.GetSingleWordInOperand(1)); + break; + case spv::Op::OpTypeFloat: + type = new Float(inst.GetSingleWordInOperand(0)); + break; + case spv::Op::OpTypeVector: + type = new Vector(GetType(inst.GetSingleWordInOperand(0)), + inst.GetSingleWordInOperand(1)); + break; + case spv::Op::OpTypeMatrix: + type = new Matrix(GetType(inst.GetSingleWordInOperand(0)), + inst.GetSingleWordInOperand(1)); + break; + case spv::Op::OpTypeImage: { + const spv::AccessQualifier access = + inst.NumInOperands() < 8 ? spv::AccessQualifier::ReadOnly + : static_cast( + inst.GetSingleWordInOperand(7)); + type = new Image( + GetType(inst.GetSingleWordInOperand(0)), + static_cast(inst.GetSingleWordInOperand(1)), + inst.GetSingleWordInOperand(2), inst.GetSingleWordInOperand(3) == 1, + inst.GetSingleWordInOperand(4) == 1, inst.GetSingleWordInOperand(5), + static_cast(inst.GetSingleWordInOperand(6)), + access); + } break; + case spv::Op::OpTypeSampler: + type = new Sampler(); + break; + case spv::Op::OpTypeSampledImage: + type = new SampledImage(GetType(inst.GetSingleWordInOperand(0))); + break; + case spv::Op::OpTypeArray: { + const uint32_t length_id = inst.GetSingleWordInOperand(1); + const Instruction* length_constant_inst = id_to_constant_inst_[length_id]; + assert(length_constant_inst); + + // How will we distinguish one length value from another? + // Determine extra words required to distinguish this array length + // from another. + std::vector extra_words{Array::LengthInfo::kDefiningId}; + // If it is a specialised constant, retrieve its SpecId. + // Only OpSpecConstant has a SpecId. + uint32_t spec_id = 0u; + bool has_spec_id = false; + if (length_constant_inst->opcode() == spv::Op::OpSpecConstant) { + context()->get_decoration_mgr()->ForEachDecoration( + length_id, uint32_t(spv::Decoration::SpecId), + [&spec_id, &has_spec_id](const Instruction& decoration) { + assert(decoration.opcode() == spv::Op::OpDecorate); + spec_id = decoration.GetSingleWordOperand(2u); + has_spec_id = true; + }); + } + const auto opcode = length_constant_inst->opcode(); + if (has_spec_id) { + extra_words.push_back(spec_id); + } + if ((opcode == spv::Op::OpConstant) || + (opcode == spv::Op::OpSpecConstant)) { + // Always include the literal constant words. In the spec constant + // case, the constant might not be overridden, so it's still + // significant. + extra_words.insert(extra_words.end(), + length_constant_inst->GetOperand(2).words.begin(), + length_constant_inst->GetOperand(2).words.end()); + extra_words[0] = has_spec_id ? Array::LengthInfo::kConstantWithSpecId + : Array::LengthInfo::kConstant; + } else { + assert(extra_words[0] == Array::LengthInfo::kDefiningId); + extra_words.push_back(length_id); + } + assert(extra_words.size() >= 2); + Array::LengthInfo length_info{length_id, extra_words}; + + type = new Array(GetType(inst.GetSingleWordInOperand(0)), length_info); + + if (id_to_incomplete_type_.count(inst.GetSingleWordInOperand(0))) { + incomplete_types_.emplace_back(inst.result_id(), type); + id_to_incomplete_type_[inst.result_id()] = type; + return type; + } + } break; + case spv::Op::OpTypeRuntimeArray: + type = new RuntimeArray(GetType(inst.GetSingleWordInOperand(0))); + if (id_to_incomplete_type_.count(inst.GetSingleWordInOperand(0))) { + incomplete_types_.emplace_back(inst.result_id(), type); + id_to_incomplete_type_[inst.result_id()] = type; + return type; + } + break; + case spv::Op::OpTypeStruct: { + std::vector element_types; + bool incomplete_type = false; + for (uint32_t i = 0; i < inst.NumInOperands(); ++i) { + uint32_t type_id = inst.GetSingleWordInOperand(i); + element_types.push_back(GetType(type_id)); + if (id_to_incomplete_type_.count(type_id)) { + incomplete_type = true; + } + } + type = new Struct(element_types); + + if (incomplete_type) { + incomplete_types_.emplace_back(inst.result_id(), type); + id_to_incomplete_type_[inst.result_id()] = type; + return type; + } + } break; + case spv::Op::OpTypeOpaque: { + type = new Opaque(inst.GetInOperand(0).AsString()); + } break; + case spv::Op::OpTypePointer: { + uint32_t pointee_type_id = inst.GetSingleWordInOperand(1); + type = new Pointer( + GetType(pointee_type_id), + static_cast(inst.GetSingleWordInOperand(0))); + + if (id_to_incomplete_type_.count(pointee_type_id)) { + incomplete_types_.emplace_back(inst.result_id(), type); + id_to_incomplete_type_[inst.result_id()] = type; + return type; + } + id_to_incomplete_type_.erase(inst.result_id()); + + } break; + case spv::Op::OpTypeFunction: { + bool incomplete_type = false; + uint32_t return_type_id = inst.GetSingleWordInOperand(0); + if (id_to_incomplete_type_.count(return_type_id)) { + incomplete_type = true; + } + Type* return_type = GetType(return_type_id); + std::vector param_types; + for (uint32_t i = 1; i < inst.NumInOperands(); ++i) { + uint32_t param_type_id = inst.GetSingleWordInOperand(i); + param_types.push_back(GetType(param_type_id)); + if (id_to_incomplete_type_.count(param_type_id)) { + incomplete_type = true; + } + } + + type = new Function(return_type, param_types); + + if (incomplete_type) { + incomplete_types_.emplace_back(inst.result_id(), type); + id_to_incomplete_type_[inst.result_id()] = type; + return type; + } + } break; + case spv::Op::OpTypeEvent: + type = new Event(); + break; + case spv::Op::OpTypeDeviceEvent: + type = new DeviceEvent(); + break; + case spv::Op::OpTypeReserveId: + type = new ReserveId(); + break; + case spv::Op::OpTypeQueue: + type = new Queue(); + break; + case spv::Op::OpTypePipe: + type = new Pipe( + static_cast(inst.GetSingleWordInOperand(0))); + break; + case spv::Op::OpTypeForwardPointer: { + // Handling of forward pointers is different from the other types. + uint32_t target_id = inst.GetSingleWordInOperand(0); + type = new ForwardPointer(target_id, static_cast( + inst.GetSingleWordInOperand(1))); + incomplete_types_.emplace_back(target_id, type); + id_to_incomplete_type_[target_id] = type; + return type; + } + case spv::Op::OpTypePipeStorage: + type = new PipeStorage(); + break; + case spv::Op::OpTypeNamedBarrier: + type = new NamedBarrier(); + break; + case spv::Op::OpTypeAccelerationStructureNV: + type = new AccelerationStructureNV(); + break; + case spv::Op::OpTypeCooperativeMatrixNV: + type = new CooperativeMatrixNV(GetType(inst.GetSingleWordInOperand(0)), + inst.GetSingleWordInOperand(1), + inst.GetSingleWordInOperand(2), + inst.GetSingleWordInOperand(3)); + break; + case spv::Op::OpTypeCooperativeMatrixKHR: + type = new CooperativeMatrixKHR( + GetType(inst.GetSingleWordInOperand(0)), + inst.GetSingleWordInOperand(1), inst.GetSingleWordInOperand(2), + inst.GetSingleWordInOperand(3), inst.GetSingleWordInOperand(4)); + break; + case spv::Op::OpTypeRayQueryKHR: + type = new RayQueryKHR(); + break; + case spv::Op::OpTypeHitObjectNV: + type = new HitObjectNV(); + break; + default: + assert(false && "Type not handled by the type manager."); + break; + } + + uint32_t id = inst.result_id(); + SPIRV_ASSERT(consumer_, id != 0, "instruction without result id found"); + SPIRV_ASSERT(consumer_, type != nullptr, + "type should not be nullptr at this point"); + std::vector decorations = + context()->get_decoration_mgr()->GetDecorationsFor(id, true); + for (auto dec : decorations) { + AttachDecoration(*dec, type); + } + std::unique_ptr unique(type); + auto pair = type_pool_.insert(std::move(unique)); + id_to_type_[id] = pair.first->get(); + type_to_id_[pair.first->get()] = id; + return type; +} + +void TypeManager::AttachDecoration(const Instruction& inst, Type* type) { + const spv::Op opcode = inst.opcode(); + if (!IsAnnotationInst(opcode)) return; + + switch (opcode) { + case spv::Op::OpDecorate: { + const auto count = inst.NumOperands(); + std::vector data; + for (uint32_t i = 1; i < count; ++i) { + data.push_back(inst.GetSingleWordOperand(i)); + } + type->AddDecoration(std::move(data)); + } break; + case spv::Op::OpMemberDecorate: { + const auto count = inst.NumOperands(); + const uint32_t index = inst.GetSingleWordOperand(1); + std::vector data; + for (uint32_t i = 2; i < count; ++i) { + data.push_back(inst.GetSingleWordOperand(i)); + } + if (Struct* st = type->AsStruct()) { + st->AddMemberDecoration(index, std::move(data)); + } + } break; + default: + assert(false && "Unexpected opcode for a decoration instruction."); + break; + } +} + +const Type* TypeManager::GetMemberType( + const Type* parent_type, const std::vector& access_chain) { + for (uint32_t element_index : access_chain) { + if (const Struct* struct_type = parent_type->AsStruct()) { + parent_type = struct_type->element_types()[element_index]; + } else if (const Array* array_type = parent_type->AsArray()) { + parent_type = array_type->element_type(); + } else if (const RuntimeArray* runtime_array_type = + parent_type->AsRuntimeArray()) { + parent_type = runtime_array_type->element_type(); + } else if (const Vector* vector_type = parent_type->AsVector()) { + parent_type = vector_type->element_type(); + } else if (const Matrix* matrix_type = parent_type->AsMatrix()) { + parent_type = matrix_type->element_type(); + } else { + assert(false && "Trying to get a member of a type without members."); + } + } + return parent_type; +} + +void TypeManager::ReplaceForwardPointers(Type* type) { + switch (type->kind()) { + case Type::kArray: { + const ForwardPointer* element_type = + type->AsArray()->element_type()->AsForwardPointer(); + if (element_type) { + type->AsArray()->ReplaceElementType(element_type->target_pointer()); + } + } break; + case Type::kRuntimeArray: { + const ForwardPointer* element_type = + type->AsRuntimeArray()->element_type()->AsForwardPointer(); + if (element_type) { + type->AsRuntimeArray()->ReplaceElementType( + element_type->target_pointer()); + } + } break; + case Type::kStruct: { + auto& member_types = type->AsStruct()->element_types(); + for (auto& member_type : member_types) { + if (member_type->AsForwardPointer()) { + member_type = member_type->AsForwardPointer()->target_pointer(); + assert(member_type); + } + } + } break; + case Type::kPointer: { + const ForwardPointer* pointee_type = + type->AsPointer()->pointee_type()->AsForwardPointer(); + if (pointee_type) { + type->AsPointer()->SetPointeeType(pointee_type->target_pointer()); + } + } break; + case Type::kFunction: { + Function* func_type = type->AsFunction(); + const ForwardPointer* return_type = + func_type->return_type()->AsForwardPointer(); + if (return_type) { + func_type->SetReturnType(return_type->target_pointer()); + } + + auto& param_types = func_type->param_types(); + for (auto& param_type : param_types) { + if (param_type->AsForwardPointer()) { + param_type = param_type->AsForwardPointer()->target_pointer(); + } + } + } break; + default: + break; + } +} + +void TypeManager::ReplaceType(Type* new_type, Type* original_type) { + assert(original_type->kind() == new_type->kind() && + "Types must be the same for replacement.\n"); + for (auto& p : incomplete_types_) { + Type* type = p.type(); + if (!type) { + continue; + } + + switch (type->kind()) { + case Type::kArray: { + const Type* element_type = type->AsArray()->element_type(); + if (element_type == original_type) { + type->AsArray()->ReplaceElementType(new_type); + } + } break; + case Type::kRuntimeArray: { + const Type* element_type = type->AsRuntimeArray()->element_type(); + if (element_type == original_type) { + type->AsRuntimeArray()->ReplaceElementType(new_type); + } + } break; + case Type::kStruct: { + auto& member_types = type->AsStruct()->element_types(); + for (auto& member_type : member_types) { + if (member_type == original_type) { + member_type = new_type; + } + } + } break; + case Type::kPointer: { + const Type* pointee_type = type->AsPointer()->pointee_type(); + if (pointee_type == original_type) { + type->AsPointer()->SetPointeeType(new_type); + } + } break; + case Type::kFunction: { + Function* func_type = type->AsFunction(); + const Type* return_type = func_type->return_type(); + if (return_type == original_type) { + func_type->SetReturnType(new_type); + } + + auto& param_types = func_type->param_types(); + for (auto& param_type : param_types) { + if (param_type == original_type) { + param_type = new_type; + } + } + } break; + default: + break; + } + } +} + +} // namespace analysis +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/type_manager.h b/thirdparty/glslang/External/spirv-tools/source/opt/type_manager.h new file mode 100644 index 000000000000..a70c371db036 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/type_manager.h @@ -0,0 +1,292 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_TYPE_MANAGER_H_ +#define SOURCE_OPT_TYPE_MANAGER_H_ + +#include +#include +#include +#include +#include + +#include "source/opt/module.h" +#include "source/opt/types.h" +#include "spirv-tools/libspirv.hpp" + +namespace spvtools { +namespace opt { + +class IRContext; + +namespace analysis { + +// Hashing functor. +// +// All type pointers must be non-null. +struct HashTypePointer { + size_t operator()(const Type* type) const { + assert(type); + return type->HashValue(); + } +}; +struct HashTypeUniquePointer { + size_t operator()(const std::unique_ptr& type) const { + assert(type); + return type->HashValue(); + } +}; + +// Equality functor. +// +// Checks if two types pointers are the same type. +// +// All type pointers must be non-null. +struct CompareTypePointers { + bool operator()(const Type* lhs, const Type* rhs) const { + assert(lhs && rhs); + return lhs->IsSame(rhs); + } +}; +struct CompareTypeUniquePointers { + bool operator()(const std::unique_ptr& lhs, + const std::unique_ptr& rhs) const { + assert(lhs && rhs); + return lhs->IsSame(rhs.get()); + } +}; + +// A class for managing the SPIR-V type hierarchy. +class TypeManager { + public: + using IdToTypeMap = std::unordered_map; + + // Constructs a type manager from the given |module|. All internal messages + // will be communicated to the outside via the given message |consumer|. + // This instance only keeps a reference to the |consumer|, so the |consumer| + // should outlive this instance. + TypeManager(const MessageConsumer& consumer, IRContext* c); + + TypeManager(const TypeManager&) = delete; + TypeManager(TypeManager&&) = delete; + TypeManager& operator=(const TypeManager&) = delete; + TypeManager& operator=(TypeManager&&) = delete; + + // Returns the type for the given type |id|. Returns nullptr if the given |id| + // does not define a type. + Type* GetType(uint32_t id) const; + // Returns the id for the given |type|. Returns 0 if can not find the given + // |type|. + uint32_t GetId(const Type* type) const; + // Returns the number of types hold in this manager. + size_t NumTypes() const { return id_to_type_.size(); } + // Iterators for all types contained in this manager. + IdToTypeMap::const_iterator begin() const { return id_to_type_.cbegin(); } + IdToTypeMap::const_iterator end() const { return id_to_type_.cend(); } + + // Returns a pair of the type and pointer to the type in |sc|. + // + // |id| must be a registered type. + std::pair> GetTypeAndPointerType( + uint32_t id, spv::StorageClass sc) const; + + // Returns an id for a declaration representing |type|. Returns 0 if the type + // does not exists, and could not be generated. + // + // If |type| is registered, then the registered id is returned. Otherwise, + // this function recursively adds type and annotation instructions as + // necessary to fully define |type|. + uint32_t GetTypeInstruction(const Type* type); + + // Find pointer to type and storage in module, return its resultId. If it is + // not found, a new type is created, and its id is returned. Returns 0 if the + // type could not be created. + uint32_t FindPointerToType(uint32_t type_id, spv::StorageClass storage_class); + + // Registers |id| to |type|. + // + // If GetId(|type|) already returns a non-zero id, that mapping will be + // unchanged. + void RegisterType(uint32_t id, const Type& type); + + // Return the registered type object that is the same as |type|. + Type* GetRegisteredType(const Type* type); + + // Removes knowledge of |id| from the manager. + // + // If |id| is an ambiguous type the multiple ids may be registered to |id|'s + // type (e.g. %struct1 and %struct1 might hash to the same type). In that + // case, calling GetId() with |id|'s type will return another suitable id + // defining that type. + void RemoveId(uint32_t id); + + // Returns the type of the member of |parent_type| that is identified by + // |access_chain|. The vector |access_chain| is a series of integers that are + // used to pick members as in the |OpCompositeExtract| instructions. If you + // want a member of an array, vector, or matrix that does not have a constant + // index, you can use 0 in that position. All elements have the same type. + const Type* GetMemberType(const Type* parent_type, + const std::vector& access_chain); + + // Attaches the decoration encoded in |inst| to |type|. Does nothing if the + // given instruction is not a decoration instruction. Assumes the target is + // |type| (e.g. should be called in loop of |type|'s decorations). + void AttachDecoration(const Instruction& inst, Type* type); + + Type* GetUIntType() { return GetIntType(32, false); } + + uint32_t GetUIntTypeId() { return GetTypeInstruction(GetUIntType()); } + + Type* GetIntType(int32_t bitWidth, bool isSigned) { + Integer int_type(bitWidth, isSigned); + return GetRegisteredType(&int_type); + } + + Type* GetSIntType() { return GetIntType(32, true); } + + uint32_t GetSIntTypeId() { return GetTypeInstruction(GetSIntType()); } + + Type* GetFloatType() { + Float float_type(32); + return GetRegisteredType(&float_type); + } + + uint32_t GetFloatTypeId() { return GetTypeInstruction(GetFloatType()); } + + Type* GetDoubleType() { + Float float_type(64); + return GetRegisteredType(&float_type); + } + + uint32_t GetDoubleTypeId() { return GetTypeInstruction(GetDoubleType()); } + + Type* GetUIntVectorType(uint32_t size) { + Vector vec_type(GetUIntType(), size); + return GetRegisteredType(&vec_type); + } + + uint32_t GetUIntVectorTypeId(uint32_t size) { + return GetTypeInstruction(GetUIntVectorType(size)); + } + + Type* GetSIntVectorType(uint32_t size) { + Vector vec_type(GetSIntType(), size); + return GetRegisteredType(&vec_type); + } + + uint32_t GetSIntVectorTypeId(uint32_t size) { + return GetTypeInstruction(GetSIntVectorType(size)); + } + + Type* GetFloatVectorType(uint32_t size) { + Vector vec_type(GetFloatType(), size); + return GetRegisteredType(&vec_type); + } + + uint32_t GetFloatVectorTypeId(uint32_t size) { + return GetTypeInstruction(GetFloatVectorType(size)); + } + + Type* GetBoolType() { + Bool bool_type; + return GetRegisteredType(&bool_type); + } + + uint32_t GetBoolTypeId() { return GetTypeInstruction(GetBoolType()); } + + Type* GetVoidType() { + Void void_type; + return GetRegisteredType(&void_type); + } + + uint32_t GetVoidTypeId() { return GetTypeInstruction(GetVoidType()); } + + private: + using TypeToIdMap = std::unordered_map; + using TypePool = + std::unordered_set, HashTypeUniquePointer, + CompareTypeUniquePointers>; + + class UnresolvedType { + public: + UnresolvedType(uint32_t i, Type* t) : id_(i), type_(t) {} + UnresolvedType(const UnresolvedType&) = delete; + UnresolvedType(UnresolvedType&& that) + : id_(that.id_), type_(std::move(that.type_)) {} + + uint32_t id() { return id_; } + Type* type() { return type_.get(); } + std::unique_ptr&& ReleaseType() { return std::move(type_); } + void ResetType(Type* t) { type_.reset(t); } + + private: + uint32_t id_; + std::unique_ptr type_; + }; + using IdToUnresolvedType = std::vector; + + // Analyzes the types and decorations on types in the given |module|. + void AnalyzeTypes(const Module& module); + + IRContext* context() { return context_; } + + // Attaches the decorations on |type| to |id|. + void AttachDecorations(uint32_t id, const Type* type); + + // Create the annotation instruction. + // + // If |is_member| is false, an OpDecorate of |decoration| on |id| is created, + // otherwise an OpMemberDecorate is created at |element|. The annotation is + // registered with the DefUseManager and the DecorationManager. + void CreateDecoration(uint32_t id, const std::vector& decoration, + bool is_member = false, uint32_t element = 0); + + // Creates and returns a type from the given SPIR-V |inst|. Returns nullptr if + // the given instruction is not for defining a type. + Type* RecordIfTypeDefinition(const Instruction& inst); + + // Returns an equivalent pointer to |type| built in terms of pointers owned by + // |type_pool_|. For example, if |type| is a vec3 of bool, it will be rebuilt + // replacing the bool subtype with one owned by |type_pool_|. + Type* RebuildType(const Type& type); + + // Completes the incomplete type |type|, by replaces all references to + // ForwardPointer by the defining Pointer. + void ReplaceForwardPointers(Type* type); + + // Replaces all references to |original_type| in |incomplete_types_| by + // |new_type|. + void ReplaceType(Type* new_type, Type* original_type); + + const MessageConsumer& consumer_; // Message consumer. + IRContext* context_; + IdToTypeMap id_to_type_; // Mapping from ids to their type representations. + TypeToIdMap type_to_id_; // Mapping from types to their defining ids. + TypePool type_pool_; // Memory owner of type pointers. + IdToUnresolvedType incomplete_types_; // All incomplete types. Stored in an + // std::vector to make traversals + // deterministic. + + IdToTypeMap id_to_incomplete_type_; // Maps ids to their type representations + // for incomplete types. + + std::unordered_map id_to_constant_inst_; +}; + +} // namespace analysis +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_TYPE_MANAGER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/types.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/types.cpp new file mode 100644 index 000000000000..b18b8cb1ae6b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/types.cpp @@ -0,0 +1,755 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/types.h" + +#include +#include +#include +#include +#include +#include + +#include "source/util/hash_combine.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { +namespace analysis { + +using spvtools::utils::hash_combine; +using U32VecVec = std::vector>; + +namespace { + +// Returns true if the two vector of vectors are identical. +bool CompareTwoVectors(const U32VecVec a, const U32VecVec b) { + const auto size = a.size(); + if (size != b.size()) return false; + + if (size == 0) return true; + if (size == 1) return a.front() == b.front(); + + std::vector*> a_ptrs, b_ptrs; + a_ptrs.reserve(size); + a_ptrs.reserve(size); + for (uint32_t i = 0; i < size; ++i) { + a_ptrs.push_back(&a[i]); + b_ptrs.push_back(&b[i]); + } + + const auto cmp = [](const std::vector* m, + const std::vector* n) { + return m->front() < n->front(); + }; + + std::sort(a_ptrs.begin(), a_ptrs.end(), cmp); + std::sort(b_ptrs.begin(), b_ptrs.end(), cmp); + + for (uint32_t i = 0; i < size; ++i) { + if (*a_ptrs[i] != *b_ptrs[i]) return false; + } + return true; +} + +} // namespace + +std::string Type::GetDecorationStr() const { + std::ostringstream oss; + oss << "[["; + for (const auto& decoration : decorations_) { + oss << "("; + for (size_t i = 0; i < decoration.size(); ++i) { + oss << (i > 0 ? ", " : ""); + oss << decoration.at(i); + } + oss << ")"; + } + oss << "]]"; + return oss.str(); +} + +bool Type::HasSameDecorations(const Type* that) const { + return CompareTwoVectors(decorations_, that->decorations_); +} + +bool Type::IsUniqueType() const { + switch (kind_) { + case kPointer: + case kStruct: + case kArray: + case kRuntimeArray: + return false; + default: + return true; + } +} + +std::unique_ptr Type::Clone() const { + std::unique_ptr type; + switch (kind_) { +#define DeclareKindCase(kind) \ + case k##kind: \ + type = MakeUnique(*this->As##kind()); \ + break + DeclareKindCase(Void); + DeclareKindCase(Bool); + DeclareKindCase(Integer); + DeclareKindCase(Float); + DeclareKindCase(Vector); + DeclareKindCase(Matrix); + DeclareKindCase(Image); + DeclareKindCase(Sampler); + DeclareKindCase(SampledImage); + DeclareKindCase(Array); + DeclareKindCase(RuntimeArray); + DeclareKindCase(Struct); + DeclareKindCase(Opaque); + DeclareKindCase(Pointer); + DeclareKindCase(Function); + DeclareKindCase(Event); + DeclareKindCase(DeviceEvent); + DeclareKindCase(ReserveId); + DeclareKindCase(Queue); + DeclareKindCase(Pipe); + DeclareKindCase(ForwardPointer); + DeclareKindCase(PipeStorage); + DeclareKindCase(NamedBarrier); + DeclareKindCase(AccelerationStructureNV); + DeclareKindCase(CooperativeMatrixNV); + DeclareKindCase(CooperativeMatrixKHR); + DeclareKindCase(RayQueryKHR); + DeclareKindCase(HitObjectNV); +#undef DeclareKindCase + default: + assert(false && "Unhandled type"); + } + return type; +} + +std::unique_ptr Type::RemoveDecorations() const { + std::unique_ptr type(Clone()); + type->ClearDecorations(); + return type; +} + +bool Type::operator==(const Type& other) const { + if (kind_ != other.kind_) return false; + + switch (kind_) { +#define DeclareKindCase(kind) \ + case k##kind: \ + return As##kind()->IsSame(&other) + DeclareKindCase(Void); + DeclareKindCase(Bool); + DeclareKindCase(Integer); + DeclareKindCase(Float); + DeclareKindCase(Vector); + DeclareKindCase(Matrix); + DeclareKindCase(Image); + DeclareKindCase(Sampler); + DeclareKindCase(SampledImage); + DeclareKindCase(Array); + DeclareKindCase(RuntimeArray); + DeclareKindCase(Struct); + DeclareKindCase(Opaque); + DeclareKindCase(Pointer); + DeclareKindCase(Function); + DeclareKindCase(Event); + DeclareKindCase(DeviceEvent); + DeclareKindCase(ReserveId); + DeclareKindCase(Queue); + DeclareKindCase(Pipe); + DeclareKindCase(ForwardPointer); + DeclareKindCase(PipeStorage); + DeclareKindCase(NamedBarrier); + DeclareKindCase(AccelerationStructureNV); + DeclareKindCase(CooperativeMatrixNV); + DeclareKindCase(CooperativeMatrixKHR); + DeclareKindCase(RayQueryKHR); + DeclareKindCase(HitObjectNV); +#undef DeclareKindCase + default: + assert(false && "Unhandled type"); + return false; + } +} + +size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const { + // Linear search through a dense, cache coherent vector is faster than O(log + // n) search in a complex data structure (eg std::set) for the generally small + // number of nodes. It also skips the overhead of an new/delete per Type + // (when inserting/removing from a set). + if (std::find(seen->begin(), seen->end(), this) != seen->end()) { + return hash; + } + + seen->push_back(this); + + hash = hash_combine(hash, uint32_t(kind_)); + for (const auto& d : decorations_) { + hash = hash_combine(hash, d); + } + + switch (kind_) { +#define DeclareKindCase(type) \ + case k##type: \ + hash = As##type()->ComputeExtraStateHash(hash, seen); \ + break + DeclareKindCase(Void); + DeclareKindCase(Bool); + DeclareKindCase(Integer); + DeclareKindCase(Float); + DeclareKindCase(Vector); + DeclareKindCase(Matrix); + DeclareKindCase(Image); + DeclareKindCase(Sampler); + DeclareKindCase(SampledImage); + DeclareKindCase(Array); + DeclareKindCase(RuntimeArray); + DeclareKindCase(Struct); + DeclareKindCase(Opaque); + DeclareKindCase(Pointer); + DeclareKindCase(Function); + DeclareKindCase(Event); + DeclareKindCase(DeviceEvent); + DeclareKindCase(ReserveId); + DeclareKindCase(Queue); + DeclareKindCase(Pipe); + DeclareKindCase(ForwardPointer); + DeclareKindCase(PipeStorage); + DeclareKindCase(NamedBarrier); + DeclareKindCase(AccelerationStructureNV); + DeclareKindCase(CooperativeMatrixNV); + DeclareKindCase(CooperativeMatrixKHR); + DeclareKindCase(RayQueryKHR); + DeclareKindCase(HitObjectNV); +#undef DeclareKindCase + default: + assert(false && "Unhandled type"); + break; + } + + seen->pop_back(); + return hash; +} + +size_t Type::HashValue() const { + SeenTypes seen; + return ComputeHashValue(0, &seen); +} + +uint64_t Type::NumberOfComponents() const { + switch (kind()) { + case kVector: + return AsVector()->element_count(); + case kMatrix: + return AsMatrix()->element_count(); + case kArray: { + Array::LengthInfo length_info = AsArray()->length_info(); + if (length_info.words[0] != Array::LengthInfo::kConstant) { + return UINT64_MAX; + } + assert(length_info.words.size() <= 3 && + "The size of the array could not fit size_t."); + uint64_t length = 0; + length |= length_info.words[1]; + if (length_info.words.size() > 2) { + length |= static_cast(length_info.words[2]) << 32; + } + return length; + } + case kRuntimeArray: + return UINT64_MAX; + case kStruct: + return AsStruct()->element_types().size(); + default: + return 0; + } +} + +bool Integer::IsSameImpl(const Type* that, IsSameCache*) const { + const Integer* it = that->AsInteger(); + return it && width_ == it->width_ && signed_ == it->signed_ && + HasSameDecorations(that); +} + +std::string Integer::str() const { + std::ostringstream oss; + oss << (signed_ ? "s" : "u") << "int" << width_; + return oss.str(); +} + +size_t Integer::ComputeExtraStateHash(size_t hash, SeenTypes*) const { + return hash_combine(hash, width_, signed_); +} + +bool Float::IsSameImpl(const Type* that, IsSameCache*) const { + const Float* ft = that->AsFloat(); + return ft && width_ == ft->width_ && HasSameDecorations(that); +} + +std::string Float::str() const { + std::ostringstream oss; + oss << "float" << width_; + return oss.str(); +} + +size_t Float::ComputeExtraStateHash(size_t hash, SeenTypes*) const { + return hash_combine(hash, width_); +} + +Vector::Vector(const Type* type, uint32_t count) + : Type(kVector), element_type_(type), count_(count) { + assert(type->AsBool() || type->AsInteger() || type->AsFloat()); +} + +bool Vector::IsSameImpl(const Type* that, IsSameCache* seen) const { + const Vector* vt = that->AsVector(); + if (!vt) return false; + return count_ == vt->count_ && + element_type_->IsSameImpl(vt->element_type_, seen) && + HasSameDecorations(that); +} + +std::string Vector::str() const { + std::ostringstream oss; + oss << "<" << element_type_->str() << ", " << count_ << ">"; + return oss.str(); +} + +size_t Vector::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + // prefer form that doesn't require push/pop from stack: add state and + // make tail call. + hash = hash_combine(hash, count_); + return element_type_->ComputeHashValue(hash, seen); +} + +Matrix::Matrix(const Type* type, uint32_t count) + : Type(kMatrix), element_type_(type), count_(count) { + assert(type->AsVector()); +} + +bool Matrix::IsSameImpl(const Type* that, IsSameCache* seen) const { + const Matrix* mt = that->AsMatrix(); + if (!mt) return false; + return count_ == mt->count_ && + element_type_->IsSameImpl(mt->element_type_, seen) && + HasSameDecorations(that); +} + +std::string Matrix::str() const { + std::ostringstream oss; + oss << "<" << element_type_->str() << ", " << count_ << ">"; + return oss.str(); +} + +size_t Matrix::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + hash = hash_combine(hash, count_); + return element_type_->ComputeHashValue(hash, seen); +} + +Image::Image(Type* type, spv::Dim dimen, uint32_t d, bool array, + bool multisample, uint32_t sampling, spv::ImageFormat f, + spv::AccessQualifier qualifier) + : Type(kImage), + sampled_type_(type), + dim_(dimen), + depth_(d), + arrayed_(array), + ms_(multisample), + sampled_(sampling), + format_(f), + access_qualifier_(qualifier) { + // TODO(antiagainst): check sampled_type +} + +bool Image::IsSameImpl(const Type* that, IsSameCache* seen) const { + const Image* it = that->AsImage(); + if (!it) return false; + return dim_ == it->dim_ && depth_ == it->depth_ && arrayed_ == it->arrayed_ && + ms_ == it->ms_ && sampled_ == it->sampled_ && format_ == it->format_ && + access_qualifier_ == it->access_qualifier_ && + sampled_type_->IsSameImpl(it->sampled_type_, seen) && + HasSameDecorations(that); +} + +std::string Image::str() const { + std::ostringstream oss; + oss << "image(" << sampled_type_->str() << ", " << uint32_t(dim_) << ", " + << depth_ << ", " << arrayed_ << ", " << ms_ << ", " << sampled_ << ", " + << uint32_t(format_) << ", " << uint32_t(access_qualifier_) << ")"; + return oss.str(); +} + +size_t Image::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + hash = hash_combine(hash, uint32_t(dim_), depth_, arrayed_, ms_, sampled_, + uint32_t(format_), uint32_t(access_qualifier_)); + return sampled_type_->ComputeHashValue(hash, seen); +} + +bool SampledImage::IsSameImpl(const Type* that, IsSameCache* seen) const { + const SampledImage* sit = that->AsSampledImage(); + if (!sit) return false; + return image_type_->IsSameImpl(sit->image_type_, seen) && + HasSameDecorations(that); +} + +std::string SampledImage::str() const { + std::ostringstream oss; + oss << "sampled_image(" << image_type_->str() << ")"; + return oss.str(); +} + +size_t SampledImage::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + return image_type_->ComputeHashValue(hash, seen); +} + +Array::Array(const Type* type, const Array::LengthInfo& length_info_arg) + : Type(kArray), element_type_(type), length_info_(length_info_arg) { + assert(type != nullptr); + assert(!type->AsVoid()); + // We always have a word to say which case we're in, followed + // by at least one more word. + assert(length_info_arg.words.size() >= 2); +} + +bool Array::IsSameImpl(const Type* that, IsSameCache* seen) const { + const Array* at = that->AsArray(); + if (!at) return false; + bool is_same = element_type_->IsSameImpl(at->element_type_, seen); + is_same = is_same && HasSameDecorations(that); + is_same = is_same && (length_info_.words == at->length_info_.words); + return is_same; +} + +std::string Array::str() const { + std::ostringstream oss; + oss << "[" << element_type_->str() << ", id(" << LengthId() << "), words("; + const char* spacer = ""; + for (auto w : length_info_.words) { + oss << spacer << w; + spacer = ","; + } + oss << ")]"; + return oss.str(); +} + +size_t Array::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + hash = hash_combine(hash, length_info_.words); + return element_type_->ComputeHashValue(hash, seen); +} + +void Array::ReplaceElementType(const Type* type) { element_type_ = type; } + +Array::LengthInfo Array::GetConstantLengthInfo(uint32_t const_id, + uint32_t length) const { + std::vector extra_words{LengthInfo::Case::kConstant, length}; + return {const_id, extra_words}; +} + +RuntimeArray::RuntimeArray(const Type* type) + : Type(kRuntimeArray), element_type_(type) { + assert(!type->AsVoid()); +} + +bool RuntimeArray::IsSameImpl(const Type* that, IsSameCache* seen) const { + const RuntimeArray* rat = that->AsRuntimeArray(); + if (!rat) return false; + return element_type_->IsSameImpl(rat->element_type_, seen) && + HasSameDecorations(that); +} + +std::string RuntimeArray::str() const { + std::ostringstream oss; + oss << "[" << element_type_->str() << "]"; + return oss.str(); +} + +size_t RuntimeArray::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + return element_type_->ComputeHashValue(hash, seen); +} + +void RuntimeArray::ReplaceElementType(const Type* type) { + element_type_ = type; +} + +Struct::Struct(const std::vector& types) + : Type(kStruct), element_types_(types) { + for (const auto* t : types) { + (void)t; + assert(!t->AsVoid()); + } +} + +void Struct::AddMemberDecoration(uint32_t index, + std::vector&& decoration) { + if (index >= element_types_.size()) { + assert(0 && "index out of bound"); + return; + } + + element_decorations_[index].push_back(std::move(decoration)); +} + +bool Struct::IsSameImpl(const Type* that, IsSameCache* seen) const { + const Struct* st = that->AsStruct(); + if (!st) return false; + if (element_types_.size() != st->element_types_.size()) return false; + const auto size = element_decorations_.size(); + if (size != st->element_decorations_.size()) return false; + if (!HasSameDecorations(that)) return false; + + for (size_t i = 0; i < element_types_.size(); ++i) { + if (!element_types_[i]->IsSameImpl(st->element_types_[i], seen)) + return false; + } + for (const auto& p : element_decorations_) { + if (st->element_decorations_.count(p.first) == 0) return false; + if (!CompareTwoVectors(p.second, st->element_decorations_.at(p.first))) + return false; + } + return true; +} + +std::string Struct::str() const { + std::ostringstream oss; + oss << "{"; + const size_t count = element_types_.size(); + for (size_t i = 0; i < count; ++i) { + oss << element_types_[i]->str(); + if (i + 1 != count) oss << ", "; + } + oss << "}"; + return oss.str(); +} + +size_t Struct::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + for (auto* t : element_types_) { + hash = t->ComputeHashValue(hash, seen); + } + for (const auto& pair : element_decorations_) { + hash = hash_combine(hash, pair.first, pair.second); + } + return hash; +} + +bool Opaque::IsSameImpl(const Type* that, IsSameCache*) const { + const Opaque* ot = that->AsOpaque(); + if (!ot) return false; + return name_ == ot->name_ && HasSameDecorations(that); +} + +std::string Opaque::str() const { + std::ostringstream oss; + oss << "opaque('" << name_ << "')"; + return oss.str(); +} + +size_t Opaque::ComputeExtraStateHash(size_t hash, SeenTypes*) const { + return hash_combine(hash, name_); +} + +Pointer::Pointer(const Type* type, spv::StorageClass sc) + : Type(kPointer), pointee_type_(type), storage_class_(sc) {} + +bool Pointer::IsSameImpl(const Type* that, IsSameCache* seen) const { + const Pointer* pt = that->AsPointer(); + if (!pt) return false; + if (storage_class_ != pt->storage_class_) return false; + auto p = seen->insert(std::make_pair(this, that->AsPointer())); + if (!p.second) { + return true; + } + bool same_pointee = pointee_type_->IsSameImpl(pt->pointee_type_, seen); + seen->erase(p.first); + if (!same_pointee) { + return false; + } + return HasSameDecorations(that); +} + +std::string Pointer::str() const { + std::ostringstream os; + os << pointee_type_->str() << " " << static_cast(storage_class_) + << "*"; + return os.str(); +} + +size_t Pointer::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + hash = hash_combine(hash, uint32_t(storage_class_)); + return pointee_type_->ComputeHashValue(hash, seen); +} + +void Pointer::SetPointeeType(const Type* type) { pointee_type_ = type; } + +Function::Function(const Type* ret_type, const std::vector& params) + : Type(kFunction), return_type_(ret_type), param_types_(params) {} + +Function::Function(const Type* ret_type, std::vector& params) + : Type(kFunction), return_type_(ret_type), param_types_(params) {} + +bool Function::IsSameImpl(const Type* that, IsSameCache* seen) const { + const Function* ft = that->AsFunction(); + if (!ft) return false; + if (!return_type_->IsSameImpl(ft->return_type_, seen)) return false; + if (param_types_.size() != ft->param_types_.size()) return false; + for (size_t i = 0; i < param_types_.size(); ++i) { + if (!param_types_[i]->IsSameImpl(ft->param_types_[i], seen)) return false; + } + return HasSameDecorations(that); +} + +std::string Function::str() const { + std::ostringstream oss; + const size_t count = param_types_.size(); + oss << "("; + for (size_t i = 0; i < count; ++i) { + oss << param_types_[i]->str(); + if (i + 1 != count) oss << ", "; + } + oss << ") -> " << return_type_->str(); + return oss.str(); +} + +size_t Function::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { + for (const auto* t : param_types_) { + hash = t->ComputeHashValue(hash, seen); + } + return return_type_->ComputeHashValue(hash, seen); +} + +void Function::SetReturnType(const Type* type) { return_type_ = type; } + +bool Pipe::IsSameImpl(const Type* that, IsSameCache*) const { + const Pipe* pt = that->AsPipe(); + if (!pt) return false; + return access_qualifier_ == pt->access_qualifier_ && HasSameDecorations(that); +} + +std::string Pipe::str() const { + std::ostringstream oss; + oss << "pipe(" << uint32_t(access_qualifier_) << ")"; + return oss.str(); +} + +size_t Pipe::ComputeExtraStateHash(size_t hash, SeenTypes*) const { + return hash_combine(hash, uint32_t(access_qualifier_)); +} + +bool ForwardPointer::IsSameImpl(const Type* that, IsSameCache*) const { + const ForwardPointer* fpt = that->AsForwardPointer(); + if (!fpt) return false; + return (pointer_ && fpt->pointer_ ? *pointer_ == *fpt->pointer_ + : target_id_ == fpt->target_id_) && + storage_class_ == fpt->storage_class_ && HasSameDecorations(that); +} + +std::string ForwardPointer::str() const { + std::ostringstream oss; + oss << "forward_pointer("; + if (pointer_ != nullptr) { + oss << pointer_->str(); + } else { + oss << target_id_; + } + oss << ")"; + return oss.str(); +} + +size_t ForwardPointer::ComputeExtraStateHash(size_t hash, + SeenTypes* seen) const { + hash = hash_combine(hash, target_id_, uint32_t(storage_class_)); + if (pointer_) hash = pointer_->ComputeHashValue(hash, seen); + return hash; +} + +CooperativeMatrixNV::CooperativeMatrixNV(const Type* type, const uint32_t scope, + const uint32_t rows, + const uint32_t columns) + : Type(kCooperativeMatrixNV), + component_type_(type), + scope_id_(scope), + rows_id_(rows), + columns_id_(columns) { + assert(type != nullptr); + assert(scope != 0); + assert(rows != 0); + assert(columns != 0); +} + +std::string CooperativeMatrixNV::str() const { + std::ostringstream oss; + oss << "<" << component_type_->str() << ", " << scope_id_ << ", " << rows_id_ + << ", " << columns_id_ << ">"; + return oss.str(); +} + +size_t CooperativeMatrixNV::ComputeExtraStateHash(size_t hash, + SeenTypes* seen) const { + hash = hash_combine(hash, scope_id_, rows_id_, columns_id_); + return component_type_->ComputeHashValue(hash, seen); +} + +bool CooperativeMatrixNV::IsSameImpl(const Type* that, + IsSameCache* seen) const { + const CooperativeMatrixNV* mt = that->AsCooperativeMatrixNV(); + if (!mt) return false; + return component_type_->IsSameImpl(mt->component_type_, seen) && + scope_id_ == mt->scope_id_ && rows_id_ == mt->rows_id_ && + columns_id_ == mt->columns_id_ && HasSameDecorations(that); +} + +CooperativeMatrixKHR::CooperativeMatrixKHR(const Type* type, + const uint32_t scope, + const uint32_t rows, + const uint32_t columns, + const uint32_t use) + : Type(kCooperativeMatrixKHR), + component_type_(type), + scope_id_(scope), + rows_id_(rows), + columns_id_(columns), + use_id_(use) { + assert(type != nullptr); + assert(scope != 0); + assert(rows != 0); + assert(columns != 0); +} + +std::string CooperativeMatrixKHR::str() const { + std::ostringstream oss; + oss << "<" << component_type_->str() << ", " << scope_id_ << ", " << rows_id_ + << ", " << columns_id_ << ", " << use_id_ << ">"; + return oss.str(); +} + +size_t CooperativeMatrixKHR::ComputeExtraStateHash(size_t hash, + SeenTypes* seen) const { + hash = hash_combine(hash, scope_id_, rows_id_, columns_id_, use_id_); + return component_type_->ComputeHashValue(hash, seen); +} + +bool CooperativeMatrixKHR::IsSameImpl(const Type* that, + IsSameCache* seen) const { + const CooperativeMatrixKHR* mt = that->AsCooperativeMatrixKHR(); + if (!mt) return false; + return component_type_->IsSameImpl(mt->component_type_, seen) && + scope_id_ == mt->scope_id_ && rows_id_ == mt->rows_id_ && + columns_id_ == mt->columns_id_ && HasSameDecorations(that); +} + +} // namespace analysis +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/types.h b/thirdparty/glslang/External/spirv-tools/source/opt/types.h new file mode 100644 index 000000000000..16a948cec556 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/types.h @@ -0,0 +1,700 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file provides a class hierarchy for representing SPIR-V types. + +#ifndef SOURCE_OPT_TYPES_H_ +#define SOURCE_OPT_TYPES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/latest_version_spirv_header.h" +#include "source/opt/instruction.h" +#include "source/util/small_vector.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace opt { +namespace analysis { + +class Void; +class Bool; +class Integer; +class Float; +class Vector; +class Matrix; +class Image; +class Sampler; +class SampledImage; +class Array; +class RuntimeArray; +class Struct; +class Opaque; +class Pointer; +class Function; +class Event; +class DeviceEvent; +class ReserveId; +class Queue; +class Pipe; +class ForwardPointer; +class PipeStorage; +class NamedBarrier; +class AccelerationStructureNV; +class CooperativeMatrixNV; +class CooperativeMatrixKHR; +class RayQueryKHR; +class HitObjectNV; + +// Abstract class for a SPIR-V type. It has a bunch of As() methods, +// which is used as a way to probe the actual . +class Type { + public: + typedef std::set> IsSameCache; + + using SeenTypes = spvtools::utils::SmallVector; + + // Available subtypes. + // + // When adding a new derived class of Type, please add an entry to the enum. + enum Kind { + kVoid, + kBool, + kInteger, + kFloat, + kVector, + kMatrix, + kImage, + kSampler, + kSampledImage, + kArray, + kRuntimeArray, + kStruct, + kOpaque, + kPointer, + kFunction, + kEvent, + kDeviceEvent, + kReserveId, + kQueue, + kPipe, + kForwardPointer, + kPipeStorage, + kNamedBarrier, + kAccelerationStructureNV, + kCooperativeMatrixNV, + kCooperativeMatrixKHR, + kRayQueryKHR, + kHitObjectNV, + kLast + }; + + Type(Kind k) : kind_(k) {} + + virtual ~Type() = default; + + // Attaches a decoration directly on this type. + void AddDecoration(std::vector&& d) { + decorations_.push_back(std::move(d)); + } + // Returns the decorations on this type as a string. + std::string GetDecorationStr() const; + // Returns true if this type has exactly the same decorations as |that| type. + bool HasSameDecorations(const Type* that) const; + // Returns true if this type is exactly the same as |that| type, including + // decorations. + bool IsSame(const Type* that) const { + IsSameCache seen; + return IsSameImpl(that, &seen); + } + + // Returns true if this type is exactly the same as |that| type, including + // decorations. |seen| is the set of |Pointer*| pair that are currently being + // compared in a parent call to |IsSameImpl|. + virtual bool IsSameImpl(const Type* that, IsSameCache* seen) const = 0; + + // Returns a human-readable string to represent this type. + virtual std::string str() const = 0; + + Kind kind() const { return kind_; } + const std::vector>& decorations() const { + return decorations_; + } + + // Returns true if there is no decoration on this type. For struct types, + // returns true only when there is no decoration for both the struct type + // and the struct members. + virtual bool decoration_empty() const { return decorations_.empty(); } + + // Creates a clone of |this|. + std::unique_ptr Clone() const; + + // Returns a clone of |this| minus any decorations. + std::unique_ptr RemoveDecorations() const; + + // Returns true if this cannot hash to the same value as another type in the + // module. For example, structs are not unique types because the module could + // have two types + // + // %1 = OpTypeStruct %int + // %2 = OpTypeStruct %int + // + // The only way to distinguish these types is the result id. The type manager + // will hash them to the same value. + bool IsUniqueType() const; + + bool operator==(const Type& other) const; + + // Returns the hash value of this type. + size_t HashValue() const; + + size_t ComputeHashValue(size_t hash, SeenTypes* seen) const; + + // Returns the number of components in a composite type. Returns 0 for a + // non-composite type. + uint64_t NumberOfComponents() const; + +// A bunch of methods for casting this type to a given type. Returns this if the +// cast can be done, nullptr otherwise. +// clang-format off +#define DeclareCastMethod(target) \ + virtual target* As##target() { return nullptr; } \ + virtual const target* As##target() const { return nullptr; } + DeclareCastMethod(Void) + DeclareCastMethod(Bool) + DeclareCastMethod(Integer) + DeclareCastMethod(Float) + DeclareCastMethod(Vector) + DeclareCastMethod(Matrix) + DeclareCastMethod(Image) + DeclareCastMethod(Sampler) + DeclareCastMethod(SampledImage) + DeclareCastMethod(Array) + DeclareCastMethod(RuntimeArray) + DeclareCastMethod(Struct) + DeclareCastMethod(Opaque) + DeclareCastMethod(Pointer) + DeclareCastMethod(Function) + DeclareCastMethod(Event) + DeclareCastMethod(DeviceEvent) + DeclareCastMethod(ReserveId) + DeclareCastMethod(Queue) + DeclareCastMethod(Pipe) + DeclareCastMethod(ForwardPointer) + DeclareCastMethod(PipeStorage) + DeclareCastMethod(NamedBarrier) + DeclareCastMethod(AccelerationStructureNV) + DeclareCastMethod(CooperativeMatrixNV) + DeclareCastMethod(CooperativeMatrixKHR) + DeclareCastMethod(RayQueryKHR) + DeclareCastMethod(HitObjectNV) +#undef DeclareCastMethod + +protected: + // Add any type-specific state to |hash| and returns new hash. + virtual size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const = 0; + + protected: + // Decorations attached to this type. Each decoration is encoded as a vector + // of uint32_t numbers. The first uint32_t number is the decoration value, + // and the rest are the parameters to the decoration (if exists). + std::vector> decorations_; + + private: + // Removes decorations on this type. For struct types, also removes element + // decorations. + virtual void ClearDecorations() { decorations_.clear(); } + + Kind kind_; +}; +// clang-format on + +class Integer : public Type { + public: + Integer(uint32_t w, bool is_signed) + : Type(kInteger), width_(w), signed_(is_signed) {} + Integer(const Integer&) = default; + + std::string str() const override; + + Integer* AsInteger() override { return this; } + const Integer* AsInteger() const override { return this; } + uint32_t width() const { return width_; } + bool IsSigned() const { return signed_; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + uint32_t width_; // bit width + bool signed_; // true if this integer is signed +}; + +class Float : public Type { + public: + Float(uint32_t w) : Type(kFloat), width_(w) {} + Float(const Float&) = default; + + std::string str() const override; + + Float* AsFloat() override { return this; } + const Float* AsFloat() const override { return this; } + uint32_t width() const { return width_; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + uint32_t width_; // bit width +}; + +class Vector : public Type { + public: + Vector(const Type* element_type, uint32_t count); + Vector(const Vector&) = default; + + std::string str() const override; + const Type* element_type() const { return element_type_; } + uint32_t element_count() const { return count_; } + + Vector* AsVector() override { return this; } + const Vector* AsVector() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* element_type_; + uint32_t count_; +}; + +class Matrix : public Type { + public: + Matrix(const Type* element_type, uint32_t count); + Matrix(const Matrix&) = default; + + std::string str() const override; + const Type* element_type() const { return element_type_; } + uint32_t element_count() const { return count_; } + + Matrix* AsMatrix() override { return this; } + const Matrix* AsMatrix() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* element_type_; + uint32_t count_; +}; + +class Image : public Type { + public: + Image(Type* type, spv::Dim dimen, uint32_t d, bool array, bool multisample, + uint32_t sampling, spv::ImageFormat f, + spv::AccessQualifier qualifier = spv::AccessQualifier::ReadOnly); + Image(const Image&) = default; + + std::string str() const override; + + Image* AsImage() override { return this; } + const Image* AsImage() const override { return this; } + + const Type* sampled_type() const { return sampled_type_; } + spv::Dim dim() const { return dim_; } + uint32_t depth() const { return depth_; } + bool is_arrayed() const { return arrayed_; } + bool is_multisampled() const { return ms_; } + uint32_t sampled() const { return sampled_; } + spv::ImageFormat format() const { return format_; } + spv::AccessQualifier access_qualifier() const { return access_qualifier_; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + Type* sampled_type_; + spv::Dim dim_; + uint32_t depth_; + bool arrayed_; + bool ms_; + uint32_t sampled_; + spv::ImageFormat format_; + spv::AccessQualifier access_qualifier_; +}; + +class SampledImage : public Type { + public: + SampledImage(Type* image) : Type(kSampledImage), image_type_(image) {} + SampledImage(const SampledImage&) = default; + + std::string str() const override; + + SampledImage* AsSampledImage() override { return this; } + const SampledImage* AsSampledImage() const override { return this; } + + const Type* image_type() const { return image_type_; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + Type* image_type_; +}; + +class Array : public Type { + public: + // Data about the length operand, that helps us distinguish between one + // array length and another. + struct LengthInfo { + // The result id of the instruction defining the length. + const uint32_t id; + enum Case : uint32_t { + kConstant = 0, + kConstantWithSpecId = 1, + kDefiningId = 2 + }; + // Extra words used to distinshish one array length and another. + // - if OpConstant, then it's 0, then the words in the literal constant + // value. + // - if OpSpecConstant, then it's 1, then the SpecID decoration if there + // is one, followed by the words in the literal constant value. + // The spec might not be overridden, in which case we'll end up using + // the literal value. + // - Otherwise, it's an OpSpecConsant, and this 2, then the ID (again). + const std::vector words; + }; + + // Constructs an array type with given element and length. If the length + // is an OpSpecConstant, then |spec_id| should be its SpecId decoration. + Array(const Type* element_type, const LengthInfo& length_info_arg); + Array(const Array&) = default; + + std::string str() const override; + const Type* element_type() const { return element_type_; } + uint32_t LengthId() const { return length_info_.id; } + const LengthInfo& length_info() const { return length_info_; } + + Array* AsArray() override { return this; } + const Array* AsArray() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + void ReplaceElementType(const Type* element_type); + LengthInfo GetConstantLengthInfo(uint32_t const_id, uint32_t length) const; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* element_type_; + const LengthInfo length_info_; +}; + +class RuntimeArray : public Type { + public: + RuntimeArray(const Type* element_type); + RuntimeArray(const RuntimeArray&) = default; + + std::string str() const override; + const Type* element_type() const { return element_type_; } + + RuntimeArray* AsRuntimeArray() override { return this; } + const RuntimeArray* AsRuntimeArray() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + void ReplaceElementType(const Type* element_type); + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* element_type_; +}; + +class Struct : public Type { + public: + Struct(const std::vector& element_types); + Struct(const Struct&) = default; + + // Adds a decoration to the member at the given index. The first word is the + // decoration enum, and the remaining words, if any, are its operands. + void AddMemberDecoration(uint32_t index, std::vector&& decoration); + + std::string str() const override; + const std::vector& element_types() const { + return element_types_; + } + std::vector& element_types() { return element_types_; } + bool decoration_empty() const override { + return decorations_.empty() && element_decorations_.empty(); + } + + const std::map>>& + element_decorations() const { + return element_decorations_; + } + + Struct* AsStruct() override { return this; } + const Struct* AsStruct() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + void ClearDecorations() override { + decorations_.clear(); + element_decorations_.clear(); + } + + std::vector element_types_; + // We can attach decorations to struct members and that should not affect the + // underlying element type. So we need an extra data structure here to keep + // track of element type decorations. They must be stored in an ordered map + // because |GetExtraHashWords| will traverse the structure. It must have a + // fixed order in order to hash to the same value every time. + std::map>> element_decorations_; +}; + +class Opaque : public Type { + public: + Opaque(std::string n) : Type(kOpaque), name_(std::move(n)) {} + Opaque(const Opaque&) = default; + + std::string str() const override; + + Opaque* AsOpaque() override { return this; } + const Opaque* AsOpaque() const override { return this; } + + const std::string& name() const { return name_; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + std::string name_; +}; + +class Pointer : public Type { + public: + Pointer(const Type* pointee, spv::StorageClass sc); + Pointer(const Pointer&) = default; + + std::string str() const override; + const Type* pointee_type() const { return pointee_type_; } + spv::StorageClass storage_class() const { return storage_class_; } + + Pointer* AsPointer() override { return this; } + const Pointer* AsPointer() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + void SetPointeeType(const Type* type); + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* pointee_type_; + spv::StorageClass storage_class_; +}; + +class Function : public Type { + public: + Function(const Type* ret_type, const std::vector& params); + Function(const Type* ret_type, std::vector& params); + Function(const Function&) = default; + + std::string str() const override; + + Function* AsFunction() override { return this; } + const Function* AsFunction() const override { return this; } + + const Type* return_type() const { return return_type_; } + const std::vector& param_types() const { return param_types_; } + std::vector& param_types() { return param_types_; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + void SetReturnType(const Type* type); + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* return_type_; + std::vector param_types_; +}; + +class Pipe : public Type { + public: + Pipe(spv::AccessQualifier qualifier) + : Type(kPipe), access_qualifier_(qualifier) {} + Pipe(const Pipe&) = default; + + std::string str() const override; + + Pipe* AsPipe() override { return this; } + const Pipe* AsPipe() const override { return this; } + + spv::AccessQualifier access_qualifier() const { return access_qualifier_; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + spv::AccessQualifier access_qualifier_; +}; + +class ForwardPointer : public Type { + public: + ForwardPointer(uint32_t id, spv::StorageClass sc) + : Type(kForwardPointer), + target_id_(id), + storage_class_(sc), + pointer_(nullptr) {} + ForwardPointer(const ForwardPointer&) = default; + + uint32_t target_id() const { return target_id_; } + void SetTargetPointer(const Pointer* pointer) { pointer_ = pointer; } + spv::StorageClass storage_class() const { return storage_class_; } + const Pointer* target_pointer() const { return pointer_; } + + std::string str() const override; + + ForwardPointer* AsForwardPointer() override { return this; } + const ForwardPointer* AsForwardPointer() const override { return this; } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + uint32_t target_id_; + spv::StorageClass storage_class_; + const Pointer* pointer_; +}; + +class CooperativeMatrixNV : public Type { + public: + CooperativeMatrixNV(const Type* type, const uint32_t scope, + const uint32_t rows, const uint32_t columns); + CooperativeMatrixNV(const CooperativeMatrixNV&) = default; + + std::string str() const override; + + CooperativeMatrixNV* AsCooperativeMatrixNV() override { return this; } + const CooperativeMatrixNV* AsCooperativeMatrixNV() const override { + return this; + } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + const Type* component_type() const { return component_type_; } + uint32_t scope_id() const { return scope_id_; } + uint32_t rows_id() const { return rows_id_; } + uint32_t columns_id() const { return columns_id_; } + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* component_type_; + const uint32_t scope_id_; + const uint32_t rows_id_; + const uint32_t columns_id_; +}; + +class CooperativeMatrixKHR : public Type { + public: + CooperativeMatrixKHR(const Type* type, const uint32_t scope, + const uint32_t rows, const uint32_t columns, + const uint32_t use); + CooperativeMatrixKHR(const CooperativeMatrixKHR&) = default; + + std::string str() const override; + + CooperativeMatrixKHR* AsCooperativeMatrixKHR() override { return this; } + const CooperativeMatrixKHR* AsCooperativeMatrixKHR() const override { + return this; + } + + size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; + + const Type* component_type() const { return component_type_; } + uint32_t scope_id() const { return scope_id_; } + uint32_t rows_id() const { return rows_id_; } + uint32_t columns_id() const { return columns_id_; } + uint32_t use_id() const { return use_id_; } + + private: + bool IsSameImpl(const Type* that, IsSameCache*) const override; + + const Type* component_type_; + const uint32_t scope_id_; + const uint32_t rows_id_; + const uint32_t columns_id_; + const uint32_t use_id_; +}; + +#define DefineParameterlessType(type, name) \ + class type : public Type { \ + public: \ + type() : Type(k##type) {} \ + type(const type&) = default; \ + \ + std::string str() const override { return #name; } \ + \ + type* As##type() override { return this; } \ + const type* As##type() const override { return this; } \ + \ + size_t ComputeExtraStateHash(size_t hash, SeenTypes*) const override { \ + return hash; \ + } \ + \ + private: \ + bool IsSameImpl(const Type* that, IsSameCache*) const override { \ + return that->As##type() && HasSameDecorations(that); \ + } \ + } +DefineParameterlessType(Void, void); +DefineParameterlessType(Bool, bool); +DefineParameterlessType(Sampler, sampler); +DefineParameterlessType(Event, event); +DefineParameterlessType(DeviceEvent, device_event); +DefineParameterlessType(ReserveId, reserve_id); +DefineParameterlessType(Queue, queue); +DefineParameterlessType(PipeStorage, pipe_storage); +DefineParameterlessType(NamedBarrier, named_barrier); +DefineParameterlessType(AccelerationStructureNV, accelerationStructureNV); +DefineParameterlessType(RayQueryKHR, rayQueryKHR); +DefineParameterlessType(HitObjectNV, hitObjectNV); +#undef DefineParameterlessType + +} // namespace analysis +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_TYPES_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/unify_const_pass.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/unify_const_pass.cpp new file mode 100644 index 000000000000..83dd438b63d8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/unify_const_pass.cpp @@ -0,0 +1,175 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/unify_const_pass.h" + +#include +#include +#include +#include + +#include "source/opt/def_use_manager.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace opt { +namespace { + +// The trie that stores a bunch of result ids and, for a given instruction, +// searches the result id that has been defined with the same opcode, type and +// operands. +class ResultIdTrie { + public: + ResultIdTrie() : root_(new Node) {} + + // For a given instruction, extracts its opcode, type id and operand words + // as an array of keys, looks up the trie to find a result id which is stored + // with the same opcode, type id and operand words. If none of such result id + // is found, creates a trie node with those keys, stores the instruction's + // result id and returns that result id. If an existing result id is found, + // returns the existing result id. + uint32_t LookupEquivalentResultFor(const Instruction& inst) { + auto keys = GetLookUpKeys(inst); + auto* node = root_.get(); + for (uint32_t key : keys) { + node = node->GetOrCreateTrieNodeFor(key); + } + if (node->result_id() == 0) { + node->SetResultId(inst.result_id()); + } + return node->result_id(); + } + + private: + // The trie node to store result ids. + class Node { + public: + using TrieNodeMap = std::unordered_map>; + + Node() : result_id_(0), next_() {} + uint32_t result_id() const { return result_id_; } + + // Sets the result id stored in this node. + void SetResultId(uint32_t id) { result_id_ = id; } + + // Searches for the child trie node with the given key. If the node is + // found, returns that node. Otherwise creates an empty child node with + // that key and returns that newly created node. + Node* GetOrCreateTrieNodeFor(uint32_t key) { + auto iter = next_.find(key); + if (iter == next_.end()) { + // insert a new node and return the node. + return next_.insert(std::make_pair(key, MakeUnique())) + .first->second.get(); + } + return iter->second.get(); + } + + private: + // The result id stored in this node. 0 means this node is empty. + uint32_t result_id_; + // The mapping from the keys to the child nodes of this node. + TrieNodeMap next_; + }; + + // Returns a vector of the opcode followed by the words in the raw SPIR-V + // instruction encoding but without the result id. + std::vector GetLookUpKeys(const Instruction& inst) { + std::vector keys; + // Need to use the opcode, otherwise there might be a conflict with the + // following case when 's binary value equals xx's id: + // OpSpecConstantOp tt yy zz + // OpSpecConstantComposite tt xx yy zz; + keys.push_back(static_cast(inst.opcode())); + for (const auto& operand : inst) { + if (operand.type == SPV_OPERAND_TYPE_RESULT_ID) continue; + keys.insert(keys.end(), operand.words.cbegin(), operand.words.cend()); + } + return keys; + } + + std::unique_ptr root_; // The root node of the trie. +}; +} // namespace + +Pass::Status UnifyConstantPass::Process() { + bool modified = false; + ResultIdTrie defined_constants; + + for (Instruction *next_instruction, + *inst = &*(context()->types_values_begin()); + inst; inst = next_instruction) { + next_instruction = inst->NextNode(); + + // Do not handle the instruction when there are decorations upon the result + // id. + if (get_def_use_mgr()->GetAnnotations(inst->result_id()).size() != 0) { + continue; + } + + // The overall algorithm is to store the result ids of all the eligible + // constants encountered so far in a trie. For a constant defining + // instruction under consideration, use its opcode, result type id and + // words in operands as an array of keys to lookup the trie. If a result id + // can be found for that array of keys, a constant with exactly the same + // value must has been defined before, the constant under processing + // should be replaced by the constant previously defined. If no such result + // id can be found for that array of keys, this must be the first time a + // constant with its value be defined, we then create a new trie node to + // store the result id with the keys. When replacing a duplicated constant + // with a previously defined constant, all the uses of the duplicated + // constant, which must be placed after the duplicated constant defining + // instruction, will be updated. This way, the descendants of the + // previously defined constant and the duplicated constant will both refer + // to the previously defined constant. So that the operand ids which are + // used in key arrays will be the ids of the unified constants, when + // processing is up to a descendant. This makes comparing the key array + // always valid for judging duplication. + switch (inst->opcode()) { + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: + case spv::Op::OpConstant: + case spv::Op::OpConstantNull: + case spv::Op::OpConstantSampler: + case spv::Op::OpConstantComposite: + // Only spec constants defined with OpSpecConstantOp and + // OpSpecConstantComposite should be processed in this pass. Spec + // constants defined with OpSpecConstant{|True|False} are decorated with + // 'SpecId' decoration and all of them should be treated as unique. + // 'SpecId' is not applicable to SpecConstants defined with + // OpSpecConstant{Op|Composite}, their values are not necessary to be + // unique. When all the operands/components are the same between two + // OpSpecConstant{Op|Composite} results, their result values must be the + // same so are unifiable. + case spv::Op::OpSpecConstantOp: + case spv::Op::OpSpecConstantComposite: { + uint32_t id = defined_constants.LookupEquivalentResultFor(*inst); + if (id != inst->result_id()) { + // The constant is a duplicated one, use the cached constant to + // replace the uses of this duplicated one, then turn it to nop. + context()->ReplaceAllUsesWith(inst->result_id(), id); + context()->KillInst(inst); + modified = true; + } + break; + } + default: + break; + } + } + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/unify_const_pass.h b/thirdparty/glslang/External/spirv-tools/source/opt/unify_const_pass.h new file mode 100644 index 000000000000..f2b7897ccd2a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/unify_const_pass.h @@ -0,0 +1,35 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_UNIFY_CONST_PASS_H_ +#define SOURCE_OPT_UNIFY_CONST_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class UnifyConstantPass : public Pass { + public: + const char* name() const override { return "unify-const"; } + Status Process() override; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_UNIFY_CONST_PASS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/upgrade_memory_model.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/upgrade_memory_model.cpp new file mode 100644 index 000000000000..1b439a6ef0cf --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/upgrade_memory_model.cpp @@ -0,0 +1,780 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "upgrade_memory_model.h" + +#include + +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/spirv_constant.h" +#include "source/util/make_unique.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace opt { + +Pass::Status UpgradeMemoryModel::Process() { + // TODO: This pass needs changes to support cooperative matrices. + if (context()->get_feature_mgr()->HasCapability( + spv::Capability::CooperativeMatrixNV)) { + return Pass::Status::SuccessWithoutChange; + } + + // Only update Logical GLSL450 to Logical VulkanKHR. + Instruction* memory_model = get_module()->GetMemoryModel(); + if (memory_model->GetSingleWordInOperand(0u) != + uint32_t(spv::AddressingModel::Logical) || + memory_model->GetSingleWordInOperand(1u) != + uint32_t(spv::MemoryModel::GLSL450)) { + return Pass::Status::SuccessWithoutChange; + } + + UpgradeMemoryModelInstruction(); + UpgradeInstructions(); + CleanupDecorations(); + UpgradeBarriers(); + UpgradeMemoryScope(); + + return Pass::Status::SuccessWithChange; +} + +void UpgradeMemoryModel::UpgradeMemoryModelInstruction() { + // Overall changes necessary: + // 1. Add the OpExtension. + // 2. Add the OpCapability. + // 3. Modify the memory model. + Instruction* memory_model = get_module()->GetMemoryModel(); + context()->AddCapability(MakeUnique( + context(), spv::Op::OpCapability, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_CAPABILITY, + {uint32_t(spv::Capability::VulkanMemoryModelKHR)}}})); + const std::string extension = "SPV_KHR_vulkan_memory_model"; + std::vector words = spvtools::utils::MakeVector(extension); + context()->AddExtension( + MakeUnique(context(), spv::Op::OpExtension, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_LITERAL_STRING, words}})); + memory_model->SetInOperand(1u, {uint32_t(spv::MemoryModel::VulkanKHR)}); +} + +void UpgradeMemoryModel::UpgradeInstructions() { + // Coherent and Volatile decorations are deprecated. Remove them and replace + // with flags on the memory/image operations. The decorations can occur on + // OpVariable, OpFunctionParameter (of pointer type) and OpStructType (member + // decoration). Trace from the decoration target(s) to the final memory/image + // instructions. Additionally, Workgroup storage class variables and function + // parameters are implicitly coherent in GLSL450. + + // Upgrade modf and frexp first since they generate new stores. + // In SPIR-V 1.4 or later, normalize OpCopyMemory* access operands. + for (auto& func : *get_module()) { + func.ForEachInst([this](Instruction* inst) { + if (inst->opcode() == spv::Op::OpExtInst) { + auto ext_inst = inst->GetSingleWordInOperand(1u); + if (ext_inst == GLSLstd450Modf || ext_inst == GLSLstd450Frexp) { + auto import = + get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0u)); + if (import->GetInOperand(0u).AsString() == "GLSL.std.450") { + UpgradeExtInst(inst); + } + } + } else if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + if (inst->opcode() == spv::Op::OpCopyMemory || + inst->opcode() == spv::Op::OpCopyMemorySized) { + uint32_t start_operand = + inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; + if (inst->NumInOperands() > start_operand) { + auto num_access_words = MemoryAccessNumWords( + inst->GetSingleWordInOperand(start_operand)); + if ((num_access_words + start_operand) == inst->NumInOperands()) { + // There is a single memory access operand. Duplicate it to have a + // separate operand for both source and target. + for (uint32_t i = 0; i < num_access_words; ++i) { + auto operand = inst->GetInOperand(start_operand + i); + inst->AddOperand(std::move(operand)); + } + } + } else { + // Add two memory access operands. + inst->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, + {uint32_t(spv::MemoryAccessMask::MaskNone)}}); + inst->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, + {uint32_t(spv::MemoryAccessMask::MaskNone)}}); + } + } + } + }); + } + + UpgradeMemoryAndImages(); + UpgradeAtomics(); +} + +void UpgradeMemoryModel::UpgradeMemoryAndImages() { + for (auto& func : *get_module()) { + func.ForEachInst([this](Instruction* inst) { + bool is_coherent = false; + bool is_volatile = false; + bool src_coherent = false; + bool src_volatile = false; + bool dst_coherent = false; + bool dst_volatile = false; + uint32_t start_operand = 0u; + spv::Scope scope = spv::Scope::QueueFamilyKHR; + spv::Scope src_scope = spv::Scope::QueueFamilyKHR; + spv::Scope dst_scope = spv::Scope::QueueFamilyKHR; + switch (inst->opcode()) { + case spv::Op::OpLoad: + case spv::Op::OpStore: + std::tie(is_coherent, is_volatile, scope) = + GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); + break; + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseRead: + case spv::Op::OpImageWrite: + std::tie(is_coherent, is_volatile, scope) = + GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); + break; + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + std::tie(dst_coherent, dst_volatile, dst_scope) = + GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); + std::tie(src_coherent, src_volatile, src_scope) = + GetInstructionAttributes(inst->GetSingleWordInOperand(1u)); + break; + default: + break; + } + + switch (inst->opcode()) { + case spv::Op::OpLoad: + UpgradeFlags(inst, 1u, is_coherent, is_volatile, kVisibility, + kMemory); + break; + case spv::Op::OpStore: + UpgradeFlags(inst, 2u, is_coherent, is_volatile, kAvailability, + kMemory); + break; + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + start_operand = inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; + if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // There are guaranteed to be two memory access operands at this + // point so treat source and target separately. + uint32_t num_access_words = MemoryAccessNumWords( + inst->GetSingleWordInOperand(start_operand)); + UpgradeFlags(inst, start_operand, dst_coherent, dst_volatile, + kAvailability, kMemory); + UpgradeFlags(inst, start_operand + num_access_words, src_coherent, + src_volatile, kVisibility, kMemory); + } else { + UpgradeFlags(inst, start_operand, dst_coherent, dst_volatile, + kAvailability, kMemory); + UpgradeFlags(inst, start_operand, src_coherent, src_volatile, + kVisibility, kMemory); + } + break; + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseRead: + UpgradeFlags(inst, 2u, is_coherent, is_volatile, kVisibility, kImage); + break; + case spv::Op::OpImageWrite: + UpgradeFlags(inst, 3u, is_coherent, is_volatile, kAvailability, + kImage); + break; + default: + break; + } + + // |is_coherent| is never used for the same instructions as + // |src_coherent| and |dst_coherent|. + if (is_coherent) { + inst->AddOperand( + {SPV_OPERAND_TYPE_SCOPE_ID, {GetScopeConstant(scope)}}); + } + if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // There are two memory access operands. The first is for the target and + // the second is for the source. + if (dst_coherent || src_coherent) { + start_operand = inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; + std::vector new_operands; + uint32_t num_access_words = + MemoryAccessNumWords(inst->GetSingleWordInOperand(start_operand)); + // The flags were already updated so subtract if we're adding a + // scope. + if (dst_coherent) --num_access_words; + for (uint32_t i = 0; i < start_operand + num_access_words; ++i) { + new_operands.push_back(inst->GetInOperand(i)); + } + // Add the target scope if necessary. + if (dst_coherent) { + new_operands.push_back( + {SPV_OPERAND_TYPE_SCOPE_ID, {GetScopeConstant(dst_scope)}}); + } + // Copy the remaining current operands. + for (uint32_t i = start_operand + num_access_words; + i < inst->NumInOperands(); ++i) { + new_operands.push_back(inst->GetInOperand(i)); + } + // Add the source scope if necessary. + if (src_coherent) { + new_operands.push_back( + {SPV_OPERAND_TYPE_SCOPE_ID, {GetScopeConstant(src_scope)}}); + } + inst->SetInOperands(std::move(new_operands)); + } + } else { + // According to SPV_KHR_vulkan_memory_model, if both available and + // visible flags are used the first scope operand is for availability + // (writes) and the second is for visibility (reads). + if (dst_coherent) { + inst->AddOperand( + {SPV_OPERAND_TYPE_SCOPE_ID, {GetScopeConstant(dst_scope)}}); + } + if (src_coherent) { + inst->AddOperand( + {SPV_OPERAND_TYPE_SCOPE_ID, {GetScopeConstant(src_scope)}}); + } + } + }); + } +} + +void UpgradeMemoryModel::UpgradeAtomics() { + for (auto& func : *get_module()) { + func.ForEachInst([this](Instruction* inst) { + if (spvOpcodeIsAtomicOp(inst->opcode())) { + bool unused_coherent = false; + bool is_volatile = false; + spv::Scope unused_scope = spv::Scope::QueueFamilyKHR; + std::tie(unused_coherent, is_volatile, unused_scope) = + GetInstructionAttributes(inst->GetSingleWordInOperand(0)); + + UpgradeSemantics(inst, 2u, is_volatile); + if (inst->opcode() == spv::Op::OpAtomicCompareExchange || + inst->opcode() == spv::Op::OpAtomicCompareExchangeWeak) { + UpgradeSemantics(inst, 3u, is_volatile); + } + } + }); + } +} + +void UpgradeMemoryModel::UpgradeSemantics(Instruction* inst, + uint32_t in_operand, + bool is_volatile) { + if (!is_volatile) return; + + uint32_t semantics_id = inst->GetSingleWordInOperand(in_operand); + const analysis::Constant* constant = + context()->get_constant_mgr()->FindDeclaredConstant(semantics_id); + const analysis::Integer* type = constant->type()->AsInteger(); + assert(type && type->width() == 32); + uint32_t value = 0; + if (type->IsSigned()) { + value = static_cast(constant->GetS32()); + } else { + value = constant->GetU32(); + } + + value |= uint32_t(spv::MemorySemanticsMask::Volatile); + auto new_constant = context()->get_constant_mgr()->GetConstant(type, {value}); + auto new_semantics = + context()->get_constant_mgr()->GetDefiningInstruction(new_constant); + inst->SetInOperand(in_operand, {new_semantics->result_id()}); +} + +std::tuple UpgradeMemoryModel::GetInstructionAttributes( + uint32_t id) { + // |id| is a pointer used in a memory/image instruction. Need to determine if + // that pointer points to volatile or coherent memory. Workgroup storage + // class is implicitly coherent and cannot be decorated with volatile, so + // short circuit that case. + Instruction* inst = context()->get_def_use_mgr()->GetDef(id); + analysis::Type* type = context()->get_type_mgr()->GetType(inst->type_id()); + if (type->AsPointer() && + type->AsPointer()->storage_class() == spv::StorageClass::Workgroup) { + return std::make_tuple(true, false, spv::Scope::Workgroup); + } + + bool is_coherent = false; + bool is_volatile = false; + std::unordered_set visited; + std::tie(is_coherent, is_volatile) = + TraceInstruction(context()->get_def_use_mgr()->GetDef(id), + std::vector(), &visited); + + return std::make_tuple(is_coherent, is_volatile, spv::Scope::QueueFamilyKHR); +} + +std::pair UpgradeMemoryModel::TraceInstruction( + Instruction* inst, std::vector indices, + std::unordered_set* visited) { + auto iter = cache_.find(std::make_pair(inst->result_id(), indices)); + if (iter != cache_.end()) { + return iter->second; + } + + if (!visited->insert(inst->result_id()).second) { + return std::make_pair(false, false); + } + + // Initialize the cache before |indices| is (potentially) modified. + auto& cached_result = cache_[std::make_pair(inst->result_id(), indices)]; + cached_result.first = false; + cached_result.second = false; + + bool is_coherent = false; + bool is_volatile = false; + switch (inst->opcode()) { + case spv::Op::OpVariable: + case spv::Op::OpFunctionParameter: + is_coherent |= HasDecoration(inst, 0, spv::Decoration::Coherent); + is_volatile |= HasDecoration(inst, 0, spv::Decoration::Volatile); + if (!is_coherent || !is_volatile) { + bool type_coherent = false; + bool type_volatile = false; + std::tie(type_coherent, type_volatile) = + CheckType(inst->type_id(), indices); + is_coherent |= type_coherent; + is_volatile |= type_volatile; + } + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + // Store indices in reverse order. + for (uint32_t i = inst->NumInOperands() - 1; i > 0; --i) { + indices.push_back(inst->GetSingleWordInOperand(i)); + } + break; + case spv::Op::OpPtrAccessChain: + // Store indices in reverse order. Skip the |Element| operand. + for (uint32_t i = inst->NumInOperands() - 1; i > 1; --i) { + indices.push_back(inst->GetSingleWordInOperand(i)); + } + break; + default: + break; + } + + // No point searching further. + if (is_coherent && is_volatile) { + cached_result.first = true; + cached_result.second = true; + return std::make_pair(true, true); + } + + // Variables and function parameters are sources. Continue searching until we + // reach them. + if (inst->opcode() != spv::Op::OpVariable && + inst->opcode() != spv::Op::OpFunctionParameter) { + inst->ForEachInId([this, &is_coherent, &is_volatile, &indices, + &visited](const uint32_t* id_ptr) { + Instruction* op_inst = context()->get_def_use_mgr()->GetDef(*id_ptr); + const analysis::Type* type = + context()->get_type_mgr()->GetType(op_inst->type_id()); + if (type && + (type->AsPointer() || type->AsImage() || type->AsSampledImage())) { + bool operand_coherent = false; + bool operand_volatile = false; + std::tie(operand_coherent, operand_volatile) = + TraceInstruction(op_inst, indices, visited); + is_coherent |= operand_coherent; + is_volatile |= operand_volatile; + } + }); + } + + cached_result.first = is_coherent; + cached_result.second = is_volatile; + return std::make_pair(is_coherent, is_volatile); +} + +std::pair UpgradeMemoryModel::CheckType( + uint32_t type_id, const std::vector& indices) { + bool is_coherent = false; + bool is_volatile = false; + Instruction* type_inst = context()->get_def_use_mgr()->GetDef(type_id); + assert(type_inst->opcode() == spv::Op::OpTypePointer); + Instruction* element_inst = context()->get_def_use_mgr()->GetDef( + type_inst->GetSingleWordInOperand(1u)); + for (int i = (int)indices.size() - 1; i >= 0; --i) { + if (is_coherent && is_volatile) break; + + if (element_inst->opcode() == spv::Op::OpTypePointer) { + element_inst = context()->get_def_use_mgr()->GetDef( + element_inst->GetSingleWordInOperand(1u)); + } else if (element_inst->opcode() == spv::Op::OpTypeStruct) { + uint32_t index = indices.at(i); + Instruction* index_inst = context()->get_def_use_mgr()->GetDef(index); + assert(index_inst->opcode() == spv::Op::OpConstant); + uint64_t value = GetIndexValue(index_inst); + is_coherent |= HasDecoration(element_inst, static_cast(value), + spv::Decoration::Coherent); + is_volatile |= HasDecoration(element_inst, static_cast(value), + spv::Decoration::Volatile); + element_inst = context()->get_def_use_mgr()->GetDef( + element_inst->GetSingleWordInOperand(static_cast(value))); + } else { + assert(spvOpcodeIsComposite(element_inst->opcode())); + element_inst = context()->get_def_use_mgr()->GetDef( + element_inst->GetSingleWordInOperand(0u)); + } + } + + if (!is_coherent || !is_volatile) { + bool remaining_coherent = false; + bool remaining_volatile = false; + std::tie(remaining_coherent, remaining_volatile) = + CheckAllTypes(element_inst); + is_coherent |= remaining_coherent; + is_volatile |= remaining_volatile; + } + + return std::make_pair(is_coherent, is_volatile); +} + +std::pair UpgradeMemoryModel::CheckAllTypes( + const Instruction* inst) { + std::unordered_set visited; + std::vector stack; + stack.push_back(inst); + + bool is_coherent = false; + bool is_volatile = false; + while (!stack.empty()) { + const Instruction* def = stack.back(); + stack.pop_back(); + + if (!visited.insert(def).second) continue; + + if (def->opcode() == spv::Op::OpTypeStruct) { + // Any member decorated with coherent and/or volatile is enough to have + // the related operation be flagged as coherent and/or volatile. + is_coherent |= HasDecoration(def, std::numeric_limits::max(), + spv::Decoration::Coherent); + is_volatile |= HasDecoration(def, std::numeric_limits::max(), + spv::Decoration::Volatile); + if (is_coherent && is_volatile) + return std::make_pair(is_coherent, is_volatile); + + // Check the subtypes. + for (uint32_t i = 0; i < def->NumInOperands(); ++i) { + stack.push_back(context()->get_def_use_mgr()->GetDef( + def->GetSingleWordInOperand(i))); + } + } else if (spvOpcodeIsComposite(def->opcode())) { + stack.push_back(context()->get_def_use_mgr()->GetDef( + def->GetSingleWordInOperand(0u))); + } else if (def->opcode() == spv::Op::OpTypePointer) { + stack.push_back(context()->get_def_use_mgr()->GetDef( + def->GetSingleWordInOperand(1u))); + } + } + + return std::make_pair(is_coherent, is_volatile); +} + +uint64_t UpgradeMemoryModel::GetIndexValue(Instruction* index_inst) { + const analysis::Constant* index_constant = + context()->get_constant_mgr()->GetConstantFromInst(index_inst); + assert(index_constant->AsIntConstant()); + if (index_constant->type()->AsInteger()->IsSigned()) { + if (index_constant->type()->AsInteger()->width() == 32) { + return index_constant->GetS32(); + } else { + return index_constant->GetS64(); + } + } else { + if (index_constant->type()->AsInteger()->width() == 32) { + return index_constant->GetU32(); + } else { + return index_constant->GetU64(); + } + } +} + +bool UpgradeMemoryModel::HasDecoration(const Instruction* inst, uint32_t value, + spv::Decoration decoration) { + // If the iteration was terminated early then an appropriate decoration was + // found. + return !context()->get_decoration_mgr()->WhileEachDecoration( + inst->result_id(), (uint32_t)decoration, [value](const Instruction& i) { + if (i.opcode() == spv::Op::OpDecorate || + i.opcode() == spv::Op::OpDecorateId) { + return false; + } else if (i.opcode() == spv::Op::OpMemberDecorate) { + if (value == i.GetSingleWordInOperand(1u) || + value == std::numeric_limits::max()) + return false; + } + + return true; + }); +} + +void UpgradeMemoryModel::UpgradeFlags(Instruction* inst, uint32_t in_operand, + bool is_coherent, bool is_volatile, + OperationType operation_type, + InstructionType inst_type) { + if (!is_coherent && !is_volatile) return; + + uint32_t flags = 0; + if (inst->NumInOperands() > in_operand) { + flags |= inst->GetSingleWordInOperand(in_operand); + } + if (is_coherent) { + if (inst_type == kMemory) { + flags |= uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR); + if (operation_type == kVisibility) { + flags |= uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR); + } else { + flags |= uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR); + } + } else { + flags |= uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR); + if (operation_type == kVisibility) { + flags |= uint32_t(spv::ImageOperandsMask::MakeTexelVisibleKHR); + } else { + flags |= uint32_t(spv::ImageOperandsMask::MakeTexelAvailableKHR); + } + } + } + + if (is_volatile) { + if (inst_type == kMemory) { + flags |= uint32_t(spv::MemoryAccessMask::Volatile); + } else { + flags |= uint32_t(spv::ImageOperandsMask::VolatileTexelKHR); + } + } + + if (inst->NumInOperands() > in_operand) { + inst->SetInOperand(in_operand, {flags}); + } else if (inst_type == kMemory) { + inst->AddOperand({SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, {flags}}); + } else { + inst->AddOperand({SPV_OPERAND_TYPE_OPTIONAL_IMAGE, {flags}}); + } +} + +uint32_t UpgradeMemoryModel::GetScopeConstant(spv::Scope scope) { + analysis::Integer int_ty(32, false); + uint32_t int_id = context()->get_type_mgr()->GetTypeInstruction(&int_ty); + const analysis::Constant* constant = + context()->get_constant_mgr()->GetConstant( + context()->get_type_mgr()->GetType(int_id), + {static_cast(scope)}); + return context() + ->get_constant_mgr() + ->GetDefiningInstruction(constant) + ->result_id(); +} + +void UpgradeMemoryModel::CleanupDecorations() { + // All of the volatile and coherent decorations have been dealt with, so now + // we can just remove them. + get_module()->ForEachInst([this](Instruction* inst) { + if (inst->result_id() != 0) { + context()->get_decoration_mgr()->RemoveDecorationsFrom( + inst->result_id(), [](const Instruction& dec) { + switch (dec.opcode()) { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + if (spv::Decoration(dec.GetSingleWordInOperand(1u)) == + spv::Decoration::Coherent || + spv::Decoration(dec.GetSingleWordInOperand(1u)) == + spv::Decoration::Volatile) + return true; + break; + case spv::Op::OpMemberDecorate: + if (spv::Decoration(dec.GetSingleWordInOperand(2u)) == + spv::Decoration::Coherent || + spv::Decoration(dec.GetSingleWordInOperand(2u)) == + spv::Decoration::Volatile) + return true; + break; + default: + break; + } + return false; + }); + } + }); +} + +void UpgradeMemoryModel::UpgradeBarriers() { + std::vector barriers; + // Collects all the control barriers in |function|. Returns true if the + // function operates on the Output storage class. + ProcessFunction CollectBarriers = [this, &barriers](Function* function) { + bool operates_on_output = false; + for (auto& block : *function) { + block.ForEachInst([this, &barriers, + &operates_on_output](Instruction* inst) { + if (inst->opcode() == spv::Op::OpControlBarrier) { + barriers.push_back(inst); + } else if (!operates_on_output) { + // This instruction operates on output storage class if it is a + // pointer to output type or any input operand is a pointer to output + // type. + analysis::Type* type = + context()->get_type_mgr()->GetType(inst->type_id()); + if (type && type->AsPointer() && + type->AsPointer()->storage_class() == spv::StorageClass::Output) { + operates_on_output = true; + return; + } + inst->ForEachInId([this, &operates_on_output](uint32_t* id_ptr) { + Instruction* op_inst = + context()->get_def_use_mgr()->GetDef(*id_ptr); + analysis::Type* op_type = + context()->get_type_mgr()->GetType(op_inst->type_id()); + if (op_type && op_type->AsPointer() && + op_type->AsPointer()->storage_class() == + spv::StorageClass::Output) + operates_on_output = true; + }); + } + }); + } + return operates_on_output; + }; + + std::queue roots; + for (auto& e : get_module()->entry_points()) + if (spv::ExecutionModel(e.GetSingleWordInOperand(0u)) == + spv::ExecutionModel::TessellationControl) { + roots.push(e.GetSingleWordInOperand(1u)); + if (context()->ProcessCallTreeFromRoots(CollectBarriers, &roots)) { + for (auto barrier : barriers) { + // Add OutputMemoryKHR to the semantics of the barriers. + uint32_t semantics_id = barrier->GetSingleWordInOperand(2u); + Instruction* semantics_inst = + context()->get_def_use_mgr()->GetDef(semantics_id); + analysis::Type* semantics_type = + context()->get_type_mgr()->GetType(semantics_inst->type_id()); + uint64_t semantics_value = GetIndexValue(semantics_inst); + const analysis::Constant* constant = + context()->get_constant_mgr()->GetConstant( + semantics_type, + {static_cast(semantics_value) | + uint32_t(spv::MemorySemanticsMask::OutputMemoryKHR)}); + barrier->SetInOperand(2u, {context() + ->get_constant_mgr() + ->GetDefiningInstruction(constant) + ->result_id()}); + } + } + barriers.clear(); + } +} + +void UpgradeMemoryModel::UpgradeMemoryScope() { + get_module()->ForEachInst([this](Instruction* inst) { + // Don't need to handle all the operations that take a scope. + // * Group operations can only be subgroup + // * Non-uniform can only be workgroup or subgroup + // * Named barriers are not supported by Vulkan + // * Workgroup ops (e.g. async_copy) have at most workgroup scope. + if (spvOpcodeIsAtomicOp(inst->opcode())) { + if (IsDeviceScope(inst->GetSingleWordInOperand(1))) { + inst->SetInOperand(1, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); + } + } else if (inst->opcode() == spv::Op::OpControlBarrier) { + if (IsDeviceScope(inst->GetSingleWordInOperand(1))) { + inst->SetInOperand(1, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); + } + } else if (inst->opcode() == spv::Op::OpMemoryBarrier) { + if (IsDeviceScope(inst->GetSingleWordInOperand(0))) { + inst->SetInOperand(0, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); + } + } + }); +} + +bool UpgradeMemoryModel::IsDeviceScope(uint32_t scope_id) { + const analysis::Constant* constant = + context()->get_constant_mgr()->FindDeclaredConstant(scope_id); + assert(constant && "Memory scope must be a constant"); + + const analysis::Integer* type = constant->type()->AsInteger(); + assert(type); + assert(type->width() == 32 || type->width() == 64); + if (type->width() == 32) { + if (type->IsSigned()) + return static_cast(constant->GetS32()) == spv::Scope::Device; + else + return static_cast(constant->GetU32()) == spv::Scope::Device; + } else { + if (type->IsSigned()) + return static_cast(constant->GetS64()) == spv::Scope::Device; + else + return static_cast(constant->GetU64()) == spv::Scope::Device; + } + + assert(false); + return false; +} + +void UpgradeMemoryModel::UpgradeExtInst(Instruction* ext_inst) { + const bool is_modf = ext_inst->GetSingleWordInOperand(1u) == GLSLstd450Modf; + auto ptr_id = ext_inst->GetSingleWordInOperand(3u); + auto ptr_type_id = get_def_use_mgr()->GetDef(ptr_id)->type_id(); + auto pointee_type_id = + get_def_use_mgr()->GetDef(ptr_type_id)->GetSingleWordInOperand(1u); + auto element_type_id = ext_inst->type_id(); + std::vector element_types(2); + element_types[0] = context()->get_type_mgr()->GetType(element_type_id); + element_types[1] = context()->get_type_mgr()->GetType(pointee_type_id); + analysis::Struct struct_type(element_types); + uint32_t struct_id = + context()->get_type_mgr()->GetTypeInstruction(&struct_type); + // Change the operation + GLSLstd450 new_op = is_modf ? GLSLstd450ModfStruct : GLSLstd450FrexpStruct; + ext_inst->SetOperand(3u, {static_cast(new_op)}); + // Remove the pointer argument + ext_inst->RemoveOperand(5u); + // Set the type id to the new struct. + ext_inst->SetResultType(struct_id); + + // The result is now a struct of the original result. The zero'th element is + // old result and should replace the old result. The one'th element needs to + // be stored via a new instruction. + auto where = ext_inst->NextNode(); + InstructionBuilder builder( + context(), where, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + auto extract_0 = + builder.AddCompositeExtract(element_type_id, ext_inst->result_id(), {0}); + context()->ReplaceAllUsesWith(ext_inst->result_id(), extract_0->result_id()); + // The extract's input was just changed to itself, so fix that. + extract_0->SetInOperand(0u, {ext_inst->result_id()}); + auto extract_1 = + builder.AddCompositeExtract(pointee_type_id, ext_inst->result_id(), {1}); + builder.AddStore(ptr_id, extract_1->result_id()); +} + +uint32_t UpgradeMemoryModel::MemoryAccessNumWords(uint32_t mask) { + uint32_t result = 1; + if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) ++result; + return result; +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/upgrade_memory_model.h b/thirdparty/glslang/External/spirv-tools/source/opt/upgrade_memory_model.h new file mode 100644 index 000000000000..489436b6df58 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/upgrade_memory_model.h @@ -0,0 +1,150 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBSPIRV_OPT_UPGRADE_MEMORY_MODEL_H_ +#define LIBSPIRV_OPT_UPGRADE_MEMORY_MODEL_H_ + +#include +#include + +#include "pass.h" + +namespace spvtools { +namespace opt { + +// Hashing functor for the memoized result store. +struct CacheHash { + size_t operator()( + const std::pair>& item) const { + std::u32string to_hash; + to_hash.push_back(item.first); + for (auto i : item.second) to_hash.push_back(i); + return std::hash()(to_hash); + } +}; + +// Upgrades the memory model from Logical GLSL450 to Logical VulkanKHR. +// +// This pass remove deprecated decorations (Volatile and Coherent) and replaces +// them with new flags on individual instructions. It adds the Output storage +// class semantic to control barriers in tessellation control shaders that have +// an access to Output memory. +class UpgradeMemoryModel : public Pass { + public: + const char* name() const override { return "upgrade-memory-model"; } + Status Process() override; + + private: + // Used to indicate whether the operation performs an availability or + // visibility operation. + enum OperationType { kVisibility, kAvailability }; + + // Used to indicate whether the instruction is a memory or image instruction. + enum InstructionType { kMemory, kImage }; + + // Modifies the OpMemoryModel to use VulkanKHR. Adds the Vulkan memory model + // capability and extension. + void UpgradeMemoryModelInstruction(); + + // Upgrades memory, image and atomic instructions. + // Memory and image instructions convert coherent and volatile decorations + // into flags on the instruction. + // Atomic memory semantics convert volatile decoration into flags on the + // instruction. + void UpgradeInstructions(); + + // Upgrades memory and image operands for instructions that have them. + void UpgradeMemoryAndImages(); + + // Adds the volatile memory semantic if necessary. + void UpgradeAtomics(); + + // Returns whether |id| is coherent and/or volatile. + std::tuple GetInstructionAttributes(uint32_t id); + + // Traces |inst| to determine if it is coherent and/or volatile. + // |indices| tracks the access chain indices seen so far. + std::pair TraceInstruction(Instruction* inst, + std::vector indices, + std::unordered_set* visited); + + // Return true if |inst| is decorated with |decoration|. + // If |inst| is decorated by member decorations then either |value| must + // match the index or |value| must be a maximum allowable value. The max + // value allows any element to match. + bool HasDecoration(const Instruction* inst, uint32_t value, + spv::Decoration decoration); + + // Returns whether |type_id| indexed via |indices| is coherent and/or + // volatile. + std::pair CheckType(uint32_t type_id, + const std::vector& indices); + + // Returns whether any type/element under |inst| is coherent and/or volatile. + std::pair CheckAllTypes(const Instruction* inst); + + // Modifies the flags of |inst| to include the new flags for the Vulkan + // memory model. |operation_type| indicates whether flags should use + // MakeVisible or MakeAvailable variants. |inst_type| indicates whether the + // Pointer or Texel variants of flags should be used. + void UpgradeFlags(Instruction* inst, uint32_t in_operand, bool is_coherent, + bool is_volatile, OperationType operation_type, + InstructionType inst_type); + + // Modifies the semantics at |in_operand| of |inst| to include the volatile + // bit if |is_volatile| is true. + void UpgradeSemantics(Instruction* inst, uint32_t in_operand, + bool is_volatile); + + // Returns the result id for a constant for |scope|. + uint32_t GetScopeConstant(spv::Scope scope); + + // Returns the value of |index_inst|. |index_inst| must be an OpConstant of + // integer type.g + uint64_t GetIndexValue(Instruction* index_inst); + + // Removes coherent and volatile decorations. + void CleanupDecorations(); + + // For all tessellation control entry points, if there is an operation on + // Output storage class, then all barriers are modified to include the + // OutputMemoryKHR semantic. + void UpgradeBarriers(); + + // If the Vulkan memory model is specified, device scope actually means + // device scope. The memory scope must be modified to be QueueFamilyKHR + // scope. + void UpgradeMemoryScope(); + + // Returns true if |scope_id| is spv::Scope::Device. + bool IsDeviceScope(uint32_t scope_id); + + // Upgrades GLSL.std.450 modf and frexp. Both instructions are replaced with + // their struct versions. New extracts and a store are added in order to + // facilitate adding memory model flags. + void UpgradeExtInst(Instruction* modf); + + // Returns the number of words taken up by a memory access argument and its + // implied operands. + uint32_t MemoryAccessNumWords(uint32_t mask); + + // Caches the result of TraceInstruction. For a given result id and set of + // indices, stores whether that combination is coherent and/or volatile. + std::unordered_map>, + std::pair, CacheHash> + cache_; +}; +} // namespace opt +} // namespace spvtools +#endif // LIBSPIRV_OPT_UPGRADE_MEMORY_MODEL_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/value_number_table.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/value_number_table.cpp new file mode 100644 index 000000000000..743dc52bb11c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/value_number_table.cpp @@ -0,0 +1,240 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/value_number_table.h" + +#include + +#include "source/opt/cfg.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +uint32_t ValueNumberTable::GetValueNumber(Instruction* inst) const { + assert(inst->result_id() != 0 && + "inst must have a result id to get a value number."); + + // Check if this instruction already has a value. + auto result_id_to_val = id_to_value_.find(inst->result_id()); + if (result_id_to_val != id_to_value_.end()) { + return result_id_to_val->second; + } + return 0; +} + +uint32_t ValueNumberTable::GetValueNumber(uint32_t id) const { + return GetValueNumber(context()->get_def_use_mgr()->GetDef(id)); +} + +uint32_t ValueNumberTable::AssignValueNumber(Instruction* inst) { + // If it already has a value return that. + uint32_t value = GetValueNumber(inst); + if (value != 0) { + return value; + } + + // If the instruction has other side effects, then it must + // have its own value number. + // OpSampledImage and OpImage must remain in the same basic block in which + // they are used, because of this we will assign each one it own value number. + if (!context()->IsCombinatorInstruction(inst) && + !inst->IsCommonDebugInstr()) { + value = TakeNextValueNumber(); + id_to_value_[inst->result_id()] = value; + return value; + } + + switch (inst->opcode()) { + case spv::Op::OpSampledImage: + case spv::Op::OpImage: + case spv::Op::OpVariable: + value = TakeNextValueNumber(); + id_to_value_[inst->result_id()] = value; + return value; + default: + break; + } + + // If it is a load from memory that can be modified, we have to assume the + // memory has been modified, so we give it a new value number. + // + // Note that this test will also handle volatile loads because they are not + // read only. However, if this is ever relaxed because we analyze stores, we + // will have to add a new case for volatile loads. + if (inst->IsLoad() && !inst->IsReadOnlyLoad()) { + value = TakeNextValueNumber(); + id_to_value_[inst->result_id()] = value; + return value; + } + + analysis::DecorationManager* dec_mgr = context()->get_decoration_mgr(); + + // When we copy an object, the value numbers should be the same. + if (inst->opcode() == spv::Op::OpCopyObject && + dec_mgr->HaveTheSameDecorations(inst->result_id(), + inst->GetSingleWordInOperand(0))) { + value = GetValueNumber(inst->GetSingleWordInOperand(0)); + if (value != 0) { + id_to_value_[inst->result_id()] = value; + return value; + } + } + + // Phi nodes are a type of copy. If all of the inputs have the same value + // number, then we can assign the result of the phi the same value number. + if (inst->opcode() == spv::Op::OpPhi && inst->NumInOperands() > 0 && + dec_mgr->HaveTheSameDecorations(inst->result_id(), + inst->GetSingleWordInOperand(0))) { + value = GetValueNumber(inst->GetSingleWordInOperand(0)); + if (value != 0) { + for (uint32_t op = 2; op < inst->NumInOperands(); op += 2) { + if (value != GetValueNumber(inst->GetSingleWordInOperand(op))) { + value = 0; + break; + } + } + if (value != 0) { + id_to_value_[inst->result_id()] = value; + return value; + } + } + } + + // Replace all of the operands by their value number. The sign bit will be + // set to distinguish between an id and a value number. + Instruction value_ins(context(), inst->opcode(), inst->type_id(), + inst->result_id(), {}); + for (uint32_t o = 0; o < inst->NumInOperands(); ++o) { + const Operand& op = inst->GetInOperand(o); + if (spvIsIdType(op.type)) { + uint32_t id_value = op.words[0]; + auto use_id_to_val = id_to_value_.find(id_value); + if (use_id_to_val != id_to_value_.end()) { + id_value = (1 << 31) | use_id_to_val->second; + } + value_ins.AddOperand(Operand(op.type, {id_value})); + } else { + value_ins.AddOperand(Operand(op.type, op.words)); + } + } + + // TODO: Implement a normal form for opcodes that commute like integer + // addition. This will let us know that a+b is the same value as b+a. + + // Otherwise, we check if this value has been computed before. + auto value_iterator = instruction_to_value_.find(value_ins); + if (value_iterator != instruction_to_value_.end()) { + value = id_to_value_[value_iterator->first.result_id()]; + id_to_value_[inst->result_id()] = value; + return value; + } + + // If not, assign it a new value number. + value = TakeNextValueNumber(); + id_to_value_[inst->result_id()] = value; + instruction_to_value_[value_ins] = value; + return value; +} + +void ValueNumberTable::BuildDominatorTreeValueNumberTable() { + // First value number the headers. + for (auto& inst : context()->annotations()) { + if (inst.result_id() != 0) { + AssignValueNumber(&inst); + } + } + + for (auto& inst : context()->capabilities()) { + if (inst.result_id() != 0) { + AssignValueNumber(&inst); + } + } + + for (auto& inst : context()->types_values()) { + if (inst.result_id() != 0) { + AssignValueNumber(&inst); + } + } + + for (auto& inst : context()->module()->ext_inst_imports()) { + if (inst.result_id() != 0) { + AssignValueNumber(&inst); + } + } + + for (auto& inst : context()->module()->ext_inst_debuginfo()) { + if (inst.result_id() != 0) { + AssignValueNumber(&inst); + } + } + + for (Function& func : *context()->module()) { + // For best results we want to traverse the code in reverse post order. + // This happens naturally because of the forward referencing rules. + for (BasicBlock& block : func) { + for (Instruction& inst : block) { + if (inst.result_id() != 0) { + AssignValueNumber(&inst); + } + } + } + } +} + +bool ComputeSameValue::operator()(const Instruction& lhs, + const Instruction& rhs) const { + if (lhs.result_id() == 0 || rhs.result_id() == 0) { + return false; + } + + if (lhs.opcode() != rhs.opcode()) { + return false; + } + + if (lhs.type_id() != rhs.type_id()) { + return false; + } + + if (lhs.NumInOperands() != rhs.NumInOperands()) { + return false; + } + + for (uint32_t i = 0; i < lhs.NumInOperands(); ++i) { + if (lhs.GetInOperand(i) != rhs.GetInOperand(i)) { + return false; + } + } + + return lhs.context()->get_decoration_mgr()->HaveTheSameDecorations( + lhs.result_id(), rhs.result_id()); +} + +std::size_t ValueTableHash::operator()(const Instruction& inst) const { + // We hash the opcode and in-operands, not the result, because we want + // instructions that are the same except for the result to hash to the + // same value. + std::u32string h; + h.push_back(uint32_t(inst.opcode())); + h.push_back(inst.type_id()); + for (uint32_t i = 0; i < inst.NumInOperands(); ++i) { + const auto& opnd = inst.GetInOperand(i); + for (uint32_t word : opnd.words) { + h.push_back(word); + } + } + return std::hash()(h); +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/value_number_table.h b/thirdparty/glslang/External/spirv-tools/source/opt/value_number_table.h new file mode 100644 index 000000000000..39129ffa3535 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/value_number_table.h @@ -0,0 +1,91 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_VALUE_NUMBER_TABLE_H_ +#define SOURCE_OPT_VALUE_NUMBER_TABLE_H_ + +#include +#include + +#include "source/opt/instruction.h" + +namespace spvtools { +namespace opt { + +class IRContext; + +// Returns true if the two instructions compute the same value. Used by the +// value number table to compare two instructions. +class ComputeSameValue { + public: + bool operator()(const Instruction& lhs, const Instruction& rhs) const; +}; + +// The hash function used in the value number table. +class ValueTableHash { + public: + std::size_t operator()(const Instruction& inst) const; +}; + +// This class implements the value number analysis. It is using a hash-based +// approach to value numbering. It is essentially doing dominator-tree value +// numbering described in +// +// Preston Briggs, Keith D. Cooper, and L. Taylor Simpson. 1997. Value +// numbering. Softw. Pract. Exper. 27, 6 (June 1997), 701-724. +// https://www.cs.rice.edu/~keith/Promo/CRPC-TR94517.pdf.gz +// +// The main difference is that because we do not perform redundancy elimination +// as we build the value number table, we do not have to deal with cleaning up +// the scope. +class ValueNumberTable { + public: + ValueNumberTable(IRContext* ctx) : context_(ctx), next_value_number_(1) { + BuildDominatorTreeValueNumberTable(); + } + + // Returns the value number of the value computed by |inst|. |inst| must have + // a result id that will hold the computed value. If no value number has been + // assigned to the result id, then the return value is 0. + uint32_t GetValueNumber(Instruction* inst) const; + + // Returns the value number of the value contain in |id|. Returns 0 if it + // has not been assigned a value number. + uint32_t GetValueNumber(uint32_t id) const; + + IRContext* context() const { return context_; } + + private: + // Assigns a value number to every result id in the module. + void BuildDominatorTreeValueNumberTable(); + + // Returns the new value number. + uint32_t TakeNextValueNumber() { return next_value_number_++; } + + // Assigns a new value number to the result of |inst| if it does not already + // have one. Return the value number for |inst|. |inst| must have a result + // id. + uint32_t AssignValueNumber(Instruction* inst); + + std::unordered_map + instruction_to_value_; + std::unordered_map id_to_value_; + IRContext* context_; + uint32_t next_value_number_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_VALUE_NUMBER_TABLE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/vector_dce.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/vector_dce.cpp new file mode 100644 index 000000000000..1e8d255dd95c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/vector_dce.cpp @@ -0,0 +1,431 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/vector_dce.h" + +#include + +namespace spvtools { +namespace opt { +namespace { +constexpr uint32_t kExtractCompositeIdInIdx = 0; +constexpr uint32_t kInsertObjectIdInIdx = 0; +constexpr uint32_t kInsertCompositeIdInIdx = 1; +} // namespace + +Pass::Status VectorDCE::Process() { + bool modified = false; + for (Function& function : *get_module()) { + modified |= VectorDCEFunction(&function); + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool VectorDCE::VectorDCEFunction(Function* function) { + LiveComponentMap live_components; + FindLiveComponents(function, &live_components); + return RewriteInstructions(function, live_components); +} + +void VectorDCE::FindLiveComponents(Function* function, + LiveComponentMap* live_components) { + std::vector work_list; + + // Prime the work list. We will assume that any instruction that does + // not result in a vector is live. + // + // Extending to structures and matrices is not as straight forward because of + // the nesting. We cannot simply us a bit vector to keep track of which + // components are live because of arbitrary nesting of structs. + function->ForEachInst( + [&work_list, this, live_components](Instruction* current_inst) { + if (current_inst->IsCommonDebugInstr()) { + return; + } + if (!HasVectorOrScalarResult(current_inst) || + !context()->IsCombinatorInstruction(current_inst)) { + MarkUsesAsLive(current_inst, all_components_live_, live_components, + &work_list); + } + }); + + // Process the work list propagating liveness. + for (uint32_t i = 0; i < work_list.size(); i++) { + WorkListItem current_item = work_list[i]; + Instruction* current_inst = current_item.instruction; + + switch (current_inst->opcode()) { + case spv::Op::OpCompositeExtract: + MarkExtractUseAsLive(current_inst, current_item.components, + live_components, &work_list); + break; + case spv::Op::OpCompositeInsert: + MarkInsertUsesAsLive(current_item, live_components, &work_list); + break; + case spv::Op::OpVectorShuffle: + MarkVectorShuffleUsesAsLive(current_item, live_components, &work_list); + break; + case spv::Op::OpCompositeConstruct: + MarkCompositeContructUsesAsLive(current_item, live_components, + &work_list); + break; + default: + if (current_inst->IsScalarizable()) { + MarkUsesAsLive(current_inst, current_item.components, live_components, + &work_list); + } else { + MarkUsesAsLive(current_inst, all_components_live_, live_components, + &work_list); + } + break; + } + } +} + +void VectorDCE::MarkExtractUseAsLive(const Instruction* current_inst, + const utils::BitVector& live_elements, + LiveComponentMap* live_components, + std::vector* work_list) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + uint32_t operand_id = + current_inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); + Instruction* operand_inst = def_use_mgr->GetDef(operand_id); + + if (HasVectorOrScalarResult(operand_inst)) { + WorkListItem new_item; + new_item.instruction = operand_inst; + if (current_inst->NumInOperands() < 2) { + new_item.components = live_elements; + } else { + uint32_t element_index = current_inst->GetSingleWordInOperand(1); + uint32_t item_size = GetVectorComponentCount(operand_inst->type_id()); + if (element_index < item_size) { + new_item.components.Set(element_index); + } + } + AddItemToWorkListIfNeeded(new_item, live_components, work_list); + } +} + +void VectorDCE::MarkInsertUsesAsLive( + const VectorDCE::WorkListItem& current_item, + LiveComponentMap* live_components, + std::vector* work_list) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + + if (current_item.instruction->NumInOperands() > 2) { + uint32_t insert_position = + current_item.instruction->GetSingleWordInOperand(2); + + // Add the elements of the composite object that are used. + uint32_t operand_id = current_item.instruction->GetSingleWordInOperand( + kInsertCompositeIdInIdx); + Instruction* operand_inst = def_use_mgr->GetDef(operand_id); + + WorkListItem new_item; + new_item.instruction = operand_inst; + new_item.components = current_item.components; + new_item.components.Clear(insert_position); + + AddItemToWorkListIfNeeded(new_item, live_components, work_list); + + // Add the element being inserted if it is used. + if (current_item.components.Get(insert_position)) { + uint32_t obj_operand_id = + current_item.instruction->GetSingleWordInOperand( + kInsertObjectIdInIdx); + Instruction* obj_operand_inst = def_use_mgr->GetDef(obj_operand_id); + WorkListItem new_item_for_obj; + new_item_for_obj.instruction = obj_operand_inst; + new_item_for_obj.components.Set(0); + AddItemToWorkListIfNeeded(new_item_for_obj, live_components, work_list); + } + } else { + // If there are no indices, then this is a copy of the object being + // inserted. + uint32_t object_id = + current_item.instruction->GetSingleWordInOperand(kInsertObjectIdInIdx); + Instruction* object_inst = def_use_mgr->GetDef(object_id); + + WorkListItem new_item; + new_item.instruction = object_inst; + new_item.components = current_item.components; + AddItemToWorkListIfNeeded(new_item, live_components, work_list); + } +} + +void VectorDCE::MarkVectorShuffleUsesAsLive( + const WorkListItem& current_item, + VectorDCE::LiveComponentMap* live_components, + std::vector* work_list) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + + WorkListItem first_operand; + first_operand.instruction = + def_use_mgr->GetDef(current_item.instruction->GetSingleWordInOperand(0)); + WorkListItem second_operand; + second_operand.instruction = + def_use_mgr->GetDef(current_item.instruction->GetSingleWordInOperand(1)); + + uint32_t size_of_first_operand = + GetVectorComponentCount(first_operand.instruction->type_id()); + uint32_t size_of_second_operand = + GetVectorComponentCount(second_operand.instruction->type_id()); + + for (uint32_t in_op = 2; in_op < current_item.instruction->NumInOperands(); + ++in_op) { + uint32_t index = current_item.instruction->GetSingleWordInOperand(in_op); + if (current_item.components.Get(in_op - 2)) { + if (index < size_of_first_operand) { + first_operand.components.Set(index); + } else if (index - size_of_first_operand < size_of_second_operand) { + second_operand.components.Set(index - size_of_first_operand); + } + } + } + + AddItemToWorkListIfNeeded(first_operand, live_components, work_list); + AddItemToWorkListIfNeeded(second_operand, live_components, work_list); +} + +void VectorDCE::MarkCompositeContructUsesAsLive( + VectorDCE::WorkListItem work_item, + VectorDCE::LiveComponentMap* live_components, + std::vector* work_list) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + + uint32_t current_component = 0; + Instruction* current_inst = work_item.instruction; + uint32_t num_in_operands = current_inst->NumInOperands(); + for (uint32_t i = 0; i < num_in_operands; ++i) { + uint32_t id = current_inst->GetSingleWordInOperand(i); + Instruction* op_inst = def_use_mgr->GetDef(id); + + if (HasScalarResult(op_inst)) { + WorkListItem new_work_item; + new_work_item.instruction = op_inst; + if (work_item.components.Get(current_component)) { + new_work_item.components.Set(0); + } + AddItemToWorkListIfNeeded(new_work_item, live_components, work_list); + current_component++; + } else { + assert(HasVectorResult(op_inst)); + WorkListItem new_work_item; + new_work_item.instruction = op_inst; + uint32_t op_vector_size = GetVectorComponentCount(op_inst->type_id()); + + for (uint32_t op_vector_idx = 0; op_vector_idx < op_vector_size; + op_vector_idx++, current_component++) { + if (work_item.components.Get(current_component)) { + new_work_item.components.Set(op_vector_idx); + } + } + AddItemToWorkListIfNeeded(new_work_item, live_components, work_list); + } + } +} + +void VectorDCE::MarkUsesAsLive( + Instruction* current_inst, const utils::BitVector& live_elements, + LiveComponentMap* live_components, + std::vector* work_list) { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + + current_inst->ForEachInId([&work_list, &live_elements, this, live_components, + def_use_mgr](uint32_t* operand_id) { + Instruction* operand_inst = def_use_mgr->GetDef(*operand_id); + + if (HasVectorResult(operand_inst)) { + WorkListItem new_item; + new_item.instruction = operand_inst; + new_item.components = live_elements; + AddItemToWorkListIfNeeded(new_item, live_components, work_list); + } else if (HasScalarResult(operand_inst)) { + WorkListItem new_item; + new_item.instruction = operand_inst; + new_item.components.Set(0); + AddItemToWorkListIfNeeded(new_item, live_components, work_list); + } + }); +} + +bool VectorDCE::HasVectorOrScalarResult(const Instruction* inst) const { + return HasScalarResult(inst) || HasVectorResult(inst); +} + +bool VectorDCE::HasVectorResult(const Instruction* inst) const { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + if (inst->type_id() == 0) { + return false; + } + + const analysis::Type* current_type = type_mgr->GetType(inst->type_id()); + switch (current_type->kind()) { + case analysis::Type::kVector: + return true; + default: + return false; + } +} + +bool VectorDCE::HasScalarResult(const Instruction* inst) const { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + if (inst->type_id() == 0) { + return false; + } + + const analysis::Type* current_type = type_mgr->GetType(inst->type_id()); + switch (current_type->kind()) { + case analysis::Type::kBool: + case analysis::Type::kInteger: + case analysis::Type::kFloat: + return true; + default: + return false; + } +} + +uint32_t VectorDCE::GetVectorComponentCount(uint32_t type_id) { + assert(type_id != 0 && + "Trying to get the vector element count, but the type id is 0"); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + const analysis::Type* type = type_mgr->GetType(type_id); + const analysis::Vector* vector_type = type->AsVector(); + assert( + vector_type && + "Trying to get the vector element count, but the type is not a vector"); + return vector_type->element_count(); +} + +bool VectorDCE::RewriteInstructions( + Function* function, const VectorDCE::LiveComponentMap& live_components) { + bool modified = false; + + // Kill DebugValue in the middle of the instruction iteration will result + // in accessing a dangling pointer. We keep dead DebugValue instructions + // in |dead_dbg_value| to kill them once after the iteration. + std::vector dead_dbg_value; + + function->ForEachInst([&modified, this, live_components, + &dead_dbg_value](Instruction* current_inst) { + if (!context()->IsCombinatorInstruction(current_inst)) { + return; + } + + auto live_component = live_components.find(current_inst->result_id()); + if (live_component == live_components.end()) { + // If this instruction is not in live_components then it does not + // produce a vector, or it is never referenced and ADCE will remove + // it. No point in trying to differentiate. + return; + } + + // If no element in the current instruction is used replace it with an + // OpUndef. + if (live_component->second.Empty()) { + modified = true; + MarkDebugValueUsesAsDead(current_inst, &dead_dbg_value); + uint32_t undef_id = this->Type2Undef(current_inst->type_id()); + context()->KillNamesAndDecorates(current_inst); + context()->ReplaceAllUsesWith(current_inst->result_id(), undef_id); + context()->KillInst(current_inst); + return; + } + + switch (current_inst->opcode()) { + case spv::Op::OpCompositeInsert: + modified |= RewriteInsertInstruction( + current_inst, live_component->second, &dead_dbg_value); + break; + case spv::Op::OpCompositeConstruct: + // TODO: The members that are not live can be replaced by an undef + // or constant. This will remove uses of those values, and possibly + // create opportunities for ADCE. + break; + default: + // Do nothing. + break; + } + }); + for (auto* i : dead_dbg_value) context()->KillInst(i); + return modified; +} + +bool VectorDCE::RewriteInsertInstruction( + Instruction* current_inst, const utils::BitVector& live_components, + std::vector* dead_dbg_value) { + // If the value being inserted is not live, then we can skip the insert. + + if (current_inst->NumInOperands() == 2) { + // If there are no indices, then this is the same as a copy. + context()->KillNamesAndDecorates(current_inst->result_id()); + uint32_t object_id = + current_inst->GetSingleWordInOperand(kInsertObjectIdInIdx); + context()->ReplaceAllUsesWith(current_inst->result_id(), object_id); + return true; + } + + uint32_t insert_index = current_inst->GetSingleWordInOperand(2); + if (!live_components.Get(insert_index)) { + MarkDebugValueUsesAsDead(current_inst, dead_dbg_value); + context()->KillNamesAndDecorates(current_inst->result_id()); + uint32_t composite_id = + current_inst->GetSingleWordInOperand(kInsertCompositeIdInIdx); + context()->ReplaceAllUsesWith(current_inst->result_id(), composite_id); + return true; + } + + // If the values already in the composite are not used, then replace it with + // an undef. + utils::BitVector temp = live_components; + temp.Clear(insert_index); + if (temp.Empty()) { + context()->ForgetUses(current_inst); + uint32_t undef_id = Type2Undef(current_inst->type_id()); + current_inst->SetInOperand(kInsertCompositeIdInIdx, {undef_id}); + context()->AnalyzeUses(current_inst); + return true; + } + + return false; +} + +void VectorDCE::MarkDebugValueUsesAsDead( + Instruction* composite, std::vector* dead_dbg_value) { + context()->get_def_use_mgr()->ForEachUser( + composite, [&dead_dbg_value](Instruction* use) { + if (use->GetCommonDebugOpcode() == CommonDebugInfoDebugValue) + dead_dbg_value->push_back(use); + }); +} + +void VectorDCE::AddItemToWorkListIfNeeded( + WorkListItem work_item, VectorDCE::LiveComponentMap* live_components, + std::vector* work_list) { + Instruction* current_inst = work_item.instruction; + auto it = live_components->find(current_inst->result_id()); + if (it == live_components->end()) { + live_components->emplace( + std::make_pair(current_inst->result_id(), work_item.components)); + work_list->emplace_back(work_item); + } else { + if (it->second.Or(work_item.components)) { + work_list->emplace_back(work_item); + } + } +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/vector_dce.h b/thirdparty/glslang/External/spirv-tools/source/opt/vector_dce.h new file mode 100644 index 000000000000..a55bda692c6f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/vector_dce.h @@ -0,0 +1,160 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_VECTOR_DCE_H_ +#define SOURCE_OPT_VECTOR_DCE_H_ + +#include +#include + +#include "source/opt/mem_pass.h" +#include "source/util/bit_vector.h" + +namespace spvtools { +namespace opt { + +class VectorDCE : public MemPass { + private: + using LiveComponentMap = std::unordered_map; + + // According to the SPEC the maximum size for a vector is 16. See the data + // rules in the universal validation rules (section 2.16.1). + enum { kMaxVectorSize = 16 }; + + struct WorkListItem { + WorkListItem() : instruction(nullptr), components(kMaxVectorSize) {} + + Instruction* instruction; + utils::BitVector components; + }; + + public: + VectorDCE() : all_components_live_(kMaxVectorSize) { + for (uint32_t i = 0; i < kMaxVectorSize; i++) { + all_components_live_.Set(i); + } + } + + const char* name() const override { return "vector-dce"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | IRContext::kAnalysisCFG | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisDecorations | + IRContext::kAnalysisDominatorAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Runs the vector dce pass on |function|. Returns true if |function| was + // modified. + bool VectorDCEFunction(Function* function); + + // Identifies the live components of the vectors that are results of + // instructions in |function|. The results are stored in |live_components|. + void FindLiveComponents(Function* function, + LiveComponentMap* live_components); + + // Rewrites instructions in |function| that are dead or partially dead. If an + // instruction does not have an entry in |live_components|, then it is not + // changed. Returns true if |function| was modified. + bool RewriteInstructions(Function* function, + const LiveComponentMap& live_components); + + // Makes all DebugValue instructions that use |composite| for their values as + // dead instructions by putting them into |dead_dbg_value|. + void MarkDebugValueUsesAsDead(Instruction* composite, + std::vector* dead_dbg_value); + + // Rewrites the OpCompositeInsert instruction |current_inst| to avoid + // unnecessary computes given that the only components of the result that are + // live are |live_components|. + // + // If the value being inserted is not live, then the result of |current_inst| + // is replaced by the composite input to |current_inst|. + // + // If the composite input to |current_inst| is not live, then it is replaced + // by and OpUndef in |current_inst|. + bool RewriteInsertInstruction(Instruction* current_inst, + const utils::BitVector& live_components, + std::vector* dead_dbg_value); + + // Returns true if the result of |inst| is a vector or a scalar. + bool HasVectorOrScalarResult(const Instruction* inst) const; + + // Returns true if the result of |inst| is a vector. + bool HasVectorResult(const Instruction* inst) const; + + // Returns true if the result of |inst| is a scalar. + bool HasScalarResult(const Instruction* inst) const; + + // Returns the number of elements in the vector type with id |type_id|. + uint32_t GetVectorComponentCount(uint32_t type_id); + + // Adds |work_item| to |work_list| if it is not already live according to + // |live_components|. |live_components| is updated to indicate that + // |work_item| is now live. + void AddItemToWorkListIfNeeded(WorkListItem work_item, + LiveComponentMap* live_components, + std::vector* work_list); + + // Marks the components |live_elements| of the uses in |current_inst| as live + // according to |live_components|. If they were not live before, then they are + // added to |work_list|. + void MarkUsesAsLive(Instruction* current_inst, + const utils::BitVector& live_elements, + LiveComponentMap* live_components, + std::vector* work_list); + + // Marks the uses in the OpVectorShuffle instruction in |current_item| as live + // based on the live components in |current_item|. If anything becomes live + // they are added to |work_list| and |live_components| is updated + // accordingly. + void MarkVectorShuffleUsesAsLive(const WorkListItem& current_item, + VectorDCE::LiveComponentMap* live_components, + std::vector* work_list); + + // Marks the uses in the OpCompositeInsert instruction in |current_item| as + // live based on the live components in |current_item|. If anything becomes + // live they are added to |work_list| and |live_components| is updated + // accordingly. + void MarkInsertUsesAsLive(const WorkListItem& current_item, + LiveComponentMap* live_components, + std::vector* work_list); + + // Marks the uses in the OpCompositeExtract instruction |current_inst| as + // live. If anything becomes live they are added to |work_list| and + // |live_components| is updated accordingly. + void MarkExtractUseAsLive(const Instruction* current_inst, + const utils::BitVector& live_elements, + LiveComponentMap* live_components, + std::vector* work_list); + + // Marks the uses in the OpCompositeConstruct instruction |current_inst| as + // live. If anything becomes live they are added to |work_list| and + // |live_components| is updated accordingly. + void MarkCompositeContructUsesAsLive(WorkListItem work_item, + LiveComponentMap* live_components, + std::vector* work_list); + + // A BitVector that can always be used to say that all components of a vector + // are live. + utils::BitVector all_components_live_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_VECTOR_DCE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/workaround1209.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/workaround1209.cpp new file mode 100644 index 000000000000..0cf954afd0c0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/workaround1209.cpp @@ -0,0 +1,69 @@ +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/workaround1209.h" + +#include +#include +#include +#include + +namespace spvtools { +namespace opt { + +Pass::Status Workaround1209::Process() { + bool modified = false; + modified = RemoveOpUnreachableInLoops(); + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool Workaround1209::RemoveOpUnreachableInLoops() { + bool modified = false; + for (auto& func : *get_module()) { + std::list structured_order; + cfg()->ComputeStructuredOrder(&func, &*func.begin(), &structured_order); + + // Keep track of the loop merges. The top of the stack will always be the + // loop merge for the loop that immediately contains the basic block being + // processed. + std::stack loop_merges; + for (BasicBlock* bb : structured_order) { + if (!loop_merges.empty() && bb->id() == loop_merges.top()) { + loop_merges.pop(); + } + + if (bb->tail()->opcode() == spv::Op::OpUnreachable) { + if (!loop_merges.empty()) { + // We found an OpUnreachable inside a loop. + // Replace it with an unconditional branch to the loop merge. + context()->KillInst(&*bb->tail()); + std::unique_ptr new_branch( + new Instruction(context(), spv::Op::OpBranch, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {loop_merges.top()}}})); + context()->AnalyzeDefUse(&*new_branch); + bb->AddInstruction(std::move(new_branch)); + modified = true; + } + } else { + if (bb->GetLoopMergeInst()) { + loop_merges.push(bb->MergeBlockIdIfAny()); + } + } + } + } + return modified; +} +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/workaround1209.h b/thirdparty/glslang/External/spirv-tools/source/opt/workaround1209.h new file mode 100644 index 000000000000..9a1f88d93cad --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/workaround1209.h @@ -0,0 +1,41 @@ +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_WORKAROUND1209_H_ +#define SOURCE_OPT_WORKAROUND1209_H_ + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// See optimizer.hpp for documentation. +class Workaround1209 : public Pass { + public: + const char* name() const override { return "workaround-1209"; } + Status Process() override; + + private: + // There is at least one driver where an OpUnreachable found in a loop is not + // handled correctly. Workaround that by changing the OpUnreachable into a + // branch to the loop merge. + // + // Returns true if the code changed. + bool RemoveOpUnreachableInLoops(); +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_WORKAROUND1209_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/wrap_opkill.cpp b/thirdparty/glslang/External/spirv-tools/source/opt/wrap_opkill.cpp new file mode 100644 index 000000000000..c0c6d6221b77 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/wrap_opkill.cpp @@ -0,0 +1,201 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/wrap_opkill.h" + +#include "ir_builder.h" + +namespace spvtools { +namespace opt { + +Pass::Status WrapOpKill::Process() { + bool modified = false; + + auto func_to_process = + context()->GetStructuredCFGAnalysis()->FindFuncsCalledFromContinue(); + for (uint32_t func_id : func_to_process) { + Function* func = context()->GetFunction(func_id); + bool successful = func->WhileEachInst([this, &modified](Instruction* inst) { + const auto opcode = inst->opcode(); + if ((opcode == spv::Op::OpKill) || + (opcode == spv::Op::OpTerminateInvocation)) { + modified = true; + if (!ReplaceWithFunctionCall(inst)) { + return false; + } + } + return true; + }); + + if (!successful) { + return Status::Failure; + } + } + + if (opkill_function_ != nullptr) { + assert(modified && + "The function should only be generated if something was modified."); + context()->AddFunction(std::move(opkill_function_)); + } + if (opterminateinvocation_function_ != nullptr) { + assert(modified && + "The function should only be generated if something was modified."); + context()->AddFunction(std::move(opterminateinvocation_function_)); + } + return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); +} + +bool WrapOpKill::ReplaceWithFunctionCall(Instruction* inst) { + assert((inst->opcode() == spv::Op::OpKill || + inst->opcode() == spv::Op::OpTerminateInvocation) && + "|inst| must be an OpKill or OpTerminateInvocation instruction."); + InstructionBuilder ir_builder( + context(), inst, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + uint32_t func_id = GetKillingFuncId(inst->opcode()); + if (func_id == 0) { + return false; + } + Instruction* call_inst = + ir_builder.AddFunctionCall(GetVoidTypeId(), func_id, {}); + if (call_inst == nullptr) { + return false; + } + call_inst->UpdateDebugInfoFrom(inst); + + Instruction* return_inst = nullptr; + uint32_t return_type_id = GetOwningFunctionsReturnType(inst); + if (return_type_id != GetVoidTypeId()) { + Instruction* undef = + ir_builder.AddNullaryOp(return_type_id, spv::Op::OpUndef); + if (undef == nullptr) { + return false; + } + return_inst = + ir_builder.AddUnaryOp(0, spv::Op::OpReturnValue, undef->result_id()); + } else { + return_inst = ir_builder.AddNullaryOp(0, spv::Op::OpReturn); + } + + if (return_inst == nullptr) { + return false; + } + + context()->KillInst(inst); + return true; +} + +uint32_t WrapOpKill::GetVoidTypeId() { + if (void_type_id_ != 0) { + return void_type_id_; + } + + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Void void_type; + void_type_id_ = type_mgr->GetTypeInstruction(&void_type); + return void_type_id_; +} + +uint32_t WrapOpKill::GetVoidFunctionTypeId() { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Void void_type; + const analysis::Type* registered_void_type = + type_mgr->GetRegisteredType(&void_type); + + analysis::Function func_type(registered_void_type, {}); + return type_mgr->GetTypeInstruction(&func_type); +} + +uint32_t WrapOpKill::GetKillingFuncId(spv::Op opcode) { + // Parameterize by opcode + assert(opcode == spv::Op::OpKill || opcode == spv::Op::OpTerminateInvocation); + + std::unique_ptr* const killing_func = + (opcode == spv::Op::OpKill) ? &opkill_function_ + : &opterminateinvocation_function_; + + if (*killing_func != nullptr) { + return (*killing_func)->result_id(); + } + + uint32_t killing_func_id = TakeNextId(); + if (killing_func_id == 0) { + return 0; + } + + uint32_t void_type_id = GetVoidTypeId(); + if (void_type_id == 0) { + return 0; + } + + // Generate the function start instruction + std::unique_ptr func_start(new Instruction( + context(), spv::Op::OpFunction, void_type_id, killing_func_id, {})); + func_start->AddOperand({SPV_OPERAND_TYPE_FUNCTION_CONTROL, {0}}); + func_start->AddOperand({SPV_OPERAND_TYPE_ID, {GetVoidFunctionTypeId()}}); + (*killing_func).reset(new Function(std::move(func_start))); + + // Generate the function end instruction + std::unique_ptr func_end( + new Instruction(context(), spv::Op::OpFunctionEnd, 0, 0, {})); + (*killing_func)->SetFunctionEnd(std::move(func_end)); + + // Create the one basic block for the function. + uint32_t lab_id = TakeNextId(); + if (lab_id == 0) { + return 0; + } + std::unique_ptr label_inst( + new Instruction(context(), spv::Op::OpLabel, 0, lab_id, {})); + std::unique_ptr bb(new BasicBlock(std::move(label_inst))); + + // Add the OpKill to the basic block + std::unique_ptr kill_inst( + new Instruction(context(), opcode, 0, 0, {})); + bb->AddInstruction(std::move(kill_inst)); + + // Add the bb to the function + (*killing_func)->AddBasicBlock(std::move(bb)); + + // Add the function to the module. + if (context()->AreAnalysesValid(IRContext::kAnalysisDefUse)) { + (*killing_func)->ForEachInst([this](Instruction* inst) { + context()->AnalyzeDefUse(inst); + }); + } + + if (context()->AreAnalysesValid(IRContext::kAnalysisInstrToBlockMapping)) { + for (BasicBlock& basic_block : *(*killing_func)) { + context()->set_instr_block(basic_block.GetLabelInst(), &basic_block); + for (Instruction& inst : basic_block) { + context()->set_instr_block(&inst, &basic_block); + } + } + } + + return (*killing_func)->result_id(); +} + +uint32_t WrapOpKill::GetOwningFunctionsReturnType(Instruction* inst) { + BasicBlock* bb = context()->get_instr_block(inst); + if (bb == nullptr) { + return 0; + } + + Function* func = bb->GetParent(); + return func->type_id(); +} + +} // namespace opt +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/opt/wrap_opkill.h b/thirdparty/glslang/External/spirv-tools/source/opt/wrap_opkill.h new file mode 100644 index 000000000000..c9eb88877d2c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/opt/wrap_opkill.h @@ -0,0 +1,80 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_WRAP_OPKILL_H_ +#define SOURCE_OPT_WRAP_OPKILL_H_ + +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// Documented in optimizer.hpp +class WrapOpKill : public Pass { + public: + WrapOpKill() : void_type_id_(0) {} + + const char* name() const override { return "wrap-opkill"; } + + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisDefUse | + IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisNameMap | IRContext::kAnalysisBuiltinVarId | + IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; + } + + private: + // Replaces the OpKill or OpTerminateInvocation instruction |inst| with a + // function call to a function that contains a single instruction, a clone of + // |inst|. An OpUnreachable instruction will be placed after the function + // call. Return true if successful. + bool ReplaceWithFunctionCall(Instruction* inst); + + // Returns the id of the void type. + uint32_t GetVoidTypeId(); + + // Returns the id of the function type for a void function with no parameters. + uint32_t GetVoidFunctionTypeId(); + + // Return the id of a function that has return type void, has no parameters, + // and contains a single instruction, which is |opcode|, either OpKill or + // OpTerminateInvocation. Returns 0 if the function could not be generated. + uint32_t GetKillingFuncId(spv::Op opcode); + + // Returns the id of the return type for the function that contains |inst|. + // Returns 0 if |inst| is not in a function. + uint32_t GetOwningFunctionsReturnType(Instruction* inst); + + // The id of the void type. If its value is 0, then the void type has not + // been found or created yet. + uint32_t void_type_id_; + + // The function that is a single instruction, which is an OpKill. The + // function has a void return type and takes no parameters. If the function is + // |nullptr|, then the function has not been generated. + std::unique_ptr opkill_function_; + // The function that is a single instruction, which is an + // OpTerminateInvocation. The function has a void return type and takes no + // parameters. If the function is |nullptr|, then the function has not been + // generated. + std::unique_ptr opterminateinvocation_function_; +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_WRAP_OPKILL_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/parsed_operand.cpp b/thirdparty/glslang/External/spirv-tools/source/parsed_operand.cpp new file mode 100644 index 000000000000..cc33f8ba2c05 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/parsed_operand.cpp @@ -0,0 +1,77 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains utility functions for spv_parsed_operand_t. + +#include "source/parsed_operand.h" + +#include +#include "source/util/hex_float.h" + +namespace spvtools { + +void EmitNumericLiteral(std::ostream* out, const spv_parsed_instruction_t& inst, + const spv_parsed_operand_t& operand) { + if (operand.type != SPV_OPERAND_TYPE_LITERAL_INTEGER && + operand.type != SPV_OPERAND_TYPE_LITERAL_FLOAT && + operand.type != SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER && + operand.type != SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER && + operand.type != SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER) + return; + if (operand.num_words < 1) return; + // TODO(dneto): Support more than 64-bits at a time. + if (operand.num_words > 2) return; + + const uint32_t word = inst.words[operand.offset]; + if (operand.num_words == 1) { + switch (operand.number_kind) { + case SPV_NUMBER_SIGNED_INT: + *out << int32_t(word); + break; + case SPV_NUMBER_UNSIGNED_INT: + *out << word; + break; + case SPV_NUMBER_FLOATING: + if (operand.number_bit_width == 16) { + *out << spvtools::utils::FloatProxy( + uint16_t(word & 0xFFFF)); + } else { + // Assume 32-bit floats. + *out << spvtools::utils::FloatProxy(word); + } + break; + default: + break; + } + } else if (operand.num_words == 2) { + // Multi-word numbers are presented with lower order words first. + uint64_t bits = + uint64_t(word) | (uint64_t(inst.words[operand.offset + 1]) << 32); + switch (operand.number_kind) { + case SPV_NUMBER_SIGNED_INT: + *out << int64_t(bits); + break; + case SPV_NUMBER_UNSIGNED_INT: + *out << bits; + break; + case SPV_NUMBER_FLOATING: + // Assume only 64-bit floats. + *out << spvtools::utils::FloatProxy(bits); + break; + default: + break; + } + } +} +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/parsed_operand.h b/thirdparty/glslang/External/spirv-tools/source/parsed_operand.h new file mode 100644 index 000000000000..bab861107759 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/parsed_operand.h @@ -0,0 +1,33 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_PARSED_OPERAND_H_ +#define SOURCE_PARSED_OPERAND_H_ + +#include + +#include "spirv-tools/libspirv.h" + +namespace spvtools { + +// Emits the numeric literal representation of the given instruction operand +// to the stream. The operand must be of numeric type. If integral it may +// be up to 64 bits wide. If floating point, then it must be 16, 32, or 64 +// bits wide. +void EmitNumericLiteral(std::ostream* out, const spv_parsed_instruction_t& inst, + const spv_parsed_operand_t& operand); + +} // namespace spvtools + +#endif // SOURCE_PARSED_OPERAND_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/pch_source.cpp b/thirdparty/glslang/External/spirv-tools/source/pch_source.cpp new file mode 100644 index 000000000000..032e29ec4fe1 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/pch_source.cpp @@ -0,0 +1,15 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "pch_source.h" diff --git a/thirdparty/glslang/External/spirv-tools/source/pch_source.h b/thirdparty/glslang/External/spirv-tools/source/pch_source.h new file mode 100644 index 000000000000..6695ba268b0c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/pch_source.h @@ -0,0 +1,15 @@ +// Copyright (c) 2018 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/validation_state.h" diff --git a/thirdparty/glslang/External/spirv-tools/source/print.cpp b/thirdparty/glslang/External/spirv-tools/source/print.cpp new file mode 100644 index 000000000000..f36812ef56e6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/print.cpp @@ -0,0 +1,127 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/print.h" + +#if defined(SPIRV_ANDROID) || defined(SPIRV_LINUX) || defined(SPIRV_MAC) || \ + defined(SPIRV_IOS) || defined(SPIRV_TVOS) || defined(SPIRV_FREEBSD) || \ + defined(SPIRV_OPENBSD) || defined(SPIRV_EMSCRIPTEN) || \ + defined(SPIRV_FUCHSIA) || defined(SPIRV_GNU) || defined(SPIRV_QNX) +namespace spvtools { + +clr::reset::operator const char*() { return "\x1b[0m"; } + +clr::grey::operator const char*() { return "\x1b[1;30m"; } + +clr::red::operator const char*() { return "\x1b[31m"; } + +clr::green::operator const char*() { return "\x1b[32m"; } + +clr::yellow::operator const char*() { return "\x1b[33m"; } + +clr::blue::operator const char*() { return "\x1b[34m"; } + +} // namespace spvtools +#elif defined(SPIRV_WINDOWS) +#include + +namespace spvtools { + +static void SetConsoleForegroundColorPrimary(HANDLE hConsole, WORD color) { + // Get screen buffer information from console handle + CONSOLE_SCREEN_BUFFER_INFO bufInfo; + GetConsoleScreenBufferInfo(hConsole, &bufInfo); + + // Get background color + color = WORD(color | (bufInfo.wAttributes & 0xfff0)); + + // Set foreground color + SetConsoleTextAttribute(hConsole, color); +} + +static void SetConsoleForegroundColor(WORD color) { + SetConsoleForegroundColorPrimary(GetStdHandle(STD_OUTPUT_HANDLE), color); + SetConsoleForegroundColorPrimary(GetStdHandle(STD_ERROR_HANDLE), color); +} + +clr::reset::operator const char*() { + if (isPrint) { + SetConsoleForegroundColor(0xf); + return ""; + } + return "\x1b[0m"; +} + +clr::grey::operator const char*() { + if (isPrint) { + SetConsoleForegroundColor(FOREGROUND_INTENSITY); + return ""; + } + return "\x1b[1;30m"; +} + +clr::red::operator const char*() { + if (isPrint) { + SetConsoleForegroundColor(FOREGROUND_RED); + return ""; + } + return "\x1b[31m"; +} + +clr::green::operator const char*() { + if (isPrint) { + SetConsoleForegroundColor(FOREGROUND_GREEN); + return ""; + } + return "\x1b[32m"; +} + +clr::yellow::operator const char*() { + if (isPrint) { + SetConsoleForegroundColor(FOREGROUND_RED | FOREGROUND_GREEN); + return ""; + } + return "\x1b[33m"; +} + +clr::blue::operator const char*() { + // Blue all by itself is hard to see against a black background (the + // default on command shell), or a medium blue background (the default + // on PowerShell). So increase its intensity. + + if (isPrint) { + SetConsoleForegroundColor(FOREGROUND_BLUE | FOREGROUND_INTENSITY); + return ""; + } + return "\x1b[94m"; +} + +} // namespace spvtools +#else +namespace spvtools { + +clr::reset::operator const char*() { return ""; } + +clr::grey::operator const char*() { return ""; } + +clr::red::operator const char*() { return ""; } + +clr::green::operator const char*() { return ""; } + +clr::yellow::operator const char*() { return ""; } + +clr::blue::operator const char*() { return ""; } + +} // namespace spvtools +#endif diff --git a/thirdparty/glslang/External/spirv-tools/source/print.h b/thirdparty/glslang/External/spirv-tools/source/print.h new file mode 100644 index 000000000000..f31ba38e70a5 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/print.h @@ -0,0 +1,75 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_PRINT_H_ +#define SOURCE_PRINT_H_ + +#include +#include + +namespace spvtools { + +// Wrapper for out stream selection. +class out_stream { + public: + out_stream() : pStream(nullptr) {} + explicit out_stream(std::stringstream& stream) : pStream(&stream) {} + + std::ostream& get() { + if (pStream) { + return *pStream; + } + return std::cout; + } + + private: + std::stringstream* pStream; +}; + +namespace clr { +// Resets console color. +struct reset { + operator const char*(); + bool isPrint; +}; +// Sets console color to grey. +struct grey { + operator const char*(); + bool isPrint; +}; +// Sets console color to red. +struct red { + operator const char*(); + bool isPrint; +}; +// Sets console color to green. +struct green { + operator const char*(); + bool isPrint; +}; +// Sets console color to yellow. +struct yellow { + operator const char*(); + bool isPrint; +}; +// Sets console color to blue. +struct blue { + operator const char*(); + bool isPrint; +}; +} // namespace clr + +} // namespace spvtools + +#endif // SOURCE_PRINT_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/software_version.cpp b/thirdparty/glslang/External/spirv-tools/source/software_version.cpp new file mode 100644 index 000000000000..b258ebe90d4c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/software_version.cpp @@ -0,0 +1,27 @@ +// Copyright (c) 2015-2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "spirv-tools/libspirv.h" + +namespace { + +const char* kBuildVersions[] = { +#include "build-version.inc" +}; + +} // anonymous namespace + +const char* spvSoftwareVersionString(void) { return kBuildVersions[0]; } + +const char* spvSoftwareVersionDetailsString(void) { return kBuildVersions[1]; } diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_constant.h b/thirdparty/glslang/External/spirv-tools/source/spirv_constant.h new file mode 100644 index 000000000000..8636806c5472 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_constant.h @@ -0,0 +1,101 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_SPIRV_CONSTANT_H_ +#define SOURCE_SPIRV_CONSTANT_H_ + +#include "source/latest_version_spirv_header.h" +#include "spirv-tools/libspirv.h" + +// Version number macros. + +// Evaluates to a well-formed version header word, given valid +// SPIR-V version major and minor version numbers. +#define SPV_SPIRV_VERSION_WORD(MAJOR, MINOR) \ + ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8)) +// Returns the major version extracted from a version header word. +#define SPV_SPIRV_VERSION_MAJOR_PART(WORD) ((uint32_t(WORD) >> 16) & 0xff) +// Returns the minor version extracted from a version header word. +#define SPV_SPIRV_VERSION_MINOR_PART(WORD) ((uint32_t(WORD) >> 8) & 0xff) + +// Header indices + +#define SPV_INDEX_MAGIC_NUMBER 0u +#define SPV_INDEX_VERSION_NUMBER 1u +#define SPV_INDEX_GENERATOR_NUMBER 2u +#define SPV_INDEX_BOUND 3u +#define SPV_INDEX_SCHEMA 4u +#define SPV_INDEX_INSTRUCTION 5u + +// Universal limits + +// SPIR-V 1.0 limits +#define SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX 0xffff +#define SPV_LIMIT_LITERAL_STRING_UTF8_CHARS_MAX 0xffff + +// A single Unicode character in UTF-8 encoding can take +// up 4 bytes. +#define SPV_LIMIT_LITERAL_STRING_BYTES_MAX \ + (SPV_LIMIT_LITERAL_STRING_UTF8_CHARS_MAX * 4) + +// NOTE: These are set to the minimum maximum values +// TODO(dneto): Check these. + +// libspirv limits. +#define SPV_LIMIT_RESULT_ID_BOUND 0x00400000 +#define SPV_LIMIT_CONTROL_FLOW_NEST_DEPTH 0x00000400 +#define SPV_LIMIT_GLOBAL_VARIABLES_MAX 0x00010000 +#define SPV_LIMIT_LOCAL_VARIABLES_MAX 0x00080000 +// TODO: Decorations per target ID max, depends on decoration table size +#define SPV_LIMIT_EXECUTION_MODE_PER_ENTRY_POINT_MAX 0x00000100 +#define SPV_LIMIT_INDICIES_MAX_ACCESS_CHAIN_COMPOSITE_MAX 0x00000100 +#define SPV_LIMIT_FUNCTION_PARAMETERS_PER_FUNCTION_DECL 0x00000100 +#define SPV_LIMIT_FUNCTION_CALL_ARGUMENTS_MAX 0x00000100 +#define SPV_LIMIT_EXT_FUNCTION_CALL_ARGUMENTS_MAX 0x00000100 +#define SPV_LIMIT_SWITCH_LITERAL_LABEL_PAIRS_MAX 0x00004000 +#define SPV_LIMIT_STRUCT_MEMBERS_MAX 0x0000400 +#define SPV_LIMIT_STRUCT_NESTING_DEPTH_MAX 0x00000100 + +// Enumerations + +// Values mapping to registered tools. See the registry at +// https://www.khronos.org/registry/spir-v/api/spir-v.xml +// These values occupy the higher order 16 bits of the generator magic word. +typedef enum spv_generator_t { + // TODO(dneto) Values 0 through 5 were registered only as vendor. + SPV_GENERATOR_KHRONOS = 0, + SPV_GENERATOR_LUNARG = 1, + SPV_GENERATOR_VALVE = 2, + SPV_GENERATOR_CODEPLAY = 3, + SPV_GENERATOR_NVIDIA = 4, + SPV_GENERATOR_ARM = 5, + // These are vendor and tool. + SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR = 6, + SPV_GENERATOR_KHRONOS_ASSEMBLER = 7, + SPV_GENERATOR_KHRONOS_GLSLANG = 8, + SPV_GENERATOR_KHRONOS_LINKER = 17, + SPV_GENERATOR_NUM_ENTRIES, + SPV_FORCE_16_BIT_ENUM(spv_generator_t) +} spv_generator_t; + +// Evaluates to a well-formed generator magic word from a tool value and +// miscellaneous 16-bit value. +#define SPV_GENERATOR_WORD(TOOL, MISC) \ + ((uint32_t(uint16_t(TOOL)) << 16) | uint16_t(MISC)) +// Returns the tool component of the generator word. +#define SPV_GENERATOR_TOOL_PART(WORD) (uint32_t(WORD) >> 16) +// Returns the misc part of the generator word. +#define SPV_GENERATOR_MISC_PART(WORD) (uint32_t(WORD) & 0xFFFF) + +#endif // SOURCE_SPIRV_CONSTANT_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_definition.h b/thirdparty/glslang/External/spirv-tools/source/spirv_definition.h new file mode 100644 index 000000000000..5dbd6ab20566 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_definition.h @@ -0,0 +1,33 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_SPIRV_DEFINITION_H_ +#define SOURCE_SPIRV_DEFINITION_H_ + +#include + +#include "source/latest_version_spirv_header.h" + +#define spvIsInBitfield(value, bitfield) ((value) == ((value)&bitfield)) + +typedef struct spv_header_t { + uint32_t magic; + uint32_t version; + uint32_t generator; + uint32_t bound; + uint32_t schema; // NOTE: Reserved + const uint32_t* instructions; // NOTE: Unfixed pointer to instruction stream +} spv_header_t; + +#endif // SOURCE_SPIRV_DEFINITION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_endian.cpp b/thirdparty/glslang/External/spirv-tools/source/spirv_endian.cpp new file mode 100644 index 000000000000..1d770917848e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_endian.cpp @@ -0,0 +1,77 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/spirv_endian.h" + +#include + +enum { + I32_ENDIAN_LITTLE = 0x03020100ul, + I32_ENDIAN_BIG = 0x00010203ul, +}; + +// This constant value allows the detection of the host machine's endianness. +// Accessing it through the "value" member is valid due to C++11 section 3.10 +// paragraph 10. +static const union { + unsigned char bytes[4]; + uint32_t value; +} o32_host_order = {{0, 1, 2, 3}}; + +#define I32_ENDIAN_HOST (o32_host_order.value) + +uint32_t spvFixWord(const uint32_t word, const spv_endianness_t endian) { + if ((SPV_ENDIANNESS_LITTLE == endian && I32_ENDIAN_HOST == I32_ENDIAN_BIG) || + (SPV_ENDIANNESS_BIG == endian && I32_ENDIAN_HOST == I32_ENDIAN_LITTLE)) { + return (word & 0x000000ff) << 24 | (word & 0x0000ff00) << 8 | + (word & 0x00ff0000) >> 8 | (word & 0xff000000) >> 24; + } + + return word; +} + +uint64_t spvFixDoubleWord(const uint32_t low, const uint32_t high, + const spv_endianness_t endian) { + return (uint64_t(spvFixWord(high, endian)) << 32) | spvFixWord(low, endian); +} + +spv_result_t spvBinaryEndianness(spv_const_binary binary, + spv_endianness_t* pEndian) { + if (!binary->code || !binary->wordCount) return SPV_ERROR_INVALID_BINARY; + if (!pEndian) return SPV_ERROR_INVALID_POINTER; + + uint8_t bytes[4]; + memcpy(bytes, binary->code, sizeof(uint32_t)); + + if (0x03 == bytes[0] && 0x02 == bytes[1] && 0x23 == bytes[2] && + 0x07 == bytes[3]) { + *pEndian = SPV_ENDIANNESS_LITTLE; + return SPV_SUCCESS; + } + + if (0x07 == bytes[0] && 0x23 == bytes[1] && 0x02 == bytes[2] && + 0x03 == bytes[3]) { + *pEndian = SPV_ENDIANNESS_BIG; + return SPV_SUCCESS; + } + + return SPV_ERROR_INVALID_BINARY; +} + +bool spvIsHostEndian(spv_endianness_t endian) { + return ((SPV_ENDIANNESS_LITTLE == endian) && + (I32_ENDIAN_LITTLE == I32_ENDIAN_HOST)) || + ((SPV_ENDIANNESS_BIG == endian) && + (I32_ENDIAN_BIG == I32_ENDIAN_HOST)); +} diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_endian.h b/thirdparty/glslang/External/spirv-tools/source/spirv_endian.h new file mode 100644 index 000000000000..b4927f318d4d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_endian.h @@ -0,0 +1,37 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_SPIRV_ENDIAN_H_ +#define SOURCE_SPIRV_ENDIAN_H_ + +#include "spirv-tools/libspirv.h" + +// Converts a word in the specified endianness to the host native endianness. +uint32_t spvFixWord(const uint32_t word, const spv_endianness_t endianness); + +// Converts a pair of words in the specified endianness to the host native +// endianness. +uint64_t spvFixDoubleWord(const uint32_t low, const uint32_t high, + const spv_endianness_t endianness); + +// Gets the endianness of the SPIR-V module given in the binary parameter. +// Returns SPV_ENDIANNESS_UNKNOWN if the SPIR-V magic number is invalid, +// otherwise writes the determined endianness into *endian. +spv_result_t spvBinaryEndianness(const spv_const_binary binary, + spv_endianness_t* endian); + +// Returns true if the given endianness matches the host's native endianness. +bool spvIsHostEndian(spv_endianness_t endian); + +#endif // SOURCE_SPIRV_ENDIAN_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_fuzzer_options.cpp b/thirdparty/glslang/External/spirv-tools/source/spirv_fuzzer_options.cpp new file mode 100644 index 000000000000..3f62e0e0f711 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_fuzzer_options.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/spirv_fuzzer_options.h" + +namespace { +// The default maximum number of steps for the reducer to run before giving up. +const uint32_t kDefaultStepLimit = 250; +} // namespace + +spv_fuzzer_options_t::spv_fuzzer_options_t() + : has_random_seed(false), + random_seed(0), + replay_range(0), + replay_validation_enabled(false), + shrinker_step_limit(kDefaultStepLimit), + fuzzer_pass_validation_enabled(false), + all_passes_enabled(false) {} + +SPIRV_TOOLS_EXPORT spv_fuzzer_options spvFuzzerOptionsCreate() { + return new spv_fuzzer_options_t(); +} + +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsDestroy(spv_fuzzer_options options) { + delete options; +} + +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableReplayValidation( + spv_fuzzer_options options) { + options->replay_validation_enabled = true; +} + +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetRandomSeed( + spv_fuzzer_options options, uint32_t seed) { + options->has_random_seed = true; + options->random_seed = seed; +} + +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetReplayRange( + spv_fuzzer_options options, int32_t replay_range) { + options->replay_range = replay_range; +} + +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetShrinkerStepLimit( + spv_fuzzer_options options, uint32_t shrinker_step_limit) { + options->shrinker_step_limit = shrinker_step_limit; +} + +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableFuzzerPassValidation( + spv_fuzzer_options options) { + options->fuzzer_pass_validation_enabled = true; +} + +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableAllPasses( + spv_fuzzer_options options) { + options->all_passes_enabled = true; +} diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_fuzzer_options.h b/thirdparty/glslang/External/spirv-tools/source/spirv_fuzzer_options.h new file mode 100644 index 000000000000..bb8d91037149 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_fuzzer_options.h @@ -0,0 +1,48 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_SPIRV_FUZZER_OPTIONS_H_ +#define SOURCE_SPIRV_FUZZER_OPTIONS_H_ + +#include "spirv-tools/libspirv.h" + +#include +#include + +// Manages command line options passed to the SPIR-V Fuzzer. New struct +// members may be added for any new option. +struct spv_fuzzer_options_t { + spv_fuzzer_options_t(); + + // See spvFuzzerOptionsSetRandomSeed. + bool has_random_seed; + uint32_t random_seed; + + // See spvFuzzerOptionsSetReplayRange. + int32_t replay_range; + + // See spvFuzzerOptionsEnableReplayValidation. + bool replay_validation_enabled; + + // See spvFuzzerOptionsSetShrinkerStepLimit. + uint32_t shrinker_step_limit; + + // See spvFuzzerOptionsValidateAfterEveryPass. + bool fuzzer_pass_validation_enabled; + + // See spvFuzzerOptionsEnableAllPasses. + bool all_passes_enabled; +}; + +#endif // SOURCE_SPIRV_FUZZER_OPTIONS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_optimizer_options.cpp b/thirdparty/glslang/External/spirv-tools/source/spirv_optimizer_options.cpp new file mode 100644 index 000000000000..e92ffc0f42c2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_optimizer_options.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "source/spirv_optimizer_options.h" + +SPIRV_TOOLS_EXPORT spv_optimizer_options spvOptimizerOptionsCreate(void) { + return new spv_optimizer_options_t(); +} + +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsDestroy( + spv_optimizer_options options) { + delete options; +} + +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetRunValidator( + spv_optimizer_options options, bool val) { + options->run_validator_ = val; +} + +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetValidatorOptions( + spv_optimizer_options options, spv_validator_options val) { + options->val_options_ = *val; +} +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetMaxIdBound( + spv_optimizer_options options, uint32_t val) { + options->max_id_bound_ = val; +} + +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetPreserveBindings( + spv_optimizer_options options, bool val) { + options->preserve_bindings_ = val; +} + +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetPreserveSpecConstants( + spv_optimizer_options options, bool val) { + options->preserve_spec_constants_ = val; +} diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_optimizer_options.h b/thirdparty/glslang/External/spirv-tools/source/spirv_optimizer_options.h new file mode 100644 index 000000000000..aa76d20b18af --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_optimizer_options.h @@ -0,0 +1,49 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_SPIRV_OPTIMIZER_OPTIONS_H_ +#define SOURCE_SPIRV_OPTIMIZER_OPTIONS_H_ + +#include "source/spirv_validator_options.h" +#include "spirv-tools/libspirv.h" + +// Manages command line options passed to the SPIR-V Validator. New struct +// members may be added for any new option. +struct spv_optimizer_options_t { + spv_optimizer_options_t() + : run_validator_(true), + val_options_(), + max_id_bound_(kDefaultMaxIdBound), + preserve_bindings_(false), + preserve_spec_constants_(false) {} + + // When true the validator will be run before optimizations are run. + bool run_validator_; + + // Options to pass to the validator if it is run. + spv_validator_options_t val_options_; + + // The maximum value the id bound for a module can have. The Spir-V spec says + // this value must be at least 0x3FFFFF, but implementations can allow for a + // higher value. + uint32_t max_id_bound_; + + // When true, all binding declarations within the module should be preserved. + bool preserve_bindings_; + + // When true, all specialization constants within the module should be + // preserved. + bool preserve_spec_constants_; +}; +#endif // SOURCE_SPIRV_OPTIMIZER_OPTIONS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_reducer_options.cpp b/thirdparty/glslang/External/spirv-tools/source/spirv_reducer_options.cpp new file mode 100644 index 000000000000..9086433e5d06 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_reducer_options.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "source/spirv_reducer_options.h" + +namespace { +// The default maximum number of steps the reducer will take before giving up. +const uint32_t kDefaultStepLimit = 2500; +} // namespace + +spv_reducer_options_t::spv_reducer_options_t() + : step_limit(kDefaultStepLimit), + fail_on_validation_error(false), + target_function(0) {} + +SPIRV_TOOLS_EXPORT spv_reducer_options spvReducerOptionsCreate() { + return new spv_reducer_options_t(); +} + +SPIRV_TOOLS_EXPORT void spvReducerOptionsDestroy(spv_reducer_options options) { + delete options; +} + +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetStepLimit( + spv_reducer_options options, uint32_t step_limit) { + options->step_limit = step_limit; +} + +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetFailOnValidationError( + spv_reducer_options options, bool fail_on_validation_error) { + options->fail_on_validation_error = fail_on_validation_error; +} + +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetTargetFunction( + spv_reducer_options options, uint32_t target_function) { + options->target_function = target_function; +} diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_reducer_options.h b/thirdparty/glslang/External/spirv-tools/source/spirv_reducer_options.h new file mode 100644 index 000000000000..911747dd26db --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_reducer_options.h @@ -0,0 +1,38 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_SPIRV_REDUCER_OPTIONS_H_ +#define SOURCE_SPIRV_REDUCER_OPTIONS_H_ + +#include "spirv-tools/libspirv.h" + +#include +#include + +// Manages command line options passed to the SPIR-V Reducer. New struct +// members may be added for any new option. +struct spv_reducer_options_t { + spv_reducer_options_t(); + + // See spvReducerOptionsSetStepLimit. + uint32_t step_limit; + + // See spvReducerOptionsSetFailOnValidationError. + bool fail_on_validation_error; + + // See spvReducerOptionsSetTargetFunction. + uint32_t target_function; +}; + +#endif // SOURCE_SPIRV_REDUCER_OPTIONS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_target_env.cpp b/thirdparty/glslang/External/spirv-tools/source/spirv_target_env.cpp new file mode 100644 index 000000000000..585f8b65a257 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_target_env.cpp @@ -0,0 +1,425 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/spirv_target_env.h" + +#include +#include +#include +#include + +#include "source/spirv_constant.h" +#include "spirv-tools/libspirv.h" + +const char* spvTargetEnvDescription(spv_target_env env) { + switch (env) { + case SPV_ENV_UNIVERSAL_1_0: + return "SPIR-V 1.0"; + case SPV_ENV_VULKAN_1_0: + return "SPIR-V 1.0 (under Vulkan 1.0 semantics)"; + case SPV_ENV_UNIVERSAL_1_1: + return "SPIR-V 1.1"; + case SPV_ENV_OPENCL_1_2: + return "SPIR-V 1.0 (under OpenCL 1.2 Full Profile semantics)"; + case SPV_ENV_OPENCL_EMBEDDED_1_2: + return "SPIR-V 1.0 (under OpenCL 1.2 Embedded Profile semantics)"; + case SPV_ENV_OPENCL_2_0: + return "SPIR-V 1.0 (under OpenCL 2.0 Full Profile semantics)"; + case SPV_ENV_OPENCL_EMBEDDED_2_0: + return "SPIR-V 1.0 (under OpenCL 2.0 Embedded Profile semantics)"; + case SPV_ENV_OPENCL_2_1: + return "SPIR-V 1.0 (under OpenCL 2.1 Full Profile semantics)"; + case SPV_ENV_OPENCL_EMBEDDED_2_1: + return "SPIR-V 1.0 (under OpenCL 2.1 Embedded Profile semantics)"; + case SPV_ENV_OPENCL_2_2: + return "SPIR-V 1.2 (under OpenCL 2.2 Full Profile semantics)"; + case SPV_ENV_OPENCL_EMBEDDED_2_2: + return "SPIR-V 1.2 (under OpenCL 2.2 Embedded Profile semantics)"; + case SPV_ENV_OPENGL_4_0: + return "SPIR-V 1.0 (under OpenGL 4.0 semantics)"; + case SPV_ENV_OPENGL_4_1: + return "SPIR-V 1.0 (under OpenGL 4.1 semantics)"; + case SPV_ENV_OPENGL_4_2: + return "SPIR-V 1.0 (under OpenGL 4.2 semantics)"; + case SPV_ENV_OPENGL_4_3: + return "SPIR-V 1.0 (under OpenGL 4.3 semantics)"; + case SPV_ENV_OPENGL_4_5: + return "SPIR-V 1.0 (under OpenGL 4.5 semantics)"; + case SPV_ENV_UNIVERSAL_1_2: + return "SPIR-V 1.2"; + case SPV_ENV_UNIVERSAL_1_3: + return "SPIR-V 1.3"; + case SPV_ENV_VULKAN_1_1: + return "SPIR-V 1.3 (under Vulkan 1.1 semantics)"; + case SPV_ENV_WEBGPU_0: + assert(false && "Deprecated target environment value."); + break; + case SPV_ENV_UNIVERSAL_1_4: + return "SPIR-V 1.4"; + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + return "SPIR-V 1.4 (under Vulkan 1.1 semantics)"; + case SPV_ENV_UNIVERSAL_1_5: + return "SPIR-V 1.5"; + case SPV_ENV_VULKAN_1_2: + return "SPIR-V 1.5 (under Vulkan 1.2 semantics)"; + case SPV_ENV_UNIVERSAL_1_6: + return "SPIR-V 1.6"; + case SPV_ENV_VULKAN_1_3: + return "SPIR-V 1.6 (under Vulkan 1.3 semantics)"; + case SPV_ENV_MAX: + assert(false && "Invalid target environment value."); + break; + } + return ""; +} + +uint32_t spvVersionForTargetEnv(spv_target_env env) { + switch (env) { + case SPV_ENV_UNIVERSAL_1_0: + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_OPENCL_1_2: + case SPV_ENV_OPENCL_EMBEDDED_1_2: + case SPV_ENV_OPENCL_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_0: + case SPV_ENV_OPENCL_2_1: + case SPV_ENV_OPENCL_EMBEDDED_2_1: + case SPV_ENV_OPENGL_4_0: + case SPV_ENV_OPENGL_4_1: + case SPV_ENV_OPENGL_4_2: + case SPV_ENV_OPENGL_4_3: + case SPV_ENV_OPENGL_4_5: + return SPV_SPIRV_VERSION_WORD(1, 0); + case SPV_ENV_UNIVERSAL_1_1: + return SPV_SPIRV_VERSION_WORD(1, 1); + case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_OPENCL_2_2: + case SPV_ENV_OPENCL_EMBEDDED_2_2: + return SPV_SPIRV_VERSION_WORD(1, 2); + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + return SPV_SPIRV_VERSION_WORD(1, 3); + case SPV_ENV_WEBGPU_0: + assert(false && "Deprecated target environment value."); + break; + case SPV_ENV_UNIVERSAL_1_4: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + return SPV_SPIRV_VERSION_WORD(1, 4); + case SPV_ENV_UNIVERSAL_1_5: + case SPV_ENV_VULKAN_1_2: + return SPV_SPIRV_VERSION_WORD(1, 5); + case SPV_ENV_UNIVERSAL_1_6: + case SPV_ENV_VULKAN_1_3: + return SPV_SPIRV_VERSION_WORD(1, 6); + case SPV_ENV_MAX: + assert(false && "Invalid target environment value."); + break; + } + return SPV_SPIRV_VERSION_WORD(0, 0); +} + +static const std::pair spvTargetEnvNameMap[] = { + {"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4}, + {"vulkan1.0", SPV_ENV_VULKAN_1_0}, + {"vulkan1.1", SPV_ENV_VULKAN_1_1}, + {"vulkan1.2", SPV_ENV_VULKAN_1_2}, + {"vulkan1.3", SPV_ENV_VULKAN_1_3}, + {"spv1.0", SPV_ENV_UNIVERSAL_1_0}, + {"spv1.1", SPV_ENV_UNIVERSAL_1_1}, + {"spv1.2", SPV_ENV_UNIVERSAL_1_2}, + {"spv1.3", SPV_ENV_UNIVERSAL_1_3}, + {"spv1.4", SPV_ENV_UNIVERSAL_1_4}, + {"spv1.5", SPV_ENV_UNIVERSAL_1_5}, + {"spv1.6", SPV_ENV_UNIVERSAL_1_6}, + {"opencl1.2embedded", SPV_ENV_OPENCL_EMBEDDED_1_2}, + {"opencl1.2", SPV_ENV_OPENCL_1_2}, + {"opencl2.0embedded", SPV_ENV_OPENCL_EMBEDDED_2_0}, + {"opencl2.0", SPV_ENV_OPENCL_2_0}, + {"opencl2.1embedded", SPV_ENV_OPENCL_EMBEDDED_2_1}, + {"opencl2.1", SPV_ENV_OPENCL_2_1}, + {"opencl2.2embedded", SPV_ENV_OPENCL_EMBEDDED_2_2}, + {"opencl2.2", SPV_ENV_OPENCL_2_2}, + {"opengl4.0", SPV_ENV_OPENGL_4_0}, + {"opengl4.1", SPV_ENV_OPENGL_4_1}, + {"opengl4.2", SPV_ENV_OPENGL_4_2}, + {"opengl4.3", SPV_ENV_OPENGL_4_3}, + {"opengl4.5", SPV_ENV_OPENGL_4_5}, +}; + +bool spvParseTargetEnv(const char* s, spv_target_env* env) { + auto match = [s](const char* b) { + return s && (0 == strncmp(s, b, strlen(b))); + }; + for (auto& name_env : spvTargetEnvNameMap) { + if (match(name_env.first)) { + if (env) { + *env = name_env.second; + } + return true; + } + } + if (env) *env = SPV_ENV_UNIVERSAL_1_0; + return false; +} + +#define VULKAN_VER(MAJOR, MINOR) ((MAJOR << 22) | (MINOR << 12)) +#define SPIRV_VER(MAJOR, MINOR) ((MAJOR << 16) | (MINOR << 8)) + +struct VulkanEnv { + spv_target_env vulkan_env; + uint32_t vulkan_ver; + uint32_t spirv_ver; +}; +// Maps each Vulkan target environment enum to the Vulkan version, and the +// maximum supported SPIR-V version for that Vulkan environment. +// Keep this ordered from least capable to most capable. +static const VulkanEnv ordered_vulkan_envs[] = { + {SPV_ENV_VULKAN_1_0, VULKAN_VER(1, 0), SPIRV_VER(1, 0)}, + {SPV_ENV_VULKAN_1_1, VULKAN_VER(1, 1), SPIRV_VER(1, 3)}, + {SPV_ENV_VULKAN_1_1_SPIRV_1_4, VULKAN_VER(1, 1), SPIRV_VER(1, 4)}, + {SPV_ENV_VULKAN_1_2, VULKAN_VER(1, 2), SPIRV_VER(1, 5)}, + {SPV_ENV_VULKAN_1_3, VULKAN_VER(1, 3), SPIRV_VER(1, 6)}}; + +bool spvParseVulkanEnv(uint32_t vulkan_ver, uint32_t spirv_ver, + spv_target_env* env) { + for (auto triple : ordered_vulkan_envs) { + if (triple.vulkan_ver >= vulkan_ver && triple.spirv_ver >= spirv_ver) { + *env = triple.vulkan_env; + return true; + } + } + return false; +} + +bool spvIsVulkanEnv(spv_target_env env) { + switch (env) { + case SPV_ENV_UNIVERSAL_1_0: + case SPV_ENV_OPENCL_1_2: + case SPV_ENV_OPENCL_EMBEDDED_1_2: + case SPV_ENV_OPENCL_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_0: + case SPV_ENV_OPENCL_2_1: + case SPV_ENV_OPENCL_EMBEDDED_2_1: + case SPV_ENV_OPENGL_4_0: + case SPV_ENV_OPENGL_4_1: + case SPV_ENV_OPENGL_4_2: + case SPV_ENV_OPENGL_4_3: + case SPV_ENV_OPENGL_4_5: + case SPV_ENV_UNIVERSAL_1_1: + case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_OPENCL_2_2: + case SPV_ENV_OPENCL_EMBEDDED_2_2: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_UNIVERSAL_1_4: + case SPV_ENV_UNIVERSAL_1_5: + case SPV_ENV_UNIVERSAL_1_6: + return false; + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_VULKAN_1_1: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + case SPV_ENV_VULKAN_1_2: + case SPV_ENV_VULKAN_1_3: + return true; + case SPV_ENV_WEBGPU_0: + assert(false && "Deprecated target environment value."); + break; + case SPV_ENV_MAX: + assert(false && "Invalid target environment value."); + break; + } + return false; +} + +bool spvIsOpenCLEnv(spv_target_env env) { + switch (env) { + case SPV_ENV_UNIVERSAL_1_0: + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_UNIVERSAL_1_1: + case SPV_ENV_OPENGL_4_0: + case SPV_ENV_OPENGL_4_1: + case SPV_ENV_OPENGL_4_2: + case SPV_ENV_OPENGL_4_3: + case SPV_ENV_OPENGL_4_5: + case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + case SPV_ENV_UNIVERSAL_1_4: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + case SPV_ENV_UNIVERSAL_1_5: + case SPV_ENV_VULKAN_1_2: + case SPV_ENV_UNIVERSAL_1_6: + case SPV_ENV_VULKAN_1_3: + return false; + case SPV_ENV_OPENCL_1_2: + case SPV_ENV_OPENCL_EMBEDDED_1_2: + case SPV_ENV_OPENCL_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_1: + case SPV_ENV_OPENCL_EMBEDDED_2_2: + case SPV_ENV_OPENCL_2_1: + case SPV_ENV_OPENCL_2_2: + return true; + case SPV_ENV_WEBGPU_0: + assert(false && "Deprecated target environment value."); + break; + case SPV_ENV_MAX: + assert(false && "Invalid target environment value."); + break; + } + return false; +} + +bool spvIsOpenGLEnv(spv_target_env env) { + switch (env) { + case SPV_ENV_UNIVERSAL_1_0: + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_UNIVERSAL_1_1: + case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + case SPV_ENV_OPENCL_1_2: + case SPV_ENV_OPENCL_EMBEDDED_1_2: + case SPV_ENV_OPENCL_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_1: + case SPV_ENV_OPENCL_EMBEDDED_2_2: + case SPV_ENV_OPENCL_2_1: + case SPV_ENV_OPENCL_2_2: + case SPV_ENV_UNIVERSAL_1_4: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + case SPV_ENV_UNIVERSAL_1_5: + case SPV_ENV_VULKAN_1_2: + case SPV_ENV_UNIVERSAL_1_6: + case SPV_ENV_VULKAN_1_3: + return false; + case SPV_ENV_OPENGL_4_0: + case SPV_ENV_OPENGL_4_1: + case SPV_ENV_OPENGL_4_2: + case SPV_ENV_OPENGL_4_3: + case SPV_ENV_OPENGL_4_5: + return true; + case SPV_ENV_WEBGPU_0: + assert(false && "Deprecated target environment value."); + break; + case SPV_ENV_MAX: + assert(false && "Invalid target environment value."); + break; + } + return false; +} + +bool spvIsValidEnv(spv_target_env env) { + switch (env) { + case SPV_ENV_UNIVERSAL_1_0: + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_UNIVERSAL_1_1: + case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + case SPV_ENV_OPENCL_1_2: + case SPV_ENV_OPENCL_EMBEDDED_1_2: + case SPV_ENV_OPENCL_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_1: + case SPV_ENV_OPENCL_EMBEDDED_2_2: + case SPV_ENV_OPENCL_2_1: + case SPV_ENV_OPENCL_2_2: + case SPV_ENV_UNIVERSAL_1_4: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + case SPV_ENV_UNIVERSAL_1_5: + case SPV_ENV_VULKAN_1_2: + case SPV_ENV_UNIVERSAL_1_6: + case SPV_ENV_VULKAN_1_3: + case SPV_ENV_OPENGL_4_0: + case SPV_ENV_OPENGL_4_1: + case SPV_ENV_OPENGL_4_2: + case SPV_ENV_OPENGL_4_3: + case SPV_ENV_OPENGL_4_5: + return true; + case SPV_ENV_WEBGPU_0: + case SPV_ENV_MAX: + break; + } + return false; +} + +std::string spvLogStringForEnv(spv_target_env env) { + switch (env) { + case SPV_ENV_OPENCL_1_2: + case SPV_ENV_OPENCL_2_0: + case SPV_ENV_OPENCL_2_1: + case SPV_ENV_OPENCL_2_2: + case SPV_ENV_OPENCL_EMBEDDED_1_2: + case SPV_ENV_OPENCL_EMBEDDED_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_1: + case SPV_ENV_OPENCL_EMBEDDED_2_2: { + return "OpenCL"; + } + case SPV_ENV_OPENGL_4_0: + case SPV_ENV_OPENGL_4_1: + case SPV_ENV_OPENGL_4_2: + case SPV_ENV_OPENGL_4_3: + case SPV_ENV_OPENGL_4_5: { + return "OpenGL"; + } + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_VULKAN_1_1: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + case SPV_ENV_VULKAN_1_2: + case SPV_ENV_VULKAN_1_3: { + return "Vulkan"; + } + case SPV_ENV_UNIVERSAL_1_0: + case SPV_ENV_UNIVERSAL_1_1: + case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_UNIVERSAL_1_4: + case SPV_ENV_UNIVERSAL_1_5: + case SPV_ENV_UNIVERSAL_1_6: { + return "Universal"; + } + case SPV_ENV_WEBGPU_0: + assert(false && "Deprecated target environment value."); + break; + case SPV_ENV_MAX: + assert(false && "Invalid target environment value."); + break; + } + return "Unknown"; +} + +std::string spvTargetEnvList(const int pad, const int wrap) { + std::string ret; + size_t max_line_len = wrap - pad; // The first line isn't padded + std::string line; + std::string sep = ""; + + for (auto& name_env : spvTargetEnvNameMap) { + std::string word = sep + name_env.first; + if (line.length() + word.length() > max_line_len) { + // Adding one word wouldn't fit, commit the line in progress and + // start a new one. + ret += line + "\n"; + line.assign(pad, ' '); + // The first line is done. The max length now comprises the + // padding. + max_line_len = wrap; + } + line += word; + sep = "|"; + } + + ret += line; + + return ret; +} diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_target_env.h b/thirdparty/glslang/External/spirv-tools/source/spirv_target_env.h new file mode 100644 index 000000000000..f3b0c2f6f2a2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_target_env.h @@ -0,0 +1,49 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_SPIRV_TARGET_ENV_H_ +#define SOURCE_SPIRV_TARGET_ENV_H_ + +#include + +#include "spirv-tools/libspirv.h" + +// Returns true if |env| is a VULKAN environment, false otherwise. +bool spvIsVulkanEnv(spv_target_env env); + +// Returns true if |env| is an OPENCL environment, false otherwise. +bool spvIsOpenCLEnv(spv_target_env env); + +// Returns true if |env| is an OPENGL environment, false otherwise. +bool spvIsOpenGLEnv(spv_target_env env); + +// Returns true if |env| is an implemented/valid environment, false otherwise. +bool spvIsValidEnv(spv_target_env env); + +// Returns the version number for the given SPIR-V target environment. +uint32_t spvVersionForTargetEnv(spv_target_env env); + +// Returns a string to use in logging messages that indicates the class of +// environment, i.e. "Vulkan", "OpenCL", etc. +std::string spvLogStringForEnv(spv_target_env env); + +// Returns a formatted list of all SPIR-V target environment names that +// can be parsed by spvParseTargetEnv. +// |pad| is the number of space characters that the beginning of each line +// except the first one will be padded with. +// |wrap| is the max length of lines the user desires. Word-wrapping will +// occur to satisfy this limit. +std::string spvTargetEnvList(const int pad, const int wrap); + +#endif // SOURCE_SPIRV_TARGET_ENV_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_validator_options.cpp b/thirdparty/glslang/External/spirv-tools/source/spirv_validator_options.cpp new file mode 100644 index 000000000000..b72a64460dca --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_validator_options.cpp @@ -0,0 +1,132 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/spirv_validator_options.h" + +#include +#include + +bool spvParseUniversalLimitsOptions(const char* s, spv_validator_limit* type) { + auto match = [s](const char* b) { + return s && (0 == strncmp(s, b, strlen(b))); + }; + if (match("--max-struct-members")) { + *type = spv_validator_limit_max_struct_members; + } else if (match("--max-struct_depth")) { + *type = spv_validator_limit_max_struct_depth; + } else if (match("--max-local-variables")) { + *type = spv_validator_limit_max_local_variables; + } else if (match("--max-global-variables")) { + *type = spv_validator_limit_max_global_variables; + } else if (match("--max-switch-branches")) { + *type = spv_validator_limit_max_global_variables; + } else if (match("--max-function-args")) { + *type = spv_validator_limit_max_function_args; + } else if (match("--max-control-flow-nesting-depth")) { + *type = spv_validator_limit_max_control_flow_nesting_depth; + } else if (match("--max-access-chain-indexes")) { + *type = spv_validator_limit_max_access_chain_indexes; + } else if (match("--max-id-bound")) { + *type = spv_validator_limit_max_id_bound; + } else { + // The command line option for this validator limit has not been added. + // Therefore we return false. + return false; + } + + return true; +} + +spv_validator_options spvValidatorOptionsCreate(void) { + return new spv_validator_options_t; +} + +void spvValidatorOptionsDestroy(spv_validator_options options) { + delete options; +} + +void spvValidatorOptionsSetUniversalLimit(spv_validator_options options, + spv_validator_limit limit_type, + uint32_t limit) { + assert(options && "Validator options object may not be Null"); + switch (limit_type) { +#define LIMIT(TYPE, FIELD) \ + case TYPE: \ + options->universal_limits_.FIELD = limit; \ + break; + LIMIT(spv_validator_limit_max_struct_members, max_struct_members) + LIMIT(spv_validator_limit_max_struct_depth, max_struct_depth) + LIMIT(spv_validator_limit_max_local_variables, max_local_variables) + LIMIT(spv_validator_limit_max_global_variables, max_global_variables) + LIMIT(spv_validator_limit_max_switch_branches, max_switch_branches) + LIMIT(spv_validator_limit_max_function_args, max_function_args) + LIMIT(spv_validator_limit_max_control_flow_nesting_depth, + max_control_flow_nesting_depth) + LIMIT(spv_validator_limit_max_access_chain_indexes, + max_access_chain_indexes) + LIMIT(spv_validator_limit_max_id_bound, max_id_bound) +#undef LIMIT + } +} + +void spvValidatorOptionsSetRelaxStoreStruct(spv_validator_options options, + bool val) { + options->relax_struct_store = val; +} + +void spvValidatorOptionsSetRelaxLogicalPointer(spv_validator_options options, + bool val) { + options->relax_logical_pointer = val; +} + +void spvValidatorOptionsSetBeforeHlslLegalization(spv_validator_options options, + bool val) { + options->before_hlsl_legalization = val; + options->relax_logical_pointer = val; +} + +void spvValidatorOptionsSetRelaxBlockLayout(spv_validator_options options, + bool val) { + options->relax_block_layout = val; +} + +void spvValidatorOptionsSetUniformBufferStandardLayout( + spv_validator_options options, bool val) { + options->uniform_buffer_standard_layout = val; +} + +void spvValidatorOptionsSetScalarBlockLayout(spv_validator_options options, + bool val) { + options->scalar_block_layout = val; +} + +void spvValidatorOptionsSetWorkgroupScalarBlockLayout(spv_validator_options options, + bool val) { + options->workgroup_scalar_block_layout = val; +} + +void spvValidatorOptionsSetSkipBlockLayout(spv_validator_options options, + bool val) { + options->skip_block_layout = val; +} + +void spvValidatorOptionsSetAllowLocalSizeId(spv_validator_options options, + bool val) { + options->allow_localsizeid = val; +} + +void spvValidatorOptionsSetFriendlyNames(spv_validator_options options, + bool val) { + options->use_friendly_names = val; +} diff --git a/thirdparty/glslang/External/spirv-tools/source/spirv_validator_options.h b/thirdparty/glslang/External/spirv-tools/source/spirv_validator_options.h new file mode 100644 index 000000000000..01450480c910 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spirv_validator_options.h @@ -0,0 +1,67 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_SPIRV_VALIDATOR_OPTIONS_H_ +#define SOURCE_SPIRV_VALIDATOR_OPTIONS_H_ + +#include "spirv-tools/libspirv.h" + +// Return true if the command line option for the validator limit is valid (Also +// returns the Enum for option in this case). Returns false otherwise. +bool spvParseUniversalLimitsOptions(const char* s, spv_validator_limit* limit); + +// Default initialization of this structure is to the default Universal Limits +// described in the SPIR-V Spec. +struct validator_universal_limits_t { + uint32_t max_struct_members{16383}; + uint32_t max_struct_depth{255}; + uint32_t max_local_variables{524287}; + uint32_t max_global_variables{65535}; + uint32_t max_switch_branches{16383}; + uint32_t max_function_args{255}; + uint32_t max_control_flow_nesting_depth{1023}; + uint32_t max_access_chain_indexes{255}; + uint32_t max_id_bound{0x3FFFFF}; +}; + +// Manages command line options passed to the SPIR-V Validator. New struct +// members may be added for any new option. +struct spv_validator_options_t { + spv_validator_options_t() + : universal_limits_(), + relax_struct_store(false), + relax_logical_pointer(false), + relax_block_layout(false), + uniform_buffer_standard_layout(false), + scalar_block_layout(false), + workgroup_scalar_block_layout(false), + skip_block_layout(false), + allow_localsizeid(false), + before_hlsl_legalization(false), + use_friendly_names(true) {} + + validator_universal_limits_t universal_limits_; + bool relax_struct_store; + bool relax_logical_pointer; + bool relax_block_layout; + bool uniform_buffer_standard_layout; + bool scalar_block_layout; + bool workgroup_scalar_block_layout; + bool skip_block_layout; + bool allow_localsizeid; + bool before_hlsl_legalization; + bool use_friendly_names; +}; + +#endif // SOURCE_SPIRV_VALIDATOR_OPTIONS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/spv-amd-gcn-shader.insts.inc b/thirdparty/glslang/External/spirv-tools/source/spv-amd-gcn-shader.insts.inc new file mode 100644 index 000000000000..1682aff5f6de --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spv-amd-gcn-shader.insts.inc @@ -0,0 +1,7 @@ + + +static const spv_ext_inst_desc_t spv_amd_gcn_shader_entries[] = { + {"CubeFaceIndexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"CubeFaceCoordAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"TimeAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-ballot.insts.inc b/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-ballot.insts.inc new file mode 100644 index 000000000000..c3b4aa09b8b8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-ballot.insts.inc @@ -0,0 +1,8 @@ + + +static const spv_ext_inst_desc_t spv_amd_shader_ballot_entries[] = { + {"SwizzleInvocationsAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SwizzleInvocationsMaskedAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"WriteInvocationAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"MbcntAMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-explicit-vertex-parameter.insts.inc b/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-explicit-vertex-parameter.insts.inc new file mode 100644 index 000000000000..1ed559596d1a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-explicit-vertex-parameter.insts.inc @@ -0,0 +1,5 @@ + + +static const spv_ext_inst_desc_t spv_amd_shader_explicit_vertex_parameter_entries[] = { + {"InterpolateAtVertexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-trinary-minmax.insts.inc b/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-trinary-minmax.insts.inc new file mode 100644 index 000000000000..af7ce826add6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/spv-amd-shader-trinary-minmax.insts.inc @@ -0,0 +1,13 @@ + + +static const spv_ext_inst_desc_t spv_amd_shader_trinary_minmax_entries[] = { + {"FMin3AMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMin3AMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMin3AMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMax3AMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMax3AMD", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMax3AMD", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"FMid3AMD", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"UMid3AMD", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"SMid3AMD", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/thirdparty/glslang/External/spirv-tools/source/table.cpp b/thirdparty/glslang/External/spirv-tools/source/table.cpp new file mode 100644 index 000000000000..822cefebd7b0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/table.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/table.h" + +#include + +spv_context spvContextCreate(spv_target_env env) { + switch (env) { + case SPV_ENV_UNIVERSAL_1_0: + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_UNIVERSAL_1_1: + case SPV_ENV_OPENCL_1_2: + case SPV_ENV_OPENCL_EMBEDDED_1_2: + case SPV_ENV_OPENCL_2_0: + case SPV_ENV_OPENCL_EMBEDDED_2_0: + case SPV_ENV_OPENCL_2_1: + case SPV_ENV_OPENCL_EMBEDDED_2_1: + case SPV_ENV_OPENCL_2_2: + case SPV_ENV_OPENCL_EMBEDDED_2_2: + case SPV_ENV_OPENGL_4_0: + case SPV_ENV_OPENGL_4_1: + case SPV_ENV_OPENGL_4_2: + case SPV_ENV_OPENGL_4_3: + case SPV_ENV_OPENGL_4_5: + case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + case SPV_ENV_UNIVERSAL_1_4: + case SPV_ENV_UNIVERSAL_1_5: + case SPV_ENV_VULKAN_1_2: + case SPV_ENV_UNIVERSAL_1_6: + case SPV_ENV_VULKAN_1_3: + break; + default: + return nullptr; + } + + spv_opcode_table opcode_table; + spv_operand_table operand_table; + spv_ext_inst_table ext_inst_table; + + spvOpcodeTableGet(&opcode_table, env); + spvOperandTableGet(&operand_table, env); + spvExtInstTableGet(&ext_inst_table, env); + + return new spv_context_t{env, opcode_table, operand_table, ext_inst_table, + nullptr /* a null default consumer */}; +} + +void spvContextDestroy(spv_context context) { delete context; } + +void spvtools::SetContextMessageConsumer(spv_context context, + spvtools::MessageConsumer consumer) { + context->consumer = std::move(consumer); +} diff --git a/thirdparty/glslang/External/spirv-tools/source/table.h b/thirdparty/glslang/External/spirv-tools/source/table.h new file mode 100644 index 000000000000..8097f13f7763 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/table.h @@ -0,0 +1,133 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_TABLE_H_ +#define SOURCE_TABLE_H_ + +#include "source/extensions.h" +#include "source/latest_version_spirv_header.h" +#include "spirv-tools/libspirv.hpp" + +typedef struct spv_opcode_desc_t { + const char* name; + const spv::Op opcode; + const uint32_t numCapabilities; + const spv::Capability* capabilities; + // operandTypes[0..numTypes-1] describe logical operands for the instruction. + // The operand types include result id and result-type id, followed by + // the types of arguments. + const uint16_t numTypes; + spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger? + const bool hasResult; // Does the instruction have a result ID operand? + const bool hasType; // Does the instruction have a type ID operand? + // A set of extensions that enable this feature. If empty then this operand + // value is in core and its availability is subject to minVersion. The + // assembler, binary parser, and disassembler ignore this rule, so you can + // freely process invalid modules. + const uint32_t numExtensions; + const spvtools::Extension* extensions; + // Minimal core SPIR-V version required for this feature, if without + // extensions. ~0u means reserved for future use. ~0u and non-empty extension + // lists means only available in extensions. + const uint32_t minVersion; + const uint32_t lastVersion; +} spv_opcode_desc_t; + +typedef struct spv_operand_desc_t { + const char* name; + const uint32_t value; + const uint32_t numCapabilities; + const spv::Capability* capabilities; + // A set of extensions that enable this feature. If empty then this operand + // value is in core and its availability is subject to minVersion. The + // assembler, binary parser, and disassembler ignore this rule, so you can + // freely process invalid modules. + const uint32_t numExtensions; + const spvtools::Extension* extensions; + const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger? + // Minimal core SPIR-V version required for this feature, if without + // extensions. ~0u means reserved for future use. ~0u and non-empty extension + // lists means only available in extensions. + const uint32_t minVersion; + const uint32_t lastVersion; +} spv_operand_desc_t; + +typedef struct spv_operand_desc_group_t { + const spv_operand_type_t type; + const uint32_t count; + const spv_operand_desc_t* entries; +} spv_operand_desc_group_t; + +typedef struct spv_ext_inst_desc_t { + const char* name; + const uint32_t ext_inst; + const uint32_t numCapabilities; + const spv::Capability* capabilities; + const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger? +} spv_ext_inst_desc_t; + +typedef struct spv_ext_inst_group_t { + const spv_ext_inst_type_t type; + const uint32_t count; + const spv_ext_inst_desc_t* entries; +} spv_ext_inst_group_t; + +typedef struct spv_opcode_table_t { + const uint32_t count; + const spv_opcode_desc_t* entries; +} spv_opcode_table_t; + +typedef struct spv_operand_table_t { + const uint32_t count; + const spv_operand_desc_group_t* types; +} spv_operand_table_t; + +typedef struct spv_ext_inst_table_t { + const uint32_t count; + const spv_ext_inst_group_t* groups; +} spv_ext_inst_table_t; + +typedef const spv_opcode_desc_t* spv_opcode_desc; +typedef const spv_operand_desc_t* spv_operand_desc; +typedef const spv_ext_inst_desc_t* spv_ext_inst_desc; + +typedef const spv_opcode_table_t* spv_opcode_table; +typedef const spv_operand_table_t* spv_operand_table; +typedef const spv_ext_inst_table_t* spv_ext_inst_table; + +struct spv_context_t { + const spv_target_env target_env; + const spv_opcode_table opcode_table; + const spv_operand_table operand_table; + const spv_ext_inst_table ext_inst_table; + spvtools::MessageConsumer consumer; +}; + +namespace spvtools { + +// Sets the message consumer to |consumer| in the given |context|. The original +// message consumer will be overwritten. +void SetContextMessageConsumer(spv_context context, MessageConsumer consumer); +} // namespace spvtools + +// Populates *table with entries for env. +spv_result_t spvOpcodeTableGet(spv_opcode_table* table, spv_target_env env); + +// Populates *table with entries for env. +spv_result_t spvOperandTableGet(spv_operand_table* table, spv_target_env env); + +// Populates *table with entries for env. +spv_result_t spvExtInstTableGet(spv_ext_inst_table* table, spv_target_env env); + +#endif // SOURCE_TABLE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/text.cpp b/thirdparty/glslang/External/spirv-tools/source/text.cpp new file mode 100644 index 000000000000..737c223b5342 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/text.cpp @@ -0,0 +1,864 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/text.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/assembly_grammar.h" +#include "source/binary.h" +#include "source/diagnostic.h" +#include "source/ext_inst.h" +#include "source/instruction.h" +#include "source/opcode.h" +#include "source/operand.h" +#include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/table.h" +#include "source/text_handler.h" +#include "source/util/bitutils.h" +#include "source/util/parse_number.h" +#include "spirv-tools/libspirv.h" + +bool spvIsValidIDCharacter(const char value) { + return value == '_' || 0 != ::isalnum(value); +} + +// Returns true if the given string represents a valid ID name. +bool spvIsValidID(const char* textValue) { + const char* c = textValue; + for (; *c != '\0'; ++c) { + if (!spvIsValidIDCharacter(*c)) { + return false; + } + } + // If the string was empty, then the ID also is not valid. + return c != textValue; +} + +// Text API + +spv_result_t spvTextToLiteral(const char* textValue, spv_literal_t* pLiteral) { + bool isSigned = false; + int numPeriods = 0; + bool isString = false; + + const size_t len = strlen(textValue); + if (len == 0) return SPV_FAILED_MATCH; + + for (uint64_t index = 0; index < len; ++index) { + switch (textValue[index]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + case '.': + numPeriods++; + break; + case '-': + if (index == 0) { + isSigned = true; + } else { + isString = true; + } + break; + default: + isString = true; + index = len; // break out of the loop too. + break; + } + } + + pLiteral->type = spv_literal_type_t(99); + + if (isString || numPeriods > 1 || (isSigned && len == 1)) { + if (len < 2 || textValue[0] != '"' || textValue[len - 1] != '"') + return SPV_FAILED_MATCH; + bool escaping = false; + for (const char* val = textValue + 1; val != textValue + len - 1; ++val) { + if ((*val == '\\') && (!escaping)) { + escaping = true; + } else { + // Have to save space for the null-terminator + if (pLiteral->str.size() >= SPV_LIMIT_LITERAL_STRING_BYTES_MAX) + return SPV_ERROR_OUT_OF_MEMORY; + pLiteral->str.push_back(*val); + escaping = false; + } + } + + pLiteral->type = SPV_LITERAL_TYPE_STRING; + } else if (numPeriods == 1) { + double d = std::strtod(textValue, nullptr); + float f = (float)d; + if (d == (double)f) { + pLiteral->type = SPV_LITERAL_TYPE_FLOAT_32; + pLiteral->value.f = f; + } else { + pLiteral->type = SPV_LITERAL_TYPE_FLOAT_64; + pLiteral->value.d = d; + } + } else if (isSigned) { + int64_t i64 = strtoll(textValue, nullptr, 10); + int32_t i32 = (int32_t)i64; + if (i64 == (int64_t)i32) { + pLiteral->type = SPV_LITERAL_TYPE_INT_32; + pLiteral->value.i32 = i32; + } else { + pLiteral->type = SPV_LITERAL_TYPE_INT_64; + pLiteral->value.i64 = i64; + } + } else { + uint64_t u64 = strtoull(textValue, nullptr, 10); + uint32_t u32 = (uint32_t)u64; + if (u64 == (uint64_t)u32) { + pLiteral->type = SPV_LITERAL_TYPE_UINT_32; + pLiteral->value.u32 = u32; + } else { + pLiteral->type = SPV_LITERAL_TYPE_UINT_64; + pLiteral->value.u64 = u64; + } + } + + return SPV_SUCCESS; +} + +namespace { + +/// Parses an immediate integer from text, guarding against overflow. If +/// successful, adds the parsed value to pInst, advances the context past it, +/// and returns SPV_SUCCESS. Otherwise, leaves pInst alone, emits diagnostics, +/// and returns SPV_ERROR_INVALID_TEXT. +spv_result_t encodeImmediate(spvtools::AssemblyContext* context, + const char* text, spv_instruction_t* pInst) { + assert(*text == '!'); + uint32_t parse_result; + if (!spvtools::utils::ParseNumber(text + 1, &parse_result)) { + return context->diagnostic(SPV_ERROR_INVALID_TEXT) + << "Invalid immediate integer: !" << text + 1; + } + context->binaryEncodeU32(parse_result, pInst); + context->seekForward(static_cast(strlen(text))); + return SPV_SUCCESS; +} + +} // anonymous namespace + +/// @brief Translate an Opcode operand to binary form +/// +/// @param[in] grammar the grammar to use for compilation +/// @param[in, out] context the dynamic compilation info +/// @param[in] type of the operand +/// @param[in] textValue word of text to be parsed +/// @param[out] pInst return binary Opcode +/// @param[in,out] pExpectedOperands the operand types expected +/// +/// @return result code +spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, + spvtools::AssemblyContext* context, + const spv_operand_type_t type, + const char* textValue, + spv_instruction_t* pInst, + spv_operand_pattern_t* pExpectedOperands) { + // NOTE: Handle immediate int in the stream + if ('!' == textValue[0]) { + if (auto error = encodeImmediate(context, textValue, pInst)) { + return error; + } + *pExpectedOperands = + spvAlternatePatternFollowingImmediate(*pExpectedOperands); + return SPV_SUCCESS; + } + + // Optional literal operands can fail to parse. In that case use + // SPV_FAILED_MATCH to avoid emitting a diagostic. Use the following + // for those situations. + spv_result_t error_code_for_literals = + spvOperandIsOptional(type) ? SPV_FAILED_MATCH : SPV_ERROR_INVALID_TEXT; + + switch (type) { + case SPV_OPERAND_TYPE_ID: + case SPV_OPERAND_TYPE_TYPE_ID: + case SPV_OPERAND_TYPE_RESULT_ID: + case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: + case SPV_OPERAND_TYPE_SCOPE_ID: + case SPV_OPERAND_TYPE_OPTIONAL_ID: { + if ('%' == textValue[0]) { + textValue++; + } else { + return context->diagnostic() << "Expected id to start with %."; + } + if (!spvIsValidID(textValue)) { + return context->diagnostic() << "Invalid ID " << textValue; + } + const uint32_t id = context->spvNamedIdAssignOrGet(textValue); + if (type == SPV_OPERAND_TYPE_TYPE_ID) pInst->resultTypeId = id; + spvInstructionAddWord(pInst, id); + + // Set the extended instruction type. + // The import set id is the 3rd operand of OpExtInst. + if (spv::Op(pInst->opcode) == spv::Op::OpExtInst && + pInst->words.size() == 4) { + auto ext_inst_type = context->getExtInstTypeForId(pInst->words[3]); + if (ext_inst_type == SPV_EXT_INST_TYPE_NONE) { + return context->diagnostic() + << "Invalid extended instruction import Id " + << pInst->words[2]; + } + pInst->extInstType = ext_inst_type; + } + } break; + + case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: { + // The assembler accepts the symbolic name for an extended instruction, + // and emits its corresponding number. + spv_ext_inst_desc extInst; + if (grammar.lookupExtInst(pInst->extInstType, textValue, &extInst) == + SPV_SUCCESS) { + // if we know about this extended instruction, push the numeric value + spvInstructionAddWord(pInst, extInst->ext_inst); + + // Prepare to parse the operands for the extended instructions. + spvPushOperandTypes(extInst->operandTypes, pExpectedOperands); + } else { + // if we don't know this extended instruction and the set isn't + // non-semantic, we cannot process further + if (!spvExtInstIsNonSemantic(pInst->extInstType)) { + return context->diagnostic() + << "Invalid extended instruction name '" << textValue << "'."; + } else { + // for non-semantic instruction sets, as long as the text name is an + // integer value we can encode it since we know the form of all such + // extended instructions + spv_literal_t extInstValue; + if (spvTextToLiteral(textValue, &extInstValue) || + extInstValue.type != SPV_LITERAL_TYPE_UINT_32) { + return context->diagnostic() + << "Couldn't translate unknown extended instruction name '" + << textValue << "' to unsigned integer."; + } + + spvInstructionAddWord(pInst, extInstValue.value.u32); + + // opcode contains an unknown number of IDs. + pExpectedOperands->push_back(SPV_OPERAND_TYPE_VARIABLE_ID); + } + } + } break; + + case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: { + // The assembler accepts the symbolic name for the opcode, but without + // the "Op" prefix. For example, "IAdd" is accepted. The number + // of the opcode is emitted. + spv::Op opcode; + if (grammar.lookupSpecConstantOpcode(textValue, &opcode)) { + return context->diagnostic() << "Invalid " << spvOperandTypeStr(type) + << " '" << textValue << "'."; + } + spv_opcode_desc opcodeEntry = nullptr; + if (grammar.lookupOpcode(opcode, &opcodeEntry)) { + return context->diagnostic(SPV_ERROR_INTERNAL) + << "OpSpecConstant opcode table out of sync"; + } + spvInstructionAddWord(pInst, uint32_t(opcodeEntry->opcode)); + + // Prepare to parse the operands for the opcode. Except skip the + // type Id and result Id, since they've already been processed. + assert(opcodeEntry->hasType); + assert(opcodeEntry->hasResult); + assert(opcodeEntry->numTypes >= 2); + spvPushOperandTypes(opcodeEntry->operandTypes + 2, pExpectedOperands); + } break; + + case SPV_OPERAND_TYPE_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER: { + // The current operand is an *unsigned* 32-bit integer. + // That's just how the grammar works. + spvtools::IdType expected_type = { + 32, false, spvtools::IdTypeClass::kScalarIntegerType}; + if (auto error = context->binaryEncodeNumericLiteral( + textValue, error_code_for_literals, expected_type, pInst)) { + return error; + } + } break; + + case SPV_OPERAND_TYPE_LITERAL_FLOAT: { + // The current operand is a 32-bit float. + // That's just how the grammar works. + spvtools::IdType expected_type = { + 32, false, spvtools::IdTypeClass::kScalarFloatType}; + if (auto error = context->binaryEncodeNumericLiteral( + textValue, error_code_for_literals, expected_type, pInst)) { + return error; + } + } break; + + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER: + // This is a context-independent literal number which can be a 32-bit + // number of floating point value. + if (auto error = context->binaryEncodeNumericLiteral( + textValue, error_code_for_literals, spvtools::kUnknownType, + pInst)) { + return error; + } + break; + + case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: + case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: { + spvtools::IdType expected_type = spvtools::kUnknownType; + // The encoding for OpConstant, OpSpecConstant and OpSwitch all + // depend on either their own result-id or the result-id of + // one of their parameters. + if (spv::Op::OpConstant == pInst->opcode || + spv::Op::OpSpecConstant == pInst->opcode) { + // The type of the literal is determined by the type Id of the + // instruction. + expected_type = + context->getTypeOfTypeGeneratingValue(pInst->resultTypeId); + if (!spvtools::isScalarFloating(expected_type) && + !spvtools::isScalarIntegral(expected_type)) { + spv_opcode_desc d; + const char* opcode_name = "opcode"; + if (SPV_SUCCESS == grammar.lookupOpcode(pInst->opcode, &d)) { + opcode_name = d->name; + } + return context->diagnostic() + << "Type for " << opcode_name + << " must be a scalar floating point or integer type"; + } + } else if (pInst->opcode == spv::Op::OpSwitch) { + // The type of the literal is the same as the type of the selector. + expected_type = context->getTypeOfValueInstruction(pInst->words[1]); + if (!spvtools::isScalarIntegral(expected_type)) { + return context->diagnostic() + << "The selector operand for OpSwitch must be the result" + " of an instruction that generates an integer scalar"; + } + } + if (auto error = context->binaryEncodeNumericLiteral( + textValue, error_code_for_literals, expected_type, pInst)) { + return error; + } + } break; + + case SPV_OPERAND_TYPE_LITERAL_STRING: + case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: { + spv_literal_t literal = {}; + spv_result_t error = spvTextToLiteral(textValue, &literal); + if (error != SPV_SUCCESS) { + if (error == SPV_ERROR_OUT_OF_MEMORY) return error; + return context->diagnostic(error_code_for_literals) + << "Invalid literal string '" << textValue << "'."; + } + if (literal.type != SPV_LITERAL_TYPE_STRING) { + return context->diagnostic() + << "Expected literal string, found literal number '" << textValue + << "'."; + } + + // NOTE: Special case for extended instruction library import + if (spv::Op::OpExtInstImport == pInst->opcode) { + const spv_ext_inst_type_t ext_inst_type = + spvExtInstImportTypeGet(literal.str.c_str()); + if (SPV_EXT_INST_TYPE_NONE == ext_inst_type) { + return context->diagnostic() + << "Invalid extended instruction import '" << literal.str + << "'"; + } + if ((error = context->recordIdAsExtInstImport(pInst->words[1], + ext_inst_type))) + return error; + } + + if (context->binaryEncodeString(literal.str.c_str(), pInst)) + return SPV_ERROR_INVALID_TEXT; + } break; + + // Masks. + case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE: + case SPV_OPERAND_TYPE_FUNCTION_CONTROL: + case SPV_OPERAND_TYPE_LOOP_CONTROL: + case SPV_OPERAND_TYPE_IMAGE: + case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: + case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: + case SPV_OPERAND_TYPE_SELECTION_CONTROL: + case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: { + uint32_t value; + if (auto error = grammar.parseMaskOperand(type, textValue, &value)) { + return context->diagnostic(error) + << "Invalid " << spvOperandTypeStr(type) << " operand '" + << textValue << "'."; + } + if (auto error = context->binaryEncodeU32(value, pInst)) return error; + // Prepare to parse the operands for this logical operand. + grammar.pushOperandTypesForMask(type, value, pExpectedOperands); + } break; + case SPV_OPERAND_TYPE_OPTIONAL_CIV: { + auto error = spvTextEncodeOperand( + grammar, context, SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER, textValue, + pInst, pExpectedOperands); + if (error == SPV_FAILED_MATCH) { + // It's not a literal number -- is it a literal string? + error = spvTextEncodeOperand(grammar, context, + SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING, + textValue, pInst, pExpectedOperands); + } + if (error == SPV_FAILED_MATCH) { + // It's not a literal -- is it an ID? + error = + spvTextEncodeOperand(grammar, context, SPV_OPERAND_TYPE_OPTIONAL_ID, + textValue, pInst, pExpectedOperands); + } + if (error) { + return context->diagnostic(error) + << "Invalid word following !: " << textValue; + } + if (pExpectedOperands->empty()) { + pExpectedOperands->push_back(SPV_OPERAND_TYPE_OPTIONAL_CIV); + } + } break; + default: { + // NOTE: All non literal operands are handled here using the operand + // table. + spv_operand_desc entry; + if (grammar.lookupOperand(type, textValue, strlen(textValue), &entry)) { + return context->diagnostic() << "Invalid " << spvOperandTypeStr(type) + << " '" << textValue << "'."; + } + if (context->binaryEncodeU32(entry->value, pInst)) { + return context->diagnostic() << "Invalid " << spvOperandTypeStr(type) + << " '" << textValue << "'."; + } + + // Prepare to parse the operands for this logical operand. + spvPushOperandTypes(entry->operandTypes, pExpectedOperands); + } break; + } + return SPV_SUCCESS; +} + +namespace { + +/// Encodes an instruction started by ! at the given position in text. +/// +/// Puts the encoded words into *pInst. If successful, moves position past the +/// instruction and returns SPV_SUCCESS. Otherwise, returns an error code and +/// leaves position pointing to the error in text. +spv_result_t encodeInstructionStartingWithImmediate( + const spvtools::AssemblyGrammar& grammar, + spvtools::AssemblyContext* context, spv_instruction_t* pInst) { + std::string firstWord; + spv_position_t nextPosition = {}; + auto error = context->getWord(&firstWord, &nextPosition); + if (error) return context->diagnostic(error) << "Internal Error"; + + if ((error = encodeImmediate(context, firstWord.c_str(), pInst))) { + return error; + } + while (context->advance() != SPV_END_OF_STREAM) { + // A beginning of a new instruction means we're done. + if (context->isStartOfNewInst()) return SPV_SUCCESS; + + // Otherwise, there must be an operand that's either a literal, an ID, or + // an immediate. + std::string operandValue; + if ((error = context->getWord(&operandValue, &nextPosition))) + return context->diagnostic(error) << "Internal Error"; + + if (operandValue == "=") + return context->diagnostic() << firstWord << " not allowed before =."; + + // Needed to pass to spvTextEncodeOpcode(), but it shouldn't ever be + // expanded. + spv_operand_pattern_t dummyExpectedOperands; + error = spvTextEncodeOperand( + grammar, context, SPV_OPERAND_TYPE_OPTIONAL_CIV, operandValue.c_str(), + pInst, &dummyExpectedOperands); + if (error) return error; + context->setPosition(nextPosition); + } + return SPV_SUCCESS; +} + +/// @brief Translate single Opcode and operands to binary form +/// +/// @param[in] grammar the grammar to use for compilation +/// @param[in, out] context the dynamic compilation info +/// @param[in] text stream to translate +/// @param[out] pInst returned binary Opcode +/// @param[in,out] pPosition in the text stream +/// +/// @return result code +spv_result_t spvTextEncodeOpcode(const spvtools::AssemblyGrammar& grammar, + spvtools::AssemblyContext* context, + spv_instruction_t* pInst) { + // Check for ! first. + if ('!' == context->peek()) { + return encodeInstructionStartingWithImmediate(grammar, context, pInst); + } + + std::string firstWord; + spv_position_t nextPosition = {}; + spv_result_t error = context->getWord(&firstWord, &nextPosition); + if (error) return context->diagnostic() << "Internal Error"; + + std::string opcodeName; + std::string result_id; + spv_position_t result_id_position = {}; + if (context->startsWithOp()) { + opcodeName = firstWord; + } else { + result_id = firstWord; + if ('%' != result_id.front()) { + return context->diagnostic() + << "Expected or at the beginning " + "of an instruction, found '" + << result_id << "'."; + } + result_id_position = context->position(); + + // The '=' sign. + context->setPosition(nextPosition); + if (context->advance()) + return context->diagnostic() << "Expected '=', found end of stream."; + std::string equal_sign; + error = context->getWord(&equal_sign, &nextPosition); + if ("=" != equal_sign) + return context->diagnostic() << "'=' expected after result id but found '" + << equal_sign << "'."; + + // The after the '=' sign. + context->setPosition(nextPosition); + if (context->advance()) + return context->diagnostic() << "Expected opcode, found end of stream."; + error = context->getWord(&opcodeName, &nextPosition); + if (error) return context->diagnostic(error) << "Internal Error"; + if (!context->startsWithOp()) { + return context->diagnostic() + << "Invalid Opcode prefix '" << opcodeName << "'."; + } + } + + // NOTE: The table contains Opcode names without the "Op" prefix. + const char* pInstName = opcodeName.data() + 2; + + spv_opcode_desc opcodeEntry; + error = grammar.lookupOpcode(pInstName, &opcodeEntry); + if (error) { + return context->diagnostic(error) + << "Invalid Opcode name '" << opcodeName << "'"; + } + if (opcodeEntry->hasResult && result_id.empty()) { + return context->diagnostic() + << "Expected at the beginning of an instruction, found '" + << firstWord << "'."; + } + if (!opcodeEntry->hasResult && !result_id.empty()) { + return context->diagnostic() + << "Cannot set ID " << result_id << " because " << opcodeName + << " does not produce a result ID."; + } + pInst->opcode = opcodeEntry->opcode; + context->setPosition(nextPosition); + // Reserve the first word for the instruction. + spvInstructionAddWord(pInst, 0); + + // Maintains the ordered list of expected operand types. + // For many instructions we only need the {numTypes, operandTypes} + // entries in opcodeEntry. However, sometimes we need to modify + // the list as we parse the operands. This occurs when an operand + // has its own logical operands (such as the LocalSize operand for + // ExecutionMode), or for extended instructions that may have their + // own operands depending on the selected extended instruction. + spv_operand_pattern_t expectedOperands; + expectedOperands.reserve(opcodeEntry->numTypes); + for (auto i = 0; i < opcodeEntry->numTypes; i++) + expectedOperands.push_back( + opcodeEntry->operandTypes[opcodeEntry->numTypes - i - 1]); + + while (!expectedOperands.empty()) { + const spv_operand_type_t type = expectedOperands.back(); + expectedOperands.pop_back(); + + // Expand optional tuples lazily. + if (spvExpandOperandSequenceOnce(type, &expectedOperands)) continue; + + if (type == SPV_OPERAND_TYPE_RESULT_ID && !result_id.empty()) { + // Handle the for value generating instructions. + // We've already consumed it from the text stream. Here + // we inject its words into the instruction. + spv_position_t temp_pos = context->position(); + error = spvTextEncodeOperand(grammar, context, SPV_OPERAND_TYPE_RESULT_ID, + result_id.c_str(), pInst, nullptr); + result_id_position = context->position(); + // Because we are injecting we have to reset the position afterwards. + context->setPosition(temp_pos); + if (error) return error; + } else { + // Find the next word. + error = context->advance(); + if (error == SPV_END_OF_STREAM) { + if (spvOperandIsOptional(type)) { + // This would have been the last potential operand for the + // instruction, + // and we didn't find one. We're finished parsing this instruction. + break; + } else { + return context->diagnostic() + << "Expected operand for " << opcodeName + << " instruction, but found the end of the stream."; + } + } + assert(error == SPV_SUCCESS && "Somebody added another way to fail"); + + if (context->isStartOfNewInst()) { + if (spvOperandIsOptional(type)) { + break; + } else { + return context->diagnostic() + << "Expected operand for " << opcodeName + << " instruction, but found the next instruction instead."; + } + } + + std::string operandValue; + error = context->getWord(&operandValue, &nextPosition); + if (error) return context->diagnostic(error) << "Internal Error"; + + error = spvTextEncodeOperand(grammar, context, type, operandValue.c_str(), + pInst, &expectedOperands); + + if (error == SPV_FAILED_MATCH && spvOperandIsOptional(type)) + return SPV_SUCCESS; + + if (error) return error; + + context->setPosition(nextPosition); + } + } + + if (spvOpcodeGeneratesType(pInst->opcode)) { + if (context->recordTypeDefinition(pInst) != SPV_SUCCESS) { + return SPV_ERROR_INVALID_TEXT; + } + } else if (opcodeEntry->hasType) { + // SPIR-V dictates that if an instruction has both a return value and a + // type ID then the type id is first, and the return value is second. + assert(opcodeEntry->hasResult && + "Unknown opcode: has a type but no result."); + context->recordTypeIdForValue(pInst->words[2], pInst->words[1]); + } + + if (pInst->words.size() > SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX) { + return context->diagnostic() + << opcodeName << " Instruction too long: " << pInst->words.size() + << " words, but the limit is " + << SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX; + } + + pInst->words[0] = + spvOpcodeMake(uint16_t(pInst->words.size()), opcodeEntry->opcode); + + return SPV_SUCCESS; +} + +enum { kAssemblerVersion = 0 }; + +// Populates a binary stream's |header|. The target environment is specified via +// |env| and Id bound is via |bound|. +spv_result_t SetHeader(spv_target_env env, const uint32_t bound, + uint32_t* header) { + if (!header) return SPV_ERROR_INVALID_BINARY; + + header[SPV_INDEX_MAGIC_NUMBER] = spv::MagicNumber; + header[SPV_INDEX_VERSION_NUMBER] = spvVersionForTargetEnv(env); + header[SPV_INDEX_GENERATOR_NUMBER] = + SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, kAssemblerVersion); + header[SPV_INDEX_BOUND] = bound; + header[SPV_INDEX_SCHEMA] = 0; // NOTE: Reserved + + return SPV_SUCCESS; +} + +// Collects all numeric ids in the module source into |numeric_ids|. +// This function is essentially a dry-run of spvTextToBinary. +spv_result_t GetNumericIds(const spvtools::AssemblyGrammar& grammar, + const spvtools::MessageConsumer& consumer, + const spv_text text, + std::set* numeric_ids) { + spvtools::AssemblyContext context(text, consumer); + + if (!text->str) return context.diagnostic() << "Missing assembly text."; + + if (!grammar.isValid()) { + return SPV_ERROR_INVALID_TABLE; + } + + // Skip past whitespace and comments. + context.advance(); + + while (context.hasText()) { + spv_instruction_t inst; + + // Operand parsing sometimes involves knowing the opcode of the instruction + // being parsed. A malformed input might feature such an operand *before* + // the opcode is known. To guard against accessing an uninitialized opcode, + // the instruction's opcode is initialized to a default value. + inst.opcode = spv::Op::Max; + + if (spvTextEncodeOpcode(grammar, &context, &inst)) { + return SPV_ERROR_INVALID_TEXT; + } + + if (context.advance()) break; + } + + *numeric_ids = context.GetNumericIds(); + return SPV_SUCCESS; +} + +// Translates a given assembly language module into binary form. +// If a diagnostic is generated, it is not yet marked as being +// for a text-based input. +spv_result_t spvTextToBinaryInternal(const spvtools::AssemblyGrammar& grammar, + const spvtools::MessageConsumer& consumer, + const spv_text text, + const uint32_t options, + spv_binary* pBinary) { + // The ids in this set will have the same values both in source and binary. + // All other ids will be generated by filling in the gaps. + std::set ids_to_preserve; + + if (options & SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS) { + // Collect all numeric ids from the source into ids_to_preserve. + const spv_result_t result = + GetNumericIds(grammar, consumer, text, &ids_to_preserve); + if (result != SPV_SUCCESS) return result; + } + + spvtools::AssemblyContext context(text, consumer, std::move(ids_to_preserve)); + + if (!text->str) return context.diagnostic() << "Missing assembly text."; + + if (!grammar.isValid()) { + return SPV_ERROR_INVALID_TABLE; + } + if (!pBinary) return SPV_ERROR_INVALID_POINTER; + + std::vector instructions; + + // Skip past whitespace and comments. + context.advance(); + + while (context.hasText()) { + instructions.push_back({}); + spv_instruction_t& inst = instructions.back(); + + if (auto error = spvTextEncodeOpcode(grammar, &context, &inst)) { + return error; + } + + if (context.advance()) break; + } + + size_t totalSize = SPV_INDEX_INSTRUCTION; + for (auto& inst : instructions) { + totalSize += inst.words.size(); + } + + uint32_t* data = new uint32_t[totalSize]; + if (!data) return SPV_ERROR_OUT_OF_MEMORY; + uint64_t currentIndex = SPV_INDEX_INSTRUCTION; + for (auto& inst : instructions) { + memcpy(data + currentIndex, inst.words.data(), + sizeof(uint32_t) * inst.words.size()); + currentIndex += inst.words.size(); + } + + if (auto error = SetHeader(grammar.target_env(), context.getBound(), data)) + return error; + + spv_binary binary = new spv_binary_t(); + if (!binary) { + delete[] data; + return SPV_ERROR_OUT_OF_MEMORY; + } + binary->code = data; + binary->wordCount = totalSize; + + *pBinary = binary; + + return SPV_SUCCESS; +} + +} // anonymous namespace + +spv_result_t spvTextToBinary(const spv_const_context context, + const char* input_text, + const size_t input_text_size, spv_binary* pBinary, + spv_diagnostic* pDiagnostic) { + return spvTextToBinaryWithOptions(context, input_text, input_text_size, + SPV_TEXT_TO_BINARY_OPTION_NONE, pBinary, + pDiagnostic); +} + +spv_result_t spvTextToBinaryWithOptions(const spv_const_context context, + const char* input_text, + const size_t input_text_size, + const uint32_t options, + spv_binary* pBinary, + spv_diagnostic* pDiagnostic) { + spv_context_t hijack_context = *context; + if (pDiagnostic) { + *pDiagnostic = nullptr; + spvtools::UseDiagnosticAsMessageConsumer(&hijack_context, pDiagnostic); + } + + spv_text_t text = {input_text, input_text_size}; + spvtools::AssemblyGrammar grammar(&hijack_context); + + spv_result_t result = spvTextToBinaryInternal( + grammar, hijack_context.consumer, &text, options, pBinary); + if (pDiagnostic && *pDiagnostic) (*pDiagnostic)->isTextSource = true; + + return result; +} + +void spvTextDestroy(spv_text text) { + if (text) { + if (text->str) delete[] text->str; + delete text; + } +} diff --git a/thirdparty/glslang/External/spirv-tools/source/text.h b/thirdparty/glslang/External/spirv-tools/source/text.h new file mode 100644 index 000000000000..fa34ee16be17 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/text.h @@ -0,0 +1,53 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_TEXT_H_ +#define SOURCE_TEXT_H_ + +#include + +#include "source/operand.h" +#include "source/spirv_constant.h" +#include "spirv-tools/libspirv.h" + +typedef enum spv_literal_type_t { + SPV_LITERAL_TYPE_INT_32, + SPV_LITERAL_TYPE_INT_64, + SPV_LITERAL_TYPE_UINT_32, + SPV_LITERAL_TYPE_UINT_64, + SPV_LITERAL_TYPE_FLOAT_32, + SPV_LITERAL_TYPE_FLOAT_64, + SPV_LITERAL_TYPE_STRING, + SPV_FORCE_32_BIT_ENUM(spv_literal_type_t) +} spv_literal_type_t; + +typedef struct spv_literal_t { + spv_literal_type_t type; + union value_t { + int32_t i32; + int64_t i64; + uint32_t u32; + uint64_t u64; + float f; + double d; + } value; + std::string str; // Special field for literal string. +} spv_literal_t; + +// Converts the given text string to a number/string literal and writes the +// result to *literal. String literals must be surrounded by double-quotes ("), +// which are then stripped. +spv_result_t spvTextToLiteral(const char* text, spv_literal_t* literal); + +#endif // SOURCE_TEXT_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/text_handler.cpp b/thirdparty/glslang/External/spirv-tools/source/text_handler.cpp new file mode 100644 index 000000000000..35c4b83c1063 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/text_handler.cpp @@ -0,0 +1,394 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/text_handler.h" + +#include +#include +#include +#include +#include + +#include "source/assembly_grammar.h" +#include "source/binary.h" +#include "source/ext_inst.h" +#include "source/instruction.h" +#include "source/opcode.h" +#include "source/text.h" +#include "source/util/bitutils.h" +#include "source/util/hex_float.h" +#include "source/util/parse_number.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace { + +// Advances |text| to the start of the next line and writes the new position to +// |position|. +spv_result_t advanceLine(spv_text text, spv_position position) { + while (true) { + if (position->index >= text->length) return SPV_END_OF_STREAM; + switch (text->str[position->index]) { + case '\0': + return SPV_END_OF_STREAM; + case '\n': + position->column = 0; + position->line++; + position->index++; + return SPV_SUCCESS; + default: + position->column++; + position->index++; + break; + } + } +} + +// Advances |text| to first non white space character and writes the new +// position to |position|. +// If a null terminator is found during the text advance, SPV_END_OF_STREAM is +// returned, SPV_SUCCESS otherwise. No error checking is performed on the +// parameters, its the users responsibility to ensure these are non null. +spv_result_t advance(spv_text text, spv_position position) { + // NOTE: Consume white space, otherwise don't advance. + while (true) { + if (position->index >= text->length) return SPV_END_OF_STREAM; + switch (text->str[position->index]) { + case '\0': + return SPV_END_OF_STREAM; + case ';': + if (spv_result_t error = advanceLine(text, position)) return error; + continue; + case ' ': + case '\t': + case '\r': + position->column++; + position->index++; + continue; + case '\n': + position->column = 0; + position->line++; + position->index++; + continue; + default: + return SPV_SUCCESS; + } + } +} + +// Fetches the next word from the given text stream starting from the given +// *position. On success, writes the decoded word into *word and updates +// *position to the location past the returned word. +// +// A word ends at the next comment or whitespace. However, double-quoted +// strings remain intact, and a backslash always escapes the next character. +spv_result_t getWord(spv_text text, spv_position position, std::string* word) { + if (!text->str || !text->length) return SPV_ERROR_INVALID_TEXT; + if (!position) return SPV_ERROR_INVALID_POINTER; + + const size_t start_index = position->index; + + bool quoting = false; + bool escaping = false; + + // NOTE: Assumes first character is not white space! + while (true) { + if (position->index >= text->length) { + word->assign(text->str + start_index, text->str + position->index); + return SPV_SUCCESS; + } + const char ch = text->str[position->index]; + if (ch == '\\') { + escaping = !escaping; + } else { + switch (ch) { + case '"': + if (!escaping) quoting = !quoting; + break; + case ' ': + case ';': + case '\t': + case '\n': + case '\r': + if (escaping || quoting) break; + word->assign(text->str + start_index, text->str + position->index); + return SPV_SUCCESS; + case '\0': { // NOTE: End of word found! + word->assign(text->str + start_index, text->str + position->index); + return SPV_SUCCESS; + } + default: + break; + } + escaping = false; + } + + position->column++; + position->index++; + } +} + +// Returns true if the characters in the text as position represent +// the start of an Opcode. +bool startsWithOp(spv_text text, spv_position position) { + if (text->length < position->index + 3) return false; + char ch0 = text->str[position->index]; + char ch1 = text->str[position->index + 1]; + char ch2 = text->str[position->index + 2]; + return ('O' == ch0 && 'p' == ch1 && ('A' <= ch2 && ch2 <= 'Z')); +} + +} // namespace + +const IdType kUnknownType = {0, false, IdTypeClass::kBottom}; + +// TODO(dneto): Reorder AssemblyContext definitions to match declaration order. + +// This represents all of the data that is only valid for the duration of +// a single compilation. +uint32_t AssemblyContext::spvNamedIdAssignOrGet(const char* textValue) { + if (!ids_to_preserve_.empty()) { + uint32_t id = 0; + if (spvtools::utils::ParseNumber(textValue, &id)) { + if (ids_to_preserve_.find(id) != ids_to_preserve_.end()) { + bound_ = std::max(bound_, id + 1); + return id; + } + } + } + + const auto it = named_ids_.find(textValue); + if (it == named_ids_.end()) { + uint32_t id = next_id_++; + if (!ids_to_preserve_.empty()) { + while (ids_to_preserve_.find(id) != ids_to_preserve_.end()) { + id = next_id_++; + } + } + + named_ids_.emplace(textValue, id); + bound_ = std::max(bound_, id + 1); + return id; + } + + return it->second; +} + +uint32_t AssemblyContext::getBound() const { return bound_; } + +spv_result_t AssemblyContext::advance() { + return spvtools::advance(text_, ¤t_position_); +} + +spv_result_t AssemblyContext::getWord(std::string* word, + spv_position next_position) { + *next_position = current_position_; + return spvtools::getWord(text_, next_position, word); +} + +bool AssemblyContext::startsWithOp() { + return spvtools::startsWithOp(text_, ¤t_position_); +} + +bool AssemblyContext::isStartOfNewInst() { + spv_position_t pos = current_position_; + if (spvtools::advance(text_, &pos)) return false; + if (spvtools::startsWithOp(text_, &pos)) return true; + + std::string word; + pos = current_position_; + if (spvtools::getWord(text_, &pos, &word)) return false; + if ('%' != word.front()) return false; + + if (spvtools::advance(text_, &pos)) return false; + if (spvtools::getWord(text_, &pos, &word)) return false; + if ("=" != word) return false; + + if (spvtools::advance(text_, &pos)) return false; + if (spvtools::startsWithOp(text_, &pos)) return true; + return false; +} + +char AssemblyContext::peek() const { + return text_->str[current_position_.index]; +} + +bool AssemblyContext::hasText() const { + return text_->length > current_position_.index; +} + +void AssemblyContext::seekForward(uint32_t size) { + current_position_.index += size; + current_position_.column += size; +} + +spv_result_t AssemblyContext::binaryEncodeU32(const uint32_t value, + spv_instruction_t* pInst) { + pInst->words.insert(pInst->words.end(), value); + return SPV_SUCCESS; +} + +spv_result_t AssemblyContext::binaryEncodeNumericLiteral( + const char* val, spv_result_t error_code, const IdType& type, + spv_instruction_t* pInst) { + using spvtools::utils::EncodeNumberStatus; + // Populate the NumberType from the IdType for parsing. + spvtools::utils::NumberType number_type; + switch (type.type_class) { + case IdTypeClass::kOtherType: + return diagnostic(SPV_ERROR_INTERNAL) + << "Unexpected numeric literal type"; + case IdTypeClass::kScalarIntegerType: + if (type.isSigned) { + number_type = {type.bitwidth, SPV_NUMBER_SIGNED_INT}; + } else { + number_type = {type.bitwidth, SPV_NUMBER_UNSIGNED_INT}; + } + break; + case IdTypeClass::kScalarFloatType: + number_type = {type.bitwidth, SPV_NUMBER_FLOATING}; + break; + case IdTypeClass::kBottom: + // kBottom means the type is unknown and we need to infer the type before + // parsing the number. The rule is: If there is a decimal point, treat + // the value as a floating point value, otherwise a integer value, then + // if the first char of the integer text is '-', treat the integer as a + // signed integer, otherwise an unsigned integer. + uint32_t bitwidth = static_cast(assumedBitWidth(type)); + if (strchr(val, '.')) { + number_type = {bitwidth, SPV_NUMBER_FLOATING}; + } else if (type.isSigned || val[0] == '-') { + number_type = {bitwidth, SPV_NUMBER_SIGNED_INT}; + } else { + number_type = {bitwidth, SPV_NUMBER_UNSIGNED_INT}; + } + break; + } + + std::string error_msg; + EncodeNumberStatus parse_status = ParseAndEncodeNumber( + val, number_type, + [this, pInst](uint32_t d) { this->binaryEncodeU32(d, pInst); }, + &error_msg); + switch (parse_status) { + case EncodeNumberStatus::kSuccess: + return SPV_SUCCESS; + case EncodeNumberStatus::kInvalidText: + return diagnostic(error_code) << error_msg; + case EncodeNumberStatus::kUnsupported: + return diagnostic(SPV_ERROR_INTERNAL) << error_msg; + case EncodeNumberStatus::kInvalidUsage: + return diagnostic(SPV_ERROR_INVALID_TEXT) << error_msg; + } + // This line is not reachable, only added to satisfy the compiler. + return diagnostic(SPV_ERROR_INTERNAL) + << "Unexpected result code from ParseAndEncodeNumber()"; +} + +spv_result_t AssemblyContext::binaryEncodeString(const char* value, + spv_instruction_t* pInst) { + const size_t length = strlen(value); + const size_t wordCount = (length / 4) + 1; + const size_t oldWordCount = pInst->words.size(); + const size_t newWordCount = oldWordCount + wordCount; + + // TODO(dneto): We can just defer this check until later. + if (newWordCount > SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX) { + return diagnostic() << "Instruction too long: more than " + << SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX << " words."; + } + + pInst->words.reserve(newWordCount); + spvtools::utils::AppendToVector(value, &pInst->words); + + return SPV_SUCCESS; +} + +spv_result_t AssemblyContext::recordTypeDefinition( + const spv_instruction_t* pInst) { + uint32_t value = pInst->words[1]; + if (types_.find(value) != types_.end()) { + return diagnostic() << "Value " << value + << " has already been used to generate a type"; + } + + if (pInst->opcode == spv::Op::OpTypeInt) { + if (pInst->words.size() != 4) + return diagnostic() << "Invalid OpTypeInt instruction"; + types_[value] = {pInst->words[2], pInst->words[3] != 0, + IdTypeClass::kScalarIntegerType}; + } else if (pInst->opcode == spv::Op::OpTypeFloat) { + if (pInst->words.size() != 3) + return diagnostic() << "Invalid OpTypeFloat instruction"; + types_[value] = {pInst->words[2], false, IdTypeClass::kScalarFloatType}; + } else { + types_[value] = {0, false, IdTypeClass::kOtherType}; + } + return SPV_SUCCESS; +} + +IdType AssemblyContext::getTypeOfTypeGeneratingValue(uint32_t value) const { + auto type = types_.find(value); + if (type == types_.end()) { + return kUnknownType; + } + return std::get<1>(*type); +} + +IdType AssemblyContext::getTypeOfValueInstruction(uint32_t value) const { + auto type_value = value_types_.find(value); + if (type_value == value_types_.end()) { + return {0, false, IdTypeClass::kBottom}; + } + return getTypeOfTypeGeneratingValue(std::get<1>(*type_value)); +} + +spv_result_t AssemblyContext::recordTypeIdForValue(uint32_t value, + uint32_t type) { + bool successfully_inserted = false; + std::tie(std::ignore, successfully_inserted) = + value_types_.insert(std::make_pair(value, type)); + if (!successfully_inserted) + return diagnostic() << "Value is being defined a second time"; + return SPV_SUCCESS; +} + +spv_result_t AssemblyContext::recordIdAsExtInstImport( + uint32_t id, spv_ext_inst_type_t type) { + bool successfully_inserted = false; + std::tie(std::ignore, successfully_inserted) = + import_id_to_ext_inst_type_.insert(std::make_pair(id, type)); + if (!successfully_inserted) + return diagnostic() << "Import Id is being defined a second time"; + return SPV_SUCCESS; +} + +spv_ext_inst_type_t AssemblyContext::getExtInstTypeForId(uint32_t id) const { + auto type = import_id_to_ext_inst_type_.find(id); + if (type == import_id_to_ext_inst_type_.end()) { + return SPV_EXT_INST_TYPE_NONE; + } + return std::get<1>(*type); +} + +std::set AssemblyContext::GetNumericIds() const { + std::set ids; + for (const auto& kv : named_ids_) { + uint32_t id; + if (spvtools::utils::ParseNumber(kv.first.c_str(), &id)) ids.insert(id); + } + return ids; +} + +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/text_handler.h b/thirdparty/glslang/External/spirv-tools/source/text_handler.h new file mode 100644 index 000000000000..19972e95194e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/text_handler.h @@ -0,0 +1,264 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_TEXT_HANDLER_H_ +#define SOURCE_TEXT_HANDLER_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/diagnostic.h" +#include "source/instruction.h" +#include "source/text.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { + +// Structures + +// This is a lattice for tracking types. +enum class IdTypeClass { + kBottom = 0, // We have no information yet. + kScalarIntegerType, + kScalarFloatType, + kOtherType +}; + +// Contains ID type information that needs to be tracked across all Ids. +// Bitwidth is only valid when type_class is kScalarIntegerType or +// kScalarFloatType. +struct IdType { + uint32_t bitwidth; // Safe to assume that we will not have > 2^32 bits. + bool isSigned; // This is only significant if type_class is integral. + IdTypeClass type_class; +}; + +// Default equality operator for IdType. Tests if all members are the same. +inline bool operator==(const IdType& first, const IdType& second) { + return (first.bitwidth == second.bitwidth) && + (first.isSigned == second.isSigned) && + (first.type_class == second.type_class); +} + +// Tests whether any member of the IdTypes do not match. +inline bool operator!=(const IdType& first, const IdType& second) { + return !(first == second); +} + +// A value representing an unknown type. +extern const IdType kUnknownType; + +// Returns true if the type is a scalar integer type. +inline bool isScalarIntegral(const IdType& type) { + return type.type_class == IdTypeClass::kScalarIntegerType; +} + +// Returns true if the type is a scalar floating point type. +inline bool isScalarFloating(const IdType& type) { + return type.type_class == IdTypeClass::kScalarFloatType; +} + +// Returns the number of bits in the type. +// This is only valid for bottom, scalar integer, and scalar floating +// classes. For bottom, assume 32 bits. +inline int assumedBitWidth(const IdType& type) { + switch (type.type_class) { + case IdTypeClass::kBottom: + return 32; + case IdTypeClass::kScalarIntegerType: + case IdTypeClass::kScalarFloatType: + return type.bitwidth; + default: + break; + } + // We don't care about this case. + return 0; +} + +// A templated class with a static member function Clamp, where Clamp +// sets a referenced value of type T to 0 if T is an unsigned +// integer type, and returns true if it modified the referenced +// value. +template +class ClampToZeroIfUnsignedType { + public: + // The default specialization does not clamp the value. + static bool Clamp(T*) { return false; } +}; + +// The specialization of ClampToZeroIfUnsignedType for unsigned integer +// types. +template +class ClampToZeroIfUnsignedType< + T, typename std::enable_if::value>::type> { + public: + static bool Clamp(T* value_pointer) { + if (*value_pointer) { + *value_pointer = 0; + return true; + } + return false; + } +}; + +// Encapsulates the data used during the assembly of a SPIR-V module. +class AssemblyContext { + public: + AssemblyContext(spv_text text, const MessageConsumer& consumer, + std::set&& ids_to_preserve = std::set()) + : current_position_({}), + consumer_(consumer), + text_(text), + bound_(1), + next_id_(1), + ids_to_preserve_(std::move(ids_to_preserve)) {} + + // Assigns a new integer value to the given text ID, or returns the previously + // assigned integer value if the ID has been seen before. + uint32_t spvNamedIdAssignOrGet(const char* textValue); + + // Returns the largest largest numeric ID that has been assigned. + uint32_t getBound() const; + + // Advances position to point to the next word in the input stream. + // Returns SPV_SUCCESS on success. + spv_result_t advance(); + + // Sets word to the next word in the input text. Fills next_position with + // the next location past the end of the word. + spv_result_t getWord(std::string* word, spv_position next_position); + + // Returns true if the next word in the input is the start of a new Opcode. + bool startsWithOp(); + + // Returns true if the next word in the input is the start of a new + // instruction. + bool isStartOfNewInst(); + + // Returns a diagnostic object initialized with current position in the input + // stream, and for the given error code. Any data written to this object will + // show up in pDiagnsotic on destruction. + DiagnosticStream diagnostic(spv_result_t error) { + return DiagnosticStream(current_position_, consumer_, "", error); + } + + // Returns a diagnostic object with the default assembly error code. + DiagnosticStream diagnostic() { + // The default failure for assembly is invalid text. + return diagnostic(SPV_ERROR_INVALID_TEXT); + } + + // Returns then next character in the input stream. + char peek() const; + + // Returns true if there is more text in the input stream. + bool hasText() const; + + // Seeks the input stream forward by 'size' characters. + void seekForward(uint32_t size); + + // Sets the current position in the input stream to the given position. + void setPosition(const spv_position_t& newPosition) { + current_position_ = newPosition; + } + + // Returns the current position in the input stream. + const spv_position_t& position() const { return current_position_; } + + // Appends the given 32-bit value to the given instruction. + // Returns SPV_SUCCESS if the value could be correctly inserted in the + // instruction. + spv_result_t binaryEncodeU32(const uint32_t value, spv_instruction_t* pInst); + + // Appends the given string to the given instruction. + // Returns SPV_SUCCESS if the value could be correctly inserted in the + // instruction. + spv_result_t binaryEncodeString(const char* value, spv_instruction_t* pInst); + + // Appends the given numeric literal to the given instruction. + // Validates and respects the bitwidth supplied in the IdType argument. + // If the type is of class kBottom the value will be encoded as a + // 32-bit integer. + // Returns SPV_SUCCESS if the value could be correctly added to the + // instruction. Returns the given error code on failure, and emits + // a diagnostic if that error code is not SPV_FAILED_MATCH. + spv_result_t binaryEncodeNumericLiteral(const char* numeric_literal, + spv_result_t error_code, + const IdType& type, + spv_instruction_t* pInst); + + // Returns the IdType associated with this type-generating value. + // If the type has not been previously recorded with recordTypeDefinition, + // kUnknownType will be returned. + IdType getTypeOfTypeGeneratingValue(uint32_t value) const; + + // Returns the IdType that represents the return value of this Value + // generating instruction. + // If the value has not been recorded with recordTypeIdForValue, or the type + // could not be determined kUnknownType will be returned. + IdType getTypeOfValueInstruction(uint32_t value) const; + + // Tracks the type-defining instruction. The result of the tracking can + // later be queried using getValueType. + // pInst is expected to be completely filled in by the time this instruction + // is called. + // Returns SPV_SUCCESS on success, or SPV_ERROR_INVALID_VALUE on error. + spv_result_t recordTypeDefinition(const spv_instruction_t* pInst); + + // Tracks the relationship between the value and its type. + spv_result_t recordTypeIdForValue(uint32_t value, uint32_t type); + + // Records the given Id as being the import of the given extended instruction + // type. + spv_result_t recordIdAsExtInstImport(uint32_t id, spv_ext_inst_type_t type); + + // Returns the extended instruction type corresponding to the import with + // the given Id, if it exists. Returns SPV_EXT_INST_TYPE_NONE if the + // id is not the id for an extended instruction type. + spv_ext_inst_type_t getExtInstTypeForId(uint32_t id) const; + + // Returns a set consisting of each ID generated by spvNamedIdAssignOrGet from + // a numeric ID text representation. For example, generated from "%12" but not + // from "%foo". + std::set GetNumericIds() const; + + private: + // Maps ID names to their corresponding numerical ids. + using spv_named_id_table = std::unordered_map; + // Maps type-defining IDs to their IdType. + using spv_id_to_type_map = std::unordered_map; + // Maps Ids to the id of their type. + using spv_id_to_type_id = std::unordered_map; + + spv_named_id_table named_ids_; + spv_id_to_type_map types_; + spv_id_to_type_id value_types_; + // Maps an extended instruction import Id to the extended instruction type. + std::unordered_map import_id_to_ext_inst_type_; + spv_position_t current_position_; + MessageConsumer consumer_; + spv_text text_; + uint32_t bound_; + uint32_t next_id_; + std::set ids_to_preserve_; +}; + +} // namespace spvtools + +#endif // SOURCE_TEXT_HANDLER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/bit_vector.cpp b/thirdparty/glslang/External/spirv-tools/source/util/bit_vector.cpp new file mode 100644 index 000000000000..47e275bf4618 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/bit_vector.cpp @@ -0,0 +1,82 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/util/bit_vector.h" + +#include +#include + +namespace spvtools { +namespace utils { + +void BitVector::ReportDensity(std::ostream& out) { + uint32_t count = 0; + + for (BitContainer e : bits_) { + while (e != 0) { + if ((e & 1) != 0) { + ++count; + } + e = e >> 1; + } + } + + out << "count=" << count + << ", total size (bytes)=" << bits_.size() * sizeof(BitContainer) + << ", bytes per element=" + << (double)(bits_.size() * sizeof(BitContainer)) / (double)(count); +} + +bool BitVector::Or(const BitVector& other) { + auto this_it = this->bits_.begin(); + auto other_it = other.bits_.begin(); + bool modified = false; + + while (this_it != this->bits_.end() && other_it != other.bits_.end()) { + auto temp = *this_it | *other_it; + if (temp != *this_it) { + modified = true; + *this_it = temp; + } + ++this_it; + ++other_it; + } + + if (other_it != other.bits_.end()) { + modified = true; + this->bits_.insert(this->bits_.end(), other_it, other.bits_.end()); + } + + return modified; +} + +std::ostream& operator<<(std::ostream& out, const BitVector& bv) { + out << "{"; + for (uint32_t i = 0; i < bv.bits_.size(); ++i) { + BitVector::BitContainer b = bv.bits_[i]; + uint32_t j = 0; + while (b != 0) { + if (b & 1) { + out << ' ' << i * BitVector::kBitContainerSize + j; + } + ++j; + b = b >> 1; + } + } + out << "}"; + return out; +} + +} // namespace utils +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/util/bit_vector.h b/thirdparty/glslang/External/spirv-tools/source/util/bit_vector.h new file mode 100644 index 000000000000..826d62f02360 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/bit_vector.h @@ -0,0 +1,119 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_BIT_VECTOR_H_ +#define SOURCE_UTIL_BIT_VECTOR_H_ + +#include +#include +#include + +namespace spvtools { +namespace utils { + +// Implements a bit vector class. +// +// All bits default to zero, and the upper bound is 2^32-1. +class BitVector { + private: + using BitContainer = uint64_t; + enum { kBitContainerSize = 64 }; + enum { kInitialNumBits = 1024 }; + + public: + // Creates a bit vector containing 0s. + BitVector(uint32_t reserved_size = kInitialNumBits) + : bits_((reserved_size - 1) / kBitContainerSize + 1, 0) {} + + // Sets the |i|th bit to 1. Returns the |i|th bit before it was set. + bool Set(uint32_t i) { + uint32_t element_index = i / kBitContainerSize; + uint32_t bit_in_element = i % kBitContainerSize; + + if (element_index >= bits_.size()) { + bits_.resize(element_index + 1, 0); + } + + BitContainer original = bits_[element_index]; + BitContainer ith_bit = static_cast(1) << bit_in_element; + + if ((original & ith_bit) != 0) { + return true; + } else { + bits_[element_index] = original | ith_bit; + return false; + } + } + + // Sets the |i|th bit to 0. Return the |i|th bit before it was cleared. + bool Clear(uint32_t i) { + uint32_t element_index = i / kBitContainerSize; + uint32_t bit_in_element = i % kBitContainerSize; + + if (element_index >= bits_.size()) { + return false; + } + + BitContainer original = bits_[element_index]; + BitContainer ith_bit = static_cast(1) << bit_in_element; + + if ((original & ith_bit) == 0) { + return false; + } else { + bits_[element_index] = original & (~ith_bit); + return true; + } + } + + // Returns the |i|th bit. + bool Get(uint32_t i) const { + uint32_t element_index = i / kBitContainerSize; + uint32_t bit_in_element = i % kBitContainerSize; + + if (element_index >= bits_.size()) { + return false; + } + + return (bits_[element_index] & + (static_cast(1) << bit_in_element)) != 0; + } + + // Returns true if every bit is 0. + bool Empty() const { + for (BitContainer b : bits_) { + if (b != 0) { + return false; + } + } + return true; + } + + // Print a report on the densicy of the bit vector, number of 1 bits, number + // of bytes, and average bytes for 1 bit, to |out|. + void ReportDensity(std::ostream& out); + + friend std::ostream& operator<<(std::ostream&, const BitVector&); + + // Performs a bitwise-or operation on |this| and |that|, storing the result in + // |this|. Return true if |this| changed. + bool Or(const BitVector& that); + + private: + std::vector bits_; +}; + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_BIT_VECTOR_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/bitutils.h b/thirdparty/glslang/External/spirv-tools/source/util/bitutils.h new file mode 100644 index 000000000000..9ced2f9621ca --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/bitutils.h @@ -0,0 +1,187 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_BITUTILS_H_ +#define SOURCE_UTIL_BITUTILS_H_ + +#include +#include +#include +#include + +namespace spvtools { +namespace utils { + +// Performs a bitwise copy of source to the destination type Dest. +template +Dest BitwiseCast(Src source) { + Dest dest; + static_assert(sizeof(source) == sizeof(dest), + "BitwiseCast: Source and destination must have the same size"); + std::memcpy(&dest, &source, sizeof(dest)); + return dest; +} + +// Calculates the bit width of the integer type |T|. +template +struct IntegerBitWidth { + static_assert(std::is_integral::value, "Integer type required"); + static const size_t kBitsPerByte = 8; + static const size_t get = sizeof(T) * kBitsPerByte; +}; + +// SetBits returns an integer of type with bits set +// for position through , counting from the least +// significant bit. In particular when Num == 0, no positions are set to 1. +// A static assert will be triggered if First + Num > sizeof(T) * 8, that is, +// a bit that will not fit in the underlying type is set. +template +struct SetBits { + static_assert(First < IntegerBitWidth::get, + "Tried to set a bit that is shifted too far."); + const static T get = (T(1) << First) | SetBits::get; +}; + +template +struct SetBits { + const static T get = T(0); +}; + +// This is all compile-time so we can put our tests right here. +static_assert(IntegerBitWidth::get == 32, "IntegerBitWidth mismatch"); +static_assert(IntegerBitWidth::get == 32, "IntegerBitWidth mismatch"); +static_assert(IntegerBitWidth::get == 64, "IntegerBitWidth mismatch"); +static_assert(IntegerBitWidth::get == 8, "IntegerBitWidth mismatch"); + +static_assert(SetBits::get == uint32_t(0x00000000), + "SetBits failed"); +static_assert(SetBits::get == uint32_t(0x00000001), + "SetBits failed"); +static_assert(SetBits::get == uint32_t(0x80000000), + "SetBits failed"); +static_assert(SetBits::get == uint32_t(0x00000006), + "SetBits failed"); +static_assert(SetBits::get == uint32_t(0xc0000000), + "SetBits failed"); +static_assert(SetBits::get == uint32_t(0x7FFFFFFF), + "SetBits failed"); +static_assert(SetBits::get == uint32_t(0xFFFFFFFF), + "SetBits failed"); +static_assert(SetBits::get == uint32_t(0xFFFF0000), + "SetBits failed"); + +static_assert(SetBits::get == uint64_t(0x0000000000000001LL), + "SetBits failed"); +static_assert(SetBits::get == uint64_t(0x8000000000000000LL), + "SetBits failed"); +static_assert(SetBits::get == uint64_t(0xc000000000000000LL), + "SetBits failed"); +static_assert(SetBits::get == uint64_t(0x0000000080000000LL), + "SetBits failed"); +static_assert(SetBits::get == uint64_t(0x00000000FFFF0000LL), + "SetBits failed"); + +// Returns number of '1' bits in a word. +template +size_t CountSetBits(T word) { + static_assert(std::is_integral::value, + "CountSetBits requires integer type"); + size_t count = 0; + while (word) { + word &= word - 1; + ++count; + } + return count; +} + +// Checks if the bit at the |position| is set to '1'. +// Bits zero-indexed starting at the least significant bit. +// |position| must be within the bit width of |T|. +template +bool IsBitAtPositionSet(T word, size_t position) { + static_assert(std::is_integral::value, "Integer type required"); + static_assert(std::is_unsigned::value, "Unsigned type required"); + assert(position < IntegerBitWidth::get && + "position must be less than the bit width"); + return word & T(T(1) << position); +} + +// Returns a value obtained by setting a range of adjacent bits of |word| to +// |value|. Affected bits are within the range: +// [first_position, first_position + num_bits_to_mutate), +// assuming zero-based indexing starting at the least +// significant bit. Bits to mutate must be within the bit width of |T|. +template +T MutateBits(T word, size_t first_position, size_t num_bits_to_mutate, + bool value) { + static_assert(std::is_integral::value, "Integer type required"); + static_assert(std::is_unsigned::value, "Unsigned type required"); + static const size_t word_bit_width = IntegerBitWidth::get; + assert(first_position < word_bit_width && + "Mutated bits must be within bit width"); + assert(first_position + num_bits_to_mutate <= word_bit_width && + "Mutated bits must be within bit width"); + if (num_bits_to_mutate == 0) { + return word; + } + + const T all_ones = ~T(0); + const size_t num_unaffected_low_bits = first_position; + const T unaffected_low_mask = + T(T(all_ones >> num_unaffected_low_bits) << num_unaffected_low_bits); + + const size_t num_unaffected_high_bits = + word_bit_width - (first_position + num_bits_to_mutate); + const T unaffected_high_mask = + T(T(all_ones << num_unaffected_high_bits) >> num_unaffected_high_bits); + + const T mutation_mask = unaffected_low_mask & unaffected_high_mask; + if (value) { + return word | mutation_mask; + } + return word & T(~mutation_mask); +} + +// Returns a value obtained by setting the |num_bits_to_set| highest bits to +// '1'. |num_bits_to_set| must be not be greater than the bit width of |T|. +template +T SetHighBits(T word, size_t num_bits_to_set) { + if (num_bits_to_set == 0) { + return word; + } + const size_t word_bit_width = IntegerBitWidth::get; + assert(num_bits_to_set <= word_bit_width && + "Can't set more bits than bit width"); + return MutateBits(word, word_bit_width - num_bits_to_set, num_bits_to_set, + true); +} + +// Returns a value obtained by setting the |num_bits_to_set| highest bits to +// '0'. |num_bits_to_set| must be not be greater than the bit width of |T|. +template +T ClearHighBits(T word, size_t num_bits_to_set) { + if (num_bits_to_set == 0) { + return word; + } + const size_t word_bit_width = IntegerBitWidth::get; + assert(num_bits_to_set <= word_bit_width && + "Can't clear more bits than bit width"); + return MutateBits(word, word_bit_width - num_bits_to_set, num_bits_to_set, + false); +} + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_BITUTILS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/hash_combine.h b/thirdparty/glslang/External/spirv-tools/source/util/hash_combine.h new file mode 100644 index 000000000000..1a2dbc332a39 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/hash_combine.h @@ -0,0 +1,53 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_HASH_COMBINE_H_ +#define SOURCE_UTIL_HASH_COMBINE_H_ + +#include +#include +#include + +namespace spvtools { +namespace utils { + +// Helpers for incrementally computing hashes. +// For reference, see +// http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3876.pdf + +template +inline size_t hash_combine(std::size_t seed, const T& val) { + return seed ^ (std::hash()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); +} + +template +inline size_t hash_combine(std::size_t hash, const std::vector& vals) { + for (const T& val : vals) { + hash = hash_combine(hash, val); + } + return hash; +} + +inline size_t hash_combine(std::size_t hash) { return hash; } + +template +inline size_t hash_combine(std::size_t hash, const T& val, + const Types&... args) { + return hash_combine(hash_combine(hash, val), args...); +} + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_HASH_COMBINE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/hex_float.h b/thirdparty/glslang/External/spirv-tools/source/util/hex_float.h new file mode 100644 index 000000000000..98353a4ad280 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/hex_float.h @@ -0,0 +1,1259 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_HEX_FLOAT_H_ +#define SOURCE_UTIL_HEX_FLOAT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/util/bitutils.h" + +#ifndef __GNUC__ +#define GCC_VERSION 0 +#else +#define GCC_VERSION \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +namespace spvtools { +namespace utils { + +class Float16 { + public: + Float16(uint16_t v) : val(v) {} + Float16() = default; + static bool isNan(const Float16& val) { + return ((val.val & 0x7C00) == 0x7C00) && ((val.val & 0x3FF) != 0); + } + // Returns true if the given value is any kind of infinity. + static bool isInfinity(const Float16& val) { + return ((val.val & 0x7C00) == 0x7C00) && ((val.val & 0x3FF) == 0); + } + Float16(const Float16& other) { val = other.val; } + uint16_t get_value() const { return val; } + + // Returns the maximum normal value. + static Float16 max() { return Float16(0x7bff); } + // Returns the lowest normal value. + static Float16 lowest() { return Float16(0xfbff); } + + private: + uint16_t val; +}; + +// To specialize this type, you must override uint_type to define +// an unsigned integer that can fit your floating point type. +// You must also add a isNan function that returns true if +// a value is Nan. +template +struct FloatProxyTraits { + using uint_type = void; +}; + +template <> +struct FloatProxyTraits { + using uint_type = uint32_t; + static bool isNan(float f) { return std::isnan(f); } + // Returns true if the given value is any kind of infinity. + static bool isInfinity(float f) { return std::isinf(f); } + // Returns the maximum normal value. + static float max() { return std::numeric_limits::max(); } + // Returns the lowest normal value. + static float lowest() { return std::numeric_limits::lowest(); } + // Returns the value as the native floating point format. + static float getAsFloat(const uint_type& t) { return BitwiseCast(t); } + // Returns the bits from the given floating pointer number. + static uint_type getBitsFromFloat(const float& t) { + return BitwiseCast(t); + } + // Returns the bitwidth. + static uint32_t width() { return 32u; } +}; + +template <> +struct FloatProxyTraits { + using uint_type = uint64_t; + static bool isNan(double f) { return std::isnan(f); } + // Returns true if the given value is any kind of infinity. + static bool isInfinity(double f) { return std::isinf(f); } + // Returns the maximum normal value. + static double max() { return std::numeric_limits::max(); } + // Returns the lowest normal value. + static double lowest() { return std::numeric_limits::lowest(); } + // Returns the value as the native floating point format. + static double getAsFloat(const uint_type& t) { + return BitwiseCast(t); + } + // Returns the bits from the given floating pointer number. + static uint_type getBitsFromFloat(const double& t) { + return BitwiseCast(t); + } + // Returns the bitwidth. + static uint32_t width() { return 64u; } +}; + +template <> +struct FloatProxyTraits { + using uint_type = uint16_t; + static bool isNan(Float16 f) { return Float16::isNan(f); } + // Returns true if the given value is any kind of infinity. + static bool isInfinity(Float16 f) { return Float16::isInfinity(f); } + // Returns the maximum normal value. + static Float16 max() { return Float16::max(); } + // Returns the lowest normal value. + static Float16 lowest() { return Float16::lowest(); } + // Returns the value as the native floating point format. + static Float16 getAsFloat(const uint_type& t) { return Float16(t); } + // Returns the bits from the given floating pointer number. + static uint_type getBitsFromFloat(const Float16& t) { return t.get_value(); } + // Returns the bitwidth. + static uint32_t width() { return 16u; } +}; + +// Since copying a floating point number (especially if it is NaN) +// does not guarantee that bits are preserved, this class lets us +// store the type and use it as a float when necessary. +template +class FloatProxy { + public: + using uint_type = typename FloatProxyTraits::uint_type; + + // Since this is to act similar to the normal floats, + // do not initialize the data by default. + FloatProxy() = default; + + // Intentionally non-explicit. This is a proxy type so + // implicit conversions allow us to use it more transparently. + FloatProxy(T val) { data_ = FloatProxyTraits::getBitsFromFloat(val); } + + // Intentionally non-explicit. This is a proxy type so + // implicit conversions allow us to use it more transparently. + FloatProxy(uint_type val) { data_ = val; } + + // This is helpful to have and is guaranteed not to stomp bits. + FloatProxy operator-() const { + return static_cast(data_ ^ + (uint_type(0x1) << (sizeof(T) * 8 - 1))); + } + + // Returns the data as a floating point value. + T getAsFloat() const { return FloatProxyTraits::getAsFloat(data_); } + + // Returns the raw data. + uint_type data() const { return data_; } + + // Returns a vector of words suitable for use in an Operand. + std::vector GetWords() const { + std::vector words; + if (FloatProxyTraits::width() == 64) { + FloatProxyTraits::uint_type d = data(); + words.push_back(static_cast(d)); + words.push_back(static_cast(d >> 32)); + } else { + words.push_back(static_cast(data())); + } + return words; + } + + // Returns true if the value represents any type of NaN. + bool isNan() { return FloatProxyTraits::isNan(getAsFloat()); } + // Returns true if the value represents any type of infinity. + bool isInfinity() { return FloatProxyTraits::isInfinity(getAsFloat()); } + + // Returns the maximum normal value. + static FloatProxy max() { + return FloatProxy(FloatProxyTraits::max()); + } + // Returns the lowest normal value. + static FloatProxy lowest() { + return FloatProxy(FloatProxyTraits::lowest()); + } + + private: + uint_type data_; +}; + +template +bool operator==(const FloatProxy& first, const FloatProxy& second) { + return first.data() == second.data(); +} + +// Reads a FloatProxy value as a normal float from a stream. +template +std::istream& operator>>(std::istream& is, FloatProxy& value) { + T float_val = static_cast(0.0); + is >> float_val; + value = FloatProxy(float_val); + return is; +} + +// This is an example traits. It is not meant to be used in practice, but will +// be the default for any non-specialized type. +template +struct HexFloatTraits { + // Integer type that can store the bit representation of this hex-float. + using uint_type = void; + // Signed integer type that can store the bit representation of this + // hex-float. + using int_type = void; + // The numerical type that this HexFloat represents. + using underlying_type = void; + // The type needed to construct the underlying type. + using native_type = void; + // The number of bits that are actually relevant in the uint_type. + // This allows us to deal with, for example, 24-bit values in a 32-bit + // integer. + static const uint32_t num_used_bits = 0; + // Number of bits that represent the exponent. + static const uint32_t num_exponent_bits = 0; + // Number of bits that represent the fractional part. + static const uint32_t num_fraction_bits = 0; + // The bias of the exponent. (How much we need to subtract from the stored + // value to get the correct value.) + static const uint32_t exponent_bias = 0; +}; + +// Traits for IEEE float. +// 1 sign bit, 8 exponent bits, 23 fractional bits. +template <> +struct HexFloatTraits> { + using uint_type = uint32_t; + using int_type = int32_t; + using underlying_type = FloatProxy; + using native_type = float; + static const uint_type num_used_bits = 32; + static const uint_type num_exponent_bits = 8; + static const uint_type num_fraction_bits = 23; + static const uint_type exponent_bias = 127; +}; + +// Traits for IEEE double. +// 1 sign bit, 11 exponent bits, 52 fractional bits. +template <> +struct HexFloatTraits> { + using uint_type = uint64_t; + using int_type = int64_t; + using underlying_type = FloatProxy; + using native_type = double; + static const uint_type num_used_bits = 64; + static const uint_type num_exponent_bits = 11; + static const uint_type num_fraction_bits = 52; + static const uint_type exponent_bias = 1023; +}; + +// Traits for IEEE half. +// 1 sign bit, 5 exponent bits, 10 fractional bits. +template <> +struct HexFloatTraits> { + using uint_type = uint16_t; + using int_type = int16_t; + using underlying_type = uint16_t; + using native_type = uint16_t; + static const uint_type num_used_bits = 16; + static const uint_type num_exponent_bits = 5; + static const uint_type num_fraction_bits = 10; + static const uint_type exponent_bias = 15; +}; + +enum class round_direction { + kToZero, + kToNearestEven, + kToPositiveInfinity, + kToNegativeInfinity, + max = kToNegativeInfinity +}; + +// Template class that houses a floating pointer number. +// It exposes a number of constants based on the provided traits to +// assist in interpreting the bits of the value. +template > +class HexFloat { + public: + using uint_type = typename Traits::uint_type; + using int_type = typename Traits::int_type; + using underlying_type = typename Traits::underlying_type; + using native_type = typename Traits::native_type; + + explicit HexFloat(T f) : value_(f) {} + + T value() const { return value_; } + void set_value(T f) { value_ = f; } + + // These are all written like this because it is convenient to have + // compile-time constants for all of these values. + + // Pass-through values to save typing. + static const uint32_t num_used_bits = Traits::num_used_bits; + static const uint32_t exponent_bias = Traits::exponent_bias; + static const uint32_t num_exponent_bits = Traits::num_exponent_bits; + static const uint32_t num_fraction_bits = Traits::num_fraction_bits; + + // Number of bits to shift left to set the highest relevant bit. + static const uint32_t top_bit_left_shift = num_used_bits - 1; + // How many nibbles (hex characters) the fractional part takes up. + static const uint32_t fraction_nibbles = (num_fraction_bits + 3) / 4; + // If the fractional part does not fit evenly into a hex character (4-bits) + // then we have to left-shift to get rid of leading 0s. This is the amount + // we have to shift (might be 0). + static const uint32_t num_overflow_bits = + fraction_nibbles * 4 - num_fraction_bits; + + // The representation of the fraction, not the actual bits. This + // includes the leading bit that is usually implicit. + static const uint_type fraction_represent_mask = + SetBits::get; + + // The topmost bit in the nibble-aligned fraction. + static const uint_type fraction_top_bit = + uint_type(1) << (num_fraction_bits + num_overflow_bits - 1); + + // The least significant bit in the exponent, which is also the bit + // immediately to the left of the significand. + static const uint_type first_exponent_bit = uint_type(1) + << (num_fraction_bits); + + // The mask for the encoded fraction. It does not include the + // implicit bit. + static const uint_type fraction_encode_mask = + SetBits::get; + + // The bit that is used as a sign. + static const uint_type sign_mask = uint_type(1) << top_bit_left_shift; + + // The bits that represent the exponent. + static const uint_type exponent_mask = + SetBits::get; + + // How far left the exponent is shifted. + static const uint32_t exponent_left_shift = num_fraction_bits; + + // How far from the right edge the fraction is shifted. + static const uint32_t fraction_right_shift = + static_cast(sizeof(uint_type) * 8) - num_fraction_bits; + + // The maximum representable unbiased exponent. + static const int_type max_exponent = + (exponent_mask >> num_fraction_bits) - exponent_bias; + // The minimum representable exponent for normalized numbers. + static const int_type min_exponent = -static_cast(exponent_bias); + + // Returns the bits associated with the value. + uint_type getBits() const { return value_.data(); } + + // Returns the bits associated with the value, without the leading sign bit. + uint_type getUnsignedBits() const { + return static_cast(value_.data() & ~sign_mask); + } + + // Returns the bits associated with the exponent, shifted to start at the + // lsb of the type. + const uint_type getExponentBits() const { + return static_cast((getBits() & exponent_mask) >> + num_fraction_bits); + } + + // Returns the exponent in unbiased form. This is the exponent in the + // human-friendly form. + const int_type getUnbiasedExponent() const { + return static_cast(getExponentBits() - exponent_bias); + } + + // Returns just the significand bits from the value. + const uint_type getSignificandBits() const { + return getBits() & fraction_encode_mask; + } + + // If the number was normalized, returns the unbiased exponent. + // If the number was denormal, normalize the exponent first. + const int_type getUnbiasedNormalizedExponent() const { + if ((getBits() & ~sign_mask) == 0) { // special case if everything is 0 + return 0; + } + int_type exp = getUnbiasedExponent(); + if (exp == min_exponent) { // We are in denorm land. + uint_type significand_bits = getSignificandBits(); + while ((significand_bits & (first_exponent_bit >> 1)) == 0) { + significand_bits = static_cast(significand_bits << 1); + exp = static_cast(exp - 1); + } + significand_bits &= fraction_encode_mask; + } + return exp; + } + + // Returns the signficand after it has been normalized. + const uint_type getNormalizedSignificand() const { + int_type unbiased_exponent = getUnbiasedNormalizedExponent(); + uint_type significand = getSignificandBits(); + for (int_type i = unbiased_exponent; i <= min_exponent; ++i) { + significand = static_cast(significand << 1); + } + significand &= fraction_encode_mask; + return significand; + } + + // Returns true if this number represents a negative value. + bool isNegative() const { return (getBits() & sign_mask) != 0; } + + // Sets this HexFloat from the individual components. + // Note this assumes EVERY significand is normalized, and has an implicit + // leading one. This means that the only way that this method will set 0, + // is if you set a number so denormalized that it underflows. + // Do not use this method with raw bits extracted from a subnormal number, + // since subnormals do not have an implicit leading 1 in the significand. + // The significand is also expected to be in the + // lowest-most num_fraction_bits of the uint_type. + // The exponent is expected to be unbiased, meaning an exponent of + // 0 actually means 0. + // If underflow_round_up is set, then on underflow, if a number is non-0 + // and would underflow, we round up to the smallest denorm. + void setFromSignUnbiasedExponentAndNormalizedSignificand( + bool negative, int_type exponent, uint_type significand, + bool round_denorm_up) { + bool significand_is_zero = significand == 0; + + if (exponent <= min_exponent) { + // If this was denormalized, then we have to shift the bit on, meaning + // the significand is not zero. + significand_is_zero = false; + significand |= first_exponent_bit; + significand = static_cast(significand >> 1); + } + + while (exponent < min_exponent) { + significand = static_cast(significand >> 1); + ++exponent; + } + + if (exponent == min_exponent) { + if (significand == 0 && !significand_is_zero && round_denorm_up) { + significand = static_cast(0x1); + } + } + + uint_type new_value = 0; + if (negative) { + new_value = static_cast(new_value | sign_mask); + } + exponent = static_cast(exponent + exponent_bias); + assert(exponent >= 0); + + // put it all together + exponent = static_cast((exponent << exponent_left_shift) & + exponent_mask); + significand = static_cast(significand & fraction_encode_mask); + new_value = static_cast(new_value | (exponent | significand)); + value_ = T(new_value); + } + + // Increments the significand of this number by the given amount. + // If this would spill the significand into the implicit bit, + // carry is set to true and the significand is shifted to fit into + // the correct location, otherwise carry is set to false. + // All significands and to_increment are assumed to be within the bounds + // for a valid significand. + static uint_type incrementSignificand(uint_type significand, + uint_type to_increment, bool* carry) { + significand = static_cast(significand + to_increment); + *carry = false; + if (significand & first_exponent_bit) { + *carry = true; + // The implicit 1-bit will have carried, so we should zero-out the + // top bit and shift back. + significand = static_cast(significand & ~first_exponent_bit); + significand = static_cast(significand >> 1); + } + return significand; + } + +#if GCC_VERSION == 40801 + // These exist because MSVC throws warnings on negative right-shifts + // even if they are not going to be executed. Eg: + // constant_number < 0? 0: constant_number + // These convert the negative left-shifts into right shifts. + template + struct negatable_left_shift { + static uint_type val(uint_type val) { + if (N > 0) { + return static_cast(val << N); + } else { + return static_cast(val >> N); + } + } + }; + + template + struct negatable_right_shift { + static uint_type val(uint_type val) { + if (N > 0) { + return static_cast(val >> N); + } else { + return static_cast(val << N); + } + } + }; + +#else + // These exist because MSVC throws warnings on negative right-shifts + // even if they are not going to be executed. Eg: + // constant_number < 0? 0: constant_number + // These convert the negative left-shifts into right shifts. + template + struct negatable_left_shift { + static uint_type val(uint_type val) { + return static_cast(val >> -N); + } + }; + + template + struct negatable_left_shift= 0>::type> { + static uint_type val(uint_type val) { + return static_cast(val << N); + } + }; + + template + struct negatable_right_shift { + static uint_type val(uint_type val) { + return static_cast(val << -N); + } + }; + + template + struct negatable_right_shift= 0>::type> { + static uint_type val(uint_type val) { + return static_cast(val >> N); + } + }; +#endif + + // Returns the significand, rounded to fit in a significand in + // other_T. This is shifted so that the most significant + // bit of the rounded number lines up with the most significant bit + // of the returned significand. + template + typename other_T::uint_type getRoundedNormalizedSignificand( + round_direction dir, bool* carry_bit) { + using other_uint_type = typename other_T::uint_type; + static const int_type num_throwaway_bits = + static_cast(num_fraction_bits) - + static_cast(other_T::num_fraction_bits); + + static const uint_type last_significant_bit = + (num_throwaway_bits < 0) + ? 0 + : negatable_left_shift::val(1u); + static const uint_type first_rounded_bit = + (num_throwaway_bits < 1) + ? 0 + : negatable_left_shift::val(1u); + + static const uint_type throwaway_mask_bits = + num_throwaway_bits > 0 ? num_throwaway_bits : 0; + static const uint_type throwaway_mask = + SetBits::get; + + *carry_bit = false; + other_uint_type out_val = 0; + uint_type significand = getNormalizedSignificand(); + // If we are up-casting, then we just have to shift to the right location. + if (num_throwaway_bits <= 0) { + out_val = static_cast(significand); + uint_type shift_amount = static_cast(-num_throwaway_bits); + out_val = static_cast(out_val << shift_amount); + return out_val; + } + + // If every non-representable bit is 0, then we don't have any casting to + // do. + if ((significand & throwaway_mask) == 0) { + return static_cast( + negatable_right_shift::val(significand)); + } + + bool round_away_from_zero = false; + // We actually have to narrow the significand here, so we have to follow the + // rounding rules. + switch (dir) { + case round_direction::kToZero: + break; + case round_direction::kToPositiveInfinity: + round_away_from_zero = !isNegative(); + break; + case round_direction::kToNegativeInfinity: + round_away_from_zero = isNegative(); + break; + case round_direction::kToNearestEven: + // Have to round down, round bit is 0 + if ((first_rounded_bit & significand) == 0) { + break; + } + if (((significand & throwaway_mask) & ~first_rounded_bit) != 0) { + // If any subsequent bit of the rounded portion is non-0 then we round + // up. + round_away_from_zero = true; + break; + } + // We are exactly half-way between 2 numbers, pick even. + if ((significand & last_significant_bit) != 0) { + // 1 for our last bit, round up. + round_away_from_zero = true; + break; + } + break; + } + + if (round_away_from_zero) { + return static_cast( + negatable_right_shift::val(incrementSignificand( + significand, last_significant_bit, carry_bit))); + } else { + return static_cast( + negatable_right_shift::val(significand)); + } + } + + // Casts this value to another HexFloat. If the cast is widening, + // then round_dir is ignored. If the cast is narrowing, then + // the result is rounded in the direction specified. + // This number will retain Nan and Inf values. + // It will also saturate to Inf if the number overflows, and + // underflow to (0 or min depending on rounding) if the number underflows. + template + void castTo(other_T& other, round_direction round_dir) { + other = other_T(static_cast(0)); + bool negate = isNegative(); + if (getUnsignedBits() == 0) { + if (negate) { + other.set_value(-other.value()); + } + return; + } + uint_type significand = getSignificandBits(); + bool carried = false; + typename other_T::uint_type rounded_significand = + getRoundedNormalizedSignificand(round_dir, &carried); + + int_type exponent = getUnbiasedExponent(); + if (exponent == min_exponent) { + // If we are denormal, normalize the exponent, so that we can encode + // easily. + exponent = static_cast(exponent + 1); + for (uint_type check_bit = first_exponent_bit >> 1; check_bit != 0; + check_bit = static_cast(check_bit >> 1)) { + exponent = static_cast(exponent - 1); + if (check_bit & significand) break; + } + } + + bool is_nan = + (getBits() & exponent_mask) == exponent_mask && significand != 0; + bool is_inf = + !is_nan && + ((exponent + carried) > static_cast(other_T::exponent_bias) || + (significand == 0 && (getBits() & exponent_mask) == exponent_mask)); + + // If we are Nan or Inf we should pass that through. + if (is_inf) { + other.set_value(typename other_T::underlying_type( + static_cast( + (negate ? other_T::sign_mask : 0) | other_T::exponent_mask))); + return; + } + if (is_nan) { + typename other_T::uint_type shifted_significand; + shifted_significand = static_cast( + negatable_left_shift< + static_cast(other_T::num_fraction_bits) - + static_cast(num_fraction_bits)>::val(significand)); + + // We are some sort of Nan. We try to keep the bit-pattern of the Nan + // as close as possible. If we had to shift off bits so we are 0, then we + // just set the last bit. + other.set_value(typename other_T::underlying_type( + static_cast( + (negate ? other_T::sign_mask : 0) | other_T::exponent_mask | + (shifted_significand == 0 ? 0x1 : shifted_significand)))); + return; + } + + bool round_underflow_up = + isNegative() ? round_dir == round_direction::kToNegativeInfinity + : round_dir == round_direction::kToPositiveInfinity; + using other_int_type = typename other_T::int_type; + // setFromSignUnbiasedExponentAndNormalizedSignificand will + // zero out any underflowing value (but retain the sign). + other.setFromSignUnbiasedExponentAndNormalizedSignificand( + negate, static_cast(exponent), rounded_significand, + round_underflow_up); + return; + } + + private: + T value_; + + static_assert(num_used_bits == + Traits::num_exponent_bits + Traits::num_fraction_bits + 1, + "The number of bits do not fit"); + static_assert(sizeof(T) == sizeof(uint_type), "The type sizes do not match"); +}; + +// Returns 4 bits represented by the hex character. +inline uint8_t get_nibble_from_character(int character) { + const char* dec = "0123456789"; + const char* lower = "abcdef"; + const char* upper = "ABCDEF"; + const char* p = nullptr; + if ((p = strchr(dec, character))) { + return static_cast(p - dec); + } else if ((p = strchr(lower, character))) { + return static_cast(p - lower + 0xa); + } else if ((p = strchr(upper, character))) { + return static_cast(p - upper + 0xa); + } + + assert(false && "This was called with a non-hex character"); + return 0; +} + +// Outputs the given HexFloat to the stream. +template +std::ostream& operator<<(std::ostream& os, const HexFloat& value) { + using HF = HexFloat; + using uint_type = typename HF::uint_type; + using int_type = typename HF::int_type; + + static_assert(HF::num_used_bits != 0, + "num_used_bits must be non-zero for a valid float"); + static_assert(HF::num_exponent_bits != 0, + "num_exponent_bits must be non-zero for a valid float"); + static_assert(HF::num_fraction_bits != 0, + "num_fractin_bits must be non-zero for a valid float"); + + const uint_type bits = value.value().data(); + const char* const sign = (bits & HF::sign_mask) ? "-" : ""; + const uint_type exponent = static_cast( + (bits & HF::exponent_mask) >> HF::num_fraction_bits); + + uint_type fraction = static_cast((bits & HF::fraction_encode_mask) + << HF::num_overflow_bits); + + const bool is_zero = exponent == 0 && fraction == 0; + const bool is_denorm = exponent == 0 && !is_zero; + + // exponent contains the biased exponent we have to convert it back into + // the normal range. + int_type int_exponent = static_cast(exponent - HF::exponent_bias); + // If the number is all zeros, then we actually have to NOT shift the + // exponent. + int_exponent = is_zero ? 0 : int_exponent; + + // If we are denorm, then start shifting, and decreasing the exponent until + // our leading bit is 1. + + if (is_denorm) { + while ((fraction & HF::fraction_top_bit) == 0) { + fraction = static_cast(fraction << 1); + int_exponent = static_cast(int_exponent - 1); + } + // Since this is denormalized, we have to consume the leading 1 since it + // will end up being implicit. + fraction = static_cast(fraction << 1); // eat the leading 1 + fraction &= HF::fraction_represent_mask; + } + + uint_type fraction_nibbles = HF::fraction_nibbles; + // We do not have to display any trailing 0s, since this represents the + // fractional part. + while (fraction_nibbles > 0 && (fraction & 0xF) == 0) { + // Shift off any trailing values; + fraction = static_cast(fraction >> 4); + --fraction_nibbles; + } + + const auto saved_flags = os.flags(); + const auto saved_fill = os.fill(); + + os << sign << "0x" << (is_zero ? '0' : '1'); + if (fraction_nibbles) { + // Make sure to keep the leading 0s in place, since this is the fractional + // part. + os << "." << std::setw(static_cast(fraction_nibbles)) + << std::setfill('0') << std::hex << fraction; + } + os << "p" << std::dec << (int_exponent >= 0 ? "+" : "") << int_exponent; + + os.flags(saved_flags); + os.fill(saved_fill); + + return os; +} + +// Returns true if negate_value is true and the next character on the +// input stream is a plus or minus sign. In that case we also set the fail bit +// on the stream and set the value to the zero value for its type. +template +inline bool RejectParseDueToLeadingSign(std::istream& is, bool negate_value, + HexFloat& value) { + if (negate_value) { + auto next_char = is.peek(); + if (next_char == '-' || next_char == '+') { + // Fail the parse. Emulate standard behaviour by setting the value to + // the zero value, and set the fail bit on the stream. + value = HexFloat(typename HexFloat::uint_type{0}); + is.setstate(std::ios_base::failbit); + return true; + } + } + return false; +} + +// Parses a floating point number from the given stream and stores it into the +// value parameter. +// If negate_value is true then the number may not have a leading minus or +// plus, and if it successfully parses, then the number is negated before +// being stored into the value parameter. +// If the value cannot be correctly parsed or overflows the target floating +// point type, then set the fail bit on the stream. +// TODO(dneto): Promise C++11 standard behavior in how the value is set in +// the error case, but only after all target platforms implement it correctly. +// In particular, the Microsoft C++ runtime appears to be out of spec. +template +inline std::istream& ParseNormalFloat(std::istream& is, bool negate_value, + HexFloat& value) { + if (RejectParseDueToLeadingSign(is, negate_value, value)) { + return is; + } + T val; + is >> val; + if (negate_value) { + val = -val; + } + value.set_value(val); + // In the failure case, map -0.0 to 0.0. + if (is.fail() && value.getUnsignedBits() == 0u) { + value = HexFloat(typename HexFloat::uint_type{0}); + } + if (val.isInfinity()) { + // Fail the parse. Emulate standard behaviour by setting the value to + // the closest normal value, and set the fail bit on the stream. + value.set_value((value.isNegative() | negate_value) ? T::lowest() + : T::max()); + is.setstate(std::ios_base::failbit); + } + return is; +} + +// Specialization of ParseNormalFloat for FloatProxy values. +// This will parse the float as it were a 32-bit floating point number, +// and then round it down to fit into a Float16 value. +// The number is rounded towards zero. +// If negate_value is true then the number may not have a leading minus or +// plus, and if it successfully parses, then the number is negated before +// being stored into the value parameter. +// If the value cannot be correctly parsed or overflows the target floating +// point type, then set the fail bit on the stream. +// TODO(dneto): Promise C++11 standard behavior in how the value is set in +// the error case, but only after all target platforms implement it correctly. +// In particular, the Microsoft C++ runtime appears to be out of spec. +template <> +inline std::istream& +ParseNormalFloat, HexFloatTraits>>( + std::istream& is, bool negate_value, + HexFloat, HexFloatTraits>>& value) { + // First parse as a 32-bit float. + HexFloat> float_val(0.0f); + ParseNormalFloat(is, negate_value, float_val); + + // Then convert to 16-bit float, saturating at infinities, and + // rounding toward zero. + float_val.castTo(value, round_direction::kToZero); + + // Overflow on 16-bit behaves the same as for 32- and 64-bit: set the + // fail bit and set the lowest or highest value. + if (Float16::isInfinity(value.value().getAsFloat())) { + value.set_value(value.isNegative() ? Float16::lowest() : Float16::max()); + is.setstate(std::ios_base::failbit); + } + return is; +} + +namespace detail { + +// Returns a new value formed from 'value' by setting 'bit' that is the +// 'n'th most significant bit (where 0 is the most significant bit). +// If 'bit' is zero or 'n' is more than the number of bits in the integer +// type, then return the original value. +template +UINT_TYPE set_nth_most_significant_bit(UINT_TYPE value, UINT_TYPE bit, + UINT_TYPE n) { + constexpr UINT_TYPE max_position = std::numeric_limits::digits - 1; + if ((bit != 0) && (n <= max_position)) { + return static_cast(value | (bit << (max_position - n))); + } + return value; +} + +// Attempts to increment the argument. +// If it does not overflow, then increments the argument and returns true. +// If it would overflow, returns false. +template +bool saturated_inc(INT_TYPE& value) { + if (value == std::numeric_limits::max()) { + return false; + } + value++; + return true; +} + +// Attempts to decrement the argument. +// If it does not underflow, then decrements the argument and returns true. +// If it would overflow, returns false. +template +bool saturated_dec(INT_TYPE& value) { + if (value == std::numeric_limits::min()) { + return false; + } + value--; + return true; +} +} // namespace detail + +// Reads a HexFloat from the given stream. +// If the float is not encoded as a hex-float then it will be parsed +// as a regular float. +// This may fail if your stream does not support at least one unget. +// Nan values can be encoded with "0x1.p+exponent_bias". +// This would normally overflow a float and round to +// infinity but this special pattern is the exact representation for a NaN, +// and therefore is actually encoded as the correct NaN. To encode inf, +// either 0x0p+exponent_bias can be specified or any exponent greater than +// exponent_bias. +// Examples using IEEE 32-bit float encoding. +// 0x1.0p+128 (+inf) +// -0x1.0p-128 (-inf) +// +// 0x1.1p+128 (+Nan) +// -0x1.1p+128 (-Nan) +// +// 0x1p+129 (+inf) +// -0x1p+129 (-inf) +template +std::istream& operator>>(std::istream& is, HexFloat& value) { + using HF = HexFloat; + using uint_type = typename HF::uint_type; + using int_type = typename HF::int_type; + + value.set_value(static_cast(0.f)); + + if (is.flags() & std::ios::skipws) { + // If the user wants to skip whitespace , then we should obey that. + while (std::isspace(is.peek())) { + is.get(); + } + } + + auto next_char = is.peek(); + bool negate_value = false; + + if (next_char != '-' && next_char != '0') { + return ParseNormalFloat(is, negate_value, value); + } + + if (next_char == '-') { + negate_value = true; + is.get(); + next_char = is.peek(); + } + + if (next_char == '0') { + is.get(); // We may have to unget this. + auto maybe_hex_start = is.peek(); + if (maybe_hex_start != 'x' && maybe_hex_start != 'X') { + is.unget(); + return ParseNormalFloat(is, negate_value, value); + } else { + is.get(); // Throw away the 'x'; + } + } else { + return ParseNormalFloat(is, negate_value, value); + } + + // This "looks" like a hex-float so treat it as one. + bool seen_p = false; + bool seen_dot = false; + + // The mantissa bits, without the most significant 1 bit, and with the + // the most recently read bits in the least significant positions. + uint_type fraction = 0; + // The number of mantissa bits that have been read, including the leading 1 + // bit that is not written into 'fraction'. + uint_type fraction_index = 0; + + // TODO(dneto): handle overflow and underflow + int_type exponent = HF::exponent_bias; + + // Strip off leading zeros so we don't have to special-case them later. + while ((next_char = is.peek()) == '0') { + is.get(); + } + + // Does the mantissa, as written, have non-zero digits to the left of + // the decimal point. Assume no until proven otherwise. + bool has_integer_part = false; + bool bits_written = false; // Stays false until we write a bit. + + // Scan the mantissa hex digits until we see a '.' or the 'p' that + // starts the exponent. + while (!seen_p && !seen_dot) { + // Handle characters that are left of the fractional part. + if (next_char == '.') { + seen_dot = true; + } else if (next_char == 'p') { + seen_p = true; + } else if (::isxdigit(next_char)) { + // We have stripped all leading zeroes and we have not yet seen a ".". + has_integer_part = true; + int number = get_nibble_from_character(next_char); + for (int i = 0; i < 4; ++i, number <<= 1) { + uint_type write_bit = (number & 0x8) ? 0x1 : 0x0; + if (bits_written) { + // If we are here the bits represented belong in the fractional + // part of the float, and we have to adjust the exponent accordingly. + fraction = detail::set_nth_most_significant_bit(fraction, write_bit, + fraction_index); + // Increment the fraction index. If the input has bizarrely many + // significant digits, then silently drop them. + detail::saturated_inc(fraction_index); + if (!detail::saturated_inc(exponent)) { + // Overflow failure + is.setstate(std::ios::failbit); + return is; + } + } + // Since this updated after setting fraction bits, this effectively + // drops the leading 1 bit. + bits_written |= write_bit != 0; + } + } else { + // We have not found our exponent yet, so we have to fail. + is.setstate(std::ios::failbit); + return is; + } + is.get(); + next_char = is.peek(); + } + + // Finished reading the part preceding any '.' or 'p'. + + bits_written = false; + while (seen_dot && !seen_p) { + // Handle only fractional parts now. + if (next_char == 'p') { + seen_p = true; + } else if (::isxdigit(next_char)) { + int number = get_nibble_from_character(next_char); + for (int i = 0; i < 4; ++i, number <<= 1) { + uint_type write_bit = (number & 0x8) ? 0x01 : 0x00; + bits_written |= write_bit != 0; + if ((!has_integer_part) && !bits_written) { + // Handle modifying the exponent here this way we can handle + // an arbitrary number of hex values without overflowing our + // integer. + if (!detail::saturated_dec(exponent)) { + // Overflow failure + is.setstate(std::ios::failbit); + return is; + } + } else { + fraction = detail::set_nth_most_significant_bit(fraction, write_bit, + fraction_index); + // Increment the fraction index. If the input has bizarrely many + // significant digits, then silently drop them. + detail::saturated_inc(fraction_index); + } + } + } else { + // We still have not found our 'p' exponent yet, so this is not a valid + // hex-float. + is.setstate(std::ios::failbit); + return is; + } + is.get(); + next_char = is.peek(); + } + + // Finished reading the part preceding 'p'. + // In hex floats syntax, the binary exponent is required. + + bool seen_exponent_sign = false; + int8_t exponent_sign = 1; + bool seen_written_exponent_digits = false; + // The magnitude of the exponent, as written, or the sentinel value to signal + // overflow. + int_type written_exponent = 0; + // A sentinel value signalling overflow of the magnitude of the written + // exponent. We'll assume that -written_exponent_overflow is valid for the + // type. Later we may add 1 or subtract 1 from the adjusted exponent, so leave + // room for an extra 1. + const int_type written_exponent_overflow = + std::numeric_limits::max() - 1; + while (true) { + if (!seen_written_exponent_digits && + (next_char == '-' || next_char == '+')) { + if (seen_exponent_sign) { + is.setstate(std::ios::failbit); + return is; + } + seen_exponent_sign = true; + exponent_sign = (next_char == '-') ? -1 : 1; + } else if (::isdigit(next_char)) { + seen_written_exponent_digits = true; + // Hex-floats express their exponent as decimal. + int_type digit = + static_cast(static_cast(next_char) - '0'); + if (written_exponent >= (written_exponent_overflow - digit) / 10) { + // The exponent is very big. Saturate rather than overflow the exponent. + // signed integer, which would be undefined behaviour. + written_exponent = written_exponent_overflow; + } else { + written_exponent = static_cast( + static_cast(written_exponent * 10) + digit); + } + } else { + break; + } + is.get(); + next_char = is.peek(); + } + if (!seen_written_exponent_digits) { + // Binary exponent had no digits. + is.setstate(std::ios::failbit); + return is; + } + + written_exponent = static_cast(written_exponent * exponent_sign); + // Now fold in the exponent bias into the written exponent, updating exponent. + // But avoid undefined behaviour that would result from overflowing int_type. + if (written_exponent >= 0 && exponent >= 0) { + // Saturate up to written_exponent_overflow. + if (written_exponent_overflow - exponent > written_exponent) { + exponent = static_cast(written_exponent + exponent); + } else { + exponent = written_exponent_overflow; + } + } else if (written_exponent < 0 && exponent < 0) { + // Saturate down to -written_exponent_overflow. + if (written_exponent_overflow + exponent > -written_exponent) { + exponent = static_cast(written_exponent + exponent); + } else { + exponent = static_cast(-written_exponent_overflow); + } + } else { + // They're of opposing sign, so it's safe to add. + exponent = static_cast(written_exponent + exponent); + } + + bool is_zero = (!has_integer_part) && (fraction == 0); + if ((!has_integer_part) && !is_zero) { + fraction = static_cast(fraction << 1); + exponent = static_cast(exponent - 1); + } else if (is_zero) { + exponent = 0; + } + + if (exponent <= 0 && !is_zero) { + fraction = static_cast(fraction >> 1); + fraction |= static_cast(1) << HF::top_bit_left_shift; + } + + fraction = (fraction >> HF::fraction_right_shift) & HF::fraction_encode_mask; + + const int_type max_exponent = + SetBits::get; + + // Handle denorm numbers + while (exponent < 0 && !is_zero) { + fraction = static_cast(fraction >> 1); + exponent = static_cast(exponent + 1); + + fraction &= HF::fraction_encode_mask; + if (fraction == 0) { + // We have underflowed our fraction. We should clamp to zero. + is_zero = true; + exponent = 0; + } + } + + // We have overflowed so we should be inf/-inf. + if (exponent > max_exponent) { + exponent = max_exponent; + fraction = 0; + } + + uint_type output_bits = static_cast( + static_cast(negate_value ? 1 : 0) << HF::top_bit_left_shift); + output_bits |= fraction; + + uint_type shifted_exponent = static_cast( + static_cast(exponent << HF::exponent_left_shift) & + HF::exponent_mask); + output_bits |= shifted_exponent; + + T output_float(output_bits); + value.set_value(output_float); + + return is; +} + +// Writes a FloatProxy value to a stream. +// Zero and normal numbers are printed in the usual notation, but with +// enough digits to fully reproduce the value. Other values (subnormal, +// NaN, and infinity) are printed as a hex float. +template +std::ostream& operator<<(std::ostream& os, const FloatProxy& value) { + auto float_val = value.getAsFloat(); + switch (std::fpclassify(float_val)) { + case FP_ZERO: + case FP_NORMAL: { + auto saved_precision = os.precision(); + os.precision(std::numeric_limits::max_digits10); + os << float_val; + os.precision(saved_precision); + } break; + default: + os << HexFloat>(value); + break; + } + return os; +} + +template <> +inline std::ostream& operator<<(std::ostream& os, + const FloatProxy& value) { + os << HexFloat>(value); + return os; +} + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_HEX_FLOAT_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/ilist.h b/thirdparty/glslang/External/spirv-tools/source/util/ilist.h new file mode 100644 index 000000000000..42d5e62b912a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/ilist.h @@ -0,0 +1,366 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_ILIST_H_ +#define SOURCE_UTIL_ILIST_H_ + +#include +#include +#include +#include + +#include "source/util/ilist_node.h" + +namespace spvtools { +namespace utils { + +// An IntrusiveList is a generic implementation of a doubly-linked list. The +// intended convention for using this container is: +// +// class Node : public IntrusiveNodeBase { +// // Note that "Node", the class being defined is the template. +// // Must have a default constructor accessible to List. +// // Add whatever data is needed in the node +// }; +// +// using List = IntrusiveList; +// +// You can also inherit from IntrusiveList instead of a typedef if you want to +// add more functionality. +// +// The condition on the template for IntrusiveNodeBase is there to add some type +// checking to the container. The compiler will still allow inserting elements +// of type IntrusiveNodeBase, but that would be an error. This assumption +// allows NextNode and PreviousNode to return pointers to Node, and casting will +// not be required by the user. + +template +class IntrusiveList { + public: + static_assert( + std::is_base_of, NodeType>::value, + "The type from the node must be derived from IntrusiveNodeBase, with " + "itself in the template."); + + // Creates an empty list. + inline IntrusiveList(); + + // Moves the contents of the given list to the list being constructed. + IntrusiveList(IntrusiveList&&); + + // Destroys the list. Note that the elements of the list will not be deleted, + // but they will be removed from the list. + virtual ~IntrusiveList(); + + // Moves all of the elements in the list on the RHS to the list on the LHS. + IntrusiveList& operator=(IntrusiveList&&); + + // Basetype for iterators so an IntrusiveList can be traversed like STL + // containers. + template + class iterator_template { + public: + iterator_template(const iterator_template& i) : node_(i.node_) {} + + iterator_template& operator++() { + node_ = node_->next_node_; + return *this; + } + + iterator_template& operator--() { + node_ = node_->previous_node_; + return *this; + } + + iterator_template& operator=(const iterator_template& i) { + node_ = i.node_; + return *this; + } + + T& operator*() const { return *node_; } + T* operator->() const { return node_; } + + friend inline bool operator==(const iterator_template& lhs, + const iterator_template& rhs) { + return lhs.node_ == rhs.node_; + } + friend inline bool operator!=(const iterator_template& lhs, + const iterator_template& rhs) { + return !(lhs == rhs); + } + + // Moves the nodes in |list| to the list that |this| points to. The + // positions of the nodes will be immediately before the element pointed to + // by the iterator. The return value will be an iterator pointing to the + // first of the newly inserted elements. + iterator_template MoveBefore(IntrusiveList* list) { + if (list->empty()) return *this; + + NodeType* first_node = list->sentinel_.next_node_; + NodeType* last_node = list->sentinel_.previous_node_; + + this->node_->previous_node_->next_node_ = first_node; + first_node->previous_node_ = this->node_->previous_node_; + + last_node->next_node_ = this->node_; + this->node_->previous_node_ = last_node; + + list->sentinel_.next_node_ = &list->sentinel_; + list->sentinel_.previous_node_ = &list->sentinel_; + + return iterator(first_node); + } + + // Define standard iterator types needs so this class can be + // used with . + using iterator_category = std::bidirectional_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using size_type = size_t; + + protected: + iterator_template() = delete; + inline iterator_template(T* node) { node_ = node; } + T* node_; + + friend IntrusiveList; + }; + + using iterator = iterator_template; + using const_iterator = iterator_template; + + // Various types of iterators for the start (begin) and one past the end (end) + // of the list. + // + // Decrementing |end()| iterator will give and iterator pointing to the last + // element in the list, if one exists. + // + // Incrementing |end()| iterator will give |begin()|. + // + // Decrementing |begin()| will give |end()|. + // + // TODO: Not marking these functions as noexcept because Visual Studio 2013 + // does not support it. When we no longer care about that compiler, we should + // mark these as noexcept. + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; + + // Appends |node| to the end of the list. If |node| is already in a list, it + // will be removed from that list first. + void push_back(NodeType* node); + + // Returns true if the list is empty. + bool empty() const; + + // Makes the current list empty. + inline void clear(); + + // Returns references to the first or last element in the list. It is an + // error to call these functions on an empty list. + NodeType& front(); + NodeType& back(); + const NodeType& front() const; + const NodeType& back() const; + + // Transfers [|first|, |last|) from |other| into the list at |where|. + // + // If |other| is |this|, no change is made. + void Splice(iterator where, IntrusiveList* other, iterator first, + iterator last); + + protected: + // Doing a deep copy of the list does not make sense if the list does not own + // the data. It is not clear who will own the newly created data. Making + // copies illegal for that reason. + IntrusiveList(const IntrusiveList&) = delete; + IntrusiveList& operator=(const IntrusiveList&) = delete; + + // This function will assert if it finds the list containing |node| is not in + // a valid state. + static void Check(NodeType* node); + + // A special node used to represent both the start and end of the list, + // without being part of the list. + NodeType sentinel_; +}; + +// Implementation of IntrusiveList + +template +inline IntrusiveList::IntrusiveList() : sentinel_() { + sentinel_.next_node_ = &sentinel_; + sentinel_.previous_node_ = &sentinel_; + sentinel_.is_sentinel_ = true; +} + +template +IntrusiveList::IntrusiveList(IntrusiveList&& list) : sentinel_() { + sentinel_.next_node_ = &sentinel_; + sentinel_.previous_node_ = &sentinel_; + sentinel_.is_sentinel_ = true; + list.sentinel_.ReplaceWith(&sentinel_); +} + +template +IntrusiveList::~IntrusiveList() { + clear(); +} + +template +IntrusiveList& IntrusiveList::operator=( + IntrusiveList&& list) { + list.sentinel_.ReplaceWith(&sentinel_); + return *this; +} + +template +inline typename IntrusiveList::iterator +IntrusiveList::begin() { + return iterator(sentinel_.next_node_); +} + +template +inline typename IntrusiveList::iterator +IntrusiveList::end() { + return iterator(&sentinel_); +} + +template +inline typename IntrusiveList::const_iterator +IntrusiveList::begin() const { + return const_iterator(sentinel_.next_node_); +} + +template +inline typename IntrusiveList::const_iterator +IntrusiveList::end() const { + return const_iterator(&sentinel_); +} + +template +inline typename IntrusiveList::const_iterator +IntrusiveList::cbegin() const { + return const_iterator(sentinel_.next_node_); +} + +template +inline typename IntrusiveList::const_iterator +IntrusiveList::cend() const { + return const_iterator(&sentinel_); +} + +template +void IntrusiveList::push_back(NodeType* node) { + node->InsertBefore(&sentinel_); +} + +template +bool IntrusiveList::empty() const { + return sentinel_.NextNode() == nullptr; +} + +template +void IntrusiveList::clear() { + while (!empty()) { + front().RemoveFromList(); + } +} + +template +NodeType& IntrusiveList::front() { + NodeType* node = sentinel_.NextNode(); + assert(node != nullptr && "Can't get the front of an empty list."); + return *node; +} + +template +NodeType& IntrusiveList::back() { + NodeType* node = sentinel_.PreviousNode(); + assert(node != nullptr && "Can't get the back of an empty list."); + return *node; +} + +template +const NodeType& IntrusiveList::front() const { + NodeType* node = sentinel_.NextNode(); + assert(node != nullptr && "Can't get the front of an empty list."); + return *node; +} + +template +const NodeType& IntrusiveList::back() const { + NodeType* node = sentinel_.PreviousNode(); + assert(node != nullptr && "Can't get the back of an empty list."); + return *node; +} + +template +void IntrusiveList::Splice(iterator where, + IntrusiveList* other, + iterator first, iterator last) { + if (first == last) return; + if (other == this) return; + + NodeType* first_prev = first.node_->previous_node_; + NodeType* where_next = where.node_->next_node_; + + // Attach first. + where.node_->next_node_ = first.node_; + first.node_->previous_node_ = where.node_; + + // Attach last. + where_next->previous_node_ = last.node_->previous_node_; + last.node_->previous_node_->next_node_ = where_next; + + // Fixup other. + first_prev->next_node_ = last.node_; + last.node_->previous_node_ = first_prev; +} + +template +void IntrusiveList::Check(NodeType* start) { + int sentinel_count = 0; + NodeType* p = start; + do { + assert(p != nullptr); + assert(p->next_node_->previous_node_ == p); + assert(p->previous_node_->next_node_ == p); + if (p->is_sentinel_) sentinel_count++; + p = p->next_node_; + } while (p != start); + assert(sentinel_count == 1 && "List should have exactly 1 sentinel node."); + (void)sentinel_count; + + p = start; + do { + assert(p != nullptr); + assert(p->previous_node_->next_node_ == p); + assert(p->next_node_->previous_node_ == p); + if (p->is_sentinel_) sentinel_count++; + p = p->previous_node_; + } while (p != start); +} + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_ILIST_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/ilist_node.h b/thirdparty/glslang/External/spirv-tools/source/util/ilist_node.h new file mode 100644 index 000000000000..0579534b89ff --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/ilist_node.h @@ -0,0 +1,265 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_ILIST_NODE_H_ +#define SOURCE_UTIL_ILIST_NODE_H_ + +#include + +namespace spvtools { +namespace utils { + +template +class IntrusiveList; + +// IntrusiveNodeBase is the base class for nodes in an IntrusiveList. +// See the comments in ilist.h on how to use the class. + +template +class IntrusiveNodeBase { + public: + // Creates a new node that is not in a list. + inline IntrusiveNodeBase(); + inline IntrusiveNodeBase(const IntrusiveNodeBase&); + inline IntrusiveNodeBase& operator=(const IntrusiveNodeBase&); + inline IntrusiveNodeBase(IntrusiveNodeBase&& that); + + // Destroys a node. It is an error to destroy a node that is part of a + // list, unless it is a sentinel. + virtual ~IntrusiveNodeBase(); + + IntrusiveNodeBase& operator=(IntrusiveNodeBase&& that); + + // Returns true if |this| is in a list. + inline bool IsInAList() const; + + // Returns the node that comes after the given node in the list, if one + // exists. If the given node is not in a list or is at the end of the list, + // the return value is nullptr. + inline NodeType* NextNode() const; + + // Returns the node that comes before the given node in the list, if one + // exists. If the given node is not in a list or is at the start of the + // list, the return value is nullptr. + inline NodeType* PreviousNode() const; + + // Inserts the given node immediately before |pos| in the list. + // If the given node is already in a list, it will first be removed + // from that list. + // + // It is assumed that the given node is of type NodeType. It is an error if + // |pos| is not already in a list. + inline void InsertBefore(NodeType* pos); + + // Inserts the given node immediately after |pos| in the list. + // If the given node is already in a list, it will first be removed + // from that list. + // + // It is assumed that the given node is of type NodeType. It is an error if + // |pos| is not already in a list, or if |pos| is equal to |this|. + inline void InsertAfter(NodeType* pos); + + // Removes the given node from the list. It is assumed that the node is + // in a list. Note that this does not free any storage related to the node, + // it becomes the caller's responsibility to free the storage. + inline void RemoveFromList(); + + protected: + // Replaces |this| with |target|. |this| is a sentinel if and only if + // |target| is also a sentinel. + // + // If neither node is a sentinel, |target| takes + // the place of |this|. It is assumed that |target| is not in a list. + // + // If both are sentinels, then it will cause all of the + // nodes in the list containing |this| to be moved to the list containing + // |target|. In this case, it is assumed that |target| is an empty list. + // + // No storage will be deleted. + void ReplaceWith(NodeType* target); + + // Returns true if |this| is the sentinel node of an empty list. + bool IsEmptyList(); + + // The pointers to the next and previous nodes in the list. + // If the current node is not part of a list, then |next_node_| and + // |previous_node_| are equal to |nullptr|. + NodeType* next_node_; + NodeType* previous_node_; + + // Only true for the sentinel node stored in the list itself. + bool is_sentinel_; + + friend IntrusiveList; +}; + +// Implementation of IntrusiveNodeBase + +template +inline IntrusiveNodeBase::IntrusiveNodeBase() + : next_node_(nullptr), previous_node_(nullptr), is_sentinel_(false) {} + +template +inline IntrusiveNodeBase::IntrusiveNodeBase( + const IntrusiveNodeBase&) { + next_node_ = nullptr; + previous_node_ = nullptr; + is_sentinel_ = false; +} + +template +inline IntrusiveNodeBase& IntrusiveNodeBase::operator=( + const IntrusiveNodeBase&) { + assert(!is_sentinel_); + if (IsInAList()) { + RemoveFromList(); + } + return *this; +} + +template +inline IntrusiveNodeBase::IntrusiveNodeBase(IntrusiveNodeBase&& that) + : next_node_(nullptr), + previous_node_(nullptr), + is_sentinel_(that.is_sentinel_) { + if (is_sentinel_) { + next_node_ = this; + previous_node_ = this; + } + that.ReplaceWith(this); +} + +template +IntrusiveNodeBase::~IntrusiveNodeBase() { + assert(is_sentinel_ || !IsInAList()); +} + +template +IntrusiveNodeBase& IntrusiveNodeBase::operator=( + IntrusiveNodeBase&& that) { + that.ReplaceWith(this); + return *this; +} + +template +inline bool IntrusiveNodeBase::IsInAList() const { + return next_node_ != nullptr; +} + +template +inline NodeType* IntrusiveNodeBase::NextNode() const { + if (!next_node_->is_sentinel_) return next_node_; + return nullptr; +} + +template +inline NodeType* IntrusiveNodeBase::PreviousNode() const { + if (!previous_node_->is_sentinel_) return previous_node_; + return nullptr; +} + +template +inline void IntrusiveNodeBase::InsertBefore(NodeType* pos) { + assert(!this->is_sentinel_ && "Sentinel nodes cannot be moved around."); + assert(pos->IsInAList() && "Pos should already be in a list."); + if (this->IsInAList()) this->RemoveFromList(); + + this->next_node_ = pos; + this->previous_node_ = pos->previous_node_; + pos->previous_node_ = static_cast(this); + this->previous_node_->next_node_ = static_cast(this); +} + +template +inline void IntrusiveNodeBase::InsertAfter(NodeType* pos) { + assert(!this->is_sentinel_ && "Sentinel nodes cannot be moved around."); + assert(pos->IsInAList() && "Pos should already be in a list."); + assert(this != pos && "Can't insert a node after itself."); + + if (this->IsInAList()) { + this->RemoveFromList(); + } + + this->previous_node_ = pos; + this->next_node_ = pos->next_node_; + pos->next_node_ = static_cast(this); + this->next_node_->previous_node_ = static_cast(this); +} + +template +inline void IntrusiveNodeBase::RemoveFromList() { + assert(!this->is_sentinel_ && "Sentinel nodes cannot be moved around."); + assert(this->IsInAList() && + "Cannot remove a node from a list if it is not in a list."); + + this->next_node_->previous_node_ = this->previous_node_; + this->previous_node_->next_node_ = this->next_node_; + this->next_node_ = nullptr; + this->previous_node_ = nullptr; +} + +template +void IntrusiveNodeBase::ReplaceWith(NodeType* target) { + if (this->is_sentinel_) { + assert(target->IsEmptyList() && + "If target is not an empty list, the nodes in that list would not " + "be linked to a sentinel."); + } else { + assert(IsInAList() && "The node being replaced must be in a list."); + assert(!target->is_sentinel_ && + "Cannot turn a sentinel node into one that is not."); + } + + if (!this->IsEmptyList()) { + // Link target into the same position that |this| was in. + target->next_node_ = this->next_node_; + target->previous_node_ = this->previous_node_; + target->next_node_->previous_node_ = target; + target->previous_node_->next_node_ = target; + + // Reset |this| to itself default value. + if (!this->is_sentinel_) { + // Reset |this| so that it is not in a list. + this->next_node_ = nullptr; + this->previous_node_ = nullptr; + } else { + // Set |this| so that it is the head of an empty list. + // We cannot treat sentinel nodes like others because it is invalid for + // a sentinel node to not be in a list. + this->next_node_ = static_cast(this); + this->previous_node_ = static_cast(this); + } + } else { + // If |this| points to itself, it must be a sentinel node with an empty + // list. Reset |this| so that it is the head of an empty list. We want + // |target| to be the same. The asserts above guarantee that. + } +} + +template +bool IntrusiveNodeBase::IsEmptyList() { + if (next_node_ == this) { + assert(is_sentinel_ && + "None sentinel nodes should never point to themselves."); + assert(previous_node_ == this && + "Inconsistency with the previous and next nodes."); + return true; + } + return false; +} + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_ILIST_NODE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/make_unique.h b/thirdparty/glslang/External/spirv-tools/source/util/make_unique.h new file mode 100644 index 000000000000..ad7976c34955 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/make_unique.h @@ -0,0 +1,30 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_MAKE_UNIQUE_H_ +#define SOURCE_UTIL_MAKE_UNIQUE_H_ + +#include +#include + +namespace spvtools { + +template +std::unique_ptr MakeUnique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} + +} // namespace spvtools + +#endif // SOURCE_UTIL_MAKE_UNIQUE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/parse_number.cpp b/thirdparty/glslang/External/spirv-tools/source/util/parse_number.cpp new file mode 100644 index 000000000000..c3351c236515 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/parse_number.cpp @@ -0,0 +1,217 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/util/parse_number.h" + +#include +#include +#include +#include +#include +#include + +#include "source/util/hex_float.h" +#include "source/util/make_unique.h" + +namespace spvtools { +namespace utils { +namespace { + +// A helper class that temporarily stores error messages and dump the messages +// to a string which given as as pointer when it is destructed. If the given +// pointer is a nullptr, this class does not store error message. +class ErrorMsgStream { + public: + explicit ErrorMsgStream(std::string* error_msg_sink) + : error_msg_sink_(error_msg_sink) { + if (error_msg_sink_) stream_ = MakeUnique(); + } + ~ErrorMsgStream() { + if (error_msg_sink_ && stream_) *error_msg_sink_ = stream_->str(); + } + template + ErrorMsgStream& operator<<(T val) { + if (stream_) *stream_ << val; + return *this; + } + + private: + std::unique_ptr stream_; + // The destination string to which this class dump the error message when + // destructor is called. + std::string* error_msg_sink_; +}; +} // namespace + +EncodeNumberStatus ParseAndEncodeIntegerNumber( + const char* text, const NumberType& type, + std::function emit, std::string* error_msg) { + if (!text) { + ErrorMsgStream(error_msg) << "The given text is a nullptr"; + return EncodeNumberStatus::kInvalidText; + } + + if (!IsIntegral(type)) { + ErrorMsgStream(error_msg) << "The expected type is not a integer type"; + return EncodeNumberStatus::kInvalidUsage; + } + + const uint32_t bit_width = AssumedBitWidth(type); + + if (bit_width > 64) { + ErrorMsgStream(error_msg) + << "Unsupported " << bit_width << "-bit integer literals"; + return EncodeNumberStatus::kUnsupported; + } + + // Either we are expecting anything or integer. + bool is_negative = text[0] == '-'; + bool can_be_signed = IsSigned(type); + + if (is_negative && !can_be_signed) { + ErrorMsgStream(error_msg) + << "Cannot put a negative number in an unsigned literal"; + return EncodeNumberStatus::kInvalidUsage; + } + + const bool is_hex = text[0] == '0' && (text[1] == 'x' || text[1] == 'X'); + + uint64_t decoded_bits; + if (is_negative) { + int64_t decoded_signed = 0; + + if (!ParseNumber(text, &decoded_signed)) { + ErrorMsgStream(error_msg) << "Invalid signed integer literal: " << text; + return EncodeNumberStatus::kInvalidText; + } + + if (!CheckRangeAndIfHexThenSignExtend(decoded_signed, type, is_hex, + &decoded_signed)) { + ErrorMsgStream(error_msg) + << "Integer " << (is_hex ? std::hex : std::dec) << std::showbase + << decoded_signed << " does not fit in a " << std::dec << bit_width + << "-bit " << (IsSigned(type) ? "signed" : "unsigned") << " integer"; + return EncodeNumberStatus::kInvalidText; + } + decoded_bits = decoded_signed; + } else { + // There's no leading minus sign, so parse it as an unsigned integer. + if (!ParseNumber(text, &decoded_bits)) { + ErrorMsgStream(error_msg) << "Invalid unsigned integer literal: " << text; + return EncodeNumberStatus::kInvalidText; + } + if (!CheckRangeAndIfHexThenSignExtend(decoded_bits, type, is_hex, + &decoded_bits)) { + ErrorMsgStream(error_msg) + << "Integer " << (is_hex ? std::hex : std::dec) << std::showbase + << decoded_bits << " does not fit in a " << std::dec << bit_width + << "-bit " << (IsSigned(type) ? "signed" : "unsigned") << " integer"; + return EncodeNumberStatus::kInvalidText; + } + } + if (bit_width > 32) { + uint32_t low = uint32_t(0x00000000ffffffff & decoded_bits); + uint32_t high = uint32_t((0xffffffff00000000 & decoded_bits) >> 32); + emit(low); + emit(high); + } else { + emit(uint32_t(decoded_bits)); + } + return EncodeNumberStatus::kSuccess; +} + +EncodeNumberStatus ParseAndEncodeFloatingPointNumber( + const char* text, const NumberType& type, + std::function emit, std::string* error_msg) { + if (!text) { + ErrorMsgStream(error_msg) << "The given text is a nullptr"; + return EncodeNumberStatus::kInvalidText; + } + + if (!IsFloating(type)) { + ErrorMsgStream(error_msg) << "The expected type is not a float type"; + return EncodeNumberStatus::kInvalidUsage; + } + + const auto bit_width = AssumedBitWidth(type); + switch (bit_width) { + case 16: { + HexFloat> hVal(0); + if (!ParseNumber(text, &hVal)) { + ErrorMsgStream(error_msg) << "Invalid 16-bit float literal: " << text; + return EncodeNumberStatus::kInvalidText; + } + // getAsFloat will return the Float16 value, and get_value + // will return a uint16_t representing the bits of the float. + // The encoding is therefore correct from the perspective of the SPIR-V + // spec since the top 16 bits will be 0. + emit(static_cast(hVal.value().getAsFloat().get_value())); + return EncodeNumberStatus::kSuccess; + } break; + case 32: { + HexFloat> fVal(0.0f); + if (!ParseNumber(text, &fVal)) { + ErrorMsgStream(error_msg) << "Invalid 32-bit float literal: " << text; + return EncodeNumberStatus::kInvalidText; + } + emit(BitwiseCast(fVal)); + return EncodeNumberStatus::kSuccess; + } break; + case 64: { + HexFloat> dVal(0.0); + if (!ParseNumber(text, &dVal)) { + ErrorMsgStream(error_msg) << "Invalid 64-bit float literal: " << text; + return EncodeNumberStatus::kInvalidText; + } + uint64_t decoded_val = BitwiseCast(dVal); + uint32_t low = uint32_t(0x00000000ffffffff & decoded_val); + uint32_t high = uint32_t((0xffffffff00000000 & decoded_val) >> 32); + emit(low); + emit(high); + return EncodeNumberStatus::kSuccess; + } break; + default: + break; + } + ErrorMsgStream(error_msg) + << "Unsupported " << bit_width << "-bit float literals"; + return EncodeNumberStatus::kUnsupported; +} + +EncodeNumberStatus ParseAndEncodeNumber(const char* text, + const NumberType& type, + std::function emit, + std::string* error_msg) { + if (!text) { + ErrorMsgStream(error_msg) << "The given text is a nullptr"; + return EncodeNumberStatus::kInvalidText; + } + + if (IsUnknown(type)) { + ErrorMsgStream(error_msg) + << "The expected type is not a integer or float type"; + return EncodeNumberStatus::kInvalidUsage; + } + + // If we explicitly expect a floating-point number, we should handle that + // first. + if (IsFloating(type)) { + return ParseAndEncodeFloatingPointNumber(text, type, emit, error_msg); + } + + return ParseAndEncodeIntegerNumber(text, type, emit, error_msg); +} + +} // namespace utils +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/util/parse_number.h b/thirdparty/glslang/External/spirv-tools/source/util/parse_number.h new file mode 100644 index 000000000000..d0f2a09a364c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/parse_number.h @@ -0,0 +1,252 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_PARSE_NUMBER_H_ +#define SOURCE_UTIL_PARSE_NUMBER_H_ + +#include +#include +#include + +#include "source/util/hex_float.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace utils { + +// A struct to hold the expected type information for the number in text to be +// parsed. +struct NumberType { + uint32_t bitwidth; + // SPV_NUMBER_NONE means the type is unknown and is invalid to be used with + // ParseAndEncode{|Integer|Floating}Number(). + spv_number_kind_t kind; +}; + +// Returns true if the type is a scalar integer type. +inline bool IsIntegral(const NumberType& type) { + return type.kind == SPV_NUMBER_UNSIGNED_INT || + type.kind == SPV_NUMBER_SIGNED_INT; +} + +// Returns true if the type is a scalar floating point type. +inline bool IsFloating(const NumberType& type) { + return type.kind == SPV_NUMBER_FLOATING; +} + +// Returns true if the type is a signed value. +inline bool IsSigned(const NumberType& type) { + return type.kind == SPV_NUMBER_FLOATING || type.kind == SPV_NUMBER_SIGNED_INT; +} + +// Returns true if the type is unknown. +inline bool IsUnknown(const NumberType& type) { + return type.kind == SPV_NUMBER_NONE; +} + +// Returns the number of bits in the type. This is only valid for integer and +// floating types. +inline int AssumedBitWidth(const NumberType& type) { + switch (type.kind) { + case SPV_NUMBER_SIGNED_INT: + case SPV_NUMBER_UNSIGNED_INT: + case SPV_NUMBER_FLOATING: + return type.bitwidth; + default: + break; + } + // We don't care about this case. + return 0; +} + +// A templated class with a static member function Clamp, where Clamp sets a +// referenced value of type T to 0 if T is an unsigned integer type, and +// returns true if it modified the referenced value. +template +class ClampToZeroIfUnsignedType { + public: + // The default specialization does not clamp the value. + static bool Clamp(T*) { return false; } +}; + +// The specialization of ClampToZeroIfUnsignedType for unsigned integer types. +template +class ClampToZeroIfUnsignedType< + T, typename std::enable_if::value>::type> { + public: + static bool Clamp(T* value_pointer) { + if (*value_pointer) { + *value_pointer = 0; + return true; + } + return false; + } +}; + +// Returns true if the given value fits within the target scalar integral type. +// The target type may have an unusual bit width. If the value was originally +// specified as a hexadecimal number, then the overflow bits should be zero. +// If it was hex and the target type is signed, then return the sign-extended +// value through the updated_value_for_hex pointer argument. On failure, +// returns false. +template +bool CheckRangeAndIfHexThenSignExtend(T value, const NumberType& type, + bool is_hex, T* updated_value_for_hex) { + // The encoded result has three regions of bits that are of interest, from + // least to most significant: + // - magnitude bits, where the magnitude of the number would be stored if + // we were using a signed-magnitude representation. + // - an optional sign bit + // - overflow bits, up to bit 63 of a 64-bit number + // For example: + // Type Overflow Sign Magnitude + // --------------- -------- ---- --------- + // unsigned 8 bit 8-63 n/a 0-7 + // signed 8 bit 8-63 7 0-6 + // unsigned 16 bit 16-63 n/a 0-15 + // signed 16 bit 16-63 15 0-14 + + // We'll use masks to define the three regions. + // At first we'll assume the number is unsigned. + const uint32_t bit_width = AssumedBitWidth(type); + uint64_t magnitude_mask = + (bit_width == 64) ? -1 : ((uint64_t(1) << bit_width) - 1); + uint64_t sign_mask = 0; + uint64_t overflow_mask = ~magnitude_mask; + + if (value < 0 || IsSigned(type)) { + // Accommodate the sign bit. + magnitude_mask >>= 1; + sign_mask = magnitude_mask + 1; + } + + bool failed = false; + if (value < 0) { + // The top bits must all be 1 for a negative signed value. + failed = ((value & overflow_mask) != overflow_mask) || + ((value & sign_mask) != sign_mask); + } else { + if (is_hex) { + // Hex values are a bit special. They decode as unsigned values, but may + // represent a negative number. In this case, the overflow bits should + // be zero. + failed = (value & overflow_mask) != 0; + } else { + const uint64_t value_as_u64 = static_cast(value); + // Check overflow in the ordinary case. + failed = (value_as_u64 & magnitude_mask) != value_as_u64; + } + } + + if (failed) { + return false; + } + + // Sign extend hex the number. + if (is_hex && (value & sign_mask)) + *updated_value_for_hex = (value | overflow_mask); + + return true; +} + +// Parses a numeric value of a given type from the given text. The number +// should take up the entire string, and should be within bounds for the target +// type. On success, returns true and populates the object referenced by +// value_pointer. On failure, returns false. +template +bool ParseNumber(const char* text, T* value_pointer) { + // C++11 doesn't define std::istringstream(int8_t&), so calling this method + // with a single-byte type leads to implementation-defined behaviour. + // Similarly for uint8_t. + static_assert(sizeof(T) > 1, + "Single-byte types are not supported in this parse method"); + + if (!text) return false; + std::istringstream text_stream(text); + // Allow both decimal and hex input for integers. + // It also allows octal input, but we don't care about that case. + text_stream >> std::setbase(0); + text_stream >> *value_pointer; + + // We should have read something. + bool ok = (text[0] != 0) && !text_stream.bad(); + // It should have been all the text. + ok = ok && text_stream.eof(); + // It should have been in range. + ok = ok && !text_stream.fail(); + + // Work around a bug in the GNU C++11 library. It will happily parse + // "-1" for uint16_t as 65535. + if (ok && text[0] == '-') + ok = !ClampToZeroIfUnsignedType::Clamp(value_pointer); + + return ok; +} + +// Enum to indicate the parsing and encoding status. +enum class EncodeNumberStatus { + kSuccess = 0, + // Unsupported bit width etc. + kUnsupported, + // Expected type (NumberType) is not a scalar int or float, or putting a + // negative number in an unsigned literal. + kInvalidUsage, + // Number value does not fit the bit width of the expected type etc. + kInvalidText, +}; + +// Parses an integer value of a given |type| from the given |text| and encodes +// the number by the given |emit| function. On success, returns +// EncodeNumberStatus::kSuccess and the parsed number will be consumed by the +// given |emit| function word by word (least significant word first). On +// failure, this function returns the error code of the encoding status and +// |emit| function will not be called. If the string pointer |error_msg| is not +// a nullptr, it will be overwritten with error messages in case of failure. In +// case of success, |error_msg| will not be touched. Integers up to 64 bits are +// supported. +EncodeNumberStatus ParseAndEncodeIntegerNumber( + const char* text, const NumberType& type, + std::function emit, std::string* error_msg); + +// Parses a floating point value of a given |type| from the given |text| and +// encodes the number by the given |emit| function. On success, returns +// EncodeNumberStatus::kSuccess and the parsed number will be consumed by the +// given |emit| function word by word (least significant word first). On +// failure, this function returns the error code of the encoding status and +// |emit| function will not be called. If the string pointer |error_msg| is not +// a nullptr, it will be overwritten with error messages in case of failure. In +// case of success, |error_msg| will not be touched. Only 16, 32 and 64 bit +// floating point numbers are supported. +EncodeNumberStatus ParseAndEncodeFloatingPointNumber( + const char* text, const NumberType& type, + std::function emit, std::string* error_msg); + +// Parses an integer or floating point number of a given |type| from the given +// |text| and encodes the number by the given |emit| function. On success, +// returns EncodeNumberStatus::kSuccess and the parsed number will be consumed +// by the given |emit| function word by word (least significant word first). On +// failure, this function returns the error code of the encoding status and +// |emit| function will not be called. If the string pointer |error_msg| is not +// a nullptr, it will be overwritten with error messages in case of failure. In +// case of success, |error_msg| will not be touched. Integers up to 64 bits +// and 16/32/64 bit floating point values are supported. +EncodeNumberStatus ParseAndEncodeNumber(const char* text, + const NumberType& type, + std::function emit, + std::string* error_msg); + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_PARSE_NUMBER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/small_vector.h b/thirdparty/glslang/External/spirv-tools/source/util/small_vector.h new file mode 100644 index 000000000000..1351475bd83d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/small_vector.h @@ -0,0 +1,489 @@ +// Copyright (c) 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_SMALL_VECTOR_H_ +#define SOURCE_UTIL_SMALL_VECTOR_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "source/util/make_unique.h" + +namespace spvtools { +namespace utils { + +// The |SmallVector| class is intended to be a drop-in replacement for +// |std::vector|. The difference is in the implementation. A |SmallVector| is +// optimized for when the number of elements in the vector are small. Small is +// defined by the template parameter |small_size|. +// +// Note that |SmallVector| is not always faster than an |std::vector|, so you +// should experiment with different values for |small_size| and compare to +// using and |std::vector|. +// +// TODO: I have implemented the public member functions from |std::vector| that +// I needed. If others are needed they should be implemented. Do not implement +// public member functions that are not defined by std::vector. +template +class SmallVector { + public: + using iterator = T*; + using const_iterator = const T*; + + SmallVector() + : size_(0), + small_data_(reinterpret_cast(buffer)), + large_data_(nullptr) {} + + SmallVector(const SmallVector& that) : SmallVector() { *this = that; } + + SmallVector(SmallVector&& that) : SmallVector() { *this = std::move(that); } + + SmallVector(const std::vector& vec) : SmallVector() { + if (vec.size() > small_size) { + large_data_ = MakeUnique>(vec); + } else { + size_ = vec.size(); + for (uint32_t i = 0; i < size_; i++) { + new (small_data_ + i) T(vec[i]); + } + } + } + + template + SmallVector(InputIt first, InputIt last) : SmallVector() { + insert(end(), first, last); + } + + SmallVector(std::vector&& vec) : SmallVector() { + if (vec.size() > small_size) { + large_data_ = MakeUnique>(std::move(vec)); + } else { + size_ = vec.size(); + for (uint32_t i = 0; i < size_; i++) { + new (small_data_ + i) T(std::move(vec[i])); + } + } + vec.clear(); + } + + SmallVector(std::initializer_list init_list) : SmallVector() { + if (init_list.size() < small_size) { + for (auto it = init_list.begin(); it != init_list.end(); ++it) { + new (small_data_ + (size_++)) T(std::move(*it)); + } + } else { + large_data_ = MakeUnique>(std::move(init_list)); + } + } + + SmallVector(size_t s, const T& v) : SmallVector() { resize(s, v); } + + virtual ~SmallVector() { + for (T* p = small_data_; p < small_data_ + size_; ++p) { + p->~T(); + } + } + + SmallVector& operator=(const SmallVector& that) { + assert(small_data_); + if (that.large_data_) { + if (large_data_) { + *large_data_ = *that.large_data_; + } else { + large_data_ = MakeUnique>(*that.large_data_); + } + } else { + large_data_.reset(nullptr); + size_t i = 0; + // Do a copy for any element in |this| that is already constructed. + for (; i < size_ && i < that.size_; ++i) { + small_data_[i] = that.small_data_[i]; + } + + if (i >= that.size_) { + // If the size of |this| becomes smaller after the assignment, then + // destroy any extra elements. + for (; i < size_; ++i) { + small_data_[i].~T(); + } + } else { + // If the size of |this| becomes larger after the assignement, copy + // construct the new elements that are needed. + for (; i < that.size_; ++i) { + new (small_data_ + i) T(that.small_data_[i]); + } + } + size_ = that.size_; + } + return *this; + } + + SmallVector& operator=(SmallVector&& that) { + if (that.large_data_) { + large_data_.reset(that.large_data_.release()); + } else { + large_data_.reset(nullptr); + size_t i = 0; + // Do a move for any element in |this| that is already constructed. + for (; i < size_ && i < that.size_; ++i) { + small_data_[i] = std::move(that.small_data_[i]); + } + + if (i >= that.size_) { + // If the size of |this| becomes smaller after the assignment, then + // destroy any extra elements. + for (; i < size_; ++i) { + small_data_[i].~T(); + } + } else { + // If the size of |this| becomes larger after the assignement, move + // construct the new elements that are needed. + for (; i < that.size_; ++i) { + new (small_data_ + i) T(std::move(that.small_data_[i])); + } + } + size_ = that.size_; + } + + // Reset |that| because all of the data has been moved to |this|. + that.DestructSmallData(); + return *this; + } + + template + friend bool operator==(const SmallVector& lhs, const OtherVector& rhs) { + if (lhs.size() != rhs.size()) { + return false; + } + + auto rit = rhs.begin(); + for (auto lit = lhs.begin(); lit != lhs.end(); ++lit, ++rit) { + if (*lit != *rit) { + return false; + } + } + return true; + } + +// Avoid infinite recursion from rewritten operators in C++20 +#if __cplusplus <= 201703L + friend bool operator==(const std::vector& lhs, const SmallVector& rhs) { + return rhs == lhs; + } +#endif + + friend bool operator!=(const SmallVector& lhs, const std::vector& rhs) { + return !(lhs == rhs); + } + + friend bool operator!=(const std::vector& lhs, const SmallVector& rhs) { + return rhs != lhs; + } + + T& operator[](size_t i) { + if (!large_data_) { + return small_data_[i]; + } else { + return (*large_data_)[i]; + } + } + + const T& operator[](size_t i) const { + if (!large_data_) { + return small_data_[i]; + } else { + return (*large_data_)[i]; + } + } + + size_t size() const { + if (!large_data_) { + return size_; + } else { + return large_data_->size(); + } + } + + iterator begin() { + if (large_data_) { + return large_data_->data(); + } else { + return small_data_; + } + } + + const_iterator begin() const { + if (large_data_) { + return large_data_->data(); + } else { + return small_data_; + } + } + + const_iterator cbegin() const { return begin(); } + + iterator end() { + if (large_data_) { + return large_data_->data() + large_data_->size(); + } else { + return small_data_ + size_; + } + } + + const_iterator end() const { + if (large_data_) { + return large_data_->data() + large_data_->size(); + } else { + return small_data_ + size_; + } + } + + const_iterator cend() const { return end(); } + + T* data() { return begin(); } + + const T* data() const { return cbegin(); } + + T& front() { return (*this)[0]; } + + const T& front() const { return (*this)[0]; } + + iterator erase(const_iterator pos) { return erase(pos, pos + 1); } + + iterator erase(const_iterator first, const_iterator last) { + if (large_data_) { + size_t start_index = first - large_data_->data(); + size_t end_index = last - large_data_->data(); + auto r = large_data_->erase(large_data_->begin() + start_index, + large_data_->begin() + end_index); + return large_data_->data() + (r - large_data_->begin()); + } + + // Since C++11, std::vector has |const_iterator| for the parameters, so I + // follow that. However, I need iterators to modify the current container, + // which is not const. This is why I cast away the const. + iterator f = const_cast(first); + iterator l = const_cast(last); + iterator e = end(); + + size_t num_of_del_elements = last - first; + iterator ret = f; + if (first == last) { + return ret; + } + + // Move |last| and any elements after it their earlier position. + while (l != e) { + *f = std::move(*l); + ++f; + ++l; + } + + // Destroy the elements that were supposed to be deleted. + while (f != l) { + f->~T(); + ++f; + } + + // Update the size. + size_ -= num_of_del_elements; + return ret; + } + + void push_back(const T& value) { + if (!large_data_ && size_ == small_size) { + MoveToLargeData(); + } + + if (large_data_) { + large_data_->push_back(value); + return; + } + + new (small_data_ + size_) T(value); + ++size_; + } + + void push_back(T&& value) { + if (!large_data_ && size_ == small_size) { + MoveToLargeData(); + } + + if (large_data_) { + large_data_->push_back(std::move(value)); + return; + } + + new (small_data_ + size_) T(std::move(value)); + ++size_; + } + + void pop_back() { + if (large_data_) { + large_data_->pop_back(); + } else { + --size_; + small_data_[size_].~T(); + } + } + + template + iterator insert(iterator pos, InputIt first, InputIt last) { + size_t element_idx = (pos - begin()); + size_t num_of_new_elements = std::distance(first, last); + size_t new_size = size_ + num_of_new_elements; + if (!large_data_ && new_size > small_size) { + MoveToLargeData(); + } + + if (large_data_) { + typename std::vector::iterator new_pos = + large_data_->begin() + element_idx; + large_data_->insert(new_pos, first, last); + return begin() + element_idx; + } + + // Move |pos| and all of the elements after it over |num_of_new_elements| + // places. We start at the end and work backwards, to make sure we do not + // overwrite data that we have not moved yet. + for (iterator i = begin() + new_size - 1, j = end() - 1; j >= pos; + --i, --j) { + if (i >= begin() + size_) { + new (i) T(std::move(*j)); + } else { + *i = std::move(*j); + } + } + + // Copy the new elements into position. + iterator p = pos; + for (; first != last; ++p, ++first) { + if (p >= small_data_ + size_) { + new (p) T(*first); + } else { + *p = *first; + } + } + + // Update the size. + size_ += num_of_new_elements; + return pos; + } + + bool empty() const { + if (large_data_) { + return large_data_->empty(); + } + return size_ == 0; + } + + void clear() { + if (large_data_) { + large_data_->clear(); + } else { + DestructSmallData(); + } + } + + template + void emplace_back(Args&&... args) { + if (!large_data_ && size_ == small_size) { + MoveToLargeData(); + } + + if (large_data_) { + large_data_->emplace_back(std::forward(args)...); + } else { + new (small_data_ + size_) T(std::forward(args)...); + ++size_; + } + } + + void resize(size_t new_size, const T& v) { + if (!large_data_ && new_size > small_size) { + MoveToLargeData(); + } + + if (large_data_) { + large_data_->resize(new_size, v); + return; + } + + // If |new_size| < |size_|, then destroy the extra elements. + for (size_t i = new_size; i < size_; ++i) { + small_data_[i].~T(); + } + + // If |new_size| > |size_|, the copy construct the new elements. + for (size_t i = size_; i < new_size; ++i) { + new (small_data_ + i) T(v); + } + + // Update the size. + size_ = new_size; + } + + private: + // Moves all of the element from |small_data_| into a new std::vector that can + // be access through |large_data|. + void MoveToLargeData() { + assert(!large_data_); + large_data_ = MakeUnique>(); + for (size_t i = 0; i < size_; ++i) { + large_data_->emplace_back(std::move(small_data_[i])); + } + DestructSmallData(); + } + + // Destroys all of the elements in |small_data_| that have been constructed. + void DestructSmallData() { + for (size_t i = 0; i < size_; ++i) { + small_data_[i].~T(); + } + size_ = 0; + } + + // The number of elements in |small_data_| that have been constructed. + size_t size_; + + // A type with the same alignment and size as T, but will is POD. + struct alignas(T) PodType { + std::array data; + }; + + // The actual data used to store the array elements. It must never be used + // directly, but must only be accessed through |small_data_|. + PodType buffer[small_size]; + + // The pointed used to access the array of elements when the number of + // elements is small. + T* small_data_; + + // A pointer to a vector that is used to store the elements of the vector when + // this size exceeds |small_size|. If |large_data_| is nullptr, then the data + // is stored in |small_data_|. Otherwise, the data is stored in + // |large_data_|. + std::unique_ptr> large_data_; +}; // namespace utils + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_SMALL_VECTOR_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/string_utils.cpp b/thirdparty/glslang/External/spirv-tools/source/util/string_utils.cpp new file mode 100644 index 000000000000..b56c353af912 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/string_utils.cpp @@ -0,0 +1,58 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include "source/util/string_utils.h" + +namespace spvtools { +namespace utils { + +std::string CardinalToOrdinal(size_t cardinal) { + const size_t mod10 = cardinal % 10; + const size_t mod100 = cardinal % 100; + std::string suffix; + if (mod10 == 1 && mod100 != 11) + suffix = "st"; + else if (mod10 == 2 && mod100 != 12) + suffix = "nd"; + else if (mod10 == 3 && mod100 != 13) + suffix = "rd"; + else + suffix = "th"; + + return ToString(cardinal) + suffix; +} + +std::pair SplitFlagArgs(const std::string& flag) { + if (flag.size() < 2) return make_pair(flag, std::string()); + + // Detect the last dash before the pass name. Since we have to + // handle single dash options (-O and -Os), count up to two dashes. + size_t dash_ix = 0; + if (flag[0] == '-' && flag[1] == '-') + dash_ix = 2; + else if (flag[0] == '-') + dash_ix = 1; + + size_t ix = flag.find('='); + return (ix != std::string::npos) + ? make_pair(flag.substr(dash_ix, ix - 2), flag.substr(ix + 1)) + : make_pair(flag.substr(dash_ix), std::string()); +} + +} // namespace utils +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/util/string_utils.h b/thirdparty/glslang/External/spirv-tools/source/util/string_utils.h new file mode 100644 index 000000000000..03e20b3d637b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/string_utils.h @@ -0,0 +1,131 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_UTIL_STRING_UTILS_H_ +#define SOURCE_UTIL_STRING_UTILS_H_ + +#include + +#include +#include +#include +#include + +#include "source/util/string_utils.h" + +namespace spvtools { +namespace utils { + +// Converts arithmetic value |val| to its default string representation. +template +std::string ToString(T val) { + static_assert( + std::is_arithmetic::value, + "spvtools::utils::ToString is restricted to only arithmetic values"); + std::stringstream os; + os << val; + return os.str(); +} + +// Converts cardinal number to ordinal number string. +std::string CardinalToOrdinal(size_t cardinal); + +// Splits the string |flag|, of the form '--pass_name[=pass_args]' into two +// strings "pass_name" and "pass_args". If |flag| has no arguments, the second +// string will be empty. +std::pair SplitFlagArgs(const std::string& flag); + +// Encodes a string as a sequence of words, using the SPIR-V encoding, appending +// to an existing vector. +inline void AppendToVector(const std::string& input, + std::vector* result) { + uint32_t word = 0; + size_t num_bytes = input.size(); + // SPIR-V strings are null-terminated. The byte_index == num_bytes + // case is used to push the terminating null byte. + for (size_t byte_index = 0; byte_index <= num_bytes; byte_index++) { + const auto new_byte = + (byte_index < num_bytes ? uint8_t(input[byte_index]) : uint8_t(0)); + word |= (new_byte << (8 * (byte_index % sizeof(uint32_t)))); + if (3 == (byte_index % sizeof(uint32_t))) { + result->push_back(word); + word = 0; + } + } + // Emit a trailing partial word. + if ((num_bytes + 1) % sizeof(uint32_t)) { + result->push_back(word); + } +} + +// Encodes a string as a sequence of words, using the SPIR-V encoding. +inline std::vector MakeVector(const std::string& input) { + std::vector result; + AppendToVector(input, &result); + return result; +} + +// Decode a string from a sequence of words between first and last, using the +// SPIR-V encoding. Assert that a terminating 0-byte was found (unless +// assert_found_terminating_null is passed as false). +template +inline std::string MakeString(InputIt first, InputIt last, + bool assert_found_terminating_null = true) { + std::string result; + constexpr size_t kCharsPerWord = sizeof(*first); + static_assert(kCharsPerWord == 4, "expect 4-byte word"); + + for (InputIt pos = first; pos != last; ++pos) { + uint32_t word = *pos; + for (size_t byte_index = 0; byte_index < kCharsPerWord; byte_index++) { + uint32_t extracted_word = (word >> (8 * byte_index)) & 0xFF; + char c = static_cast(extracted_word); + if (c == 0) { + return result; + } + result += c; + } + } + assert(!assert_found_terminating_null && + "Did not find terminating null for the string."); + (void)assert_found_terminating_null; /* No unused parameters in release + builds. */ + return result; +} + +// Decode a string from a sequence of words in a vector, using the SPIR-V +// encoding. +template +inline std::string MakeString(const VectorType& words, + bool assert_found_terminating_null = true) { + return MakeString(words.cbegin(), words.cend(), + assert_found_terminating_null); +} + +// Decode a string from array words, consuming up to count words, using the +// SPIR-V encoding. +inline std::string MakeString(const uint32_t* words, size_t num_words, + bool assert_found_terminating_null = true) { + return MakeString(words, words + num_words, assert_found_terminating_null); +} + +// Check if str starts with prefix (only included since C++20) +inline bool starts_with(const std::string& str, const char* prefix) { + return 0 == str.compare(0, std::strlen(prefix), prefix); +} + +} // namespace utils +} // namespace spvtools + +#endif // SOURCE_UTIL_STRING_UTILS_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/util/timer.cpp b/thirdparty/glslang/External/spirv-tools/source/util/timer.cpp new file mode 100644 index 000000000000..c8b8d5b61f40 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/timer.cpp @@ -0,0 +1,102 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if defined(SPIRV_TIMER_ENABLED) + +#include "source/util/timer.h" + +#include +#include +#include +#include +#include + +namespace spvtools { +namespace utils { + +void PrintTimerDescription(std::ostream* out, bool measure_mem_usage) { + if (out) { + *out << std::setw(30) << "PASS name" << std::setw(12) << "CPU time" + << std::setw(12) << "WALL time" << std::setw(12) << "USR time" + << std::setw(12) << "SYS time"; + if (measure_mem_usage) { + *out << std::setw(12) << "RSS delta" << std::setw(16) << "PGFault delta"; + } + *out << std::endl; + } +} + +// Do not change the order of invoking system calls. We want to make CPU/Wall +// time correct as much as possible. Calling functions to get CPU/Wall time must +// closely surround the target code of measuring. +void Timer::Start() { + if (report_stream_) { + if (getrusage(RUSAGE_SELF, &usage_before_) == -1) + usage_status_ |= kGetrusageFailed; + if (clock_gettime(CLOCK_MONOTONIC, &wall_before_) == -1) + usage_status_ |= kClockGettimeWalltimeFailed; + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_before_) == -1) + usage_status_ |= kClockGettimeCPUtimeFailed; + } +} + +// The order of invoking system calls is important with the same reason as +// Timer::Start(). +void Timer::Stop() { + if (report_stream_ && usage_status_ == kSucceeded) { + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_after_) == -1) + usage_status_ |= kClockGettimeCPUtimeFailed; + if (clock_gettime(CLOCK_MONOTONIC, &wall_after_) == -1) + usage_status_ |= kClockGettimeWalltimeFailed; + if (getrusage(RUSAGE_SELF, &usage_after_) == -1) + usage_status_ = kGetrusageFailed; + } +} + +void Timer::Report(const char* tag) { + if (!report_stream_) return; + + report_stream_->precision(2); + *report_stream_ << std::fixed << std::setw(30) << tag; + + if (usage_status_ & kClockGettimeCPUtimeFailed) + *report_stream_ << std::setw(12) << "Failed"; + else + *report_stream_ << std::setw(12) << CPUTime(); + + if (usage_status_ & kClockGettimeWalltimeFailed) + *report_stream_ << std::setw(12) << "Failed"; + else + *report_stream_ << std::setw(12) << WallTime(); + + if (usage_status_ & kGetrusageFailed) { + *report_stream_ << std::setw(12) << "Failed" << std::setw(12) << "Failed"; + if (measure_mem_usage_) { + *report_stream_ << std::setw(12) << "Failed" << std::setw(12) << "Failed"; + } + } else { + *report_stream_ << std::setw(12) << UserTime() << std::setw(12) + << SystemTime(); + if (measure_mem_usage_) { + *report_stream_ << std::fixed << std::setw(12) << RSS() << std::setw(16) + << PageFault(); + } + } + *report_stream_ << std::endl; +} + +} // namespace utils +} // namespace spvtools + +#endif // defined(SPIRV_TIMER_ENABLED) diff --git a/thirdparty/glslang/External/spirv-tools/source/util/timer.h b/thirdparty/glslang/External/spirv-tools/source/util/timer.h new file mode 100644 index 000000000000..080831196f53 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/util/timer.h @@ -0,0 +1,392 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Contains utils for getting resource utilization + +#ifndef SOURCE_UTIL_TIMER_H_ +#define SOURCE_UTIL_TIMER_H_ + +#if defined(SPIRV_TIMER_ENABLED) + +#include +#include +#include + +// A macro to call spvtools::utils::PrintTimerDescription(std::ostream*, bool). +// The first argument must be given as std::ostream*. If it is NULL, the +// function does nothing. Otherwise, it prints resource types measured by Timer +// class. The second is optional and if it is true, the function also prints +// resource type fields related to memory. Otherwise, it does not print memory +// related fields. Its default is false. In usual, this must be placed before +// calling Timer::Report() to inform what those fields printed by +// Timer::Report() indicate (or spvtools::utils::PrintTimerDescription() must be +// used instead). +#define SPIRV_TIMER_DESCRIPTION(...) \ + spvtools::utils::PrintTimerDescription(__VA_ARGS__) + +// Creates an object of ScopedTimer to measure the resource utilization for the +// scope surrounding it as the following example: +// +// { // <-- beginning of this scope +// +// /* ... code out of interest ... */ +// +// SPIRV_TIMER_SCOPED(std::cout, tag); +// +// /* ... lines of code that we want to know its resource usage ... */ +// +// } // <-- end of this scope. The destructor of ScopedTimer prints tag and +// the resource utilization to std::cout. +#define SPIRV_TIMER_SCOPED(...) \ + spvtools::utils::ScopedTimer timer##__LINE__( \ + __VA_ARGS__) + +namespace spvtools { +namespace utils { + +// Prints the description of resource types measured by Timer class. If |out| is +// NULL, it does nothing. Otherwise, it prints resource types. The second is +// optional and if it is true, the function also prints resource type fields +// related to memory. Its default is false. In usual, this must be placed before +// calling Timer::Report() to inform what those fields printed by +// Timer::Report() indicate. +void PrintTimerDescription(std::ostream*, bool = false); + +// Status of Timer. kGetrusageFailed means it failed in calling getrusage(). +// kClockGettimeWalltimeFailed means it failed in getting wall time when calling +// clock_gettime(). kClockGettimeCPUtimeFailed means it failed in getting CPU +// time when calling clock_gettime(). +enum UsageStatus { + kSucceeded = 0, + kGetrusageFailed = 1 << 0, + kClockGettimeWalltimeFailed = 1 << 1, + kClockGettimeCPUtimeFailed = 1 << 2, +}; + +// Timer measures the resource utilization for a range of code. The resource +// utilization consists of CPU time (i.e., process time), WALL time (elapsed +// time), USR time, SYS time, RSS delta, and the delta of the number of page +// faults. RSS delta and the delta of the number of page faults are measured +// only when |measure_mem_usage| given to the constructor is true. This class +// should be used as the following example: +// +// spvtools::utils::Timer timer(std::cout); +// timer.Start(); // <-- set |usage_before_|, |wall_before_|, +// and |cpu_before_| +// +// /* ... lines of code that we want to know its resource usage ... */ +// +// timer.Stop(); // <-- set |cpu_after_|, |wall_after_|, and +// |usage_after_| +// timer.Report(tag); // <-- print tag and the resource utilization to +// std::cout. +class Timer { + public: + Timer(std::ostream* out, bool measure_mem_usage = false) + : report_stream_(out), + usage_status_(kSucceeded), + measure_mem_usage_(measure_mem_usage) {} + + // Sets |usage_before_|, |wall_before_|, and |cpu_before_| as results of + // getrusage(), clock_gettime() for the wall time, and clock_gettime() for the + // CPU time respectively. Note that this method erases all previous state of + // |usage_before_|, |wall_before_|, |cpu_before_|. + virtual void Start(); + + // Sets |cpu_after_|, |wall_after_|, and |usage_after_| as results of + // clock_gettime() for the wall time, and clock_gettime() for the CPU time, + // getrusage() respectively. Note that this method erases all previous state + // of |cpu_after_|, |wall_after_|, |usage_after_|. + virtual void Stop(); + + // If |report_stream_| is NULL, it does nothing. Otherwise, it prints the + // resource utilization (i.e., CPU/WALL/USR/SYS time, RSS delta) between the + // time of calling Timer::Start() and the time of calling Timer::Stop(). If we + // cannot get a resource usage because of failures, it prints "Failed" instead + // for the resource. + void Report(const char* tag); + + // Returns the measured CPU Time (i.e., process time) for a range of code + // execution. If kClockGettimeCPUtimeFailed is set by the failure of calling + // clock_gettime(), it returns -1. + virtual double CPUTime() { + if (usage_status_ & kClockGettimeCPUtimeFailed) return -1; + return TimeDifference(cpu_before_, cpu_after_); + } + + // Returns the measured Wall Time (i.e., elapsed time) for a range of code + // execution. If kClockGettimeWalltimeFailed is set by the failure of + // calling clock_gettime(), it returns -1. + virtual double WallTime() { + if (usage_status_ & kClockGettimeWalltimeFailed) return -1; + return TimeDifference(wall_before_, wall_after_); + } + + // Returns the measured USR Time for a range of code execution. If + // kGetrusageFailed is set because of the failure of calling getrusage(), it + // returns -1. + virtual double UserTime() { + if (usage_status_ & kGetrusageFailed) return -1; + return TimeDifference(usage_before_.ru_utime, usage_after_.ru_utime); + } + + // Returns the measured SYS Time for a range of code execution. If + // kGetrusageFailed is set because of the failure of calling getrusage(), it + // returns -1. + virtual double SystemTime() { + if (usage_status_ & kGetrusageFailed) return -1; + return TimeDifference(usage_before_.ru_stime, usage_after_.ru_stime); + } + + // Returns the measured RSS delta for a range of code execution. If + // kGetrusageFailed is set because of the failure of calling getrusage(), it + // returns -1. + virtual long RSS() const { + if (usage_status_ & kGetrusageFailed) return -1; + return usage_after_.ru_maxrss - usage_before_.ru_maxrss; + } + + // Returns the measured the delta of the number of page faults for a range of + // code execution. If kGetrusageFailed is set because of the failure of + // calling getrusage(), it returns -1. + virtual long PageFault() const { + if (usage_status_ & kGetrusageFailed) return -1; + return (usage_after_.ru_minflt - usage_before_.ru_minflt) + + (usage_after_.ru_majflt - usage_before_.ru_majflt); + } + + virtual ~Timer() {} + + private: + // Returns the time gap between |from| and |to| in seconds. + static double TimeDifference(const timeval& from, const timeval& to) { + assert((to.tv_sec > from.tv_sec) || + (to.tv_sec == from.tv_sec && to.tv_usec >= from.tv_usec)); + return static_cast(to.tv_sec - from.tv_sec) + + static_cast(to.tv_usec - from.tv_usec) * .000001; + } + + // Returns the time gap between |from| and |to| in seconds. + static double TimeDifference(const timespec& from, const timespec& to) { + assert((to.tv_sec > from.tv_sec) || + (to.tv_sec == from.tv_sec && to.tv_nsec >= from.tv_nsec)); + return static_cast(to.tv_sec - from.tv_sec) + + static_cast(to.tv_nsec - from.tv_nsec) * .000000001; + } + + // Output stream to print out the resource utilization. If it is NULL, + // Report() does nothing. + std::ostream* report_stream_; + + // Status to stop measurement if a system call returns an error. + unsigned usage_status_; + + // Variable to save the result of clock_gettime(CLOCK_PROCESS_CPUTIME_ID) when + // Timer::Start() is called. It is used as the base status of CPU time. + timespec cpu_before_; + + // Variable to save the result of clock_gettime(CLOCK_MONOTONIC) when + // Timer::Start() is called. It is used as the base status of WALL time. + timespec wall_before_; + + // Variable to save the result of getrusage() when Timer::Start() is called. + // It is used as the base status of USR time, SYS time, and RSS. + rusage usage_before_; + + // Variable to save the result of clock_gettime(CLOCK_PROCESS_CPUTIME_ID) when + // Timer::Stop() is called. It is used as the last status of CPU time. The + // resource usage is measured by subtracting |cpu_before_| from it. + timespec cpu_after_; + + // Variable to save the result of clock_gettime(CLOCK_MONOTONIC) when + // Timer::Stop() is called. It is used as the last status of WALL time. The + // resource usage is measured by subtracting |wall_before_| from it. + timespec wall_after_; + + // Variable to save the result of getrusage() when Timer::Stop() is called. It + // is used as the last status of USR time, SYS time, and RSS. Those resource + // usages are measured by subtracting |usage_before_| from it. + rusage usage_after_; + + // If true, Timer reports the memory usage information too. Otherwise, Timer + // reports only USR time, WALL time, SYS time. + bool measure_mem_usage_; +}; + +// The purpose of ScopedTimer is to measure the resource utilization for a +// scope. Simply creating a local variable of ScopedTimer will call +// Timer::Start() and it calls Timer::Stop() and Timer::Report() at the end of +// the scope by its destructor. When we use this class, we must choose the +// proper Timer class (for class TimerType template) in advance. This class +// should be used as the following example: +// +// { // <-- beginning of this scope +// +// /* ... code out of interest ... */ +// +// spvtools::utils::ScopedTimer +// scopedtimer(std::cout, tag); +// +// /* ... lines of code that we want to know its resource usage ... */ +// +// } // <-- end of this scope. The destructor of ScopedTimer prints tag and +// the resource utilization to std::cout. +// +// The template is used to choose a Timer class. Currently, +// only options for the Timer class are Timer and MockTimer in the unit test. +template +class ScopedTimer { + public: + ScopedTimer(std::ostream* out, const char* tag, + bool measure_mem_usage = false) + : timer(new TimerType(out, measure_mem_usage)), tag_(tag) { + timer->Start(); + } + + // At the end of the scope surrounding the instance of this class, this + // destructor saves the last status of resource usage and reports it. + virtual ~ScopedTimer() { + timer->Stop(); + timer->Report(tag_); + delete timer; + } + + private: + // Actual timer that measures the resource utilization. It must be an instance + // of Timer class if there is no special reason to use other class. + TimerType* timer; + + // A tag that will be printed in front of the trace reported by Timer class. + const char* tag_; +}; + +// CumulativeTimer is the same as Timer class, but it supports a cumulative +// measurement as the following example: +// +// CumulativeTimer *ctimer = new CumulativeTimer(std::cout); +// ctimer->Start(); +// +// /* ... lines of code that we want to know its resource usage ... */ +// +// ctimer->Stop(); +// +// /* ... code out of interest ... */ +// +// ctimer->Start(); +// +// /* ... lines of code that we want to know its resource usage ... */ +// +// ctimer->Stop(); +// ctimer->Report(tag); +// delete ctimer; +// +class CumulativeTimer : public Timer { + public: + CumulativeTimer(std::ostream* out, bool measure_mem_usage = false) + : Timer(out, measure_mem_usage), + cpu_time_(0), + wall_time_(0), + usr_time_(0), + sys_time_(0), + rss_(0), + pgfaults_(0) {} + + // If we cannot get a resource usage because of failures, it sets -1 for the + // resource usage. + void Stop() override { + Timer::Stop(); + + if (cpu_time_ >= 0 && Timer::CPUTime() >= 0) + cpu_time_ += Timer::CPUTime(); + else + cpu_time_ = -1; + + if (wall_time_ >= 0 && Timer::WallTime() >= 0) + wall_time_ += Timer::WallTime(); + else + wall_time_ = -1; + + if (usr_time_ >= 0 && Timer::UserTime() >= 0) + usr_time_ += Timer::UserTime(); + else + usr_time_ = -1; + + if (sys_time_ >= 0 && Timer::SystemTime() >= 0) + sys_time_ += Timer::SystemTime(); + else + sys_time_ = -1; + + if (rss_ >= 0 && Timer::RSS() >= 0) + rss_ += Timer::RSS(); + else + rss_ = -1; + + if (pgfaults_ >= 0 && Timer::PageFault() >= 0) + pgfaults_ += Timer::PageFault(); + else + pgfaults_ = -1; + } + + // Returns the cumulative CPU Time (i.e., process time) for a range of code + // execution. + double CPUTime() override { return cpu_time_; } + + // Returns the cumulative Wall Time (i.e., elapsed time) for a range of code + // execution. + double WallTime() override { return wall_time_; } + + // Returns the cumulative USR Time for a range of code execution. + double UserTime() override { return usr_time_; } + + // Returns the cumulative SYS Time for a range of code execution. + double SystemTime() override { return sys_time_; } + + // Returns the cumulative RSS delta for a range of code execution. + long RSS() const override { return rss_; } + + // Returns the cumulative delta of number of page faults for a range of code + // execution. + long PageFault() const override { return pgfaults_; } + + private: + // Variable to save the cumulative CPU time (i.e., process time). + double cpu_time_; + + // Variable to save the cumulative wall time (i.e., elapsed time). + double wall_time_; + + // Variable to save the cumulative user time. + double usr_time_; + + // Variable to save the cumulative system time. + double sys_time_; + + // Variable to save the cumulative RSS delta. + long rss_; + + // Variable to save the cumulative delta of the number of page faults. + long pgfaults_; +}; + +} // namespace utils +} // namespace spvtools + +#else // defined(SPIRV_TIMER_ENABLED) + +#define SPIRV_TIMER_DESCRIPTION(...) +#define SPIRV_TIMER_SCOPED(...) + +#endif // defined(SPIRV_TIMER_ENABLED) + +#endif // SOURCE_UTIL_TIMER_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/val/basic_block.cpp b/thirdparty/glslang/External/spirv-tools/source/val/basic_block.cpp new file mode 100644 index 000000000000..9a358fcb97fd --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/basic_block.cpp @@ -0,0 +1,187 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/basic_block.h" + +#include +#include + +namespace spvtools { +namespace val { + +BasicBlock::BasicBlock(uint32_t label_id) + : id_(label_id), + immediate_dominator_(nullptr), + immediate_structural_dominator_(nullptr), + immediate_structural_post_dominator_(nullptr), + predecessors_(), + successors_(), + type_(0), + reachable_(false), + structurally_reachable_(false), + label_(nullptr), + terminator_(nullptr) {} + +void BasicBlock::SetImmediateDominator(BasicBlock* dom_block) { + immediate_dominator_ = dom_block; +} + +void BasicBlock::SetImmediateStructuralDominator(BasicBlock* dom_block) { + immediate_structural_dominator_ = dom_block; +} + +void BasicBlock::SetImmediateStructuralPostDominator(BasicBlock* pdom_block) { + immediate_structural_post_dominator_ = pdom_block; +} + +const BasicBlock* BasicBlock::immediate_dominator() const { + return immediate_dominator_; +} + +const BasicBlock* BasicBlock::immediate_structural_dominator() const { + return immediate_structural_dominator_; +} + +const BasicBlock* BasicBlock::immediate_structural_post_dominator() const { + return immediate_structural_post_dominator_; +} + +BasicBlock* BasicBlock::immediate_dominator() { return immediate_dominator_; } +BasicBlock* BasicBlock::immediate_structural_dominator() { + return immediate_structural_dominator_; +} +BasicBlock* BasicBlock::immediate_structural_post_dominator() { + return immediate_structural_post_dominator_; +} + +void BasicBlock::RegisterSuccessors( + const std::vector& next_blocks) { + for (auto& block : next_blocks) { + block->predecessors_.push_back(this); + successors_.push_back(block); + + // Register structural successors/predecessors too. + block->structural_predecessors_.push_back(this); + structural_successors_.push_back(block); + } +} + +bool BasicBlock::dominates(const BasicBlock& other) const { + return (this == &other) || + !(other.dom_end() == + std::find(other.dom_begin(), other.dom_end(), this)); +} + +bool BasicBlock::structurally_dominates(const BasicBlock& other) const { + return (this == &other) || !(other.structural_dom_end() == + std::find(other.structural_dom_begin(), + other.structural_dom_end(), this)); +} + +bool BasicBlock::structurally_postdominates(const BasicBlock& other) const { + return (this == &other) || !(other.structural_pdom_end() == + std::find(other.structural_pdom_begin(), + other.structural_pdom_end(), this)); +} + +BasicBlock::DominatorIterator::DominatorIterator() : current_(nullptr) {} + +BasicBlock::DominatorIterator::DominatorIterator( + const BasicBlock* block, + std::function dominator_func) + : current_(block), dom_func_(dominator_func) {} + +BasicBlock::DominatorIterator& BasicBlock::DominatorIterator::operator++() { + if (current_ == dom_func_(current_)) { + current_ = nullptr; + } else { + current_ = dom_func_(current_); + } + return *this; +} + +const BasicBlock::DominatorIterator BasicBlock::dom_begin() const { + return DominatorIterator( + this, [](const BasicBlock* b) { return b->immediate_dominator(); }); +} + +BasicBlock::DominatorIterator BasicBlock::dom_begin() { + return DominatorIterator( + this, [](const BasicBlock* b) { return b->immediate_dominator(); }); +} + +const BasicBlock::DominatorIterator BasicBlock::dom_end() const { + return DominatorIterator(); +} + +BasicBlock::DominatorIterator BasicBlock::dom_end() { + return DominatorIterator(); +} + +const BasicBlock::DominatorIterator BasicBlock::structural_dom_begin() const { + return DominatorIterator(this, [](const BasicBlock* b) { + return b->immediate_structural_dominator(); + }); +} + +BasicBlock::DominatorIterator BasicBlock::structural_dom_begin() { + return DominatorIterator(this, [](const BasicBlock* b) { + return b->immediate_structural_dominator(); + }); +} + +const BasicBlock::DominatorIterator BasicBlock::structural_dom_end() const { + return DominatorIterator(); +} + +BasicBlock::DominatorIterator BasicBlock::structural_dom_end() { + return DominatorIterator(); +} + +const BasicBlock::DominatorIterator BasicBlock::structural_pdom_begin() const { + return DominatorIterator(this, [](const BasicBlock* b) { + return b->immediate_structural_post_dominator(); + }); +} + +BasicBlock::DominatorIterator BasicBlock::structural_pdom_begin() { + return DominatorIterator(this, [](const BasicBlock* b) { + return b->immediate_structural_post_dominator(); + }); +} + +const BasicBlock::DominatorIterator BasicBlock::structural_pdom_end() const { + return DominatorIterator(); +} + +BasicBlock::DominatorIterator BasicBlock::structural_pdom_end() { + return DominatorIterator(); +} + +bool operator==(const BasicBlock::DominatorIterator& lhs, + const BasicBlock::DominatorIterator& rhs) { + return lhs.current_ == rhs.current_; +} + +bool operator!=(const BasicBlock::DominatorIterator& lhs, + const BasicBlock::DominatorIterator& rhs) { + return !(lhs == rhs); +} + +const BasicBlock*& BasicBlock::DominatorIterator::operator*() { + return current_; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/basic_block.h b/thirdparty/glslang/External/spirv-tools/source/val/basic_block.h new file mode 100644 index 000000000000..be5657ea55d6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/basic_block.h @@ -0,0 +1,320 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_VAL_BASIC_BLOCK_H_ +#define SOURCE_VAL_BASIC_BLOCK_H_ + +#include +#include +#include +#include +#include + +#include "source/latest_version_spirv_header.h" + +namespace spvtools { +namespace val { + +enum BlockType : uint32_t { + kBlockTypeUndefined, + kBlockTypeSelection, + kBlockTypeLoop, + kBlockTypeMerge, + kBlockTypeBreak, + kBlockTypeContinue, + kBlockTypeReturn, + kBlockTypeCOUNT ///< Total number of block types. (must be the last element) +}; + +class Instruction; + +// This class represents a basic block in a SPIR-V module +class BasicBlock { + public: + /// Constructor for a BasicBlock + /// + /// @param[in] id The ID of the basic block + explicit BasicBlock(uint32_t id); + + /// Returns the id of the BasicBlock + uint32_t id() const { return id_; } + + /// Returns the predecessors of the BasicBlock + const std::vector* predecessors() const { + return &predecessors_; + } + + /// Returns the predecessors of the BasicBlock + std::vector* predecessors() { return &predecessors_; } + + /// Returns the successors of the BasicBlock + const std::vector* successors() const { return &successors_; } + + /// Returns the successors of the BasicBlock + std::vector* successors() { return &successors_; } + + /// Returns the structural successors of the BasicBlock + std::vector* structural_predecessors() { + return &structural_predecessors_; + } + + /// Returns the structural predecessors of the BasicBlock + const std::vector* structural_predecessors() const { + return &structural_predecessors_; + } + + /// Returns the structural successors of the BasicBlock + std::vector* structural_successors() { + return &structural_successors_; + } + + /// Returns the structural predecessors of the BasicBlock + const std::vector* structural_successors() const { + return &structural_successors_; + } + + /// Returns true if the block is reachable in the CFG. + bool reachable() const { return reachable_; } + + /// Returns true if the block is structurally reachable in the CFG. + bool structurally_reachable() const { return structurally_reachable_; } + + /// Returns true if BasicBlock is of the given type + bool is_type(BlockType type) const { + if (type == kBlockTypeUndefined) return type_.none(); + return type_.test(type); + } + + /// Sets the reachability of the basic block in the CFG + void set_reachable(bool reachability) { reachable_ = reachability; } + + /// Sets the structural reachability of the basic block in the CFG + void set_structurally_reachable(bool reachability) { + structurally_reachable_ = reachability; + } + + /// Sets the type of the BasicBlock + void set_type(BlockType type) { + if (type == kBlockTypeUndefined) + type_.reset(); + else + type_.set(type); + } + + /// Sets the immediate dominator of this basic block + /// + /// @param[in] dom_block The dominator block + void SetImmediateDominator(BasicBlock* dom_block); + + /// Sets the immediate dominator of this basic block + /// + /// @param[in] dom_block The dominator block + void SetImmediateStructuralDominator(BasicBlock* dom_block); + + /// Sets the immediate post dominator of this basic block + /// + /// @param[in] pdom_block The post dominator block + void SetImmediateStructuralPostDominator(BasicBlock* pdom_block); + + /// Returns the immediate dominator of this basic block + BasicBlock* immediate_dominator(); + + /// Returns the immediate dominator of this basic block + const BasicBlock* immediate_dominator() const; + + /// Returns the immediate dominator of this basic block + BasicBlock* immediate_structural_dominator(); + + /// Returns the immediate dominator of this basic block + const BasicBlock* immediate_structural_dominator() const; + + /// Returns the immediate post dominator of this basic block + BasicBlock* immediate_structural_post_dominator(); + + /// Returns the immediate post dominator of this basic block + const BasicBlock* immediate_structural_post_dominator() const; + + /// Returns the label instruction for the block, or nullptr if not set. + const Instruction* label() const { return label_; } + + //// Registers the label instruction for the block. + void set_label(const Instruction* t) { label_ = t; } + + /// Registers the terminator instruction for the block. + void set_terminator(const Instruction* t) { terminator_ = t; } + + /// Returns the terminator instruction for the block. + const Instruction* terminator() const { return terminator_; } + + /// Adds @p next BasicBlocks as successors of this BasicBlock + void RegisterSuccessors( + const std::vector& next = std::vector()); + + /// Returns true if the id of the BasicBlock matches + bool operator==(const BasicBlock& other) const { return other.id_ == id_; } + + /// Returns true if the id of the BasicBlock matches + bool operator==(const uint32_t& other_id) const { return other_id == id_; } + + /// Returns true if this block dominates the other block. + /// Assumes dominators have been computed. + bool dominates(const BasicBlock& other) const; + + /// Returns true if this block structurally dominates the other block. + /// Assumes structural dominators have been computed. + bool structurally_dominates(const BasicBlock& other) const; + + /// Returns true if this block structurally postdominates the other block. + /// Assumes structural dominators have been computed. + bool structurally_postdominates(const BasicBlock& other) const; + + void RegisterStructuralSuccessor(BasicBlock* block) { + block->structural_predecessors_.push_back(this); + structural_successors_.push_back(block); + } + + /// @brief A BasicBlock dominator iterator class + /// + /// This iterator will iterate over the (post)dominators of the block + class DominatorIterator { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = BasicBlock*; + using pointer = value_type*; + using reference = value_type&; + using difference_type = std::ptrdiff_t; + + /// @brief Constructs the end of dominator iterator + /// + /// This will create an iterator which will represent the element + /// before the root node of the dominator tree + DominatorIterator(); + + /// @brief Constructs an iterator for the given block which points to + /// @p block + /// + /// @param block The block which is referenced by the iterator + /// @param dominator_func This function will be called to get the immediate + /// (post)dominator of the current block + DominatorIterator( + const BasicBlock* block, + std::function dominator_func); + + /// @brief Advances the iterator + DominatorIterator& operator++(); + + /// @brief Returns the current element + const BasicBlock*& operator*(); + + friend bool operator==(const DominatorIterator& lhs, + const DominatorIterator& rhs); + + private: + const BasicBlock* current_; + std::function dom_func_; + }; + + /// Returns a dominator iterator which points to the current block + const DominatorIterator dom_begin() const; + + /// Returns a dominator iterator which points to the current block + DominatorIterator dom_begin(); + + /// Returns a dominator iterator which points to one element past the first + /// block + const DominatorIterator dom_end() const; + + /// Returns a dominator iterator which points to one element past the first + /// block + DominatorIterator dom_end(); + + /// Returns a dominator iterator which points to the current block + const DominatorIterator structural_dom_begin() const; + + /// Returns a dominator iterator which points to the current block + DominatorIterator structural_dom_begin(); + + /// Returns a dominator iterator which points to one element past the first + /// block + const DominatorIterator structural_dom_end() const; + + /// Returns a dominator iterator which points to one element past the first + /// block + DominatorIterator structural_dom_end(); + + /// Returns a post dominator iterator which points to the current block + const DominatorIterator structural_pdom_begin() const; + /// Returns a post dominator iterator which points to the current block + DominatorIterator structural_pdom_begin(); + + /// Returns a post dominator iterator which points to one element past the + /// last block + const DominatorIterator structural_pdom_end() const; + + /// Returns a post dominator iterator which points to one element past the + /// last block + DominatorIterator structural_pdom_end(); + + private: + /// Id of the BasicBlock + const uint32_t id_; + + /// Pointer to the immediate dominator of the BasicBlock + BasicBlock* immediate_dominator_; + + /// Pointer to the immediate structural dominator of the BasicBlock + BasicBlock* immediate_structural_dominator_; + + /// Pointer to the immediate structural post dominator of the BasicBlock + BasicBlock* immediate_structural_post_dominator_; + + /// The set of predecessors of the BasicBlock + std::vector predecessors_; + + /// The set of successors of the BasicBlock + std::vector successors_; + + /// The type of the block + std::bitset type_; + + /// True if the block is reachable in the CFG + bool reachable_; + + /// True if the block is structurally reachable in the CFG + bool structurally_reachable_; + + /// label of this block, if any. + const Instruction* label_; + + /// Terminator of this block. + const Instruction* terminator_; + + std::vector structural_predecessors_; + std::vector structural_successors_; +}; + +/// @brief Returns true if the iterators point to the same element or if both +/// iterators point to the @p dom_end block +bool operator==(const BasicBlock::DominatorIterator& lhs, + const BasicBlock::DominatorIterator& rhs); + +/// @brief Returns true if the iterators point to different elements and they +/// do not both point to the @p dom_end block +bool operator!=(const BasicBlock::DominatorIterator& lhs, + const BasicBlock::DominatorIterator& rhs); + +} // namespace val +} // namespace spvtools + +#endif // SOURCE_VAL_BASIC_BLOCK_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/val/construct.cpp b/thirdparty/glslang/External/spirv-tools/source/val/construct.cpp new file mode 100644 index 000000000000..10af155da2b9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/construct.cpp @@ -0,0 +1,222 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/construct.h" + +#include +#include + +#include "source/val/function.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +Construct::Construct(ConstructType construct_type, BasicBlock* entry, + BasicBlock* exit, std::vector constructs) + : type_(construct_type), + corresponding_constructs_(constructs), + entry_block_(entry), + exit_block_(exit) {} + +ConstructType Construct::type() const { return type_; } + +const std::vector& Construct::corresponding_constructs() const { + return corresponding_constructs_; +} +std::vector& Construct::corresponding_constructs() { + return corresponding_constructs_; +} + +bool ValidateConstructSize(ConstructType type, size_t size) { + switch (type) { + case ConstructType::kSelection: + return size == 0; + case ConstructType::kContinue: + return size == 1; + case ConstructType::kLoop: + return size == 1; + case ConstructType::kCase: + return size >= 1; + default: + assert(1 == 0 && "Type not defined"); + } + return false; +} + +void Construct::set_corresponding_constructs( + std::vector constructs) { + assert(ValidateConstructSize(type_, constructs.size())); + corresponding_constructs_ = constructs; +} + +const BasicBlock* Construct::entry_block() const { return entry_block_; } +BasicBlock* Construct::entry_block() { return entry_block_; } + +const BasicBlock* Construct::exit_block() const { return exit_block_; } +BasicBlock* Construct::exit_block() { return exit_block_; } + +void Construct::set_exit(BasicBlock* block) { exit_block_ = block; } + +Construct::ConstructBlockSet Construct::blocks(Function* /*function*/) const { + const auto header = entry_block(); + const auto exit = exit_block(); + const bool is_continue = type() == ConstructType::kContinue; + const bool is_loop = type() == ConstructType::kLoop; + const BasicBlock* continue_header = nullptr; + if (is_loop) { + // The only corresponding construct for a loop is the continue. + continue_header = (*corresponding_constructs().begin())->entry_block(); + } + std::vector stack; + stack.push_back(const_cast(header)); + ConstructBlockSet construct_blocks; + while (!stack.empty()) { + auto* block = stack.back(); + stack.pop_back(); + + if (header->structurally_dominates(*block)) { + bool include = false; + if (is_continue && exit->structurally_postdominates(*block)) { + // Continue construct include blocks dominated by the continue target + // and post-dominated by the back-edge block. + include = true; + } else if (!exit->structurally_dominates(*block)) { + // Selection and loop constructs include blocks dominated by the header + // and not dominated by the merge. + include = true; + if (is_loop && continue_header->structurally_dominates(*block)) { + // Loop constructs have an additional constraint that they do not + // include blocks dominated by the continue construct. Since all + // blocks in the continue construct are dominated by the continue + // target, we just test for dominance by continue target. + include = false; + } + } + if (include) { + if (!construct_blocks.insert(block).second) continue; + + for (auto succ : *block->structural_successors()) { + stack.push_back(succ); + } + } + } + } + + return construct_blocks; +} + +bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const { + // Structured Exits: + // - Selection: + // - branch to its merge + // - branch to nearest enclosing loop merge or continue + // - branch to nearest enclosing switch selection merge + // - Loop: + // - branch to its merge + // - branch to its continue + // - Continue: + // - branch to loop header + // - branch to loop merge + // + // Note: we will never see a case construct here. + assert(type() != ConstructType::kCase); + if (type() == ConstructType::kLoop) { + auto header = entry_block(); + auto terminator = header->terminator(); + auto index = terminator - &_.ordered_instructions()[0]; + auto merge_inst = &_.ordered_instructions()[index - 1]; + auto merge_block_id = merge_inst->GetOperandAs(0u); + auto continue_block_id = merge_inst->GetOperandAs(1u); + if (dest->id() == merge_block_id || dest->id() == continue_block_id) { + return true; + } + } else if (type() == ConstructType::kContinue) { + auto loop_construct = corresponding_constructs()[0]; + auto header = loop_construct->entry_block(); + auto terminator = header->terminator(); + auto index = terminator - &_.ordered_instructions()[0]; + auto merge_inst = &_.ordered_instructions()[index - 1]; + auto merge_block_id = merge_inst->GetOperandAs(0u); + if (dest == header || dest->id() == merge_block_id) { + return true; + } + } else { + assert(type() == ConstructType::kSelection); + if (dest == exit_block()) { + return true; + } + + // The next block in the traversal is either: + // i. The header block that declares |block| as its merge block. + // ii. The immediate dominator of |block|. + auto NextBlock = [](const BasicBlock* block) -> const BasicBlock* { + for (auto& use : block->label()->uses()) { + if ((use.first->opcode() == spv::Op::OpLoopMerge || + use.first->opcode() == spv::Op::OpSelectionMerge) && + use.second == 1 && + use.first->block()->structurally_dominates(*block) && + // A header likely declared itself as its merge. + use.first->block() != block) { + return use.first->block(); + } + } + return block->immediate_structural_dominator(); + }; + + bool seen_switch = false; + auto header = entry_block(); + auto block = NextBlock(header); + while (block) { + auto terminator = block->terminator(); + auto index = terminator - &_.ordered_instructions()[0]; + auto merge_inst = &_.ordered_instructions()[index - 1]; + if (merge_inst->opcode() == spv::Op::OpLoopMerge || + (header->terminator()->opcode() != spv::Op::OpSwitch && + merge_inst->opcode() == spv::Op::OpSelectionMerge && + terminator->opcode() == spv::Op::OpSwitch)) { + auto merge_target = merge_inst->GetOperandAs(0u); + auto merge_block = merge_inst->function()->GetBlock(merge_target).first; + if (merge_block->structurally_dominates(*header)) { + block = NextBlock(block); + continue; + } + + if ((!seen_switch || merge_inst->opcode() == spv::Op::OpLoopMerge) && + dest->id() == merge_target) { + return true; + } else if (merge_inst->opcode() == spv::Op::OpLoopMerge) { + auto continue_target = merge_inst->GetOperandAs(1u); + if (dest->id() == continue_target) { + return true; + } + } + + if (terminator->opcode() == spv::Op::OpSwitch) { + seen_switch = true; + } + + // Hit an enclosing loop and didn't break or continue. + if (merge_inst->opcode() == spv::Op::OpLoopMerge) return false; + } + + block = NextBlock(block); + } + } + + return false; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/construct.h b/thirdparty/glslang/External/spirv-tools/source/val/construct.h new file mode 100644 index 000000000000..9476760a3541 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/construct.h @@ -0,0 +1,170 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_VAL_CONSTRUCT_H_ +#define SOURCE_VAL_CONSTRUCT_H_ + +#include +#include +#include + +#include "source/val/basic_block.h" + +namespace spvtools { +namespace val { +class ValidationState_t; + +/// Functor for ordering BasicBlocks. BasicBlock pointers must not be null. +struct less_than_id { + bool operator()(const BasicBlock* lhs, const BasicBlock* rhs) const { + return lhs->id() < rhs->id(); + } +}; + +enum class ConstructType : int { + kNone = 0, + /// The set of blocks dominated by a selection header, minus the set of blocks + /// dominated by the header's merge block + kSelection, + /// The set of blocks dominated by an OpLoopMerge's Continue Target and post + /// dominated by the corresponding back + kContinue, + /// The set of blocks dominated by a loop header, minus the set of blocks + /// dominated by the loop's merge block, minus the loop's corresponding + /// continue construct + kLoop, + /// The set of blocks dominated by an OpSwitch's Target or Default, minus the + /// set of blocks dominated by the OpSwitch's merge block (this construct is + /// only defined for those OpSwitch Target or Default that are not equal to + /// the OpSwitch's corresponding merge block) + kCase +}; + +class Function; + +/// @brief This class tracks the CFG constructs as defined in the SPIR-V spec +class Construct { + public: + Construct(ConstructType type, BasicBlock* dominator, + BasicBlock* exit = nullptr, + std::vector constructs = std::vector()); + + /// Returns the type of the construct + ConstructType type() const; + + const std::vector& corresponding_constructs() const; + std::vector& corresponding_constructs(); + void set_corresponding_constructs(std::vector constructs); + + /// Returns the dominator block of the construct. + /// + /// This is usually the header block or the first block of the construct. + const BasicBlock* entry_block() const; + + /// Returns the dominator block of the construct. + /// + /// This is usually the header block or the first block of the construct. + BasicBlock* entry_block(); + + /// Returns the exit block of the construct. + /// + /// For a continue construct it is the backedge block of the corresponding + /// loop construct. For the case construct it is the block that branches to + /// the OpSwitch merge block or other case blocks. Otherwise it is the merge + /// block of the corresponding header block + const BasicBlock* exit_block() const; + + /// Returns the exit block of the construct. + /// + /// For a continue construct it is the backedge block of the corresponding + /// loop construct. For the case construct it is the block that branches to + /// the OpSwitch merge block or other case blocks. Otherwise it is the merge + /// block of the corresponding header block + BasicBlock* exit_block(); + + /// Sets the exit block for this construct. This is useful for continue + /// constructs which do not know the back-edge block during construction + void set_exit(BasicBlock* exit_block); + + // Returns whether the exit block of this construct is the merge block + // for an OpLoopMerge or OpSelectionMerge + bool ExitBlockIsMergeBlock() const { + return type_ == ConstructType::kLoop || type_ == ConstructType::kSelection; + } + + using ConstructBlockSet = std::set; + + // Returns the basic blocks in this construct. This function should not + // be called before the exit block is set and dominators have been + // calculated. + ConstructBlockSet blocks(Function* function) const; + + // Returns true if |dest| is structured exit from the construct. Structured + // exits depend on the construct type. + // Selection: + // * branch to the associated merge + // * branch to the merge or continue of the innermost loop containing the + // selection + // * branch to the merge block of the innermost switch containing the + // selection + // Loop: + // * branch to the associated merge or continue + // Continue: + // * back-edge to the associated loop header + // * branch to the associated loop merge + // + // Note: the validator does not generate case constructs. Switches are + // checked separately from other constructs. + bool IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const; + + private: + /// The type of the construct + ConstructType type_; + + /// These are the constructs that are related to this construct. These + /// constructs can be the continue construct, for the corresponding loop + /// construct, the case construct that are part of the same OpSwitch + /// instruction + /// + /// Here is a table that describes what constructs are included in + /// @p corresponding_constructs_ + /// | this construct | corresponding construct | + /// |----------------|----------------------------------| + /// | loop | continue | + /// | continue | loop | + /// | case | other cases in the same OpSwitch | + /// + /// kContinue and kLoop constructs will always have corresponding + /// constructs even if they are represented by the same block + std::vector corresponding_constructs_; + + /// @brief Dominator block for the construct + /// + /// The dominator block for the construct. Depending on the construct this may + /// be a selection header, a continue target of a loop, a loop header or a + /// Target or Default block of a switch + BasicBlock* entry_block_; + + /// @brief Exiting block for the construct + /// + /// The exit block for the construct. This can be a merge block for the loop + /// and selection constructs, a back-edge block for a continue construct, or + /// the branching block for the case construct + BasicBlock* exit_block_; +}; + +} // namespace val +} // namespace spvtools + +#endif // SOURCE_VAL_CONSTRUCT_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/val/decoration.h b/thirdparty/glslang/External/spirv-tools/source/val/decoration.h new file mode 100644 index 000000000000..384cc5755e6c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/decoration.h @@ -0,0 +1,98 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_VAL_DECORATION_H_ +#define SOURCE_VAL_DECORATION_H_ + +#include +#include +#include + +#include "source/latest_version_spirv_header.h" + +namespace spvtools { +namespace val { + +// An object of this class represents a specific decoration including its +// parameters (if any). Decorations are used by OpDecorate and OpMemberDecorate, +// and they describe certain properties that can be assigned to one or several +// s. +// +// A Decoration object contains the decoration type (an enum), associated +// literal parameters, and struct member index. If the decoration does not apply +// to a struct member, then the index is kInvalidIndex. A Decoration object does +// not store the target Id, i.e. the Id to which it applies. It is +// possible for the same decoration to be applied to several s (and they +// might be assigned using separate SPIR-V instructions, possibly using an +// assignment through GroupDecorate). +// +// Example 1: Decoration for an object with no parameters: +// OpDecorate %obj Flat +// dec_type_ = spv::Decoration::Flat +// params_ = empty vector +// struct_member_index_ = kInvalidMember +// +// Example 2: Decoration for an object with two parameters: +// OpDecorate %obj LinkageAttributes "link" Import +// dec_type_ = spv::Decoration::LinkageAttributes +// params_ = vector { link, Import } +// struct_member_index_ = kInvalidMember +// +// Example 3: Decoration for a member of a structure with one parameter: +// OpMemberDecorate %struct 2 Offset 2 +// dec_type_ = spv::Decoration::Offset +// params_ = vector { 2 } +// struct_member_index_ = 2 +// +class Decoration { + public: + enum { kInvalidMember = -1 }; + Decoration(spv::Decoration t, + const std::vector& parameters = std::vector(), + uint32_t member_index = kInvalidMember) + : dec_type_(t), params_(parameters), struct_member_index_(member_index) {} + + void set_struct_member_index(uint32_t index) { struct_member_index_ = index; } + int struct_member_index() const { return struct_member_index_; } + spv::Decoration dec_type() const { return dec_type_; } + std::vector& params() { return params_; } + const std::vector& params() const { return params_; } + + inline bool operator<(const Decoration& rhs) const { + // Note: Sort by struct_member_index_ first, then type, so look up can be + // efficient using lower_bound() and upper_bound(). + if (struct_member_index_ < rhs.struct_member_index_) return true; + if (rhs.struct_member_index_ < struct_member_index_) return false; + if (dec_type_ < rhs.dec_type_) return true; + if (rhs.dec_type_ < dec_type_) return false; + return params_ < rhs.params_; + } + inline bool operator==(const Decoration& rhs) const { + return (dec_type_ == rhs.dec_type_ && params_ == rhs.params_ && + struct_member_index_ == rhs.struct_member_index_); + } + + private: + spv::Decoration dec_type_; + std::vector params_; + + // If the decoration applies to a member of a structure type, then the index + // of the member is stored here. Otherwise, this is kInvalidIndex. + int struct_member_index_; +}; + +} // namespace val +} // namespace spvtools + +#endif // SOURCE_VAL_DECORATION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/val/function.cpp b/thirdparty/glslang/External/spirv-tools/source/val/function.cpp new file mode 100644 index 000000000000..290574b859aa --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/function.cpp @@ -0,0 +1,435 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/function.h" + +#include +#include +#include +#include +#include + +#include "source/cfa.h" +#include "source/val/basic_block.h" +#include "source/val/construct.h" +#include "source/val/validate.h" + +namespace spvtools { +namespace val { + +// Universal Limit of ResultID + 1 +static const uint32_t kInvalidId = 0x400000; + +Function::Function(uint32_t function_id, uint32_t result_type_id, + spv::FunctionControlMask function_control, + uint32_t function_type_id) + : id_(function_id), + function_type_id_(function_type_id), + result_type_id_(result_type_id), + function_control_(function_control), + declaration_type_(FunctionDecl::kFunctionDeclUnknown), + end_has_been_registered_(false), + blocks_(), + current_block_(nullptr), + pseudo_entry_block_(0), + pseudo_exit_block_(kInvalidId), + cfg_constructs_(), + variable_ids_(), + parameter_ids_() {} + +bool Function::IsFirstBlock(uint32_t block_id) const { + return !ordered_blocks_.empty() && *first_block() == block_id; +} + +spv_result_t Function::RegisterFunctionParameter(uint32_t parameter_id, + uint32_t type_id) { + assert(current_block_ == nullptr && + "RegisterFunctionParameter can only be called when parsing the binary " + "outside of a block"); + // TODO(umar): Validate function parameter type order and count + // TODO(umar): Use these variables to validate parameter type + (void)parameter_id; + (void)type_id; + return SPV_SUCCESS; +} + +spv_result_t Function::RegisterLoopMerge(uint32_t merge_id, + uint32_t continue_id) { + RegisterBlock(merge_id, false); + RegisterBlock(continue_id, false); + BasicBlock& merge_block = blocks_.at(merge_id); + BasicBlock& continue_target_block = blocks_.at(continue_id); + assert(current_block_ && + "RegisterLoopMerge must be called when called within a block"); + current_block_->RegisterStructuralSuccessor(&merge_block); + current_block_->RegisterStructuralSuccessor(&continue_target_block); + + current_block_->set_type(kBlockTypeLoop); + merge_block.set_type(kBlockTypeMerge); + continue_target_block.set_type(kBlockTypeContinue); + Construct& loop_construct = + AddConstruct({ConstructType::kLoop, current_block_, &merge_block}); + Construct& continue_construct = + AddConstruct({ConstructType::kContinue, &continue_target_block}); + + continue_construct.set_corresponding_constructs({&loop_construct}); + loop_construct.set_corresponding_constructs({&continue_construct}); + merge_block_header_[&merge_block] = current_block_; + if (continue_target_headers_.find(&continue_target_block) == + continue_target_headers_.end()) { + continue_target_headers_[&continue_target_block] = {current_block_}; + } else { + continue_target_headers_[&continue_target_block].push_back(current_block_); + } + + return SPV_SUCCESS; +} + +spv_result_t Function::RegisterSelectionMerge(uint32_t merge_id) { + RegisterBlock(merge_id, false); + BasicBlock& merge_block = blocks_.at(merge_id); + current_block_->set_type(kBlockTypeSelection); + merge_block.set_type(kBlockTypeMerge); + merge_block_header_[&merge_block] = current_block_; + current_block_->RegisterStructuralSuccessor(&merge_block); + + AddConstruct({ConstructType::kSelection, current_block(), &merge_block}); + + return SPV_SUCCESS; +} + +spv_result_t Function::RegisterSetFunctionDeclType(FunctionDecl type) { + assert(declaration_type_ == FunctionDecl::kFunctionDeclUnknown); + declaration_type_ = type; + return SPV_SUCCESS; +} + +spv_result_t Function::RegisterBlock(uint32_t block_id, bool is_definition) { + assert( + declaration_type_ == FunctionDecl::kFunctionDeclDefinition && + "RegisterBlocks can only be called after declaration_type_ is defined"); + + std::unordered_map::iterator inserted_block; + bool success = false; + tie(inserted_block, success) = + blocks_.insert({block_id, BasicBlock(block_id)}); + if (is_definition) { // new block definition + assert(current_block_ == nullptr && + "Register Block can only be called when parsing a binary outside of " + "a BasicBlock"); + + undefined_blocks_.erase(block_id); + current_block_ = &inserted_block->second; + ordered_blocks_.push_back(current_block_); + } else if (success) { // Block doesn't exist but this is not a definition + undefined_blocks_.insert(block_id); + } + + return SPV_SUCCESS; +} + +void Function::RegisterBlockEnd(std::vector next_list) { + assert( + current_block_ && + "RegisterBlockEnd can only be called when parsing a binary in a block"); + std::vector next_blocks; + next_blocks.reserve(next_list.size()); + + std::unordered_map::iterator inserted_block; + bool success; + for (uint32_t successor_id : next_list) { + tie(inserted_block, success) = + blocks_.insert({successor_id, BasicBlock(successor_id)}); + if (success) { + undefined_blocks_.insert(successor_id); + } + next_blocks.push_back(&inserted_block->second); + } + + if (current_block_->is_type(kBlockTypeLoop)) { + // For each loop header, record the set of its successors, and include + // its continue target if the continue target is not the loop header + // itself. + std::vector& next_blocks_plus_continue_target = + loop_header_successors_plus_continue_target_map_[current_block_]; + next_blocks_plus_continue_target = next_blocks; + auto continue_target = + FindConstructForEntryBlock(current_block_, ConstructType::kLoop) + .corresponding_constructs() + .back() + ->entry_block(); + if (continue_target != current_block_) { + next_blocks_plus_continue_target.push_back(continue_target); + } + } + + current_block_->RegisterSuccessors(next_blocks); + current_block_ = nullptr; + return; +} + +void Function::RegisterFunctionEnd() { + if (!end_has_been_registered_) { + end_has_been_registered_ = true; + + ComputeAugmentedCFG(); + } +} + +size_t Function::block_count() const { return blocks_.size(); } + +size_t Function::undefined_block_count() const { + return undefined_blocks_.size(); +} + +const std::vector& Function::ordered_blocks() const { + return ordered_blocks_; +} +std::vector& Function::ordered_blocks() { return ordered_blocks_; } + +const BasicBlock* Function::current_block() const { return current_block_; } +BasicBlock* Function::current_block() { return current_block_; } + +const std::list& Function::constructs() const { + return cfg_constructs_; +} +std::list& Function::constructs() { return cfg_constructs_; } + +const BasicBlock* Function::first_block() const { + if (ordered_blocks_.empty()) return nullptr; + return ordered_blocks_[0]; +} +BasicBlock* Function::first_block() { + if (ordered_blocks_.empty()) return nullptr; + return ordered_blocks_[0]; +} + +bool Function::IsBlockType(uint32_t merge_block_id, BlockType type) const { + bool ret = false; + const BasicBlock* block; + std::tie(block, std::ignore) = GetBlock(merge_block_id); + if (block) { + ret = block->is_type(type); + } + return ret; +} + +std::pair Function::GetBlock(uint32_t block_id) const { + const auto b = blocks_.find(block_id); + if (b != end(blocks_)) { + const BasicBlock* block = &(b->second); + bool defined = + undefined_blocks_.find(block->id()) == std::end(undefined_blocks_); + return std::make_pair(block, defined); + } else { + return std::make_pair(nullptr, false); + } +} + +std::pair Function::GetBlock(uint32_t block_id) { + const BasicBlock* out; + bool defined; + std::tie(out, defined) = + const_cast(this)->GetBlock(block_id); + return std::make_pair(const_cast(out), defined); +} + +Function::GetBlocksFunction Function::AugmentedCFGSuccessorsFunction() const { + return [this](const BasicBlock* block) { + auto where = augmented_successors_map_.find(block); + return where == augmented_successors_map_.end() ? block->successors() + : &(*where).second; + }; +} + +Function::GetBlocksFunction Function::AugmentedCFGPredecessorsFunction() const { + return [this](const BasicBlock* block) { + auto where = augmented_predecessors_map_.find(block); + return where == augmented_predecessors_map_.end() ? block->predecessors() + : &(*where).second; + }; +} + +Function::GetBlocksFunction Function::AugmentedStructuralCFGSuccessorsFunction() + const { + return [this](const BasicBlock* block) { + auto where = augmented_successors_map_.find(block); + return where == augmented_successors_map_.end() + ? block->structural_successors() + : &(*where).second; + }; +} + +Function::GetBlocksFunction +Function::AugmentedStructuralCFGPredecessorsFunction() const { + return [this](const BasicBlock* block) { + auto where = augmented_predecessors_map_.find(block); + return where == augmented_predecessors_map_.end() + ? block->structural_predecessors() + : &(*where).second; + }; +} + +void Function::ComputeAugmentedCFG() { + // Compute the successors of the pseudo-entry block, and + // the predecessors of the pseudo exit block. + auto succ_func = [](const BasicBlock* b) { + return b->structural_successors(); + }; + auto pred_func = [](const BasicBlock* b) { + return b->structural_predecessors(); + }; + CFA::ComputeAugmentedCFG( + ordered_blocks_, &pseudo_entry_block_, &pseudo_exit_block_, + &augmented_successors_map_, &augmented_predecessors_map_, succ_func, + pred_func); +} + +Construct& Function::AddConstruct(const Construct& new_construct) { + cfg_constructs_.push_back(new_construct); + auto& result = cfg_constructs_.back(); + entry_block_to_construct_[std::make_pair(new_construct.entry_block(), + new_construct.type())] = &result; + return result; +} + +Construct& Function::FindConstructForEntryBlock(const BasicBlock* entry_block, + ConstructType type) { + auto where = + entry_block_to_construct_.find(std::make_pair(entry_block, type)); + assert(where != entry_block_to_construct_.end()); + auto construct_ptr = (*where).second; + assert(construct_ptr); + return *construct_ptr; +} + +int Function::GetBlockDepth(BasicBlock* bb) { + // Guard against nullptr. + if (!bb) { + return 0; + } + // Only calculate the depth if it's not already calculated. + // This function uses memoization to avoid duplicate CFG depth calculations. + if (block_depth_.find(bb) != block_depth_.end()) { + return block_depth_[bb]; + } + // Avoid recursion. Something is wrong if the same block is encountered + // multiple times. + block_depth_[bb] = 0; + + BasicBlock* bb_dom = bb->immediate_dominator(); + if (!bb_dom || bb == bb_dom) { + // This block has no dominator, so it's at depth 0. + block_depth_[bb] = 0; + } else if (bb->is_type(kBlockTypeContinue)) { + // This rule must precede the rule for merge blocks in order to set up + // depths correctly. If a block is both a merge and continue then the merge + // is nested within the continue's loop (or the graph is incorrect). + // The depth of the continue block entry point is 1 + loop header depth. + Construct* continue_construct = + entry_block_to_construct_[std::make_pair(bb, ConstructType::kContinue)]; + assert(continue_construct); + // Continue construct has only 1 corresponding construct (loop header). + Construct* loop_construct = + continue_construct->corresponding_constructs()[0]; + assert(loop_construct); + BasicBlock* loop_header = loop_construct->entry_block(); + // The continue target may be the loop itself (while 1). + // In such cases, the depth of the continue block is: 1 + depth of the + // loop's dominator block. + if (loop_header == bb) { + block_depth_[bb] = 1 + GetBlockDepth(bb_dom); + } else { + block_depth_[bb] = 1 + GetBlockDepth(loop_header); + } + } else if (bb->is_type(kBlockTypeMerge)) { + // If this is a merge block, its depth is equal to the block before + // branching. + BasicBlock* header = merge_block_header_[bb]; + assert(header); + block_depth_[bb] = GetBlockDepth(header); + } else if (bb_dom->is_type(kBlockTypeSelection) || + bb_dom->is_type(kBlockTypeLoop)) { + // The dominator of the given block is a header block. So, the nesting + // depth of this block is: 1 + nesting depth of the header. + block_depth_[bb] = 1 + GetBlockDepth(bb_dom); + } else { + block_depth_[bb] = GetBlockDepth(bb_dom); + } + return block_depth_[bb]; +} + +void Function::RegisterExecutionModelLimitation(spv::ExecutionModel model, + const std::string& message) { + execution_model_limitations_.push_back( + [model, message](spv::ExecutionModel in_model, std::string* out_message) { + if (model != in_model) { + if (out_message) { + *out_message = message; + } + return false; + } + return true; + }); +} + +bool Function::IsCompatibleWithExecutionModel(spv::ExecutionModel model, + std::string* reason) const { + bool return_value = true; + std::stringstream ss_reason; + + for (const auto& is_compatible : execution_model_limitations_) { + std::string message; + if (!is_compatible(model, &message)) { + if (!reason) return false; + return_value = false; + if (!message.empty()) { + ss_reason << message << "\n"; + } + } + } + + if (!return_value && reason) { + *reason = ss_reason.str(); + } + + return return_value; +} + +bool Function::CheckLimitations(const ValidationState_t& _, + const Function* entry_point, + std::string* reason) const { + bool return_value = true; + std::stringstream ss_reason; + + for (const auto& is_compatible : limitations_) { + std::string message; + if (!is_compatible(_, entry_point, &message)) { + if (!reason) return false; + return_value = false; + if (!message.empty()) { + ss_reason << message << "\n"; + } + } + } + + if (!return_value && reason) { + *reason = ss_reason.str(); + } + + return return_value; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/function.h b/thirdparty/glslang/External/spirv-tools/source/val/function.h new file mode 100644 index 000000000000..481179442e3a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/function.h @@ -0,0 +1,402 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_VAL_FUNCTION_H_ +#define SOURCE_VAL_FUNCTION_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/latest_version_spirv_header.h" +#include "source/val/basic_block.h" +#include "source/val/construct.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace val { + +struct bb_constr_type_pair_hash { + std::size_t operator()( + const std::pair& p) const { + auto h1 = std::hash{}(p.first); + auto h2 = std::hash::type>{}( + static_cast::type>(p.second)); + return (h1 ^ h2); + } +}; + +enum class FunctionDecl { + kFunctionDeclUnknown, /// < Unknown function declaration + kFunctionDeclDeclaration, /// < Function declaration + kFunctionDeclDefinition /// < Function definition +}; + +/// This class manages all function declaration and definitions in a module. It +/// handles the state and id information while parsing a function in the SPIR-V +/// binary. +class Function { + public: + Function(uint32_t id, uint32_t result_type_id, + spv::FunctionControlMask function_control, + uint32_t function_type_id); + + /// Registers a function parameter in the current function + /// @return Returns SPV_SUCCESS if the call was successful + spv_result_t RegisterFunctionParameter(uint32_t id, uint32_t type_id); + + /// Sets the declaration type of the current function + /// @return Returns SPV_SUCCESS if the call was successful + spv_result_t RegisterSetFunctionDeclType(FunctionDecl type); + + /// Registers a block in the current function. Subsequent block instructions + /// will target this block + /// @param id The ID of the label of the block + /// @return Returns SPV_SUCCESS if the call was successful + spv_result_t RegisterBlock(uint32_t id, bool is_definition = true); + + /// Registers a variable in the current block + /// + /// @param[in] type_id The type ID of the variable + /// @param[in] id The ID of the variable + /// @param[in] storage The storage of the variable + /// @param[in] init_id The initializer ID of the variable + /// + /// @return Returns SPV_SUCCESS if the call was successful + spv_result_t RegisterBlockVariable(uint32_t type_id, uint32_t id, + spv::StorageClass storage, + uint32_t init_id); + + /// Registers a loop merge construct in the function + /// + /// @param[in] merge_id The merge block ID of the loop + /// @param[in] continue_id The continue block ID of the loop + /// + /// @return Returns SPV_SUCCESS if the call was successful + spv_result_t RegisterLoopMerge(uint32_t merge_id, uint32_t continue_id); + + /// Registers a selection merge construct in the function + /// @return Returns SPV_SUCCESS if the call was successful + spv_result_t RegisterSelectionMerge(uint32_t merge_id); + + /// Registers the end of the block + /// + /// @param[in] successors_list A list of ids to the block's successors + void RegisterBlockEnd(std::vector successors_list); + + /// Registers the end of the function. This is idempotent. + void RegisterFunctionEnd(); + + /// Returns true if the \p id block is the first block of this function + bool IsFirstBlock(uint32_t id) const; + + /// Returns true if the \p merge_block_id is a BlockType of \p type + bool IsBlockType(uint32_t merge_block_id, BlockType type) const; + + /// Returns a pair consisting of the BasicBlock with \p id and a bool + /// which is true if the block has been defined, and false if it is + /// declared but not defined. This function will return nullptr if the + /// \p id was not declared and not defined at the current point in the binary + std::pair GetBlock(uint32_t id) const; + std::pair GetBlock(uint32_t id); + + /// Returns the first block of the current function + const BasicBlock* first_block() const; + + /// Returns the first block of the current function + BasicBlock* first_block(); + + /// Returns a vector of all the blocks in the function + const std::vector& ordered_blocks() const; + + /// Returns a vector of all the blocks in the function + std::vector& ordered_blocks(); + + /// Returns a list of all the cfg constructs in the function + const std::list& constructs() const; + + /// Returns a list of all the cfg constructs in the function + std::list& constructs(); + + /// Returns the number of blocks in the current function being parsed + size_t block_count() const; + + /// Returns the id of the function + uint32_t id() const { return id_; } + + /// Returns return type id of the function + uint32_t GetResultTypeId() const { return result_type_id_; } + + /// Returns the number of blocks in the current function being parsed + size_t undefined_block_count() const; + const std::unordered_set& undefined_blocks() const { + return undefined_blocks_; + } + + /// Returns the block that is currently being parsed in the binary + BasicBlock* current_block(); + + /// Returns the block that is currently being parsed in the binary + const BasicBlock* current_block() const; + + // For dominance calculations, we want to analyze all the + // blocks in the function, even in degenerate control flow cases + // including unreachable blocks. We therefore make an "augmented CFG" + // which is the same as the ordinary CFG but adds: + // - A pseudo-entry node. + // - A pseudo-exit node. + // - A minimal set of edges so that a forward traversal from the + // pseudo-entry node will visit all nodes. + // - A minimal set of edges so that a backward traversal from the + // pseudo-exit node will visit all nodes. + // In particular, the pseudo-entry node is the unique source of the + // augmented CFG, and the psueo-exit node is the unique sink of the + // augmented CFG. + + /// Returns the pseudo exit block + BasicBlock* pseudo_entry_block() { return &pseudo_entry_block_; } + + /// Returns the pseudo exit block + const BasicBlock* pseudo_entry_block() const { return &pseudo_entry_block_; } + + /// Returns the pseudo exit block + BasicBlock* pseudo_exit_block() { return &pseudo_exit_block_; } + + /// Returns the pseudo exit block + const BasicBlock* pseudo_exit_block() const { return &pseudo_exit_block_; } + + using GetBlocksFunction = + std::function*(const BasicBlock*)>; + /// Returns the block successors function for the augmented CFG. + GetBlocksFunction AugmentedCFGSuccessorsFunction() const; + /// Returns the block predecessors function for the augmented CFG. + GetBlocksFunction AugmentedCFGPredecessorsFunction() const; + /// Returns the block structural successors function for the augmented CFG. + GetBlocksFunction AugmentedStructuralCFGSuccessorsFunction() const; + /// Returns the block structural predecessors function for the augmented CFG. + GetBlocksFunction AugmentedStructuralCFGPredecessorsFunction() const; + + /// Returns the control flow nesting depth of the given basic block. + /// This function only works when you have structured control flow. + /// This function should only be called after the control flow constructs have + /// been identified and dominators have been computed. + int GetBlockDepth(BasicBlock* bb); + + /// Prints a GraphViz digraph of the CFG of the current function + void PrintDotGraph() const; + + /// Prints a directed graph of the CFG of the current function + void PrintBlocks() const; + + /// Registers execution model limitation such as "Feature X is only available + /// with Execution Model Y". + void RegisterExecutionModelLimitation(spv::ExecutionModel model, + const std::string& message); + + /// Registers execution model limitation with an |is_compatible| functor. + void RegisterExecutionModelLimitation( + std::function is_compatible) { + execution_model_limitations_.push_back(is_compatible); + } + + /// Registers limitation with an |is_compatible| functor. + void RegisterLimitation(std::function + is_compatible) { + limitations_.push_back(is_compatible); + } + + bool CheckLimitations(const ValidationState_t& _, const Function* entry_point, + std::string* reason) const; + + /// Returns true if the given execution model passes the limitations stored in + /// execution_model_limitations_. Returns false otherwise and fills optional + /// |reason| parameter. + bool IsCompatibleWithExecutionModel(spv::ExecutionModel model, + std::string* reason = nullptr) const; + + // Inserts id to the set of functions called from this function. + void AddFunctionCallTarget(uint32_t call_target_id) { + function_call_targets_.insert(call_target_id); + } + + // Returns a set with ids of all functions called from this function. + const std::set function_call_targets() const { + return function_call_targets_; + } + + // Returns the block containing the OpSelectionMerge or OpLoopMerge that + // references |merge_block|. + // Values of |merge_block_header_| inserted by CFGPass, so do not call before + // the first iteration of ordered instructions in + // ValidateBinaryUsingContextAndValidationState has completed. + BasicBlock* GetMergeHeader(BasicBlock* merge_block) { + return merge_block_header_[merge_block]; + } + + // Returns vector of the blocks containing a OpLoopMerge that references + // |continue_target|. + // Values of |continue_target_headers_| inserted by CFGPass, so do not call + // before the first iteration of ordered instructions in + // ValidateBinaryUsingContextAndValidationState has completed. + std::vector GetContinueHeaders(BasicBlock* continue_target) { + if (continue_target_headers_.find(continue_target) == + continue_target_headers_.end()) { + return {}; + } + return continue_target_headers_[continue_target]; + } + + private: + // Computes the representation of the augmented CFG. + // Populates augmented_successors_map_ and augmented_predecessors_map_. + void ComputeAugmentedCFG(); + + // Adds a copy of the given Construct, and tracks it by its entry block. + // Returns a reference to the stored construct. + Construct& AddConstruct(const Construct& new_construct); + + // Returns a reference to the construct corresponding to the given entry + // block. + Construct& FindConstructForEntryBlock(const BasicBlock* entry_block, + ConstructType t); + + /// The result id of the OpLabel that defined this block + uint32_t id_; + + /// The type of the function + uint32_t function_type_id_; + + /// The type of the return value + uint32_t result_type_id_; + + /// The control fo the function + spv::FunctionControlMask function_control_; + + /// The type of declaration of each function + FunctionDecl declaration_type_; + + // Have we finished parsing this function? + bool end_has_been_registered_; + + /// The blocks in the function mapped by block ID + std::unordered_map blocks_; + + /// A list of blocks in the order they appeared in the binary + std::vector ordered_blocks_; + + /// Blocks which are forward referenced by blocks but not defined + std::unordered_set undefined_blocks_; + + /// The block that is currently being parsed + BasicBlock* current_block_; + + /// A pseudo entry node used in dominance analysis. + /// After the function end has been registered, the successor list of the + /// pseudo entry node is the minimal set of nodes such that all nodes in the + /// CFG can be reached by following successor lists. That is, the successors + /// will be: + /// - Any basic block without predecessors. This includes the entry + /// block to the function. + /// - A single node from each otherwise unreachable cycle in the CFG, if + /// such cycles exist. + /// The pseudo entry node does not appear in the predecessor or successor + /// list of any ordinary block. + /// It has no predecessors. + /// It has Id 0. + BasicBlock pseudo_entry_block_; + + /// A pseudo exit block used in dominance analysis. + /// After the function end has been registered, the predecessor list of the + /// pseudo exit node is the minimal set of nodes such that all nodes in the + /// CFG can be reached by following predecessor lists. That is, the + /// predecessors will be: + /// - Any basic block without successors. This includes any basic block + /// ending with an OpReturn, OpReturnValue or similar instructions. + /// - A single node from each otherwise unreachable cycle in the CFG, if + /// such cycles exist. + /// The pseudo exit node does not appear in the predecessor or successor + /// list of any ordinary block. + /// It has no successors. + BasicBlock pseudo_exit_block_; + + // Maps a block to its successors in the augmented CFG, if that set is + // different from its successors in the ordinary CFG. + std::unordered_map> + augmented_successors_map_; + // Maps a block to its predecessors in the augmented CFG, if that set is + // different from its predecessors in the ordinary CFG. + std::unordered_map> + augmented_predecessors_map_; + + // Maps a structured loop header to its CFG successors and also its + // continue target if that continue target is not the loop header + // itself. This might have duplicates. + std::unordered_map> + loop_header_successors_plus_continue_target_map_; + + /// The constructs that are available in this function + std::list cfg_constructs_; + + /// The variable IDs of the functions + std::vector variable_ids_; + + /// The function parameter ids of the functions + std::vector parameter_ids_; + + /// Maps a construct's entry block to the construct(s). + /// Since a basic block may be the entry block of different types of + /// constructs, the type of the construct should also be specified in order to + /// get the unique construct. + std::unordered_map, Construct*, + bb_constr_type_pair_hash> + entry_block_to_construct_; + + /// This map provides the header block for a given merge block. + std::unordered_map merge_block_header_; + + /// This map provides the header blocks for a given continue target. + std::unordered_map> + continue_target_headers_; + + /// Stores the control flow nesting depth of a given basic block + std::unordered_map block_depth_; + + /// Stores execution model limitations imposed by instructions used within the + /// function. The functor stored in the list return true if execution model + /// is compatible, false otherwise. If the functor returns false, it can also + /// optionally fill the string parameter with the reason for incompatibility. + std::list> + execution_model_limitations_; + + /// Stores limitations imposed by instructions used within the function. + /// Similar to execution_model_limitations_; + std::list> + limitations_; + + /// Stores ids of all functions called from this function. + std::set function_call_targets_; +}; + +} // namespace val +} // namespace spvtools + +#endif // SOURCE_VAL_FUNCTION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/val/instruction.cpp b/thirdparty/glslang/External/spirv-tools/source/val/instruction.cpp new file mode 100644 index 000000000000..f16fcd7300ae --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/instruction.cpp @@ -0,0 +1,55 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/instruction.h" + +#include + +#include "source/binary.h" +#include "source/util/string_utils.h" + +namespace spvtools { +namespace val { + +Instruction::Instruction(const spv_parsed_instruction_t* inst) + : words_(inst->words, inst->words + inst->num_words), + operands_(inst->operands, inst->operands + inst->num_operands), + inst_({words_.data(), inst->num_words, inst->opcode, inst->ext_inst_type, + inst->type_id, inst->result_id, operands_.data(), + inst->num_operands}) {} + +void Instruction::RegisterUse(const Instruction* inst, uint32_t index) { + uses_.push_back(std::make_pair(inst, index)); +} + +bool operator<(const Instruction& lhs, const Instruction& rhs) { + return lhs.id() < rhs.id(); +} +bool operator<(const Instruction& lhs, uint32_t rhs) { return lhs.id() < rhs; } +bool operator==(const Instruction& lhs, const Instruction& rhs) { + return lhs.id() == rhs.id(); +} +bool operator==(const Instruction& lhs, uint32_t rhs) { + return lhs.id() == rhs; +} + +template <> +std::string Instruction::GetOperandAs(size_t index) const { + const spv_parsed_operand_t& o = operands_.at(index); + assert(o.offset + o.num_words <= inst_.num_words); + return spvtools::utils::MakeString(words_.data() + o.offset, o.num_words); +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/instruction.h b/thirdparty/glslang/External/spirv-tools/source/val/instruction.h new file mode 100644 index 000000000000..c524bd37508c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/instruction.h @@ -0,0 +1,155 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_VAL_INSTRUCTION_H_ +#define SOURCE_VAL_INSTRUCTION_H_ + +#include +#include +#include +#include +#include + +#include "source/ext_inst.h" +#include "source/table.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace val { + +class BasicBlock; +class Function; + +/// Wraps the spv_parsed_instruction struct along with use and definition of the +/// instruction's result id +class Instruction { + public: + explicit Instruction(const spv_parsed_instruction_t* inst); + + /// Registers the use of the Instruction in instruction \p inst at \p index + void RegisterUse(const Instruction* inst, uint32_t index); + + uint32_t id() const { return inst_.result_id; } + uint32_t type_id() const { return inst_.type_id; } + spv::Op opcode() const { return static_cast(inst_.opcode); } + + /// Returns the Function where the instruction was defined. nullptr if it was + /// defined outside of a Function + const Function* function() const { return function_; } + void set_function(Function* func) { function_ = func; } + + /// Returns the BasicBlock where the instruction was defined. nullptr if it + /// was defined outside of a BasicBlock + const BasicBlock* block() const { return block_; } + void set_block(BasicBlock* b) { block_ = b; } + + /// Returns a vector of pairs of all references to this instruction's result + /// id. The first element is the instruction in which this result id was + /// referenced and the second is the index of the word in that instruction + /// where this result id appeared + const std::vector>& uses() const { + return uses_; + } + + /// The word used to define the Instruction + uint32_t word(size_t index) const { return words_[index]; } + + /// The words used to define the Instruction + const std::vector& words() const { return words_; } + + /// Returns the operand at |idx|. + const spv_parsed_operand_t& operand(size_t idx) const { + return operands_[idx]; + } + + /// The operands of the Instruction + const std::vector& operands() const { + return operands_; + } + + /// Provides direct access to the stored C instruction object. + const spv_parsed_instruction_t& c_inst() const { return inst_; } + + /// Provides direct access to instructions spv_ext_inst_type_t object. + const spv_ext_inst_type_t& ext_inst_type() const { + return inst_.ext_inst_type; + } + + bool IsNonSemantic() const { + return opcode() == spv::Op::OpExtInst && + spvExtInstIsNonSemantic(inst_.ext_inst_type); + } + + /// True if this is an OpExtInst for debug info extension. + bool IsDebugInfo() const { + return opcode() == spv::Op::OpExtInst && + spvExtInstIsDebugInfo(inst_.ext_inst_type); + } + + // Casts the words belonging to the operand under |index| to |T| and returns. + template + T GetOperandAs(size_t index) const { + const spv_parsed_operand_t& o = operands_.at(index); + assert(o.num_words * 4 >= sizeof(T)); + assert(o.offset + o.num_words <= inst_.num_words); + return *reinterpret_cast(&words_[o.offset]); + } + + size_t LineNum() const { return line_num_; } + void SetLineNum(size_t pos) { line_num_ = pos; } + + private: + const std::vector words_; + const std::vector operands_; + spv_parsed_instruction_t inst_; + size_t line_num_ = 0; + + /// The function in which this instruction was declared + Function* function_ = nullptr; + + /// The basic block in which this instruction was declared + BasicBlock* block_ = nullptr; + + /// This is a vector of pairs of all references to this instruction's result + /// id. The first element is the instruction in which this result id was + /// referenced and the second is the index of the word in the referencing + /// instruction where this instruction appeared + std::vector> uses_; +}; + +bool operator<(const Instruction& lhs, const Instruction& rhs); +bool operator<(const Instruction& lhs, uint32_t rhs); +bool operator==(const Instruction& lhs, const Instruction& rhs); +bool operator==(const Instruction& lhs, uint32_t rhs); + +template <> +std::string Instruction::GetOperandAs(size_t index) const; + +} // namespace val +} // namespace spvtools + +// custom specialization of std::hash for Instruction +namespace std { +template <> +struct hash { + typedef spvtools::val::Instruction argument_type; + typedef std::size_t result_type; + result_type operator()(const argument_type& inst) const { + return hash()(inst.id()); + } +}; + +} // namespace std + +#endif // SOURCE_VAL_INSTRUCTION_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate.cpp new file mode 100644 index 000000000000..ccf26fbf1d8e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate.cpp @@ -0,0 +1,466 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/validate.h" + +#include +#include +#include +#include +#include + +#include "source/binary.h" +#include "source/diagnostic.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" +#include "source/opcode.h" +#include "source/spirv_constant.h" +#include "source/spirv_endian.h" +#include "source/spirv_target_env.h" +#include "source/val/construct.h" +#include "source/val/instruction.h" +#include "source/val/validation_state.h" +#include "spirv-tools/libspirv.h" + +namespace { +// TODO(issue 1950): The validator only returns a single message anyway, so no +// point in generating more than 1 warning. +static uint32_t kDefaultMaxNumOfWarnings = 1; +} // namespace + +namespace spvtools { +namespace val { +namespace { + +// Parses OpExtension instruction and registers extension. +void RegisterExtension(ValidationState_t& _, + const spv_parsed_instruction_t* inst) { + const std::string extension_str = spvtools::GetExtensionString(inst); + Extension extension; + if (!GetExtensionFromString(extension_str.c_str(), &extension)) { + // The error will be logged in the ProcessInstruction pass. + return; + } + + _.RegisterExtension(extension); +} + +// Parses the beginning of the module searching for OpExtension instructions. +// Registers extensions if recognized. Returns SPV_REQUESTED_TERMINATION +// once an instruction which is not spv::Op::OpCapability and +// spv::Op::OpExtension is encountered. According to the SPIR-V spec extensions +// are declared after capabilities and before everything else. +spv_result_t ProcessExtensions(void* user_data, + const spv_parsed_instruction_t* inst) { + const spv::Op opcode = static_cast(inst->opcode); + if (opcode == spv::Op::OpCapability) return SPV_SUCCESS; + + if (opcode == spv::Op::OpExtension) { + ValidationState_t& _ = *(reinterpret_cast(user_data)); + RegisterExtension(_, inst); + return SPV_SUCCESS; + } + + // OpExtension block is finished, requesting termination. + return SPV_REQUESTED_TERMINATION; +} + +spv_result_t ProcessInstruction(void* user_data, + const spv_parsed_instruction_t* inst) { + ValidationState_t& _ = *(reinterpret_cast(user_data)); + + auto* instruction = _.AddOrderedInstruction(inst); + _.RegisterDebugInstruction(instruction); + + return SPV_SUCCESS; +} + +spv_result_t ValidateForwardDecls(ValidationState_t& _) { + if (_.unresolved_forward_id_count() == 0) return SPV_SUCCESS; + + std::stringstream ss; + std::vector ids = _.UnresolvedForwardIds(); + + std::transform( + std::begin(ids), std::end(ids), + std::ostream_iterator(ss, " "), + bind(&ValidationState_t::getIdName, std::ref(_), std::placeholders::_1)); + + auto id_str = ss.str(); + return _.diag(SPV_ERROR_INVALID_ID, nullptr) + << "The following forward referenced IDs have not been defined:\n" + << id_str.substr(0, id_str.size() - 1); +} + +// Entry point validation. Based on 2.16.1 (Universal Validation Rules) of the +// SPIRV spec: +// * There is at least one OpEntryPoint instruction, unless the Linkage +// capability is being used. +// * No function can be targeted by both an OpEntryPoint instruction and an +// OpFunctionCall instruction. +// +// Additionally enforces that entry points for Vulkan should not have recursion. +spv_result_t ValidateEntryPoints(ValidationState_t& _) { + _.ComputeFunctionToEntryPointMapping(); + _.ComputeRecursiveEntryPoints(); + + if (_.entry_points().empty() && !_.HasCapability(spv::Capability::Linkage)) { + return _.diag(SPV_ERROR_INVALID_BINARY, nullptr) + << "No OpEntryPoint instruction was found. This is only allowed if " + "the Linkage capability is being used."; + } + + for (const auto& entry_point : _.entry_points()) { + if (_.IsFunctionCallTarget(entry_point)) { + return _.diag(SPV_ERROR_INVALID_BINARY, _.FindDef(entry_point)) + << "A function (" << entry_point + << ") may not be targeted by both an OpEntryPoint instruction and " + "an OpFunctionCall instruction."; + } + + // For Vulkan, the static function-call graph for an entry point + // must not contain cycles. + if (spvIsVulkanEnv(_.context()->target_env)) { + if (_.recursive_entry_points().find(entry_point) != + _.recursive_entry_points().end()) { + return _.diag(SPV_ERROR_INVALID_BINARY, _.FindDef(entry_point)) + << _.VkErrorID(4634) + << "Entry points may not have a call graph with cycles."; + } + } + } + + if (auto error = ValidateFloatControls2(_)) { + return error; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateBinaryUsingContextAndValidationState( + const spv_context_t& context, const uint32_t* words, const size_t num_words, + spv_diagnostic* pDiagnostic, ValidationState_t* vstate) { + auto binary = std::unique_ptr( + new spv_const_binary_t{words, num_words}); + + spv_endianness_t endian; + spv_position_t position = {}; + if (spvBinaryEndianness(binary.get(), &endian)) { + return DiagnosticStream(position, context.consumer, "", + SPV_ERROR_INVALID_BINARY) + << "Invalid SPIR-V magic number."; + } + + spv_header_t header; + if (spvBinaryHeaderGet(binary.get(), endian, &header)) { + return DiagnosticStream(position, context.consumer, "", + SPV_ERROR_INVALID_BINARY) + << "Invalid SPIR-V header."; + } + + if (header.version > spvVersionForTargetEnv(context.target_env)) { + return DiagnosticStream(position, context.consumer, "", + SPV_ERROR_WRONG_VERSION) + << "Invalid SPIR-V binary version " + << SPV_SPIRV_VERSION_MAJOR_PART(header.version) << "." + << SPV_SPIRV_VERSION_MINOR_PART(header.version) + << " for target environment " + << spvTargetEnvDescription(context.target_env) << "."; + } + + if (header.bound > vstate->options()->universal_limits_.max_id_bound) { + return DiagnosticStream(position, context.consumer, "", + SPV_ERROR_INVALID_BINARY) + << "Invalid SPIR-V. The id bound is larger than the max id bound " + << vstate->options()->universal_limits_.max_id_bound << "."; + } + + // Look for OpExtension instructions and register extensions. + // This parse should not produce any error messages. Hijack the context and + // replace the message consumer so that we do not pollute any state in input + // consumer. + spv_context_t hijacked_context = context; + hijacked_context.consumer = [](spv_message_level_t, const char*, + const spv_position_t&, const char*) {}; + spvBinaryParse(&hijacked_context, vstate, words, num_words, + /* parsed_header = */ nullptr, ProcessExtensions, + /* diagnostic = */ nullptr); + + // Parse the module and perform inline validation checks. These checks do + // not require the knowledge of the whole module. + if (auto error = spvBinaryParse(&context, vstate, words, num_words, + /*parsed_header =*/nullptr, + ProcessInstruction, pDiagnostic)) { + return error; + } + + bool has_mask_task_nv = false; + bool has_mask_task_ext = false; + std::vector visited_entry_points; + for (auto& instruction : vstate->ordered_instructions()) { + { + // In order to do this work outside of Process Instruction we need to be + // able to, briefly, de-const the instruction. + Instruction* inst = const_cast(&instruction); + + if (inst->opcode() == spv::Op::OpEntryPoint) { + const auto entry_point = inst->GetOperandAs(1); + const auto execution_model = inst->GetOperandAs(0); + const std::string desc_name = inst->GetOperandAs(2); + + ValidationState_t::EntryPointDescription desc; + desc.name = desc_name; + + std::vector interfaces; + for (size_t j = 3; j < inst->operands().size(); ++j) + desc.interfaces.push_back(inst->word(inst->operand(j).offset)); + + vstate->RegisterEntryPoint(entry_point, execution_model, + std::move(desc)); + + if (visited_entry_points.size() > 0) { + for (const Instruction* check_inst : visited_entry_points) { + const auto check_execution_model = + check_inst->GetOperandAs(0); + const std::string check_name = + check_inst->GetOperandAs(2); + + if (desc_name == check_name && + execution_model == check_execution_model) { + return vstate->diag(SPV_ERROR_INVALID_DATA, inst) + << "2 Entry points cannot share the same name and " + "ExecutionMode."; + } + } + } + visited_entry_points.push_back(inst); + + has_mask_task_nv |= (execution_model == spv::ExecutionModel::TaskNV || + execution_model == spv::ExecutionModel::MeshNV); + has_mask_task_ext |= (execution_model == spv::ExecutionModel::TaskEXT || + execution_model == spv::ExecutionModel::MeshEXT); + } + if (inst->opcode() == spv::Op::OpFunctionCall) { + if (!vstate->in_function_body()) { + return vstate->diag(SPV_ERROR_INVALID_LAYOUT, &instruction) + << "A FunctionCall must happen within a function body."; + } + + const auto called_id = inst->GetOperandAs(2); + vstate->AddFunctionCallTarget(called_id); + } + + if (vstate->in_function_body()) { + inst->set_function(&(vstate->current_function())); + inst->set_block(vstate->current_function().current_block()); + + if (vstate->in_block() && spvOpcodeIsBlockTerminator(inst->opcode())) { + vstate->current_function().current_block()->set_terminator(inst); + } + } + + if (auto error = IdPass(*vstate, inst)) return error; + } + + if (auto error = CapabilityPass(*vstate, &instruction)) return error; + if (auto error = ModuleLayoutPass(*vstate, &instruction)) return error; + if (auto error = CfgPass(*vstate, &instruction)) return error; + if (auto error = InstructionPass(*vstate, &instruction)) return error; + + // Now that all of the checks are done, update the state. + { + Instruction* inst = const_cast(&instruction); + vstate->RegisterInstruction(inst); + if (inst->opcode() == spv::Op::OpTypeForwardPointer) { + vstate->RegisterForwardPointer(inst->GetOperandAs(0)); + } + } + } + + if (!vstate->has_memory_model_specified()) + return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr) + << "Missing required OpMemoryModel instruction."; + + if (vstate->in_function_body()) + return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr) + << "Missing OpFunctionEnd at end of module."; + + if (vstate->HasCapability(spv::Capability::BindlessTextureNV) && + !vstate->has_samplerimage_variable_address_mode_specified()) + return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr) + << "Missing required OpSamplerImageAddressingModeNV instruction."; + + if (has_mask_task_ext && has_mask_task_nv) + return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr) + << vstate->VkErrorID(7102) + << "Module can't mix MeshEXT/TaskEXT with MeshNV/TaskNV Execution " + "Model."; + + // Catch undefined forward references before performing further checks. + if (auto error = ValidateForwardDecls(*vstate)) return error; + + // Calculate reachability after all the blocks are parsed, but early that it + // can be relied on in subsequent pases. + ReachabilityPass(*vstate); + + // ID usage needs be handled in its own iteration of the instructions, + // between the two others. It depends on the first loop to have been + // finished, so that all instructions have been registered. And the following + // loop depends on all of the usage data being populated. Thus it cannot live + // in either of those iterations. + // It should also live after the forward declaration check, since it will + // have problems with missing forward declarations, but give less useful error + // messages. + for (size_t i = 0; i < vstate->ordered_instructions().size(); ++i) { + auto& instruction = vstate->ordered_instructions()[i]; + if (auto error = UpdateIdUse(*vstate, &instruction)) return error; + } + + // Validate individual opcodes. + for (size_t i = 0; i < vstate->ordered_instructions().size(); ++i) { + auto& instruction = vstate->ordered_instructions()[i]; + + // Keep these passes in the order they appear in the SPIR-V specification + // sections to maintain test consistency. + if (auto error = MiscPass(*vstate, &instruction)) return error; + if (auto error = DebugPass(*vstate, &instruction)) return error; + if (auto error = AnnotationPass(*vstate, &instruction)) return error; + if (auto error = ExtensionPass(*vstate, &instruction)) return error; + if (auto error = ModeSettingPass(*vstate, &instruction)) return error; + if (auto error = TypePass(*vstate, &instruction)) return error; + if (auto error = ConstantPass(*vstate, &instruction)) return error; + if (auto error = MemoryPass(*vstate, &instruction)) return error; + if (auto error = FunctionPass(*vstate, &instruction)) return error; + if (auto error = ImagePass(*vstate, &instruction)) return error; + if (auto error = ConversionPass(*vstate, &instruction)) return error; + if (auto error = CompositesPass(*vstate, &instruction)) return error; + if (auto error = ArithmeticsPass(*vstate, &instruction)) return error; + if (auto error = BitwisePass(*vstate, &instruction)) return error; + if (auto error = LogicalsPass(*vstate, &instruction)) return error; + if (auto error = ControlFlowPass(*vstate, &instruction)) return error; + if (auto error = DerivativesPass(*vstate, &instruction)) return error; + if (auto error = AtomicsPass(*vstate, &instruction)) return error; + if (auto error = PrimitivesPass(*vstate, &instruction)) return error; + if (auto error = BarriersPass(*vstate, &instruction)) return error; + // Group + // Device-Side Enqueue + // Pipe + if (auto error = NonUniformPass(*vstate, &instruction)) return error; + + if (auto error = LiteralsPass(*vstate, &instruction)) return error; + if (auto error = RayQueryPass(*vstate, &instruction)) return error; + if (auto error = RayTracingPass(*vstate, &instruction)) return error; + if (auto error = RayReorderNVPass(*vstate, &instruction)) return error; + if (auto error = MeshShadingPass(*vstate, &instruction)) return error; + } + + // Validate the preconditions involving adjacent instructions. e.g. + // spv::Op::OpPhi must only be preceded by spv::Op::OpLabel, spv::Op::OpPhi, + // or spv::Op::OpLine. + if (auto error = ValidateAdjacency(*vstate)) return error; + + if (auto error = ValidateEntryPoints(*vstate)) return error; + // CFG checks are performed after the binary has been parsed + // and the CFGPass has collected information about the control flow + if (auto error = PerformCfgChecks(*vstate)) return error; + if (auto error = CheckIdDefinitionDominateUse(*vstate)) return error; + if (auto error = ValidateDecorations(*vstate)) return error; + if (auto error = ValidateInterfaces(*vstate)) return error; + // TODO(dsinclair): Restructure ValidateBuiltins so we can move into the + // for() above as it loops over all ordered_instructions internally. + if (auto error = ValidateBuiltIns(*vstate)) return error; + // These checks must be performed after individual opcode checks because + // those checks register the limitation checked here. + for (const auto& inst : vstate->ordered_instructions()) { + if (auto error = ValidateExecutionLimitations(*vstate, &inst)) return error; + if (auto error = ValidateSmallTypeUses(*vstate, &inst)) return error; + if (auto error = ValidateQCOMImageProcessingTextureUsages(*vstate, &inst)) + return error; + } + + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t ValidateBinaryAndKeepValidationState( + const spv_const_context context, spv_const_validator_options options, + const uint32_t* words, const size_t num_words, spv_diagnostic* pDiagnostic, + std::unique_ptr* vstate) { + spv_context_t hijack_context = *context; + if (pDiagnostic) { + *pDiagnostic = nullptr; + UseDiagnosticAsMessageConsumer(&hijack_context, pDiagnostic); + } + + vstate->reset(new ValidationState_t(&hijack_context, options, words, + num_words, kDefaultMaxNumOfWarnings)); + + return ValidateBinaryUsingContextAndValidationState( + hijack_context, words, num_words, pDiagnostic, vstate->get()); +} + +} // namespace val +} // namespace spvtools + +spv_result_t spvValidate(const spv_const_context context, + const spv_const_binary binary, + spv_diagnostic* pDiagnostic) { + return spvValidateBinary(context, binary->code, binary->wordCount, + pDiagnostic); +} + +spv_result_t spvValidateBinary(const spv_const_context context, + const uint32_t* words, const size_t num_words, + spv_diagnostic* pDiagnostic) { + spv_context_t hijack_context = *context; + if (pDiagnostic) { + *pDiagnostic = nullptr; + spvtools::UseDiagnosticAsMessageConsumer(&hijack_context, pDiagnostic); + } + + // This interface is used for default command line options. + spv_validator_options default_options = spvValidatorOptionsCreate(); + + // Create the ValidationState using the context and default options. + spvtools::val::ValidationState_t vstate(&hijack_context, default_options, + words, num_words, + kDefaultMaxNumOfWarnings); + + spv_result_t result = + spvtools::val::ValidateBinaryUsingContextAndValidationState( + hijack_context, words, num_words, pDiagnostic, &vstate); + + spvValidatorOptionsDestroy(default_options); + return result; +} + +spv_result_t spvValidateWithOptions(const spv_const_context context, + spv_const_validator_options options, + const spv_const_binary binary, + spv_diagnostic* pDiagnostic) { + spv_context_t hijack_context = *context; + if (pDiagnostic) { + *pDiagnostic = nullptr; + spvtools::UseDiagnosticAsMessageConsumer(&hijack_context, pDiagnostic); + } + + // Create the ValidationState using the context. + spvtools::val::ValidationState_t vstate(&hijack_context, options, + binary->code, binary->wordCount, + kDefaultMaxNumOfWarnings); + + return spvtools::val::ValidateBinaryUsingContextAndValidationState( + hijack_context, binary->code, binary->wordCount, pDiagnostic, &vstate); +} diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate.h b/thirdparty/glslang/External/spirv-tools/source/val/validate.h new file mode 100644 index 000000000000..52267c8ab6bd --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate.h @@ -0,0 +1,269 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_VAL_VALIDATE_H_ +#define SOURCE_VAL_VALIDATE_H_ + +#include +#include +#include +#include + +#include "source/instruction.h" +#include "source/table.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace val { + +class ValidationState_t; +class BasicBlock; +class Instruction; + +/// @brief Performs the Control Flow Graph checks +/// +/// @param[in] _ the validation state of the module +/// +/// @return SPV_SUCCESS if no errors are found. SPV_ERROR_INVALID_CFG otherwise +spv_result_t PerformCfgChecks(ValidationState_t& _); + +/// @brief Updates the use vectors of all instructions that can be referenced +/// +/// This function will update the vector which define where an instruction was +/// referenced in the binary. +/// +/// @param[in] _ the validation state of the module +/// +/// @return SPV_SUCCESS if no errors are found. +spv_result_t UpdateIdUse(ValidationState_t& _, const Instruction* inst); + +/// @brief This function checks all ID definitions dominate their use in the +/// CFG. +/// +/// This function will iterate over all ID definitions that are defined in the +/// functions of a module and make sure that the definitions appear in a +/// block that dominates their use. +/// +/// @param[in] _ the validation state of the module +/// +/// @return SPV_SUCCESS if no errors are found. SPV_ERROR_INVALID_ID otherwise +spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _); + +/// @brief This function checks for preconditions involving the adjacent +/// instructions. +/// +/// This function will iterate over all instructions and check for any required +/// predecessor and/or successor instructions. e.g. spv::Op::OpPhi must only be +/// preceded by spv::Op::OpLabel, spv::Op::OpPhi, or spv::Op::OpLine. +/// +/// @param[in] _ the validation state of the module +/// +/// @return SPV_SUCCESS if no errors are found. SPV_ERROR_INVALID_DATA otherwise +spv_result_t ValidateAdjacency(ValidationState_t& _); + +/// @brief Validates static uses of input and output variables +/// +/// Checks that any entry point that uses a input or output variable lists that +/// variable in its interface. +/// +/// @param[in] _ the validation state of the module +/// +/// @return SPV_SUCCESS if no errors are found. +spv_result_t ValidateInterfaces(ValidationState_t& _); + +/// @brief Validates entry point call tree requirements of +/// SPV_KHR_float_controls2 +/// +/// Checks that no entry point using FPFastMathDefault uses: +/// * FPFastMathMode Fast +/// * NoContraction +/// +/// @param[in] _ the validation state of the module +/// +/// @return SPV_SUCCESS if no errors are found. +spv_result_t ValidateFloatControls2(ValidationState_t& _); + +/// @brief Validates memory instructions +/// +/// @param[in] _ the validation state of the module +/// @return SPV_SUCCESS if no errors are found. +spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst); + +/// @brief Updates the immediate dominator for each of the block edges +/// +/// Updates the immediate dominator of the blocks for each of the edges +/// provided by the @p dom_edges parameter +/// +/// @param[in,out] dom_edges The edges of the dominator tree +/// @param[in] set_func This function will be called to updated the Immediate +/// dominator +void UpdateImmediateDominators( + const std::vector>& dom_edges, + std::function set_func); + +/// @brief Prints all of the dominators of a BasicBlock +/// +/// @param[in] block The dominators of this block will be printed +void printDominatorList(BasicBlock& block); + +/// Performs logical layout validation as described in section 2.4 of the SPIR-V +/// spec. +spv_result_t ModuleLayoutPass(ValidationState_t& _, const Instruction* inst); + +/// Performs Control Flow Graph validation and construction. +spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst); + +/// Validates Control Flow Graph instructions. +spv_result_t ControlFlowPass(ValidationState_t& _, const Instruction* inst); + +/// Performs Id and SSA validation of a module +spv_result_t IdPass(ValidationState_t& _, Instruction* inst); + +/// Performs instruction validation. +spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst); + +/// Performs decoration validation. Assumes each decoration on a group +/// has been propagated down to the group members. +spv_result_t ValidateDecorations(ValidationState_t& _); + +/// Performs validation of built-in variables. +spv_result_t ValidateBuiltIns(ValidationState_t& _); + +/// Validates type instructions. +spv_result_t TypePass(ValidationState_t& _, const Instruction* inst); + +/// Validates constant instructions. +spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of arithmetic instructions. +spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of composite instructions. +spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of conversion instructions. +spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of derivative instructions. +spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of logical instructions. +spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of bitwise instructions. +spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of image instructions. +spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of atomic instructions. +spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of barrier instructions. +spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of literal numbers. +spv_result_t LiteralsPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of extension instructions. +spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of annotation instructions. +spv_result_t AnnotationPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of non-uniform group instructions. +spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of debug instructions. +spv_result_t DebugPass(ValidationState_t& _, const Instruction* inst); + +// Validates that capability declarations use operands allowed in the current +// context. +spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of primitive instructions. +spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of mode setting instructions. +spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of function instructions. +spv_result_t FunctionPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of miscellaneous instructions. +spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of ray query instructions. +spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of ray tracing instructions. +spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of shader execution reorder instructions. +spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst); + +/// Validates correctness of mesh shading instructions. +spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst); + +/// Calculates the reachability of basic blocks. +void ReachabilityPass(ValidationState_t& _); + +/// Validates execution limitations. +/// +/// Verifies execution models are allowed for all functionality they contain. +spv_result_t ValidateExecutionLimitations(ValidationState_t& _, + const Instruction* inst); + +/// Validates restricted uses of 8- and 16-bit types. +/// +/// Validates shaders that uses 8- or 16-bit storage capabilities, but not full +/// capabilities only have appropriate uses of those types. +spv_result_t ValidateSmallTypeUses(ValidationState_t& _, + const Instruction* inst); + +/// Validates restricted uses of QCOM decorated textures +/// +/// The textures that are decorated with some of QCOM image processing +/// decorations must be used in the specified QCOM image processing built-in +/// functions and not used in any other image functions. +spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _, + const Instruction* inst); + +/// @brief Validate the ID's within a SPIR-V binary +/// +/// @param[in] pInstructions array of instructions +/// @param[in] count number of elements in instruction array +/// @param[in] bound the binary header +/// @param[in,out] position current word in the binary +/// @param[in] consumer message consumer callback +/// +/// @return result code +spv_result_t spvValidateIDs(const spv_instruction_t* pInstructions, + const uint64_t count, const uint32_t bound, + spv_position position, + const MessageConsumer& consumer); + +// Performs validation for the SPIRV-V module binary. +// The main difference between this API and spvValidateBinary is that the +// "Validation State" is not destroyed upon function return; it lives on and is +// pointed to by the vstate unique_ptr. +spv_result_t ValidateBinaryAndKeepValidationState( + const spv_const_context context, spv_const_validator_options options, + const uint32_t* words, const size_t num_words, spv_diagnostic* pDiagnostic, + std::unique_ptr* vstate); + +} // namespace val +} // namespace spvtools + +#endif // SOURCE_VAL_VALIDATE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_adjacency.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_adjacency.cpp new file mode 100644 index 000000000000..7e371c2f9fac --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_adjacency.cpp @@ -0,0 +1,129 @@ +// Copyright (c) 2018 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of the intra-block preconditions of SPIR-V +// instructions. + +#include + +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +enum { + // Status right after meeting OpFunction. + IN_NEW_FUNCTION, + // Status right after meeting the entry block. + IN_ENTRY_BLOCK, + // Status right after meeting non-entry blocks. + PHI_VALID, + // Status right after meeting non-OpVariable instructions in the entry block + // or non-OpPhi instructions in non-entry blocks, except OpLine. + PHI_AND_VAR_INVALID, +}; + +spv_result_t ValidateAdjacency(ValidationState_t& _) { + const auto& instructions = _.ordered_instructions(); + int adjacency_status = PHI_AND_VAR_INVALID; + + for (size_t i = 0; i < instructions.size(); ++i) { + const auto& inst = instructions[i]; + switch (inst.opcode()) { + case spv::Op::OpFunction: + case spv::Op::OpFunctionParameter: + adjacency_status = IN_NEW_FUNCTION; + break; + case spv::Op::OpLabel: + adjacency_status = + adjacency_status == IN_NEW_FUNCTION ? IN_ENTRY_BLOCK : PHI_VALID; + break; + case spv::Op::OpExtInst: + // If it is a debug info instruction, we do not change the status to + // allow debug info instructions before OpVariable in a function. + // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): We need + // to discuss the location of DebugScope, DebugNoScope, DebugDeclare, + // and DebugValue. + // NOTE: This does not apply to the non-semantic vulkan debug info. + if (!spvExtInstIsDebugInfo(inst.ext_inst_type()) || + inst.ext_inst_type() == + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { + adjacency_status = PHI_AND_VAR_INVALID; + } + break; + case spv::Op::OpPhi: + if (adjacency_status != PHI_VALID) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "OpPhi must appear within a non-entry block before all " + << "non-OpPhi instructions " + << "(except for OpLine, which can be mixed with OpPhi)."; + } + break; + case spv::Op::OpLine: + case spv::Op::OpNoLine: + break; + case spv::Op::OpLoopMerge: + adjacency_status = PHI_AND_VAR_INVALID; + if (i != (instructions.size() - 1)) { + switch (instructions[i + 1].opcode()) { + case spv::Op::OpBranch: + case spv::Op::OpBranchConditional: + break; + default: + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "OpLoopMerge must immediately precede either an " + << "OpBranch or OpBranchConditional instruction. " + << "OpLoopMerge must be the second-to-last instruction in " + << "its block."; + } + } + break; + case spv::Op::OpSelectionMerge: + adjacency_status = PHI_AND_VAR_INVALID; + if (i != (instructions.size() - 1)) { + switch (instructions[i + 1].opcode()) { + case spv::Op::OpBranchConditional: + case spv::Op::OpSwitch: + break; + default: + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "OpSelectionMerge must immediately precede either an " + << "OpBranchConditional or OpSwitch instruction. " + << "OpSelectionMerge must be the second-to-last " + << "instruction in its block."; + } + } + break; + case spv::Op::OpVariable: + if (inst.GetOperandAs(2) == + spv::StorageClass::Function && + adjacency_status != IN_ENTRY_BLOCK) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "All OpVariable instructions in a function must be the " + "first instructions in the first block."; + } + break; + default: + adjacency_status = PHI_AND_VAR_INVALID; + break; + } + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_annotation.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_annotation.cpp new file mode 100644 index 000000000000..106004d066a7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_annotation.cpp @@ -0,0 +1,557 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Returns true if the decoration takes ID parameters. +// TODO(dneto): This can be generated from the grammar. +bool DecorationTakesIdParameters(spv::Decoration type) { + switch (type) { + case spv::Decoration::UniformId: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffsetId: + case spv::Decoration::HlslCounterBufferGOOGLE: + return true; + default: + break; + } + return false; +} + +bool IsMemberDecorationOnly(spv::Decoration dec) { + switch (dec) { + case spv::Decoration::RowMajor: + case spv::Decoration::ColMajor: + case spv::Decoration::MatrixStride: + // SPIR-V spec bug? Offset is generated on variables when dealing with + // transform feedback. + // case spv::Decoration::Offset: + return true; + default: + break; + } + return false; +} + +bool IsNotMemberDecoration(spv::Decoration dec) { + switch (dec) { + case spv::Decoration::SpecId: + case spv::Decoration::Block: + case spv::Decoration::BufferBlock: + case spv::Decoration::ArrayStride: + case spv::Decoration::GLSLShared: + case spv::Decoration::GLSLPacked: + case spv::Decoration::CPacked: + // TODO: https://github.com/KhronosGroup/glslang/issues/703: + // glslang applies Restrict to structure members. + // case spv::Decoration::Restrict: + case spv::Decoration::Aliased: + case spv::Decoration::Constant: + case spv::Decoration::Uniform: + case spv::Decoration::UniformId: + case spv::Decoration::SaturatedConversion: + case spv::Decoration::Index: + case spv::Decoration::Binding: + case spv::Decoration::DescriptorSet: + case spv::Decoration::FuncParamAttr: + case spv::Decoration::FPRoundingMode: + case spv::Decoration::FPFastMathMode: + case spv::Decoration::LinkageAttributes: + case spv::Decoration::NoContraction: + case spv::Decoration::InputAttachmentIndex: + case spv::Decoration::Alignment: + case spv::Decoration::MaxByteOffset: + case spv::Decoration::AlignmentId: + case spv::Decoration::MaxByteOffsetId: + case spv::Decoration::NoSignedWrap: + case spv::Decoration::NoUnsignedWrap: + case spv::Decoration::NonUniform: + case spv::Decoration::RestrictPointer: + case spv::Decoration::AliasedPointer: + case spv::Decoration::CounterBuffer: + return true; + default: + break; + } + return false; +} + +spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec, + const Instruction* inst, + const Instruction* target) { + auto fail = [&_, dec, inst, target](uint32_t vuid) -> DiagnosticStream { + DiagnosticStream ds = std::move( + _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(vuid) << _.SpvDecorationString(dec) + << " decoration on target " << _.getIdName(target->id()) << " "); + return ds; + }; + switch (dec) { + case spv::Decoration::SpecId: + if (!spvOpcodeIsScalarSpecConstant(target->opcode())) { + return fail(0) << "must be a scalar specialization constant"; + } + break; + case spv::Decoration::Block: + case spv::Decoration::BufferBlock: + case spv::Decoration::GLSLShared: + case spv::Decoration::GLSLPacked: + case spv::Decoration::CPacked: + if (target->opcode() != spv::Op::OpTypeStruct) { + return fail(0) << "must be a structure type"; + } + break; + case spv::Decoration::ArrayStride: + if (target->opcode() != spv::Op::OpTypeArray && + target->opcode() != spv::Op::OpTypeRuntimeArray && + target->opcode() != spv::Op::OpTypePointer) { + return fail(0) << "must be an array or pointer type"; + } + break; + case spv::Decoration::BuiltIn: + if (target->opcode() != spv::Op::OpVariable && + !spvOpcodeIsConstant(target->opcode())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "BuiltIns can only target variables, structure members or " + "constants"; + } + if (_.HasCapability(spv::Capability::Shader) && + inst->GetOperandAs(2) == spv::BuiltIn::WorkgroupSize) { + if (!spvOpcodeIsConstant(target->opcode())) { + return fail(0) << "must be a constant for WorkgroupSize"; + } + } else if (target->opcode() != spv::Op::OpVariable) { + return fail(0) << "must be a variable"; + } + break; + case spv::Decoration::NoPerspective: + case spv::Decoration::Flat: + case spv::Decoration::Patch: + case spv::Decoration::Centroid: + case spv::Decoration::Sample: + case spv::Decoration::Restrict: + case spv::Decoration::Aliased: + case spv::Decoration::Volatile: + case spv::Decoration::Coherent: + case spv::Decoration::NonWritable: + case spv::Decoration::NonReadable: + case spv::Decoration::XfbBuffer: + case spv::Decoration::XfbStride: + case spv::Decoration::Component: + case spv::Decoration::Stream: + case spv::Decoration::RestrictPointer: + case spv::Decoration::AliasedPointer: + if (target->opcode() != spv::Op::OpVariable && + target->opcode() != spv::Op::OpFunctionParameter) { + return fail(0) << "must be a memory object declaration"; + } + if (_.GetIdOpcode(target->type_id()) != spv::Op::OpTypePointer) { + return fail(0) << "must be a pointer type"; + } + break; + case spv::Decoration::Invariant: + case spv::Decoration::Constant: + case spv::Decoration::Location: + case spv::Decoration::Index: + case spv::Decoration::Binding: + case spv::Decoration::DescriptorSet: + case spv::Decoration::InputAttachmentIndex: + if (target->opcode() != spv::Op::OpVariable) { + return fail(0) << "must be a variable"; + } + break; + default: + break; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + // The following were all checked as pointer types above. + spv::StorageClass sc = spv::StorageClass::Uniform; + const auto type = _.FindDef(target->type_id()); + if (type && type->operands().size() > 2) { + sc = type->GetOperandAs(1); + } + switch (dec) { + case spv::Decoration::Location: + case spv::Decoration::Component: + // Location is used for input, output, tile image, and ray tracing + // stages. + if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output && + sc != spv::StorageClass::RayPayloadKHR && + sc != spv::StorageClass::IncomingRayPayloadKHR && + sc != spv::StorageClass::HitAttributeKHR && + sc != spv::StorageClass::CallableDataKHR && + sc != spv::StorageClass::IncomingCallableDataKHR && + sc != spv::StorageClass::ShaderRecordBufferKHR && + sc != spv::StorageClass::HitObjectAttributeNV && + sc != spv::StorageClass::TileImageEXT) { + return _.diag(SPV_ERROR_INVALID_ID, target) + << _.VkErrorID(6672) << _.SpvDecorationString(dec) + << " decoration must not be applied to this storage class"; + } + break; + case spv::Decoration::Index: + // Langauge from SPIR-V definition of Index + if (sc != spv::StorageClass::Output) { + return fail(0) << "must be in the Output storage class"; + } + break; + case spv::Decoration::Binding: + case spv::Decoration::DescriptorSet: + if (sc != spv::StorageClass::StorageBuffer && + sc != spv::StorageClass::Uniform && + sc != spv::StorageClass::UniformConstant) { + return fail(6491) << "must be in the StorageBuffer, Uniform, or " + "UniformConstant storage class"; + } + break; + case spv::Decoration::InputAttachmentIndex: + if (sc != spv::StorageClass::UniformConstant) { + return fail(6678) << "must be in the UniformConstant storage class"; + } + break; + case spv::Decoration::Flat: + case spv::Decoration::NoPerspective: + case spv::Decoration::Centroid: + case spv::Decoration::Sample: + if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output) { + return fail(4670) << "storage class must be Input or Output"; + } + break; + case spv::Decoration::PerVertexKHR: + if (sc != spv::StorageClass::Input) { + return fail(6777) << "storage class must be Input"; + } + break; + default: + break; + } + } + return SPV_SUCCESS; +} + +spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { + const auto decoration = inst->GetOperandAs(1); + const auto target_id = inst->GetOperandAs(0); + const auto target = _.FindDef(target_id); + if (!target) { + return _.diag(SPV_ERROR_INVALID_ID, inst) << "target is not defined"; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if ((decoration == spv::Decoration::GLSLShared) || + (decoration == spv::Decoration::GLSLPacked)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4669) << "OpDecorate decoration '" + << _.SpvDecorationString(decoration) + << "' is not valid for the Vulkan execution environment."; + } + } + + if (decoration == spv::Decoration::FPFastMathMode) { + if (_.HasDecoration(target_id, spv::Decoration::NoContraction)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "FPFastMathMode and NoContraction cannot decorate the same " + "target"; + } + auto mask = inst->GetOperandAs(2); + if ((mask & spv::FPFastMathModeMask::AllowTransform) != + spv::FPFastMathModeMask::MaskNone && + ((mask & (spv::FPFastMathModeMask::AllowContract | + spv::FPFastMathModeMask::AllowReassoc)) != + (spv::FPFastMathModeMask::AllowContract | + spv::FPFastMathModeMask::AllowReassoc))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "AllowReassoc and AllowContract must be specified when " + "AllowTransform is specified"; + } + } + + // This is checked from both sides since we register decorations as we go. + if (decoration == spv::Decoration::NoContraction) { + if (_.HasDecoration(target_id, spv::Decoration::FPFastMathMode)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "FPFastMathMode and NoContraction cannot decorate the same " + "target"; + } + } + + if (DecorationTakesIdParameters(decoration)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Decorations taking ID parameters may not be used with " + "OpDecorateId"; + } + + if (target->opcode() != spv::Op::OpDecorationGroup) { + if (IsMemberDecorationOnly(decoration)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.SpvDecorationString(decoration) + << " can only be applied to structure members"; + } + + if (auto error = ValidateDecorationTarget(_, decoration, inst, target)) { + return error; + } + } + + // TODO: Add validations for all decorations. + return SPV_SUCCESS; +} + +spv_result_t ValidateDecorateId(ValidationState_t& _, const Instruction* inst) { + const auto decoration = inst->GetOperandAs(1); + if (!DecorationTakesIdParameters(decoration)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Decorations that don't take ID parameters may not be used with " + "OpDecorateId"; + } + + // No member decorations take id parameters, so we don't bother checking if + // we are using a member only decoration here. + + // TODO: Add validations for these decorations. + // UniformId is covered elsewhere. + return SPV_SUCCESS; +} + +spv_result_t ValidateMemberDecorate(ValidationState_t& _, + const Instruction* inst) { + const auto struct_type_id = inst->GetOperandAs(0); + const auto struct_type = _.FindDef(struct_type_id); + if (!struct_type || spv::Op::OpTypeStruct != struct_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpMemberDecorate Structure type " + << _.getIdName(struct_type_id) << " is not a struct type."; + } + const auto member = inst->GetOperandAs(1); + const auto member_count = + static_cast(struct_type->words().size() - 2); + if (member_count <= member) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Index " << member + << " provided in OpMemberDecorate for struct " + << _.getIdName(struct_type_id) + << " is out of bounds. The structure has " << member_count + << " members. Largest valid index is " << member_count - 1 << "."; + } + + const auto decoration = inst->GetOperandAs(2); + if (IsNotMemberDecoration(decoration)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.SpvDecorationString(decoration) + << " cannot be applied to structure members"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateDecorationGroup(ValidationState_t& _, + const Instruction* inst) { + const auto decoration_group_id = inst->GetOperandAs(0); + const auto decoration_group = _.FindDef(decoration_group_id); + for (auto pair : decoration_group->uses()) { + auto use = pair.first; + if (use->opcode() != spv::Op::OpDecorate && + use->opcode() != spv::Op::OpGroupDecorate && + use->opcode() != spv::Op::OpGroupMemberDecorate && + use->opcode() != spv::Op::OpName && + use->opcode() != spv::Op::OpDecorateId && !use->IsNonSemantic()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result id of OpDecorationGroup can only " + << "be targeted by OpName, OpGroupDecorate, " + << "OpDecorate, OpDecorateId, and OpGroupMemberDecorate"; + } + } + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupDecorate(ValidationState_t& _, + const Instruction* inst) { + const auto decoration_group_id = inst->GetOperandAs(0); + auto decoration_group = _.FindDef(decoration_group_id); + if (!decoration_group || + spv::Op::OpDecorationGroup != decoration_group->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpGroupDecorate Decoration group " + << _.getIdName(decoration_group_id) << " is not a decoration group."; + } + for (unsigned i = 1; i < inst->operands().size(); ++i) { + auto target_id = inst->GetOperandAs(i); + auto target = _.FindDef(target_id); + if (!target || target->opcode() == spv::Op::OpDecorationGroup) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpGroupDecorate may not target OpDecorationGroup " + << _.getIdName(target_id); + } + } + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupMemberDecorate(ValidationState_t& _, + const Instruction* inst) { + const auto decoration_group_id = inst->GetOperandAs(0); + const auto decoration_group = _.FindDef(decoration_group_id); + if (!decoration_group || + spv::Op::OpDecorationGroup != decoration_group->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpGroupMemberDecorate Decoration group " + << _.getIdName(decoration_group_id) << " is not a decoration group."; + } + // Grammar checks ensures that the number of arguments to this instruction + // is an odd number: 1 decoration group + (id,literal) pairs. + for (size_t i = 1; i + 1 < inst->operands().size(); i += 2) { + const uint32_t struct_id = inst->GetOperandAs(i); + const uint32_t index = inst->GetOperandAs(i + 1); + auto struct_instr = _.FindDef(struct_id); + if (!struct_instr || spv::Op::OpTypeStruct != struct_instr->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpGroupMemberDecorate Structure type " + << _.getIdName(struct_id) << " is not a struct type."; + } + const uint32_t num_struct_members = + static_cast(struct_instr->words().size() - 2); + if (index >= num_struct_members) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Index " << index + << " provided in OpGroupMemberDecorate for struct " + << _.getIdName(struct_id) + << " is out of bounds. The structure has " << num_struct_members + << " members. Largest valid index is " << num_struct_members - 1 + << "."; + } + } + return SPV_SUCCESS; +} + +// Registers necessary decoration(s) for the appropriate IDs based on the +// instruction. +spv_result_t RegisterDecorations(ValidationState_t& _, + const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: { + const uint32_t target_id = inst->word(1); + const spv::Decoration dec_type = + static_cast(inst->word(2)); + std::vector dec_params; + if (inst->words().size() > 3) { + dec_params.insert(dec_params.end(), inst->words().begin() + 3, + inst->words().end()); + } + _.RegisterDecorationForId(target_id, Decoration(dec_type, dec_params)); + break; + } + case spv::Op::OpMemberDecorate: { + const uint32_t struct_id = inst->word(1); + const uint32_t index = inst->word(2); + const spv::Decoration dec_type = + static_cast(inst->word(3)); + std::vector dec_params; + if (inst->words().size() > 4) { + dec_params.insert(dec_params.end(), inst->words().begin() + 4, + inst->words().end()); + } + _.RegisterDecorationForId(struct_id, + Decoration(dec_type, dec_params, index)); + break; + } + case spv::Op::OpDecorationGroup: { + // We don't need to do anything right now. Assigning decorations to groups + // will be taken care of via OpGroupDecorate. + break; + } + case spv::Op::OpGroupDecorate: { + // Word 1 is the group . All subsequent words are target s that + // are going to be decorated with the decorations. + const uint32_t decoration_group_id = inst->word(1); + std::set& group_decorations = + _.id_decorations(decoration_group_id); + for (size_t i = 2; i < inst->words().size(); ++i) { + const uint32_t target_id = inst->word(i); + _.RegisterDecorationsForId(target_id, group_decorations.begin(), + group_decorations.end()); + } + break; + } + case spv::Op::OpGroupMemberDecorate: { + // Word 1 is the Decoration Group followed by (struct,literal) + // pairs. All decorations of the group should be applied to all the struct + // members that are specified in the instructions. + const uint32_t decoration_group_id = inst->word(1); + std::set& group_decorations = + _.id_decorations(decoration_group_id); + // Grammar checks ensures that the number of arguments to this instruction + // is an odd number: 1 decoration group + (id,literal) pairs. + for (size_t i = 2; i + 1 < inst->words().size(); i = i + 2) { + const uint32_t struct_id = inst->word(i); + const uint32_t index = inst->word(i + 1); + // ID validation phase ensures this is in fact a struct instruction and + // that the index is not out of bound. + _.RegisterDecorationsForStructMember(struct_id, index, + group_decorations.begin(), + group_decorations.end()); + } + break; + } + default: + break; + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t AnnotationPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpDecorate: + if (auto error = ValidateDecorate(_, inst)) return error; + break; + case spv::Op::OpDecorateId: + if (auto error = ValidateDecorateId(_, inst)) return error; + break; + // TODO(dneto): spv::Op::OpDecorateStringGOOGLE + // See https://github.com/KhronosGroup/SPIRV-Tools/issues/2253 + case spv::Op::OpMemberDecorate: + if (auto error = ValidateMemberDecorate(_, inst)) return error; + break; + case spv::Op::OpDecorationGroup: + if (auto error = ValidateDecorationGroup(_, inst)) return error; + break; + case spv::Op::OpGroupDecorate: + if (auto error = ValidateGroupDecorate(_, inst)) return error; + break; + case spv::Op::OpGroupMemberDecorate: + if (auto error = ValidateGroupMemberDecorate(_, inst)) return error; + break; + default: + break; + } + + // In order to validate decoration rules, we need to know all the decorations + // that are applied to any given . + RegisterDecorations(_, inst); + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_arithmetics.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_arithmetics.cpp new file mode 100644 index 000000000000..b608a859529f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_arithmetics.cpp @@ -0,0 +1,683 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Performs validation of arithmetic instructions. + +#include + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +// Validates correctness of arithmetic instructions. +spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + switch (opcode) { + case spv::Op::OpFAdd: + case spv::Op::OpFSub: + case spv::Op::OpFMul: + case spv::Op::OpFDiv: + case spv::Op::OpFRem: + case spv::Op::OpFMod: + case spv::Op::OpFNegate: { + bool supportsCoopMat = + (opcode != spv::Op::OpFMul && opcode != spv::Op::OpFRem && + opcode != spv::Op::OpFMod); + if (!_.IsFloatScalarType(result_type) && + !_.IsFloatVectorType(result_type) && + !(supportsCoopMat && _.IsFloatCooperativeMatrixType(result_type)) && + !(opcode == spv::Op::OpFMul && + _.IsCooperativeMatrixKHRType(result_type) && + _.IsFloatCooperativeMatrixType(result_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected floating scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + for (size_t operand_index = 2; operand_index < inst->operands().size(); + ++operand_index) { + if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) { + const uint32_t type_id = _.GetOperandTypeId(inst, operand_index); + if (!_.IsCooperativeMatrixKHRType(type_id) || + !_.IsFloatCooperativeMatrixType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected arithmetic operands to be of Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + } + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, type_id, result_type); + if (ret != SPV_SUCCESS) return ret; + } else if (_.GetOperandTypeId(inst, operand_index) != result_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected arithmetic operands to be of Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + } + break; + } + + case spv::Op::OpUDiv: + case spv::Op::OpUMod: { + bool supportsCoopMat = (opcode == spv::Op::OpUDiv); + if (!_.IsUnsignedIntScalarType(result_type) && + !_.IsUnsignedIntVectorType(result_type) && + !(supportsCoopMat && + _.IsUnsignedIntCooperativeMatrixType(result_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected unsigned int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + for (size_t operand_index = 2; operand_index < inst->operands().size(); + ++operand_index) { + if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) { + const uint32_t type_id = _.GetOperandTypeId(inst, operand_index); + if (!_.IsCooperativeMatrixKHRType(type_id) || + !_.IsUnsignedIntCooperativeMatrixType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected arithmetic operands to be of Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + } + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, type_id, result_type); + if (ret != SPV_SUCCESS) return ret; + } else if (_.GetOperandTypeId(inst, operand_index) != result_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected arithmetic operands to be of Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + } + break; + } + + case spv::Op::OpISub: + case spv::Op::OpIAdd: + case spv::Op::OpIMul: + case spv::Op::OpSDiv: + case spv::Op::OpSMod: + case spv::Op::OpSRem: + case spv::Op::OpSNegate: { + bool supportsCoopMat = + (opcode != spv::Op::OpIMul && opcode != spv::Op::OpSRem && + opcode != spv::Op::OpSMod); + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && + !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)) && + !(opcode == spv::Op::OpIMul && + _.IsCooperativeMatrixKHRType(result_type) && + _.IsIntCooperativeMatrixType(result_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t dimension = _.GetDimension(result_type); + const uint32_t bit_width = _.GetBitWidth(result_type); + + for (size_t operand_index = 2; operand_index < inst->operands().size(); + ++operand_index) { + const uint32_t type_id = _.GetOperandTypeId(inst, operand_index); + + if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) { + if (!_.IsCooperativeMatrixKHRType(type_id) || + !_.IsIntCooperativeMatrixType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected arithmetic operands to be of Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + } + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, type_id, result_type); + if (ret != SPV_SUCCESS) return ret; + } + + if (!type_id || + (!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id) && + !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)) && + !(opcode == spv::Op::OpIMul && + _.IsCooperativeMatrixKHRType(result_type) && + _.IsIntCooperativeMatrixType(result_type)))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector type as operand: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + + if (_.GetDimension(type_id) != dimension) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected arithmetic operands to have the same dimension " + << "as Result Type: " << spvOpcodeString(opcode) + << " operand index " << operand_index; + + if (_.GetBitWidth(type_id) != bit_width) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected arithmetic operands to have the same bit width " + << "as Result Type: " << spvOpcodeString(opcode) + << " operand index " << operand_index; + } + break; + } + + case spv::Op::OpDot: { + if (!_.IsFloatScalarType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float scalar type as Result Type: " + << spvOpcodeString(opcode); + + uint32_t first_vector_num_components = 0; + + for (size_t operand_index = 2; operand_index < inst->operands().size(); + ++operand_index) { + const uint32_t type_id = _.GetOperandTypeId(inst, operand_index); + + if (!type_id || !_.IsFloatVectorType(type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float vector as operand: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + + const uint32_t component_type = _.GetComponentType(type_id); + if (component_type != result_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected component type to be equal to Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + + const uint32_t num_components = _.GetDimension(type_id); + if (operand_index == 2) { + first_vector_num_components = num_components; + } else if (num_components != first_vector_num_components) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operands to have the same number of components: " + << spvOpcodeString(opcode); + } + } + break; + } + + case spv::Op::OpVectorTimesScalar: { + if (!_.IsFloatVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t vector_type_id = _.GetOperandTypeId(inst, 2); + if (result_type != vector_type_id) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected vector operand type to be equal to Result Type: " + << spvOpcodeString(opcode); + + const uint32_t component_type = _.GetComponentType(vector_type_id); + + const uint32_t scalar_type_id = _.GetOperandTypeId(inst, 3); + if (component_type != scalar_type_id) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected scalar operand type to be equal to the component " + << "type of the vector operand: " << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpMatrixTimesScalar: { + if (!_.IsFloatMatrixType(result_type) && + !(_.IsCooperativeMatrixType(result_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float matrix type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 2); + if (result_type != matrix_type_id) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected matrix operand type to be equal to Result Type: " + << spvOpcodeString(opcode); + + const uint32_t component_type = _.GetComponentType(matrix_type_id); + + const uint32_t scalar_type_id = _.GetOperandTypeId(inst, 3); + if (component_type != scalar_type_id) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected scalar operand type to be equal to the component " + << "type of the matrix operand: " << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpVectorTimesMatrix: { + const uint32_t vector_type_id = _.GetOperandTypeId(inst, 2); + const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 3); + + if (!_.IsFloatVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t res_component_type = _.GetComponentType(result_type); + + if (!vector_type_id || !_.IsFloatVectorType(vector_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float vector type as left operand: " + << spvOpcodeString(opcode); + + if (res_component_type != _.GetComponentType(vector_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected component types of Result Type and vector to be " + << "equal: " << spvOpcodeString(opcode); + + uint32_t matrix_num_rows = 0; + uint32_t matrix_num_cols = 0; + uint32_t matrix_col_type = 0; + uint32_t matrix_component_type = 0; + if (!_.GetMatrixTypeInfo(matrix_type_id, &matrix_num_rows, + &matrix_num_cols, &matrix_col_type, + &matrix_component_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float matrix type as right operand: " + << spvOpcodeString(opcode); + + if (res_component_type != matrix_component_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected component types of Result Type and matrix to be " + << "equal: " << spvOpcodeString(opcode); + + if (matrix_num_cols != _.GetDimension(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected number of columns of the matrix to be equal to " + << "Result Type vector size: " << spvOpcodeString(opcode); + + if (matrix_num_rows != _.GetDimension(vector_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected number of rows of the matrix to be equal to the " + << "vector operand size: " << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpMatrixTimesVector: { + const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 2); + const uint32_t vector_type_id = _.GetOperandTypeId(inst, 3); + + if (!_.IsFloatVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float vector type as Result Type: " + << spvOpcodeString(opcode); + + uint32_t matrix_num_rows = 0; + uint32_t matrix_num_cols = 0; + uint32_t matrix_col_type = 0; + uint32_t matrix_component_type = 0; + if (!_.GetMatrixTypeInfo(matrix_type_id, &matrix_num_rows, + &matrix_num_cols, &matrix_col_type, + &matrix_component_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float matrix type as left operand: " + << spvOpcodeString(opcode); + + if (result_type != matrix_col_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected column type of the matrix to be equal to Result " + "Type: " + << spvOpcodeString(opcode); + + if (!vector_type_id || !_.IsFloatVectorType(vector_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float vector type as right operand: " + << spvOpcodeString(opcode); + + if (matrix_component_type != _.GetComponentType(vector_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected component types of the operands to be equal: " + << spvOpcodeString(opcode); + + if (matrix_num_cols != _.GetDimension(vector_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected number of columns of the matrix to be equal to the " + << "vector size: " << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpMatrixTimesMatrix: { + const uint32_t left_type_id = _.GetOperandTypeId(inst, 2); + const uint32_t right_type_id = _.GetOperandTypeId(inst, 3); + + uint32_t res_num_rows = 0; + uint32_t res_num_cols = 0; + uint32_t res_col_type = 0; + uint32_t res_component_type = 0; + if (!_.GetMatrixTypeInfo(result_type, &res_num_rows, &res_num_cols, + &res_col_type, &res_component_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float matrix type as Result Type: " + << spvOpcodeString(opcode); + + uint32_t left_num_rows = 0; + uint32_t left_num_cols = 0; + uint32_t left_col_type = 0; + uint32_t left_component_type = 0; + if (!_.GetMatrixTypeInfo(left_type_id, &left_num_rows, &left_num_cols, + &left_col_type, &left_component_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float matrix type as left operand: " + << spvOpcodeString(opcode); + + uint32_t right_num_rows = 0; + uint32_t right_num_cols = 0; + uint32_t right_col_type = 0; + uint32_t right_component_type = 0; + if (!_.GetMatrixTypeInfo(right_type_id, &right_num_rows, &right_num_cols, + &right_col_type, &right_component_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float matrix type as right operand: " + << spvOpcodeString(opcode); + + if (!_.IsFloatScalarType(res_component_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float matrix type as Result Type: " + << spvOpcodeString(opcode); + + if (res_col_type != left_col_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected column types of Result Type and left matrix to be " + << "equal: " << spvOpcodeString(opcode); + + if (res_component_type != right_component_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected component types of Result Type and right matrix to " + "be " + << "equal: " << spvOpcodeString(opcode); + + if (res_num_cols != right_num_cols) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected number of columns of Result Type and right matrix " + "to " + << "be equal: " << spvOpcodeString(opcode); + + if (left_num_cols != right_num_rows) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected number of columns of left matrix and number of " + "rows " + << "of right matrix to be equal: " << spvOpcodeString(opcode); + + assert(left_num_rows == res_num_rows); + break; + } + + case spv::Op::OpOuterProduct: { + const uint32_t left_type_id = _.GetOperandTypeId(inst, 2); + const uint32_t right_type_id = _.GetOperandTypeId(inst, 3); + + uint32_t res_num_rows = 0; + uint32_t res_num_cols = 0; + uint32_t res_col_type = 0; + uint32_t res_component_type = 0; + if (!_.GetMatrixTypeInfo(result_type, &res_num_rows, &res_num_cols, + &res_col_type, &res_component_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float matrix type as Result Type: " + << spvOpcodeString(opcode); + + if (left_type_id != res_col_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected column type of Result Type to be equal to the type " + << "of the left operand: " << spvOpcodeString(opcode); + + if (!right_type_id || !_.IsFloatVectorType(right_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float vector type as right operand: " + << spvOpcodeString(opcode); + + if (res_component_type != _.GetComponentType(right_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected component types of the operands to be equal: " + << spvOpcodeString(opcode); + + if (res_num_cols != _.GetDimension(right_type_id)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected number of columns of the matrix to be equal to the " + << "vector size of the right operand: " + << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpIAddCarry: + case spv::Op::OpISubBorrow: + case spv::Op::OpUMulExtended: + case spv::Op::OpSMulExtended: { + std::vector result_types; + if (!_.GetStructMemberTypes(result_type, &result_types)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected a struct as Result Type: " + << spvOpcodeString(opcode); + + if (result_types.size() != 2) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type struct to have two members: " + << spvOpcodeString(opcode); + + if (opcode == spv::Op::OpSMulExtended) { + if (!_.IsIntScalarType(result_types[0]) && + !_.IsIntVectorType(result_types[0])) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type struct member types to be integer " + "scalar " + << "or vector: " << spvOpcodeString(opcode); + } else { + if (!_.IsUnsignedIntScalarType(result_types[0]) && + !_.IsUnsignedIntVectorType(result_types[0])) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type struct member types to be unsigned " + << "integer scalar or vector: " << spvOpcodeString(opcode); + } + + if (result_types[0] != result_types[1]) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type struct member types to be identical: " + << spvOpcodeString(opcode); + + const uint32_t left_type_id = _.GetOperandTypeId(inst, 2); + const uint32_t right_type_id = _.GetOperandTypeId(inst, 3); + + if (left_type_id != result_types[0] || right_type_id != result_types[0]) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected both operands to be of Result Type member type: " + << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpCooperativeMatrixMulAddNV: { + const uint32_t D_type_id = _.GetOperandTypeId(inst, 1); + const uint32_t A_type_id = _.GetOperandTypeId(inst, 2); + const uint32_t B_type_id = _.GetOperandTypeId(inst, 3); + const uint32_t C_type_id = _.GetOperandTypeId(inst, 4); + + if (!_.IsCooperativeMatrixNVType(A_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected cooperative matrix type as A Type: " + << spvOpcodeString(opcode); + } + if (!_.IsCooperativeMatrixNVType(B_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected cooperative matrix type as B Type: " + << spvOpcodeString(opcode); + } + if (!_.IsCooperativeMatrixNVType(C_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected cooperative matrix type as C Type: " + << spvOpcodeString(opcode); + } + if (!_.IsCooperativeMatrixNVType(D_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected cooperative matrix type as Result Type: " + << spvOpcodeString(opcode); + } + + const auto A = _.FindDef(A_type_id); + const auto B = _.FindDef(B_type_id); + const auto C = _.FindDef(C_type_id); + const auto D = _.FindDef(D_type_id); + + std::tuple A_scope, B_scope, C_scope, D_scope, + A_rows, B_rows, C_rows, D_rows, A_cols, B_cols, C_cols, D_cols; + + A_scope = _.EvalInt32IfConst(A->GetOperandAs(2)); + B_scope = _.EvalInt32IfConst(B->GetOperandAs(2)); + C_scope = _.EvalInt32IfConst(C->GetOperandAs(2)); + D_scope = _.EvalInt32IfConst(D->GetOperandAs(2)); + + A_rows = _.EvalInt32IfConst(A->GetOperandAs(3)); + B_rows = _.EvalInt32IfConst(B->GetOperandAs(3)); + C_rows = _.EvalInt32IfConst(C->GetOperandAs(3)); + D_rows = _.EvalInt32IfConst(D->GetOperandAs(3)); + + A_cols = _.EvalInt32IfConst(A->GetOperandAs(4)); + B_cols = _.EvalInt32IfConst(B->GetOperandAs(4)); + C_cols = _.EvalInt32IfConst(C->GetOperandAs(4)); + D_cols = _.EvalInt32IfConst(D->GetOperandAs(4)); + + const auto notEqual = [](std::tuple X, + std::tuple Y) { + return (std::get<1>(X) && std::get<1>(Y) && + std::get<2>(X) != std::get<2>(Y)); + }; + + if (notEqual(A_scope, B_scope) || notEqual(A_scope, C_scope) || + notEqual(A_scope, D_scope) || notEqual(B_scope, C_scope) || + notEqual(B_scope, D_scope) || notEqual(C_scope, D_scope)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix scopes must match: " + << spvOpcodeString(opcode); + } + + if (notEqual(A_rows, C_rows) || notEqual(A_rows, D_rows) || + notEqual(C_rows, D_rows)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix 'M' mismatch: " + << spvOpcodeString(opcode); + } + + if (notEqual(B_cols, C_cols) || notEqual(B_cols, D_cols) || + notEqual(C_cols, D_cols)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix 'N' mismatch: " + << spvOpcodeString(opcode); + } + + if (notEqual(A_cols, B_rows)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix 'K' mismatch: " + << spvOpcodeString(opcode); + } + break; + } + + case spv::Op::OpCooperativeMatrixMulAddKHR: { + const uint32_t D_type_id = _.GetOperandTypeId(inst, 1); + const uint32_t A_type_id = _.GetOperandTypeId(inst, 2); + const uint32_t B_type_id = _.GetOperandTypeId(inst, 3); + const uint32_t C_type_id = _.GetOperandTypeId(inst, 4); + + if (!_.IsCooperativeMatrixAType(A_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix type must be A Type: " + << spvOpcodeString(opcode); + } + if (!_.IsCooperativeMatrixBType(B_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix type must be B Type: " + << spvOpcodeString(opcode); + } + if (!_.IsCooperativeMatrixAccType(C_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix type must be Accumulator Type: " + << spvOpcodeString(opcode); + } + if (!_.IsCooperativeMatrixKHRType(D_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected cooperative matrix type as Result Type: " + << spvOpcodeString(opcode); + } + + const auto A = _.FindDef(A_type_id); + const auto B = _.FindDef(B_type_id); + const auto C = _.FindDef(C_type_id); + const auto D = _.FindDef(D_type_id); + + std::tuple A_scope, B_scope, C_scope, D_scope, + A_rows, B_rows, C_rows, D_rows, A_cols, B_cols, C_cols, D_cols; + + A_scope = _.EvalInt32IfConst(A->GetOperandAs(2)); + B_scope = _.EvalInt32IfConst(B->GetOperandAs(2)); + C_scope = _.EvalInt32IfConst(C->GetOperandAs(2)); + D_scope = _.EvalInt32IfConst(D->GetOperandAs(2)); + + A_rows = _.EvalInt32IfConst(A->GetOperandAs(3)); + B_rows = _.EvalInt32IfConst(B->GetOperandAs(3)); + C_rows = _.EvalInt32IfConst(C->GetOperandAs(3)); + D_rows = _.EvalInt32IfConst(D->GetOperandAs(3)); + + A_cols = _.EvalInt32IfConst(A->GetOperandAs(4)); + B_cols = _.EvalInt32IfConst(B->GetOperandAs(4)); + C_cols = _.EvalInt32IfConst(C->GetOperandAs(4)); + D_cols = _.EvalInt32IfConst(D->GetOperandAs(4)); + + const auto notEqual = [](std::tuple X, + std::tuple Y) { + return (std::get<1>(X) && std::get<1>(Y) && + std::get<2>(X) != std::get<2>(Y)); + }; + + if (notEqual(A_scope, B_scope) || notEqual(A_scope, C_scope) || + notEqual(A_scope, D_scope) || notEqual(B_scope, C_scope) || + notEqual(B_scope, D_scope) || notEqual(C_scope, D_scope)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix scopes must match: " + << spvOpcodeString(opcode); + } + + if (notEqual(A_rows, C_rows) || notEqual(A_rows, D_rows) || + notEqual(C_rows, D_rows)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix 'M' mismatch: " + << spvOpcodeString(opcode); + } + + if (notEqual(B_cols, C_cols) || notEqual(B_cols, D_cols) || + notEqual(C_cols, D_cols)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix 'N' mismatch: " + << spvOpcodeString(opcode); + } + + if (notEqual(A_cols, B_rows)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix 'K' mismatch: " + << spvOpcodeString(opcode); + } + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_atomics.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_atomics.cpp new file mode 100644 index 000000000000..8ddef17896f9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_atomics.cpp @@ -0,0 +1,420 @@ +// Copyright (c) 2017 Google Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of atomic SPIR-V instructions. + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/util/bitutils.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validate_memory_semantics.h" +#include "source/val/validate_scopes.h" +#include "source/val/validation_state.h" + +namespace { + +bool IsStorageClassAllowedByUniversalRules(spv::StorageClass storage_class) { + switch (storage_class) { + case spv::StorageClass::Uniform: + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::Workgroup: + case spv::StorageClass::CrossWorkgroup: + case spv::StorageClass::Generic: + case spv::StorageClass::AtomicCounter: + case spv::StorageClass::Image: + case spv::StorageClass::Function: + case spv::StorageClass::PhysicalStorageBuffer: + case spv::StorageClass::TaskPayloadWorkgroupEXT: + return true; + break; + default: + return false; + } +} + +bool HasReturnType(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpAtomicStore: + case spv::Op::OpAtomicFlagClear: + return false; + break; + default: + return true; + } +} + +bool HasOnlyFloatReturnType(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicFMinEXT: + case spv::Op::OpAtomicFMaxEXT: + return true; + break; + default: + return false; + } +} + +bool HasOnlyIntReturnType(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + return true; + break; + default: + return false; + } +} + +bool HasIntOrFloatReturnType(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicExchange: + return true; + break; + default: + return false; + } +} + +bool HasOnlyBoolReturnType(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpAtomicFlagTestAndSet: + return true; + break; + default: + return false; + } +} + +} // namespace + +namespace spvtools { +namespace val { + +// Validates correctness of atomic instructions. +spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + switch (opcode) { + case spv::Op::OpAtomicLoad: + case spv::Op::OpAtomicStore: + case spv::Op::OpAtomicExchange: + case spv::Op::OpAtomicFAddEXT: + case spv::Op::OpAtomicCompareExchange: + case spv::Op::OpAtomicCompareExchangeWeak: + case spv::Op::OpAtomicIIncrement: + case spv::Op::OpAtomicIDecrement: + case spv::Op::OpAtomicIAdd: + case spv::Op::OpAtomicISub: + case spv::Op::OpAtomicSMin: + case spv::Op::OpAtomicUMin: + case spv::Op::OpAtomicFMinEXT: + case spv::Op::OpAtomicSMax: + case spv::Op::OpAtomicUMax: + case spv::Op::OpAtomicFMaxEXT: + case spv::Op::OpAtomicAnd: + case spv::Op::OpAtomicOr: + case spv::Op::OpAtomicXor: + case spv::Op::OpAtomicFlagTestAndSet: + case spv::Op::OpAtomicFlagClear: { + const uint32_t result_type = inst->type_id(); + + // Validate return type first so can just check if pointer type is same + // (if applicable) + if (HasReturnType(opcode)) { + if (HasOnlyFloatReturnType(opcode) && + (!(_.HasCapability(spv::Capability::AtomicFloat16VectorNV) && + _.IsFloat16Vector2Or4Type(result_type)) && + !_.IsFloatScalarType(result_type))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Result Type to be float scalar type"; + } else if (HasOnlyIntReturnType(opcode) && + !_.IsIntScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Result Type to be integer scalar type"; + } else if (HasIntOrFloatReturnType(opcode) && + !_.IsFloatScalarType(result_type) && + !(opcode == spv::Op::OpAtomicExchange && + _.HasCapability(spv::Capability::AtomicFloat16VectorNV) && + _.IsFloat16Vector2Or4Type(result_type)) && + !_.IsIntScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Result Type to be integer or float scalar type"; + } else if (HasOnlyBoolReturnType(opcode) && + !_.IsBoolScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Result Type to be bool scalar type"; + } + } + + uint32_t operand_index = HasReturnType(opcode) ? 2 : 0; + const uint32_t pointer_type = _.GetOperandTypeId(inst, operand_index++); + uint32_t data_type = 0; + spv::StorageClass storage_class; + if (!_.GetPointerTypeInfo(pointer_type, &data_type, &storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Pointer to be of type OpTypePointer"; + } + + // Can't use result_type because OpAtomicStore doesn't have a result + if (_.IsIntScalarType(data_type) && _.GetBitWidth(data_type) == 64 && + !_.HasCapability(spv::Capability::Int64Atomics)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": 64-bit atomics require the Int64Atomics capability"; + } + + // Validate storage class against universal rules + if (!IsStorageClassAllowedByUniversalRules(storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": storage class forbidden by universal validation rules."; + } + + // Then Shader rules + if (_.HasCapability(spv::Capability::Shader)) { + // Vulkan environment rule + if (spvIsVulkanEnv(_.context()->target_env)) { + if ((storage_class != spv::StorageClass::Uniform) && + (storage_class != spv::StorageClass::StorageBuffer) && + (storage_class != spv::StorageClass::Workgroup) && + (storage_class != spv::StorageClass::Image) && + (storage_class != spv::StorageClass::PhysicalStorageBuffer) && + (storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4686) << spvOpcodeString(opcode) + << ": Vulkan spec only allows storage classes for atomic to " + "be: Uniform, Workgroup, Image, StorageBuffer, " + "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT."; + } + } else if (storage_class == spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Function storage class forbidden when the Shader " + "capability is declared."; + } + + if (opcode == spv::Op::OpAtomicFAddEXT) { + // result type being float checked already + if (_.GetBitWidth(result_type) == 16) { + if (_.IsFloat16Vector2Or4Type(result_type)) { + if (!_.HasCapability(spv::Capability::AtomicFloat16VectorNV)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": float vector atomics require the " + "AtomicFloat16VectorNV capability"; + } else { + if (!_.HasCapability(spv::Capability::AtomicFloat16AddEXT)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": float add atomics require the AtomicFloat32AddEXT " + "capability"; + } + } + } + if ((_.GetBitWidth(result_type) == 32) && + (!_.HasCapability(spv::Capability::AtomicFloat32AddEXT))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": float add atomics require the AtomicFloat32AddEXT " + "capability"; + } + if ((_.GetBitWidth(result_type) == 64) && + (!_.HasCapability(spv::Capability::AtomicFloat64AddEXT))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": float add atomics require the AtomicFloat64AddEXT " + "capability"; + } + } else if (opcode == spv::Op::OpAtomicFMinEXT || + opcode == spv::Op::OpAtomicFMaxEXT) { + if (_.GetBitWidth(result_type) == 16) { + if (_.IsFloat16Vector2Or4Type(result_type)) { + if (!_.HasCapability(spv::Capability::AtomicFloat16VectorNV)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": float vector atomics require the " + "AtomicFloat16VectorNV capability"; + } else { + if (!_.HasCapability(spv::Capability::AtomicFloat16MinMaxEXT)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": float min/max atomics require the " + "AtomicFloat16MinMaxEXT capability"; + } + } + } + if ((_.GetBitWidth(result_type) == 32) && + (!_.HasCapability(spv::Capability::AtomicFloat32MinMaxEXT))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": float min/max atomics require the " + "AtomicFloat32MinMaxEXT capability"; + } + if ((_.GetBitWidth(result_type) == 64) && + (!_.HasCapability(spv::Capability::AtomicFloat64MinMaxEXT))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": float min/max atomics require the " + "AtomicFloat64MinMaxEXT capability"; + } + } + } + + // And finally OpenCL environment rules + if (spvIsOpenCLEnv(_.context()->target_env)) { + if ((storage_class != spv::StorageClass::Function) && + (storage_class != spv::StorageClass::Workgroup) && + (storage_class != spv::StorageClass::CrossWorkgroup) && + (storage_class != spv::StorageClass::Generic)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": storage class must be Function, Workgroup, " + "CrossWorkGroup or Generic in the OpenCL environment."; + } + + if (_.context()->target_env == SPV_ENV_OPENCL_1_2) { + if (storage_class == spv::StorageClass::Generic) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Storage class cannot be Generic in OpenCL 1.2 " + "environment"; + } + } + } + + // If result and pointer type are different, need to do special check here + if (opcode == spv::Op::OpAtomicFlagTestAndSet || + opcode == spv::Op::OpAtomicFlagClear) { + if (!_.IsIntScalarType(data_type) || _.GetBitWidth(data_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Pointer to point to a value of 32-bit integer " + "type"; + } + } else if (opcode == spv::Op::OpAtomicStore) { + if (!_.IsFloatScalarType(data_type) && !_.IsIntScalarType(data_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Pointer to be a pointer to integer or float " + << "scalar type"; + } + } else if (data_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Pointer to point to a value of type Result " + "Type"; + } + + auto memory_scope = inst->GetOperandAs(operand_index++); + if (auto error = ValidateMemoryScope(_, inst, memory_scope)) { + return error; + } + + const auto equal_semantics_index = operand_index++; + if (auto error = ValidateMemorySemantics(_, inst, equal_semantics_index, + memory_scope)) + return error; + + if (opcode == spv::Op::OpAtomicCompareExchange || + opcode == spv::Op::OpAtomicCompareExchangeWeak) { + const auto unequal_semantics_index = operand_index++; + if (auto error = ValidateMemorySemantics( + _, inst, unequal_semantics_index, memory_scope)) + return error; + + // Volatile bits must match for equal and unequal semantics. Previous + // checks guarantee they are 32-bit constants, but we need to recheck + // whether they are evaluatable constants. + bool is_int32 = false; + bool is_equal_const = false; + bool is_unequal_const = false; + uint32_t equal_value = 0; + uint32_t unequal_value = 0; + std::tie(is_int32, is_equal_const, equal_value) = _.EvalInt32IfConst( + inst->GetOperandAs(equal_semantics_index)); + std::tie(is_int32, is_unequal_const, unequal_value) = + _.EvalInt32IfConst( + inst->GetOperandAs(unequal_semantics_index)); + if (is_equal_const && is_unequal_const && + ((equal_value & uint32_t(spv::MemorySemanticsMask::Volatile)) ^ + (unequal_value & uint32_t(spv::MemorySemanticsMask::Volatile)))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Volatile mask setting must match for Equal and Unequal " + "memory semantics"; + } + } + + if (opcode == spv::Op::OpAtomicStore) { + const uint32_t value_type = _.GetOperandTypeId(inst, 3); + if (value_type != data_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Value type and the type pointed to by " + "Pointer to be the same"; + } + } else if (opcode != spv::Op::OpAtomicLoad && + opcode != spv::Op::OpAtomicIIncrement && + opcode != spv::Op::OpAtomicIDecrement && + opcode != spv::Op::OpAtomicFlagTestAndSet && + opcode != spv::Op::OpAtomicFlagClear) { + const uint32_t value_type = _.GetOperandTypeId(inst, operand_index++); + if (value_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Value to be of type Result Type"; + } + } + + if (opcode == spv::Op::OpAtomicCompareExchange || + opcode == spv::Op::OpAtomicCompareExchangeWeak) { + const uint32_t comparator_type = + _.GetOperandTypeId(inst, operand_index++); + if (comparator_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Comparator to be of type Result Type"; + } + } + + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_barriers.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_barriers.cpp new file mode 100644 index 000000000000..0abd5c859993 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_barriers.cpp @@ -0,0 +1,134 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of barrier SPIR-V instructions. + +#include + +#include "source/opcode.h" +#include "source/spirv_constant.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validate_memory_semantics.h" +#include "source/val/validate_scopes.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +// Validates correctness of barrier instructions. +spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + switch (opcode) { + case spv::Op::OpControlBarrier: { + if (_.version() < SPV_SPIRV_VERSION_WORD(1, 3)) { + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::TessellationControl && + model != spv::ExecutionModel::GLCompute && + model != spv::ExecutionModel::Kernel && + model != spv::ExecutionModel::TaskNV && + model != spv::ExecutionModel::MeshNV) { + if (message) { + *message = + "OpControlBarrier requires one of the following " + "Execution " + "Models: TessellationControl, GLCompute, Kernel, " + "MeshNV or TaskNV"; + } + return false; + } + return true; + }); + } + + const uint32_t execution_scope = inst->word(1); + const uint32_t memory_scope = inst->word(2); + + if (auto error = ValidateExecutionScope(_, inst, execution_scope)) { + return error; + } + + if (auto error = ValidateMemoryScope(_, inst, memory_scope)) { + return error; + } + + if (auto error = ValidateMemorySemantics(_, inst, 2, memory_scope)) { + return error; + } + break; + } + + case spv::Op::OpMemoryBarrier: { + const uint32_t memory_scope = inst->word(1); + + if (auto error = ValidateMemoryScope(_, inst, memory_scope)) { + return error; + } + + if (auto error = ValidateMemorySemantics(_, inst, 1, memory_scope)) { + return error; + } + break; + } + + case spv::Op::OpNamedBarrierInitialize: { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeNamedBarrier) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Result Type to be OpTypeNamedBarrier"; + } + + const uint32_t subgroup_count_type = _.GetOperandTypeId(inst, 2); + if (!_.IsIntScalarType(subgroup_count_type) || + _.GetBitWidth(subgroup_count_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Subgroup Count to be a 32-bit int"; + } + break; + } + + case spv::Op::OpMemoryNamedBarrier: { + const uint32_t named_barrier_type = _.GetOperandTypeId(inst, 0); + if (_.GetIdOpcode(named_barrier_type) != spv::Op::OpTypeNamedBarrier) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Named Barrier to be of type OpTypeNamedBarrier"; + } + + const uint32_t memory_scope = inst->word(2); + + if (auto error = ValidateMemoryScope(_, inst, memory_scope)) { + return error; + } + + if (auto error = ValidateMemorySemantics(_, inst, 2, memory_scope)) { + return error; + } + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_bitwise.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_bitwise.cpp new file mode 100644 index 000000000000..d8d995814d51 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_bitwise.cpp @@ -0,0 +1,232 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of bitwise instructions. + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +// Validates when base and result need to be the same type +spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst, + const uint32_t base_type) { + const spv::Op opcode = inst->opcode(); + + if (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4781) + << "Expected int scalar or vector type for Base operand: " + << spvOpcodeString(opcode); + } + + // Vulkan has a restriction to 32 bit for base + if (spvIsVulkanEnv(_.context()->target_env)) { + if (_.GetBitWidth(base_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4781) + << "Expected 32-bit int type for Base operand: " + << spvOpcodeString(opcode); + } + } + + // OpBitCount just needs same number of components + if (base_type != inst->type_id() && opcode != spv::Op::OpBitCount) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Base Type to be equal to Result Type: " + << spvOpcodeString(opcode); + } + + return SPV_SUCCESS; +} + +// Validates correctness of bitwise instructions. +spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + switch (opcode) { + case spv::Op::OpShiftRightLogical: + case spv::Op::OpShiftRightArithmetic: + case spv::Op::OpShiftLeftLogical: { + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t result_dimension = _.GetDimension(result_type); + const uint32_t base_type = _.GetOperandTypeId(inst, 2); + const uint32_t shift_type = _.GetOperandTypeId(inst, 3); + + if (!base_type || + (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Base to be int scalar or vector: " + << spvOpcodeString(opcode); + + if (_.GetDimension(base_type) != result_dimension) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Base to have the same dimension " + << "as Result Type: " << spvOpcodeString(opcode); + + if (_.GetBitWidth(base_type) != _.GetBitWidth(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Base to have the same bit width " + << "as Result Type: " << spvOpcodeString(opcode); + + if (!shift_type || + (!_.IsIntScalarType(shift_type) && !_.IsIntVectorType(shift_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Shift to be int scalar or vector: " + << spvOpcodeString(opcode); + + if (_.GetDimension(shift_type) != result_dimension) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Shift to have the same dimension " + << "as Result Type: " << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpBitwiseOr: + case spv::Op::OpBitwiseXor: + case spv::Op::OpBitwiseAnd: + case spv::Op::OpNot: { + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t result_dimension = _.GetDimension(result_type); + const uint32_t result_bit_width = _.GetBitWidth(result_type); + + for (size_t operand_index = 2; operand_index < inst->operands().size(); + ++operand_index) { + const uint32_t type_id = _.GetOperandTypeId(inst, operand_index); + if (!type_id || + (!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector as operand: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; + + if (_.GetDimension(type_id) != result_dimension) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operands to have the same dimension " + << "as Result Type: " << spvOpcodeString(opcode) + << " operand index " << operand_index; + + if (_.GetBitWidth(type_id) != result_bit_width) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operands to have the same bit width " + << "as Result Type: " << spvOpcodeString(opcode) + << " operand index " << operand_index; + } + break; + } + + case spv::Op::OpBitFieldInsert: { + const uint32_t base_type = _.GetOperandTypeId(inst, 2); + const uint32_t insert_type = _.GetOperandTypeId(inst, 3); + const uint32_t offset_type = _.GetOperandTypeId(inst, 4); + const uint32_t count_type = _.GetOperandTypeId(inst, 5); + + if (spv_result_t error = ValidateBaseType(_, inst, base_type)) { + return error; + } + + if (insert_type != result_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Insert Type to be equal to Result Type: " + << spvOpcodeString(opcode); + + if (!offset_type || !_.IsIntScalarType(offset_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Offset Type to be int scalar: " + << spvOpcodeString(opcode); + + if (!count_type || !_.IsIntScalarType(count_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Count Type to be int scalar: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpBitFieldSExtract: + case spv::Op::OpBitFieldUExtract: { + const uint32_t base_type = _.GetOperandTypeId(inst, 2); + const uint32_t offset_type = _.GetOperandTypeId(inst, 3); + const uint32_t count_type = _.GetOperandTypeId(inst, 4); + + if (spv_result_t error = ValidateBaseType(_, inst, base_type)) { + return error; + } + + if (!offset_type || !_.IsIntScalarType(offset_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Offset Type to be int scalar: " + << spvOpcodeString(opcode); + + if (!count_type || !_.IsIntScalarType(count_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Count Type to be int scalar: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpBitReverse: { + const uint32_t base_type = _.GetOperandTypeId(inst, 2); + + if (spv_result_t error = ValidateBaseType(_, inst, base_type)) { + return error; + } + + break; + } + + case spv::Op::OpBitCount: { + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t base_type = _.GetOperandTypeId(inst, 2); + + if (spv_result_t error = ValidateBaseType(_, inst, base_type)) { + return error; + } + + const uint32_t base_dimension = _.GetDimension(base_type); + const uint32_t result_dimension = _.GetDimension(result_type); + + if (base_dimension != result_dimension) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Base dimension to be equal to Result Type " + "dimension: " + << spvOpcodeString(opcode); + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_builtins.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_builtins.cpp new file mode 100644 index 000000000000..a7e9942a0ff9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_builtins.cpp @@ -0,0 +1,4561 @@ +// Copyright (c) 2018 Google LLC. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of built-in variables. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/util/bitutils.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Returns a short textual description of the id defined by the given +// instruction. +std::string GetIdDesc(const Instruction& inst) { + std::ostringstream ss; + ss << "ID <" << inst.id() << "> (Op" << spvOpcodeString(inst.opcode()) << ")"; + return ss.str(); +} + +// Gets underlying data type which is +// - member type if instruction is OpTypeStruct +// (member index is taken from decoration). +// - data type if id creates a pointer. +// - type of the constant if instruction is OpConst or OpSpecConst. +// +// Fails in any other case. The function is based on built-ins allowed by +// the Vulkan spec. +// TODO: If non-Vulkan validation rules are added then it might need +// to be refactored. +spv_result_t GetUnderlyingType(ValidationState_t& _, + const Decoration& decoration, + const Instruction& inst, + uint32_t* underlying_type) { + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + if (inst.opcode() != spv::Op::OpTypeStruct) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << GetIdDesc(inst) + << "Attempted to get underlying data type via member index for " + "non-struct type."; + } + *underlying_type = inst.word(decoration.struct_member_index() + 2); + return SPV_SUCCESS; + } + + if (inst.opcode() == spv::Op::OpTypeStruct) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << GetIdDesc(inst) + << " did not find an member index to get underlying data type for " + "struct type."; + } + + if (spvOpcodeIsConstant(inst.opcode())) { + *underlying_type = inst.type_id(); + return SPV_SUCCESS; + } + + spv::StorageClass storage_class; + if (!_.GetPointerTypeInfo(inst.type_id(), underlying_type, &storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << GetIdDesc(inst) + << " is decorated with BuiltIn. BuiltIn decoration should only be " + "applied to struct types, variables and constants."; + } + return SPV_SUCCESS; +} + +// Returns Storage Class used by the instruction if applicable. +// Returns spv::StorageClass::Max if not. +spv::StorageClass GetStorageClass(const Instruction& inst) { + switch (inst.opcode()) { + case spv::Op::OpTypePointer: + case spv::Op::OpTypeForwardPointer: { + return spv::StorageClass(inst.word(2)); + } + case spv::Op::OpVariable: { + return spv::StorageClass(inst.word(3)); + } + case spv::Op::OpGenericCastToPtrExplicit: { + return spv::StorageClass(inst.word(4)); + } + default: { break; } + } + return spv::StorageClass::Max; +} + +typedef enum VUIDError_ { + VUIDErrorExecutionModel = 0, + VUIDErrorStorageClass = 1, + VUIDErrorType = 2, + VUIDErrorMax, +} VUIDError; + +const static uint32_t NumVUIDBuiltins = 39; + +typedef struct { + spv::BuiltIn builtIn; + uint32_t vuid[VUIDErrorMax]; // execution mode, storage class, type VUIDs +} BuiltinVUIDMapping; + +// Many built-ins have the same checks (Storage Class, Type, etc) +// This table provides a nice LUT for the VUIDs +std::array builtinVUIDInfo = {{ + // clang-format off + {spv::BuiltIn::SubgroupEqMask, {0, 4370, 4371}}, + {spv::BuiltIn::SubgroupGeMask, {0, 4372, 4373}}, + {spv::BuiltIn::SubgroupGtMask, {0, 4374, 4375}}, + {spv::BuiltIn::SubgroupLeMask, {0, 4376, 4377}}, + {spv::BuiltIn::SubgroupLtMask, {0, 4378, 4379}}, + {spv::BuiltIn::SubgroupLocalInvocationId, {0, 4380, 4381}}, + {spv::BuiltIn::SubgroupSize, {0, 4382, 4383}}, + {spv::BuiltIn::GlobalInvocationId, {4236, 4237, 4238}}, + {spv::BuiltIn::LocalInvocationId, {4281, 4282, 4283}}, + {spv::BuiltIn::NumWorkgroups, {4296, 4297, 4298}}, + {spv::BuiltIn::NumSubgroups, {4293, 4294, 4295}}, + {spv::BuiltIn::SubgroupId, {4367, 4368, 4369}}, + {spv::BuiltIn::WorkgroupId, {4422, 4423, 4424}}, + {spv::BuiltIn::HitKindKHR, {4242, 4243, 4244}}, + {spv::BuiltIn::HitTNV, {4245, 4246, 4247}}, + {spv::BuiltIn::InstanceCustomIndexKHR, {4251, 4252, 4253}}, + {spv::BuiltIn::InstanceId, {4254, 4255, 4256}}, + {spv::BuiltIn::RayGeometryIndexKHR, {4345, 4346, 4347}}, + {spv::BuiltIn::ObjectRayDirectionKHR, {4299, 4300, 4301}}, + {spv::BuiltIn::ObjectRayOriginKHR, {4302, 4303, 4304}}, + {spv::BuiltIn::ObjectToWorldKHR, {4305, 4306, 4307}}, + {spv::BuiltIn::WorldToObjectKHR, {4434, 4435, 4436}}, + {spv::BuiltIn::IncomingRayFlagsKHR, {4248, 4249, 4250}}, + {spv::BuiltIn::RayTminKHR, {4351, 4352, 4353}}, + {spv::BuiltIn::RayTmaxKHR, {4348, 4349, 4350}}, + {spv::BuiltIn::WorldRayDirectionKHR, {4428, 4429, 4430}}, + {spv::BuiltIn::WorldRayOriginKHR, {4431, 4432, 4433}}, + {spv::BuiltIn::LaunchIdKHR, {4266, 4267, 4268}}, + {spv::BuiltIn::LaunchSizeKHR, {4269, 4270, 4271}}, + {spv::BuiltIn::FragInvocationCountEXT, {4217, 4218, 4219}}, + {spv::BuiltIn::FragSizeEXT, {4220, 4221, 4222}}, + {spv::BuiltIn::FragStencilRefEXT, {4223, 4224, 4225}}, + {spv::BuiltIn::FullyCoveredEXT, {4232, 4233, 4234}}, + {spv::BuiltIn::CullMaskKHR, {6735, 6736, 6737}}, + {spv::BuiltIn::BaryCoordKHR, {4154, 4155, 4156}}, + {spv::BuiltIn::BaryCoordNoPerspKHR, {4160, 4161, 4162}}, + {spv::BuiltIn::PrimitivePointIndicesEXT, {7041, 7043, 7044}}, + {spv::BuiltIn::PrimitiveLineIndicesEXT, {7047, 7049, 7050}}, + {spv::BuiltIn::PrimitiveTriangleIndicesEXT, {7053, 7055, 7056}}, + // clang-format on +}}; + +uint32_t GetVUIDForBuiltin(spv::BuiltIn builtIn, VUIDError type) { + uint32_t vuid = 0; + for (const auto& iter: builtinVUIDInfo) { + if (iter.builtIn == builtIn) { + assert(type < VUIDErrorMax); + vuid = iter.vuid[type]; + break; + } + } + return vuid; +} + +bool IsExecutionModelValidForRtBuiltIn(spv::BuiltIn builtin, + spv::ExecutionModel stage) { + switch (builtin) { + case spv::BuiltIn::HitKindKHR: + case spv::BuiltIn::HitTNV: + if (stage == spv::ExecutionModel::AnyHitKHR || + stage == spv::ExecutionModel::ClosestHitKHR) { + return true; + } + break; + case spv::BuiltIn::InstanceCustomIndexKHR: + case spv::BuiltIn::InstanceId: + case spv::BuiltIn::RayGeometryIndexKHR: + case spv::BuiltIn::ObjectRayDirectionKHR: + case spv::BuiltIn::ObjectRayOriginKHR: + case spv::BuiltIn::ObjectToWorldKHR: + case spv::BuiltIn::WorldToObjectKHR: + switch (stage) { + case spv::ExecutionModel::IntersectionKHR: + case spv::ExecutionModel::AnyHitKHR: + case spv::ExecutionModel::ClosestHitKHR: + return true; + default: + return false; + } + break; + case spv::BuiltIn::IncomingRayFlagsKHR: + case spv::BuiltIn::RayTminKHR: + case spv::BuiltIn::RayTmaxKHR: + case spv::BuiltIn::WorldRayDirectionKHR: + case spv::BuiltIn::WorldRayOriginKHR: + case spv::BuiltIn::CullMaskKHR: + switch (stage) { + case spv::ExecutionModel::IntersectionKHR: + case spv::ExecutionModel::AnyHitKHR: + case spv::ExecutionModel::ClosestHitKHR: + case spv::ExecutionModel::MissKHR: + return true; + default: + return false; + } + break; + case spv::BuiltIn::LaunchIdKHR: + case spv::BuiltIn::LaunchSizeKHR: + switch (stage) { + case spv::ExecutionModel::RayGenerationKHR: + case spv::ExecutionModel::IntersectionKHR: + case spv::ExecutionModel::AnyHitKHR: + case spv::ExecutionModel::ClosestHitKHR: + case spv::ExecutionModel::MissKHR: + case spv::ExecutionModel::CallableKHR: + return true; + default: + return false; + } + break; + default: + break; + } + return false; +} + +// Helper class managing validation of built-ins. +// TODO: Generic functionality of this class can be moved into +// ValidationState_t to be made available to other users. +class BuiltInsValidator { + public: + BuiltInsValidator(ValidationState_t& vstate) : _(vstate) {} + + // Run validation. + spv_result_t Run(); + + private: + // Goes through all decorations in the module, if decoration is BuiltIn + // calls ValidateSingleBuiltInAtDefinition(). + spv_result_t ValidateBuiltInsAtDefinition(); + + // Validates the instruction defining an id with built-in decoration. + // Can be called multiple times for the same id, if multiple built-ins are + // specified. Seeds id_to_at_reference_checks_ with decorated ids if needed. + spv_result_t ValidateSingleBuiltInAtDefinition(const Decoration& decoration, + const Instruction& inst); + + // The following section contains functions which are called when id defined + // by |inst| is decorated with BuiltIn |decoration|. + // Most functions are specific to a single built-in and have naming scheme: + // ValidateXYZAtDefinition. Some functions are common to multiple kinds of + // BuiltIn. + spv_result_t ValidateClipOrCullDistanceAtDefinition( + const Decoration& decoration, const Instruction& inst); + spv_result_t ValidateFragCoordAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateFragDepthAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateFrontFacingAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateHelperInvocationAtDefinition( + const Decoration& decoration, const Instruction& inst); + spv_result_t ValidateInvocationIdAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateInstanceIndexAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateLayerOrViewportIndexAtDefinition( + const Decoration& decoration, const Instruction& inst); + spv_result_t ValidatePatchVerticesAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidatePointCoordAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidatePointSizeAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidatePositionAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidatePrimitiveIdAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateSampleIdAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateSampleMaskAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateSamplePositionAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateTessCoordAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateTessLevelOuterAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateTessLevelInnerAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateVertexIndexAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateVertexIdAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateLocalInvocationIndexAtDefinition( + const Decoration& decoration, const Instruction& inst); + spv_result_t ValidateWorkgroupSizeAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateBaseInstanceOrVertexAtDefinition( + const Decoration& decoration, const Instruction& inst); + spv_result_t ValidateDrawIndexAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateViewIndexAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateDeviceIndexAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateFragInvocationCountAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateFragSizeAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateFragStencilRefAtDefinition(const Decoration& decoration, + const Instruction& inst); + spv_result_t ValidateFullyCoveredAtDefinition(const Decoration& decoration, + const Instruction& inst); + // Used for GlobalInvocationId, LocalInvocationId, NumWorkgroups, WorkgroupId. + spv_result_t ValidateComputeShaderI32Vec3InputAtDefinition( + const Decoration& decoration, const Instruction& inst); + spv_result_t ValidateNVSMOrARMCoreBuiltinsAtDefinition(const Decoration& decoration, + const Instruction& inst); + // Used for BaryCoord, BaryCoordNoPersp. + spv_result_t ValidateFragmentShaderF32Vec3InputAtDefinition( + const Decoration& decoration, const Instruction& inst); + // Used for SubgroupEqMask, SubgroupGeMask, SubgroupGtMask, SubgroupLtMask, + // SubgroupLeMask. + spv_result_t ValidateI32Vec4InputAtDefinition(const Decoration& decoration, + const Instruction& inst); + // Used for SubgroupLocalInvocationId, SubgroupSize. + spv_result_t ValidateI32InputAtDefinition(const Decoration& decoration, + const Instruction& inst); + // Used for SubgroupId, NumSubgroups. + spv_result_t ValidateComputeI32InputAtDefinition(const Decoration& decoration, + const Instruction& inst); + + spv_result_t ValidatePrimitiveShadingRateAtDefinition( + const Decoration& decoration, const Instruction& inst); + + spv_result_t ValidateShadingRateAtDefinition(const Decoration& decoration, + const Instruction& inst); + + spv_result_t ValidateRayTracingBuiltinsAtDefinition( + const Decoration& decoration, const Instruction& inst); + + spv_result_t ValidateMeshShadingEXTBuiltinsAtDefinition( + const Decoration& decoration, const Instruction& inst); + + // The following section contains functions which are called when id defined + // by |referenced_inst| is + // 1. referenced by |referenced_from_inst| + // 2. dependent on |built_in_inst| which is decorated with BuiltIn + // |decoration|. Most functions are specific to a single built-in and have + // naming scheme: ValidateXYZAtReference. Some functions are common to + // multiple kinds of BuiltIn. + spv_result_t ValidateFragCoordAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateFragDepthAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateFrontFacingAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateHelperInvocationAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateInvocationIdAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateInstanceIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidatePatchVerticesAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidatePointCoordAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidatePointSizeAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidatePositionAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidatePrimitiveIdAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateSampleIdAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateSampleMaskAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateSamplePositionAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateTessCoordAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateTessLevelAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateLocalInvocationIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateVertexIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateLayerOrViewportIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateWorkgroupSizeAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateClipOrCullDistanceAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateBaseInstanceOrVertexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateDrawIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateViewIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateDeviceIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateFragInvocationCountAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateFragSizeAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateFragStencilRefAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateFullyCoveredAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + // Used for GlobalInvocationId, LocalInvocationId, NumWorkgroups, WorkgroupId. + spv_result_t ValidateComputeShaderI32Vec3InputAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + // Used for BaryCoord, BaryCoordNoPersp. + spv_result_t ValidateFragmentShaderF32Vec3InputAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + // Used for SubgroupId and NumSubgroups. + spv_result_t ValidateComputeI32InputAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateNVSMOrARMCoreBuiltinsAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidatePrimitiveShadingRateAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateShadingRateAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateRayTracingBuiltinsAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + spv_result_t ValidateMeshShadingEXTBuiltinsAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + // Validates that |built_in_inst| is not (even indirectly) referenced from + // within a function which can be called with |execution_model|. + // + // |vuid| - Vulkan ID for the error, or a negative value if none. + // |comment| - text explaining why the restriction was imposed. + // |decoration| - BuiltIn decoration which causes the restriction. + // |referenced_inst| - instruction which is dependent on |built_in_inst| and + // defines the id which was referenced. + // |referenced_from_inst| - instruction which references id defined by + // |referenced_inst| from within a function. + spv_result_t ValidateNotCalledWithExecutionModel( + int vuid, const char* comment, spv::ExecutionModel execution_model, + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst); + + // The following section contains functions which check that the decorated + // variable has the type specified in the function name. |diag| would be + // called with a corresponding error message, if validation is not successful. + spv_result_t ValidateBool( + const Decoration& decoration, const Instruction& inst, + const std::function& diag); + spv_result_t ValidateI( + const Decoration& decoration, const Instruction& inst, + const std::function& diag); + spv_result_t ValidateI32( + const Decoration& decoration, const Instruction& inst, + const std::function& diag); + spv_result_t ValidateI32Vec( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag); + spv_result_t ValidateI32Arr( + const Decoration& decoration, const Instruction& inst, + const std::function& diag); + spv_result_t ValidateArrayedI32Vec( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag); + spv_result_t ValidateOptionalArrayedI32( + const Decoration& decoration, const Instruction& inst, + const std::function& diag); + spv_result_t ValidateI32Helper( + const Decoration& decoration, const Instruction& inst, + const std::function& diag, + uint32_t underlying_type); + spv_result_t ValidateF32( + const Decoration& decoration, const Instruction& inst, + const std::function& diag); + spv_result_t ValidateOptionalArrayedF32( + const Decoration& decoration, const Instruction& inst, + const std::function& diag); + spv_result_t ValidateF32Helper( + const Decoration& decoration, const Instruction& inst, + const std::function& diag, + uint32_t underlying_type); + spv_result_t ValidateF32Vec( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag); + spv_result_t ValidateOptionalArrayedF32Vec( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag); + spv_result_t ValidateF32VecHelper( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag, + uint32_t underlying_type); + // If |num_components| is zero, the number of components is not checked. + spv_result_t ValidateF32Arr( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag); + spv_result_t ValidateOptionalArrayedF32Arr( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag); + spv_result_t ValidateF32ArrHelper( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag, + uint32_t underlying_type); + spv_result_t ValidateF32Mat( + const Decoration& decoration, const Instruction& inst, + uint32_t req_num_rows, uint32_t req_num_columns, + const std::function& diag); + + // Generates strings like "Member #0 of struct ID <2>". + std::string GetDefinitionDesc(const Decoration& decoration, + const Instruction& inst) const; + + // Generates strings like "ID <51> (OpTypePointer) is referencing ID <2> + // (OpTypeStruct) which is decorated with BuiltIn Position". + std::string GetReferenceDesc( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst, + spv::ExecutionModel execution_model = spv::ExecutionModel::Max) const; + + // Generates strings like "ID <51> (OpTypePointer) uses storage class + // UniformConstant". + std::string GetStorageClassDesc(const Instruction& inst) const; + + // Updates inner working of the class. Is called sequentially for every + // instruction. + void Update(const Instruction& inst); + + ValidationState_t& _; + + // Mapping id -> list of rules which validate instruction referencing the + // id. Rules can create new rules and add them to this container. + // Using std::map, and not std::unordered_map to avoid iterator invalidation + // during rehashing. + std::map>> + id_to_at_reference_checks_; + + // Id of the function we are currently inside. 0 if not inside a function. + uint32_t function_id_ = 0; + + // Entry points which can (indirectly) call the current function. + // The pointer either points to a vector inside to function_to_entry_points_ + // or to no_entry_points_. The pointer is guaranteed to never be null. + const std::vector no_entry_points; + const std::vector* entry_points_ = &no_entry_points; + + // Execution models with which the current function can be called. + std::set execution_models_; +}; + +void BuiltInsValidator::Update(const Instruction& inst) { + const spv::Op opcode = inst.opcode(); + if (opcode == spv::Op::OpFunction) { + // Entering a function. + assert(function_id_ == 0); + function_id_ = inst.id(); + execution_models_.clear(); + entry_points_ = &_.FunctionEntryPoints(function_id_); + // Collect execution models from all entry points from which the current + // function can be called. + for (const uint32_t entry_point : *entry_points_) { + if (const auto* models = _.GetExecutionModels(entry_point)) { + execution_models_.insert(models->begin(), models->end()); + } + } + } + + if (opcode == spv::Op::OpFunctionEnd) { + // Exiting a function. + assert(function_id_ != 0); + function_id_ = 0; + entry_points_ = &no_entry_points; + execution_models_.clear(); + } +} + +std::string BuiltInsValidator::GetDefinitionDesc( + const Decoration& decoration, const Instruction& inst) const { + std::ostringstream ss; + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + assert(inst.opcode() == spv::Op::OpTypeStruct); + ss << "Member #" << decoration.struct_member_index(); + ss << " of struct ID <" << inst.id() << ">"; + } else { + ss << GetIdDesc(inst); + } + return ss.str(); +} + +std::string BuiltInsValidator::GetReferenceDesc( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, const Instruction& referenced_from_inst, + spv::ExecutionModel execution_model) const { + std::ostringstream ss; + ss << GetIdDesc(referenced_from_inst) << " is referencing " + << GetIdDesc(referenced_inst); + if (built_in_inst.id() != referenced_inst.id()) { + ss << " which is dependent on " << GetIdDesc(built_in_inst); + } + + ss << " which is decorated with BuiltIn "; + ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]); + if (function_id_) { + ss << " in function <" << function_id_ << ">"; + if (execution_model != spv::ExecutionModel::Max) { + ss << " called with execution model "; + ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_EXECUTION_MODEL, + uint32_t(execution_model)); + } + } + ss << "."; + return ss.str(); +} + +std::string BuiltInsValidator::GetStorageClassDesc( + const Instruction& inst) const { + std::ostringstream ss; + ss << GetIdDesc(inst) << " uses storage class "; + ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_STORAGE_CLASS, + uint32_t(GetStorageClass(inst))); + ss << "."; + return ss.str(); +} + +spv_result_t BuiltInsValidator::ValidateBool( + const Decoration& decoration, const Instruction& inst, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + if (!_.IsBoolScalarType(underlying_type)) { + return diag(GetDefinitionDesc(decoration, inst) + " is not a bool scalar."); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateI( + const Decoration& decoration, const Instruction& inst, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + if (!_.IsIntScalarType(underlying_type)) { + return diag(GetDefinitionDesc(decoration, inst) + " is not an int scalar."); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateI32( + const Decoration& decoration, const Instruction& inst, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + return ValidateI32Helper(decoration, inst, diag, underlying_type); +} + +spv_result_t BuiltInsValidator::ValidateOptionalArrayedI32( + const Decoration& decoration, const Instruction& inst, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + // Strip the array, if present. + if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { + underlying_type = _.FindDef(underlying_type)->word(2u); + } + + return ValidateI32Helper(decoration, inst, diag, underlying_type); +} + +spv_result_t BuiltInsValidator::ValidateI32Helper( + const Decoration& decoration, const Instruction& inst, + const std::function& diag, + uint32_t underlying_type) { + if (!_.IsIntScalarType(underlying_type)) { + return diag(GetDefinitionDesc(decoration, inst) + " is not an int scalar."); + } + + const uint32_t bit_width = _.GetBitWidth(underlying_type); + if (bit_width != 32) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) << " has bit width " << bit_width + << "."; + return diag(ss.str()); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32( + const Decoration& decoration, const Instruction& inst, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + // Strip the array, if present. + if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { + underlying_type = _.FindDef(underlying_type)->word(2u); + } + + return ValidateF32Helper(decoration, inst, diag, underlying_type); +} + +spv_result_t BuiltInsValidator::ValidateF32( + const Decoration& decoration, const Instruction& inst, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + return ValidateF32Helper(decoration, inst, diag, underlying_type); +} + +spv_result_t BuiltInsValidator::ValidateF32Helper( + const Decoration& decoration, const Instruction& inst, + const std::function& diag, + uint32_t underlying_type) { + if (!_.IsFloatScalarType(underlying_type)) { + return diag(GetDefinitionDesc(decoration, inst) + + " is not a float scalar."); + } + + const uint32_t bit_width = _.GetBitWidth(underlying_type); + if (bit_width != 32) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) << " has bit width " << bit_width + << "."; + return diag(ss.str()); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateI32Vec( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + if (!_.IsIntVectorType(underlying_type)) { + return diag(GetDefinitionDesc(decoration, inst) + " is not an int vector."); + } + + const uint32_t actual_num_components = _.GetDimension(underlying_type); + if (_.GetDimension(underlying_type) != num_components) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) << " has " + << actual_num_components << " components."; + return diag(ss.str()); + } + + const uint32_t bit_width = _.GetBitWidth(underlying_type); + if (bit_width != 32) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) + << " has components with bit width " << bit_width << "."; + return diag(ss.str()); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateArrayedI32Vec( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + const Instruction* const type_inst = _.FindDef(underlying_type); + if (type_inst->opcode() != spv::Op::OpTypeArray) { + return diag(GetDefinitionDesc(decoration, inst) + " is not an array."); + } + + const uint32_t component_type = type_inst->word(2); + if (!_.IsIntVectorType(component_type)) { + return diag(GetDefinitionDesc(decoration, inst) + " is not an int vector."); + } + + const uint32_t actual_num_components = _.GetDimension(component_type); + if (_.GetDimension(component_type) != num_components) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) << " has " + << actual_num_components << " components."; + return diag(ss.str()); + } + + const uint32_t bit_width = _.GetBitWidth(component_type); + if (bit_width != 32) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) + << " has components with bit width " << bit_width << "."; + return diag(ss.str()); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32Vec( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + // Strip the array, if present. + if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { + underlying_type = _.FindDef(underlying_type)->word(2u); + } + + return ValidateF32VecHelper(decoration, inst, num_components, diag, + underlying_type); +} + +spv_result_t BuiltInsValidator::ValidateF32Vec( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + return ValidateF32VecHelper(decoration, inst, num_components, diag, + underlying_type); +} + +spv_result_t BuiltInsValidator::ValidateF32VecHelper( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag, + uint32_t underlying_type) { + if (!_.IsFloatVectorType(underlying_type)) { + return diag(GetDefinitionDesc(decoration, inst) + + " is not a float vector."); + } + + const uint32_t actual_num_components = _.GetDimension(underlying_type); + if (_.GetDimension(underlying_type) != num_components) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) << " has " + << actual_num_components << " components."; + return diag(ss.str()); + } + + const uint32_t bit_width = _.GetBitWidth(underlying_type); + if (bit_width != 32) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) + << " has components with bit width " << bit_width << "."; + return diag(ss.str()); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateI32Arr( + const Decoration& decoration, const Instruction& inst, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + const Instruction* const type_inst = _.FindDef(underlying_type); + if (type_inst->opcode() != spv::Op::OpTypeArray) { + return diag(GetDefinitionDesc(decoration, inst) + " is not an array."); + } + + const uint32_t component_type = type_inst->word(2); + if (!_.IsIntScalarType(component_type)) { + return diag(GetDefinitionDesc(decoration, inst) + + " components are not int scalar."); + } + + const uint32_t bit_width = _.GetBitWidth(component_type); + if (bit_width != 32) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) + << " has components with bit width " << bit_width << "."; + return diag(ss.str()); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateF32Arr( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + return ValidateF32ArrHelper(decoration, inst, num_components, diag, + underlying_type); +} + +spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32Arr( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag) { + uint32_t underlying_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + + // Strip an extra layer of arraying if present. + if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { + uint32_t subtype = _.FindDef(underlying_type)->word(2u); + if (_.GetIdOpcode(subtype) == spv::Op::OpTypeArray) { + underlying_type = subtype; + } + } + + return ValidateF32ArrHelper(decoration, inst, num_components, diag, + underlying_type); +} + +spv_result_t BuiltInsValidator::ValidateF32ArrHelper( + const Decoration& decoration, const Instruction& inst, + uint32_t num_components, + const std::function& diag, + uint32_t underlying_type) { + const Instruction* const type_inst = _.FindDef(underlying_type); + if (type_inst->opcode() != spv::Op::OpTypeArray) { + return diag(GetDefinitionDesc(decoration, inst) + " is not an array."); + } + + const uint32_t component_type = type_inst->word(2); + if (!_.IsFloatScalarType(component_type)) { + return diag(GetDefinitionDesc(decoration, inst) + + " components are not float scalar."); + } + + const uint32_t bit_width = _.GetBitWidth(component_type); + if (bit_width != 32) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) + << " has components with bit width " << bit_width << "."; + return diag(ss.str()); + } + + if (num_components != 0) { + uint64_t actual_num_components = 0; + if (!_.EvalConstantValUint64(type_inst->word(3), &actual_num_components)) { + assert(0 && "Array type definition is corrupt"); + } + if (actual_num_components != num_components) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) << " has " + << actual_num_components << " components."; + return diag(ss.str()); + } + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateF32Mat( + const Decoration& decoration, const Instruction& inst, + uint32_t req_num_rows, uint32_t req_num_columns, + const std::function& diag) { + uint32_t underlying_type = 0; + uint32_t num_rows = 0; + uint32_t num_cols = 0; + uint32_t col_type = 0; + uint32_t component_type = 0; + if (spv_result_t error = + GetUnderlyingType(_, decoration, inst, &underlying_type)) { + return error; + } + if (!_.GetMatrixTypeInfo(underlying_type, &num_rows, &num_cols, &col_type, + &component_type) || + num_rows != req_num_rows || num_cols != req_num_columns) { + std::ostringstream ss; + ss << GetDefinitionDesc(decoration, inst) << " has columns " << num_cols + << " and rows " << num_rows << " not equal to expected " + << req_num_columns << "x" << req_num_rows << "."; + return diag(ss.str()); + } + + return ValidateF32VecHelper(decoration, inst, req_num_rows, diag, col_type); +} + +spv_result_t BuiltInsValidator::ValidateNotCalledWithExecutionModel( + int vuid, const char* comment, spv::ExecutionModel execution_model, + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (function_id_) { + if (execution_models_.count(execution_model)) { + const char* execution_model_str = _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model)); + const char* built_in_str = _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << (vuid < 0 ? std::string("") : _.VkErrorID(vuid)) << comment + << " " << GetIdDesc(referenced_inst) << " depends on " + << GetIdDesc(built_in_inst) << " which is decorated with BuiltIn " + << built_in_str << "." + << " Id <" << referenced_inst.id() << "> is later referenced by " + << GetIdDesc(referenced_from_inst) << " in function <" + << function_id_ << "> which is called with execution model " + << execution_model_str << "."; + } + } else { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, + vuid, comment, execution_model, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtDefinition( + const Decoration& decoration, const Instruction& inst) { + // Seed at reference checks with this built-in. + return ValidateClipOrCullDistanceAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + uint32_t operand = decoration.params()[0]; + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4190 : 4199; + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be only used for variables with Input or Output storage " + "class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + if (storage_class == spv::StorageClass::Input) { + assert(function_id_ == 0); + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4188 : 4197; + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, + "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " + "used for variables with Input storage class if execution model is " + "Vertex.", + spv::ExecutionModel::Vertex, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, + "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " + "used for variables with Input storage class if execution model is " + "MeshNV.", + spv::ExecutionModel::MeshNV, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, + "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " + "used for variables with Input storage class if execution model is " + "MeshEXT.", + spv::ExecutionModel::MeshEXT, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + + if (storage_class == spv::StorageClass::Output) { + assert(function_id_ == 0); + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4189 : 4198; + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, + "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " + "used for variables with Output storage class if execution model is " + "Fragment.", + spv::ExecutionModel::Fragment, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + switch (execution_model) { + case spv::ExecutionModel::Fragment: + case spv::ExecutionModel::Vertex: { + if (spv_result_t error = ValidateF32Arr( + decoration, built_in_inst, /* Any number of components */ 0, + [this, &decoration, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + uint32_t vuid = + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + ? 4191 + : 4200; + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit float array. " + << message; + })) { + return error; + } + break; + } + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: { + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + // The outer level of array is applied on the variable. + if (spv_result_t error = ValidateF32Arr( + decoration, built_in_inst, /* Any number of components */ 0, + [this, &decoration, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + uint32_t vuid = + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + ? 4191 + : 4200; + return _.diag(SPV_ERROR_INVALID_DATA, + &referenced_from_inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit float array. " + << message; + })) { + return error; + } + } else { + if (spv_result_t error = ValidateOptionalArrayedF32Arr( + decoration, built_in_inst, /* Any number of components */ 0, + [this, &decoration, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + uint32_t vuid = + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + ? 4191 + : 4200; + return _.diag(SPV_ERROR_INVALID_DATA, + &referenced_from_inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit float array. " + << message; + })) { + return error; + } + } + break; + } + + default: { + uint32_t vuid = + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4187 : 4196; + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be used only with Fragment, Vertex, " + "TessellationControl, TessellationEvaluation or Geometry " + "execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateClipOrCullDistanceAtReference, + this, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateFragCoordAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateF32Vec( + decoration, inst, 4, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4212) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn FragCoord " + "variable needs to be a 4-component 32-bit float " + "vector. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateFragCoordAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateFragCoordAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4211) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn FragCoord to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4210) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn FragCoord to be used only with " + "Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateFragCoordAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateFragDepthAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateF32( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4215) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn FragDepth " + "variable needs to be a 32-bit float scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateFragDepthAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Output) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4214) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn FragDepth to be only used for " + "variables with Output storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4213) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn FragDepth to be used only with " + "Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + + for (const uint32_t entry_point : *entry_points_) { + // Every entry point from which this function is called needs to have + // Execution Mode DepthReplacing. + const auto* modes = _.GetExecutionModes(entry_point); + if (!modes || !modes->count(spv::ExecutionMode::DepthReplacing)) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4216) + << spvLogStringForEnv(_.context()->target_env) + << " spec requires DepthReplacing execution mode to be " + "declared when using BuiltIn FragDepth. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateFragDepthAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateFrontFacingAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateBool( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4231) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn FrontFacing " + "variable needs to be a bool scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateFrontFacingAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateFrontFacingAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4230) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn FrontFacing to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4229) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn FrontFacing to be used only with " + "Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateFrontFacingAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateHelperInvocationAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateBool( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4241) + << "According to the Vulkan spec BuiltIn HelperInvocation " + "variable needs to be a bool scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateHelperInvocationAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateHelperInvocationAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4240) + << "Vulkan spec allows BuiltIn HelperInvocation to be only used " + "for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4239) + << "Vulkan spec allows BuiltIn HelperInvocation to be used only " + "with Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateHelperInvocationAtReference, this, + decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateInvocationIdAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4259) + << "According to the Vulkan spec BuiltIn InvocationId " + "variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateInvocationIdAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateInvocationIdAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4258) + << "Vulkan spec allows BuiltIn InvocationId to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::TessellationControl && + execution_model != spv::ExecutionModel::Geometry) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4257) + << "Vulkan spec allows BuiltIn InvocationId to be used only " + "with TessellationControl or Geometry execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateInvocationIdAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateInstanceIndexAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4265) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn InstanceIndex " + "variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateInstanceIndexAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateInstanceIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4264) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn InstanceIndex to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Vertex) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4263) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn InstanceIndex to be used only " + "with Vertex execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateInstanceIndexAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidatePatchVerticesAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4310) + << "According to the Vulkan spec BuiltIn PatchVertices " + "variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidatePatchVerticesAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidatePatchVerticesAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4309) + << "Vulkan spec allows BuiltIn PatchVertices to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::TessellationControl && + execution_model != spv::ExecutionModel::TessellationEvaluation) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4308) + << "Vulkan spec allows BuiltIn PatchVertices to be used only " + "with TessellationControl or TessellationEvaluation " + "execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidatePatchVerticesAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidatePointCoordAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateF32Vec( + decoration, inst, 2, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4313) + << "According to the Vulkan spec BuiltIn PointCoord " + "variable needs to be a 2-component 32-bit float " + "vector. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidatePointCoordAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidatePointCoordAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4312) + << "Vulkan spec allows BuiltIn PointCoord to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4311) + << "Vulkan spec allows BuiltIn PointCoord to be used only with " + "Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidatePointCoordAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidatePointSizeAtDefinition( + const Decoration& decoration, const Instruction& inst) { + // Seed at reference checks with this built-in. + return ValidatePointSizeAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidatePointSizeAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4316) + << "Vulkan spec allows BuiltIn PointSize to be only used for " + "variables with Input or Output storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + if (storage_class == spv::StorageClass::Input) { + assert(function_id_ == 0); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4315, + "Vulkan spec doesn't allow BuiltIn PointSize to be used for " + "variables with Input storage class if execution model is " + "Vertex.", + spv::ExecutionModel::Vertex, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + switch (execution_model) { + case spv::ExecutionModel::Vertex: { + if (spv_result_t error = ValidateF32( + decoration, built_in_inst, + [this, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4317) + << "According to the Vulkan spec BuiltIn PointSize " + "variable needs to be a 32-bit float scalar. " + << message; + })) { + return error; + } + break; + } + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: { + // PointSize can be a per-vertex variable for tessellation control, + // tessellation evaluation and geometry shader stages. In such cases + // variables will have an array of 32-bit floats. + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + // The array is on the variable, so this must be a 32-bit float. + if (spv_result_t error = ValidateF32( + decoration, built_in_inst, + [this, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, + &referenced_from_inst) + << _.VkErrorID(4317) + << "According to the Vulkan spec BuiltIn " + "PointSize variable needs to be a 32-bit " + "float scalar. " + << message; + })) { + return error; + } + } else { + if (spv_result_t error = ValidateOptionalArrayedF32( + decoration, built_in_inst, + [this, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, + &referenced_from_inst) + << _.VkErrorID(4317) + << "According to the Vulkan spec BuiltIn " + "PointSize variable needs to be a 32-bit " + "float scalar. " + << message; + })) { + return error; + } + } + break; + } + + default: { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4314) + << "Vulkan spec allows BuiltIn PointSize to be used only with " + "Vertex, TessellationControl, TessellationEvaluation or " + "Geometry execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidatePointSizeAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidatePositionAtDefinition( + const Decoration& decoration, const Instruction& inst) { + // Seed at reference checks with this built-in. + return ValidatePositionAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidatePositionAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4320) << "Vulkan spec allows BuiltIn Position to be only used for " + "variables with Input or Output storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + if (storage_class == spv::StorageClass::Input) { + assert(function_id_ == 0); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, + "Vulkan spec doesn't allow BuiltIn Position to be used " + "for variables " + "with Input storage class if execution model is Vertex.", + spv::ExecutionModel::Vertex, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, + "Vulkan spec doesn't allow BuiltIn Position to be used " + "for variables " + "with Input storage class if execution model is MeshNV.", + spv::ExecutionModel::MeshNV, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, + "Vulkan spec doesn't allow BuiltIn Position to be used " + "for variables " + "with Input storage class if execution model is MeshEXT.", + spv::ExecutionModel::MeshEXT, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + switch (execution_model) { + case spv::ExecutionModel::Vertex: { + if (spv_result_t error = ValidateF32Vec( + decoration, built_in_inst, 4, + [this, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4321) + << "According to the Vulkan spec BuiltIn Position " + "variable needs to be a 4-component 32-bit float " + "vector. " + << message; + })) { + return error; + } + break; + } + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: { + // Position can be a per-vertex variable for tessellation control, + // tessellation evaluation, geometry and mesh shader stages. In such + // cases variables will have an array of 4-component 32-bit float + // vectors. + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + // The array is on the variable, so this must be a 4-component + // 32-bit float vector. + if (spv_result_t error = ValidateF32Vec( + decoration, built_in_inst, 4, + [this, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, + &referenced_from_inst) + << _.VkErrorID(4321) + << "According to the Vulkan spec BuiltIn Position " + "variable needs to be a 4-component 32-bit " + "float vector. " + << message; + })) { + return error; + } + } else { + if (spv_result_t error = ValidateOptionalArrayedF32Vec( + decoration, built_in_inst, 4, + [this, &referenced_from_inst]( + const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, + &referenced_from_inst) + << _.VkErrorID(4321) + << "According to the Vulkan spec BuiltIn Position " + "variable needs to be a 4-component 32-bit " + "float vector. " + << message; + })) { + return error; + } + } + break; + } + + default: { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4318) + << "Vulkan spec allows BuiltIn Position to be used only " + "with Vertex, TessellationControl, TessellationEvaluation" + " or Geometry execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidatePositionAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + // PrimitiveId can be a per-primitive variable for mesh shader stage. + // In such cases variable will have an array of 32-bit integers. + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + // This must be a 32-bit int scalar. + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4337) + << "According to the Vulkan spec BuiltIn PrimitiveId " + "variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } else { + if (spv_result_t error = ValidateOptionalArrayedI32( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4337) + << "According to the Vulkan spec BuiltIn PrimitiveId " + "variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + } + + // Seed at reference checks with this built-in. + return ValidatePrimitiveIdAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << "Vulkan spec allows BuiltIn PrimitiveId to be only used for " + "variables with Input or Output storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + if (storage_class == spv::StorageClass::Output) { + assert(function_id_ == 0); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, + "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " + "variables with Output storage class if execution model is " + "TessellationControl.", + spv::ExecutionModel::TessellationControl, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, + "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " + "variables with Output storage class if execution model is " + "TessellationEvaluation.", + spv::ExecutionModel::TessellationEvaluation, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, + "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " + "variables with Output storage class if execution model is " + "Fragment.", + spv::ExecutionModel::Fragment, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, + "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " + "variables with Output storage class if execution model is " + "IntersectionKHR.", + spv::ExecutionModel::IntersectionKHR, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, + "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " + "variables with Output storage class if execution model is " + "AnyHitKHR.", + spv::ExecutionModel::AnyHitKHR, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, + "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " + "variables with Output storage class if execution model is " + "ClosestHitKHR.", + spv::ExecutionModel::ClosestHitKHR, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + switch (execution_model) { + case spv::ExecutionModel::Fragment: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: + case spv::ExecutionModel::IntersectionKHR: + case spv::ExecutionModel::AnyHitKHR: + case spv::ExecutionModel::ClosestHitKHR: { + // Ok. + break; + } + + default: { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4330) + << "Vulkan spec allows BuiltIn PrimitiveId to be used only " + "with Fragment, TessellationControl, " + "TessellationEvaluation, Geometry, MeshNV, MeshEXT, " + "IntersectionKHR, AnyHitKHR, and ClosestHitKHR execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidatePrimitiveIdAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateSampleIdAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4356) + << "According to the Vulkan spec BuiltIn SampleId " + "variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateSampleIdAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateSampleIdAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4355) + << "Vulkan spec allows BuiltIn SampleId to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4354) + << "Vulkan spec allows BuiltIn SampleId to be used only with " + "Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateSampleIdAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateSampleMaskAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32Arr( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4359) + << "According to the Vulkan spec BuiltIn SampleMask " + "variable needs to be a 32-bit int array. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateSampleMaskAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateSampleMaskAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4358) + << "Vulkan spec allows BuiltIn SampleMask to be only used for " + "variables with Input or Output storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4357) + << "Vulkan spec allows BuiltIn SampleMask to be used only " + "with " + "Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateSampleMaskAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateSamplePositionAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateF32Vec( + decoration, inst, 2, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4362) + << "According to the Vulkan spec BuiltIn SamplePosition " + "variable needs to be a 2-component 32-bit float " + "vector. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateSamplePositionAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateSamplePositionAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4361) + << "Vulkan spec allows BuiltIn SamplePosition to be only used " + "for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4360) + << "Vulkan spec allows BuiltIn SamplePosition to be used only " + "with " + "Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateSamplePositionAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateTessCoordAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateF32Vec( + decoration, inst, 3, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4389) + << "According to the Vulkan spec BuiltIn TessCoord " + "variable needs to be a 3-component 32-bit float " + "vector. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateTessCoordAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateTessCoordAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4388) + << "Vulkan spec allows BuiltIn TessCoord to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::TessellationEvaluation) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4387) + << "Vulkan spec allows BuiltIn TessCoord to be used only with " + "TessellationEvaluation execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateTessCoordAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateTessLevelOuterAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateF32Arr( + decoration, inst, 4, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4393) + << "According to the Vulkan spec BuiltIn TessLevelOuter " + "variable needs to be a 4-component 32-bit float " + "array. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateTessLevelAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateTessLevelInnerAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateF32Arr( + decoration, inst, 2, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4397) + << "According to the Vulkan spec BuiltIn TessLevelOuter " + "variable needs to be a 2-component 32-bit float " + "array. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateTessLevelAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + uint32_t operand = decoration.params()[0]; + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be only used for variables with Input or Output storage " + "class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + if (storage_class == spv::StorageClass::Input) { + assert(function_id_ == 0); + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4391 : 4395; + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, + "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be " + "used " + "for variables with Input storage class if execution model is " + "TessellationControl.", + spv::ExecutionModel::TessellationControl, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + + if (storage_class == spv::StorageClass::Output) { + assert(function_id_ == 0); + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4392 : 4396; + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, + "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be " + "used " + "for variables with Output storage class if execution model is " + "TessellationEvaluation.", + spv::ExecutionModel::TessellationEvaluation, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + switch (execution_model) { + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: { + // Ok. + break; + } + + default: { + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::TessLevelOuter) ? 4390 : 4394; + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be used only with TessellationControl or " + "TessellationEvaluation execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateTessLevelAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateVertexIndexAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4400) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn VertexIndex variable needs to be a " + "32-bit int scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateVertexIndexAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateVertexIdAtDefinition( + const Decoration& decoration, const Instruction& inst) { + (void)decoration; + if (spvIsVulkanEnv(_.context()->target_env)) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "Vulkan spec doesn't allow BuiltIn VertexId " + "to be used."; + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateLocalInvocationIndexAtDefinition( + const Decoration& decoration, const Instruction& inst) { + // Seed at reference checks with this built-in. + return ValidateLocalInvocationIndexAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateLocalInvocationIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction&, + const Instruction& referenced_from_inst) { + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateLocalInvocationIndexAtReference, + this, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateVertexIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4399) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn VertexIndex to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Vertex) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4398) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn VertexIndex to be used only with " + "Vertex execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateVertexIndexAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + // This can be a per-primitive variable for mesh shader stage. + // In such cases variable will have an array of 32-bit integers. + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + // This must be a 32-bit int scalar. + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &decoration, + &inst](const std::string& message) -> spv_result_t { + uint32_t vuid = + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408; + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + << "variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } else { + if (spv_result_t error = ValidateOptionalArrayedI32( + decoration, inst, + [this, &decoration, + &inst](const std::string& message) -> spv_result_t { + uint32_t vuid = + (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408; + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + << "variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + } + + // Seed at reference checks with this built-in. + return ValidateLayerOrViewportIndexAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + uint32_t operand = decoration.params()[0]; + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be only used for variables with Input or Output storage " + "class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + if (storage_class == spv::StorageClass::Input) { + assert(function_id_ == 0); + for (const auto em : + {spv::ExecutionModel::Vertex, spv::ExecutionModel::TessellationEvaluation, + spv::ExecutionModel::Geometry, spv::ExecutionModel::MeshNV, + spv::ExecutionModel::MeshEXT}) { + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, + this, ((spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4274 : 4406), + "Vulkan spec doesn't allow BuiltIn Layer and " + "ViewportIndex to be " + "used for variables with Input storage class if " + "execution model is Vertex, TessellationEvaluation, " + "Geometry, MeshNV or MeshEXT.", + em, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + } + + if (storage_class == spv::StorageClass::Output) { + assert(function_id_ == 0); + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, + this, ((spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4275 : 4407), + "Vulkan spec doesn't allow BuiltIn Layer and " + "ViewportIndex to be " + "used for variables with Output storage class if " + "execution model is " + "Fragment.", + spv::ExecutionModel::Fragment, decoration, built_in_inst, + referenced_from_inst, std::placeholders::_1)); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + switch (execution_model) { + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::Fragment: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: + // Ok. + break; + case spv::ExecutionModel::Vertex: + case spv::ExecutionModel::TessellationEvaluation: { + if (!_.HasCapability(spv::Capability::ShaderViewportIndexLayerEXT)) { + if (spv::BuiltIn(operand) == spv::BuiltIn::ViewportIndex && + _.HasCapability(spv::Capability::ShaderViewportIndex)) + break; // Ok + if (spv::BuiltIn(operand) == spv::BuiltIn::Layer && + _.HasCapability(spv::Capability::ShaderLayer)) + break; // Ok + + const char* capability = "ShaderViewportIndexLayerEXT"; + + if (spv::BuiltIn(operand) == spv::BuiltIn::ViewportIndex) + capability = "ShaderViewportIndexLayerEXT or ShaderViewportIndex"; + if (spv::BuiltIn(operand) == spv::BuiltIn::Layer) + capability = "ShaderViewportIndexLayerEXT or ShaderLayer"; + + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4273 : 4405; + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Using BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " in Vertex or Tessellation execution model requires the " + << capability << " capability."; + } + break; + } + default: { + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4272 : 4404; + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be used only with Vertex, TessellationEvaluation, " + "Geometry, or Fragment execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateLayerOrViewportIndexAtReference, + this, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (spv_result_t error = ValidateF32Vec( + decoration, inst, 3, + [this, &inst, builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + uint32_t(builtin)) + << " variable needs to be a 3-component 32-bit float " + "vector. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateFragmentShaderF32Vec3InputAtReference(decoration, inst, inst, + inst); +} + +spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be used only with Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference, this, + decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (spv_result_t error = ValidateI32Vec( + decoration, inst, 3, + [this, &inst, builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + uint32_t(builtin)) + << " variable needs to be a 3-component 32-bit int " + "vector. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateComputeShaderI32Vec3InputAtReference(decoration, inst, inst, + inst); +} + +spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + bool has_vulkan_model = execution_model == spv::ExecutionModel::GLCompute || + execution_model == spv::ExecutionModel::TaskNV || + execution_model == spv::ExecutionModel::MeshNV || + execution_model == spv::ExecutionModel::TaskEXT || + execution_model == spv::ExecutionModel::MeshEXT; + + if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or" + << " TaskEXT execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference, this, + decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateComputeI32InputAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " cannot be used as a member decoration "; + } + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " variable needs to be a 32-bit int " + "vector. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateComputeI32InputAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + bool has_vulkan_model = execution_model == spv::ExecutionModel::GLCompute || + execution_model == spv::ExecutionModel::TaskNV || + execution_model == spv::ExecutionModel::MeshNV || + execution_model == spv::ExecutionModel::TaskEXT || + execution_model == spv::ExecutionModel::MeshEXT; + if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or " + << "TaskEXT execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateComputeI32InputAtReference, this, + decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " cannot be used as a member decoration "; + } + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " variable needs to be a 32-bit int. " << message; + })) { + return error; + } + + const spv::StorageClass storage_class = GetStorageClass(inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, inst, inst, inst) << " " + << GetStorageClassDesc(inst); + } + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (decoration.struct_member_index() != Decoration::kInvalidMember) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " cannot be used as a member decoration "; + } + if (spv_result_t error = ValidateI32Vec( + decoration, inst, 4, + [this, &inst, builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " variable needs to be a 4-component 32-bit int " + "vector. " + << message; + })) { + return error; + } + + const spv::StorageClass storage_class = GetStorageClass(inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, inst, inst, inst) << " " + << GetStorageClassDesc(inst); + } + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env) && + !spvOpcodeIsConstant(inst.opcode())) { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4426) + << "Vulkan spec requires BuiltIn WorkgroupSize to be a " + "constant. " + << GetIdDesc(inst) << " is not a constant."; + } + + if (spv_result_t error = ValidateI32Vec( + decoration, inst, 3, + [this, &inst](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4427) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn WorkgroupSize variable needs to be a " + "3-component 32-bit int vector. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateWorkgroupSizeAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::GLCompute && + execution_model != spv::ExecutionModel::TaskNV && + execution_model != spv::ExecutionModel::MeshNV && + execution_model != spv::ExecutionModel::TaskEXT && + execution_model != spv::ExecutionModel::MeshEXT) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4425) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or " + << "TaskEXT execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateWorkgroupSizeAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, + &decoration](const std::string& message) -> spv_result_t { + uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::BaseInstance) + ? 4183 + : 4186; + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + return ValidateBaseInstanceOrVertexAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + uint32_t operand = decoration.params()[0]; + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::BaseInstance) ? 4182 : 4185; + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Vertex) { + uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::BaseInstance) ? 4181 : 4184; + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be used only with Vertex execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateBaseInstanceOrVertexAtReference, + this, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateDrawIndexAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, + &decoration](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4209) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + return ValidateDrawIndexAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateDrawIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + uint32_t operand = decoration.params()[0]; + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4208) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Vertex && + execution_model != spv::ExecutionModel::MeshNV && + execution_model != spv::ExecutionModel::TaskNV && + execution_model != spv::ExecutionModel::MeshEXT && + execution_model != spv::ExecutionModel::TaskEXT) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4207) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be used only with Vertex, MeshNV, TaskNV , MeshEXT or" + << " TaskEXT execution " + "model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateDrawIndexAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateViewIndexAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, + &decoration](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4403) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + return ValidateViewIndexAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateViewIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + uint32_t operand = decoration.params()[0]; + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4402) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model == spv::ExecutionModel::GLCompute) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4401) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be not be used with GLCompute execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateViewIndexAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateDeviceIndexAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, + &decoration](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4206) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + return ValidateDeviceIndexAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateDeviceIndexAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + uint32_t operand = decoration.params()[0]; + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4205) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + operand) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateDeviceIndexAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const Decoration& decoration, + const Instruction& inst) { + + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, &builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + uint32_t(builtin)) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + return ValidateFragInvocationCountAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be used only with Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateFragInvocationCountAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& decoration, + const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (spv_result_t error = ValidateI32Vec( + decoration, inst, 2, + [this, &inst, &builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + uint32_t(builtin)) + << " variable needs to be a 2-component 32-bit int vector. " + << message; + })) { + return error; + } + } + + return ValidateFragSizeAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateFragSizeAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be used only with Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateFragSizeAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decoration& decoration, + const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (spv_result_t error = ValidateI( + decoration, inst, + [this, &inst, &builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + uint32_t(builtin)) + << " variable needs to be a int scalar. " + << message; + })) { + return error; + } + } + + return ValidateFragStencilRefAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Output) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Output storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be used only with Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateFragStencilRefAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoration& decoration, + const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + if (spv_result_t error = ValidateBool( + decoration, inst, + [this, &inst, &builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + uint32_t(builtin)) + << " variable needs to be a bool scalar. " + << message; + })) { + return error; + } + } + + return ValidateFullyCoveredAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateFullyCoveredAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " to be used only with Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateFullyCoveredAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, + &decoration](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateNVSMOrARMCoreBuiltinsAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " to be only used for " + "variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, + &decoration](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4486) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidatePrimitiveShadingRateAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Output) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4485) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " to be only used for variables with Output storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + switch (execution_model) { + case spv::ExecutionModel::Vertex: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::MeshNV: + case spv::ExecutionModel::MeshEXT: + break; + default: { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4484) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " to be used only with Vertex, Geometry, or MeshNV " + "execution models. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidatePrimitiveShadingRateAtReference, + this, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateShadingRateAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, + &decoration](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(4492) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + } + + // Seed at reference checks with this built-in. + return ValidateShadingRateAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4491) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::Fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(4490) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " to be used only with the Fragment execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( + &BuiltInsValidator::ValidateShadingRateAtReference, this, decoration, + built_in_inst, referenced_from_inst, std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + switch (builtin) { + case spv::BuiltIn::HitTNV: + case spv::BuiltIn::RayTminKHR: + case spv::BuiltIn::RayTmaxKHR: + // f32 scalar + if (spv_result_t error = ValidateF32( + decoration, inst, + [this, &inst, + builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " variable needs to be a 32-bit float scalar. " + << message; + })) { + return error; + } + break; + case spv::BuiltIn::HitKindKHR: + case spv::BuiltIn::InstanceCustomIndexKHR: + case spv::BuiltIn::InstanceId: + case spv::BuiltIn::RayGeometryIndexKHR: + case spv::BuiltIn::IncomingRayFlagsKHR: + case spv::BuiltIn::CullMaskKHR: + // i32 scalar + if (spv_result_t error = ValidateI32( + decoration, inst, + [this, &inst, + builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " variable needs to be a 32-bit int scalar. " + << message; + })) { + return error; + } + break; + case spv::BuiltIn::ObjectRayDirectionKHR: + case spv::BuiltIn::ObjectRayOriginKHR: + case spv::BuiltIn::WorldRayDirectionKHR: + case spv::BuiltIn::WorldRayOriginKHR: + // f32 vec3 + if (spv_result_t error = ValidateF32Vec( + decoration, inst, 3, + [this, &inst, + builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " variable needs to be a 3-component 32-bit float " + "vector. " + << message; + })) { + return error; + } + break; + case spv::BuiltIn::LaunchIdKHR: + case spv::BuiltIn::LaunchSizeKHR: + // i32 vec3 + if (spv_result_t error = ValidateI32Vec( + decoration, inst, 3, + [this, &inst, + builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " variable needs to be a 3-component 32-bit int " + "vector. " + << message; + })) { + return error; + } + break; + case spv::BuiltIn::ObjectToWorldKHR: + case spv::BuiltIn::WorldToObjectKHR: + // f32 mat4x3 + if (spv_result_t error = ValidateF32Mat( + decoration, inst, 3, 4, + [this, &inst, + builtin](const std::string& message) -> spv_result_t { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) + << "According to the Vulkan spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << " variable needs to be a matrix with" + << " 4 columns of 3-component vectors of 32-bit " + "floats. " + << message; + })) { + return error; + } + break; + default: + assert(0 && "Unexpected ray tracing builtin"); + break; + } + } + + // Seed at reference checks with this built-in. + return ValidateRayTracingBuiltinsAtReference(decoration, inst, inst, inst); +} + +spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Input) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " to be only used for variables with Input storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (!IsExecutionModelValidForRtBuiltIn(builtin, execution_model)) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << "Vulkan spec does not allow BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " to be used with the execution model " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model)) + << ".\n" + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateRayTracingBuiltinsAtReference, + this, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition( + const Decoration& decoration, const Instruction& inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); + if (builtin == spv::BuiltIn::PrimitivePointIndicesEXT) { + if (spv_result_t error = ValidateI32Arr( + decoration, inst, + [this, &inst, &decoration, + &vuid](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + << " variable needs to be a 32-bit int array." + << message; + })) { + return error; + } + } + if (builtin == spv::BuiltIn::PrimitiveLineIndicesEXT) { + if (spv_result_t error = ValidateArrayedI32Vec( + decoration, inst, 2, + [this, &inst, &decoration, + &vuid](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + << " variable needs to be a 2-component 32-bit int " + "array." + << message; + })) { + return error; + } + } + if (builtin == spv::BuiltIn::PrimitiveTriangleIndicesEXT) { + if (spv_result_t error = ValidateArrayedI32Vec( + decoration, inst, 3, + [this, &inst, &decoration, + &vuid](const std::string& message) -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, &inst) + << _.VkErrorID(vuid) << "According to the " + << spvLogStringForEnv(_.context()->target_env) + << " spec BuiltIn " + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + << " variable needs to be a 3-component 32-bit int " + "array." + << message; + })) { + return error; + } + } + } + // Seed at reference checks with this built-in. + return ValidateMeshShadingEXTBuiltinsAtReference(decoration, inst, inst, + inst); +} + +spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference( + const Decoration& decoration, const Instruction& built_in_inst, + const Instruction& referenced_inst, + const Instruction& referenced_from_inst) { + if (spvIsVulkanEnv(_.context()->target_env)) { + const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::StorageClass storage_class = + GetStorageClass(referenced_from_inst); + if (storage_class != spv::StorageClass::Max && + storage_class != spv::StorageClass::Output) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + uint32_t(builtin)) + << " to be only used for variables with Output storage class. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst) + << " " << GetStorageClassDesc(referenced_from_inst); + } + + for (const spv::ExecutionModel execution_model : execution_models_) { + if (execution_model != spv::ExecutionModel::MeshEXT) { + uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); + return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) + << _.VkErrorID(vuid) + << spvLogStringForEnv(_.context()->target_env) + << " spec allows BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + uint32_t(builtin)) + << " to be used only with MeshEXT execution model. " + << GetReferenceDesc(decoration, built_in_inst, referenced_inst, + referenced_from_inst, execution_model); + } + } + } + + if (function_id_ == 0) { + // Propagate this rule to all dependant ids in the global scope. + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference, + this, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( + const Decoration& decoration, const Instruction& inst) { + const spv::BuiltIn label = spv::BuiltIn(decoration.params()[0]); + + if (!spvIsVulkanEnv(_.context()->target_env)) { + // Early return. All currently implemented rules are based on Vulkan spec. + // + // TODO: If you are adding validation rules for environments other than + // Vulkan (or general rules which are not environment independent), then + // you need to modify or remove this condition. Consider also adding early + // returns into BuiltIn-specific rules, so that the system doesn't spawn new + // rules which don't do anything. + return SPV_SUCCESS; + } + + // If you are adding a new BuiltIn enum, please register it here. + // If the newly added enum has validation rules associated with it + // consider leaving a TODO and/or creating an issue. + switch (label) { + case spv::BuiltIn::ClipDistance: + case spv::BuiltIn::CullDistance: { + return ValidateClipOrCullDistanceAtDefinition(decoration, inst); + } + case spv::BuiltIn::FragCoord: { + return ValidateFragCoordAtDefinition(decoration, inst); + } + case spv::BuiltIn::FragDepth: { + return ValidateFragDepthAtDefinition(decoration, inst); + } + case spv::BuiltIn::FrontFacing: { + return ValidateFrontFacingAtDefinition(decoration, inst); + } + case spv::BuiltIn::GlobalInvocationId: + case spv::BuiltIn::LocalInvocationId: + case spv::BuiltIn::NumWorkgroups: + case spv::BuiltIn::WorkgroupId: { + return ValidateComputeShaderI32Vec3InputAtDefinition(decoration, inst); + } + case spv::BuiltIn::BaryCoordKHR: + case spv::BuiltIn::BaryCoordNoPerspKHR: { + return ValidateFragmentShaderF32Vec3InputAtDefinition(decoration, inst); + } + case spv::BuiltIn::HelperInvocation: { + return ValidateHelperInvocationAtDefinition(decoration, inst); + } + case spv::BuiltIn::InvocationId: { + return ValidateInvocationIdAtDefinition(decoration, inst); + } + case spv::BuiltIn::InstanceIndex: { + return ValidateInstanceIndexAtDefinition(decoration, inst); + } + case spv::BuiltIn::Layer: + case spv::BuiltIn::ViewportIndex: { + return ValidateLayerOrViewportIndexAtDefinition(decoration, inst); + } + case spv::BuiltIn::PatchVertices: { + return ValidatePatchVerticesAtDefinition(decoration, inst); + } + case spv::BuiltIn::PointCoord: { + return ValidatePointCoordAtDefinition(decoration, inst); + } + case spv::BuiltIn::PointSize: { + return ValidatePointSizeAtDefinition(decoration, inst); + } + case spv::BuiltIn::Position: { + return ValidatePositionAtDefinition(decoration, inst); + } + case spv::BuiltIn::PrimitiveId: { + return ValidatePrimitiveIdAtDefinition(decoration, inst); + } + case spv::BuiltIn::SampleId: { + return ValidateSampleIdAtDefinition(decoration, inst); + } + case spv::BuiltIn::SampleMask: { + return ValidateSampleMaskAtDefinition(decoration, inst); + } + case spv::BuiltIn::SamplePosition: { + return ValidateSamplePositionAtDefinition(decoration, inst); + } + case spv::BuiltIn::SubgroupId: + case spv::BuiltIn::NumSubgroups: { + return ValidateComputeI32InputAtDefinition(decoration, inst); + } + case spv::BuiltIn::SubgroupLocalInvocationId: + case spv::BuiltIn::SubgroupSize: { + return ValidateI32InputAtDefinition(decoration, inst); + } + case spv::BuiltIn::SubgroupEqMask: + case spv::BuiltIn::SubgroupGeMask: + case spv::BuiltIn::SubgroupGtMask: + case spv::BuiltIn::SubgroupLeMask: + case spv::BuiltIn::SubgroupLtMask: { + return ValidateI32Vec4InputAtDefinition(decoration, inst); + } + case spv::BuiltIn::TessCoord: { + return ValidateTessCoordAtDefinition(decoration, inst); + } + case spv::BuiltIn::TessLevelOuter: { + return ValidateTessLevelOuterAtDefinition(decoration, inst); + } + case spv::BuiltIn::TessLevelInner: { + return ValidateTessLevelInnerAtDefinition(decoration, inst); + } + case spv::BuiltIn::VertexIndex: { + return ValidateVertexIndexAtDefinition(decoration, inst); + } + case spv::BuiltIn::WorkgroupSize: { + return ValidateWorkgroupSizeAtDefinition(decoration, inst); + } + case spv::BuiltIn::VertexId: { + return ValidateVertexIdAtDefinition(decoration, inst); + } + case spv::BuiltIn::LocalInvocationIndex: { + return ValidateLocalInvocationIndexAtDefinition(decoration, inst); + } + case spv::BuiltIn::CoreIDARM: + case spv::BuiltIn::CoreCountARM: + case spv::BuiltIn::CoreMaxIDARM: + case spv::BuiltIn::WarpIDARM: + case spv::BuiltIn::WarpMaxIDARM: + case spv::BuiltIn::WarpsPerSMNV: + case spv::BuiltIn::SMCountNV: + case spv::BuiltIn::WarpIDNV: + case spv::BuiltIn::SMIDNV: { + return ValidateNVSMOrARMCoreBuiltinsAtDefinition(decoration, inst); + } + case spv::BuiltIn::BaseInstance: + case spv::BuiltIn::BaseVertex: { + return ValidateBaseInstanceOrVertexAtDefinition(decoration, inst); + } + case spv::BuiltIn::DrawIndex: { + return ValidateDrawIndexAtDefinition(decoration, inst); + } + case spv::BuiltIn::ViewIndex: { + return ValidateViewIndexAtDefinition(decoration, inst); + } + case spv::BuiltIn::DeviceIndex: { + return ValidateDeviceIndexAtDefinition(decoration, inst); + } + case spv::BuiltIn::FragInvocationCountEXT: { + // alias spv::BuiltIn::InvocationsPerPixelNV + return ValidateFragInvocationCountAtDefinition(decoration, inst); + } + case spv::BuiltIn::FragSizeEXT: { + // alias spv::BuiltIn::FragmentSizeNV + return ValidateFragSizeAtDefinition(decoration, inst); + } + case spv::BuiltIn::FragStencilRefEXT: { + return ValidateFragStencilRefAtDefinition(decoration, inst); + } + case spv::BuiltIn::FullyCoveredEXT:{ + return ValidateFullyCoveredAtDefinition(decoration, inst); + } + // Ray tracing builtins + case spv::BuiltIn::HitKindKHR: // alias spv::BuiltIn::HitKindNV + case spv::BuiltIn::HitTNV: // NOT present in KHR + case spv::BuiltIn::InstanceId: + case spv::BuiltIn::LaunchIdKHR: // alias spv::BuiltIn::LaunchIdNV + case spv::BuiltIn::LaunchSizeKHR: // alias spv::BuiltIn::LaunchSizeNV + case spv::BuiltIn::WorldRayOriginKHR: // alias spv::BuiltIn::WorldRayOriginNV + case spv::BuiltIn::WorldRayDirectionKHR: // alias spv::BuiltIn::WorldRayDirectionNV + case spv::BuiltIn::ObjectRayOriginKHR: // alias spv::BuiltIn::ObjectRayOriginNV + case spv::BuiltIn::ObjectRayDirectionKHR: // alias + // spv::BuiltIn::ObjectRayDirectionNV + case spv::BuiltIn::RayTminKHR: // alias spv::BuiltIn::RayTminNV + case spv::BuiltIn::RayTmaxKHR: // alias spv::BuiltIn::RayTmaxNV + case spv::BuiltIn::InstanceCustomIndexKHR: // alias + // spv::BuiltIn::InstanceCustomIndexNV + case spv::BuiltIn::ObjectToWorldKHR: // alias spv::BuiltIn::ObjectToWorldNV + case spv::BuiltIn::WorldToObjectKHR: // alias spv::BuiltIn::WorldToObjectNV + case spv::BuiltIn::IncomingRayFlagsKHR: // alias spv::BuiltIn::IncomingRayFlagsNV + case spv::BuiltIn::RayGeometryIndexKHR: // NOT present in NV + case spv::BuiltIn::CullMaskKHR: { + return ValidateRayTracingBuiltinsAtDefinition(decoration, inst); + } + case spv::BuiltIn::PrimitivePointIndicesEXT: + case spv::BuiltIn::PrimitiveLineIndicesEXT: + case spv::BuiltIn::PrimitiveTriangleIndicesEXT: { + return ValidateMeshShadingEXTBuiltinsAtDefinition(decoration, inst); + } + case spv::BuiltIn::PrimitiveShadingRateKHR: { + return ValidatePrimitiveShadingRateAtDefinition(decoration, inst); + } + case spv::BuiltIn::ShadingRateKHR: { + return ValidateShadingRateAtDefinition(decoration, inst); + } + default: + // No validation rules (for the moment). + break; + } + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::ValidateBuiltInsAtDefinition() { + for (const auto& kv : _.id_decorations()) { + const uint32_t id = kv.first; + const auto& decorations = kv.second; + if (decorations.empty()) { + continue; + } + + const Instruction* inst = _.FindDef(id); + assert(inst); + + for (const auto& decoration : kv.second) { + if (decoration.dec_type() != spv::Decoration::BuiltIn) { + continue; + } + + if (spv_result_t error = + ValidateSingleBuiltInAtDefinition(decoration, *inst)) { + return error; + } + } + } + + return SPV_SUCCESS; +} + +spv_result_t BuiltInsValidator::Run() { + // First pass: validate all built-ins at definition and seed + // id_to_at_reference_checks_ with built-ins. + if (auto error = ValidateBuiltInsAtDefinition()) { + return error; + } + + if (id_to_at_reference_checks_.empty()) { + // No validation tasks were seeded. Nothing else to do. + return SPV_SUCCESS; + } + + // Second pass: validate every id reference in the module using + // rules in id_to_at_reference_checks_. + for (const Instruction& inst : _.ordered_instructions()) { + Update(inst); + + std::set already_checked; + + for (const auto& operand : inst.operands()) { + if (!spvIsIdType(operand.type)) { + // Not id. + continue; + } + + const uint32_t id = inst.word(operand.offset); + if (id == inst.id()) { + // No need to check result id. + continue; + } + + if (!already_checked.insert(id).second) { + // The instruction has already referenced this id. + continue; + } + + // Instruction references the id. Run all checks associated with the id + // on the instruction. id_to_at_reference_checks_ can be modified in the + // process, iterators are safe because it's a tree-based map. + const auto it = id_to_at_reference_checks_.find(id); + if (it != id_to_at_reference_checks_.end()) { + for (const auto& check : it->second) { + if (spv_result_t error = check(inst)) { + return error; + } + } + } + } + } + + return SPV_SUCCESS; +} + +} // namespace + +// Validates correctness of built-in variables. +spv_result_t ValidateBuiltIns(ValidationState_t& _) { + BuiltInsValidator validator(_); + return validator.Run(); +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_capability.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_capability.cpp new file mode 100644 index 000000000000..81d2ad52d2b7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_capability.cpp @@ -0,0 +1,383 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates OpCapability instruction. + +#include +#include + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +bool IsSupportGuaranteedVulkan_1_0(uint32_t capability) { + switch (spv::Capability(capability)) { + case spv::Capability::Matrix: + case spv::Capability::Shader: + case spv::Capability::InputAttachment: + case spv::Capability::Sampled1D: + case spv::Capability::Image1D: + case spv::Capability::SampledBuffer: + case spv::Capability::ImageBuffer: + case spv::Capability::ImageQuery: + case spv::Capability::DerivativeControl: + return true; + default: + break; + } + return false; +} + +bool IsSupportGuaranteedVulkan_1_1(uint32_t capability) { + if (IsSupportGuaranteedVulkan_1_0(capability)) return true; + switch (spv::Capability(capability)) { + case spv::Capability::DeviceGroup: + case spv::Capability::MultiView: + return true; + default: + break; + } + return false; +} + +bool IsSupportGuaranteedVulkan_1_2(uint32_t capability) { + if (IsSupportGuaranteedVulkan_1_1(capability)) return true; + switch (spv::Capability(capability)) { + case spv::Capability::ShaderNonUniform: + return true; + default: + break; + } + return false; +} + +bool IsSupportOptionalVulkan_1_0(uint32_t capability) { + switch (spv::Capability(capability)) { + case spv::Capability::Geometry: + case spv::Capability::Tessellation: + case spv::Capability::Float64: + case spv::Capability::Int64: + case spv::Capability::Int16: + case spv::Capability::TessellationPointSize: + case spv::Capability::GeometryPointSize: + case spv::Capability::ImageGatherExtended: + case spv::Capability::StorageImageMultisample: + case spv::Capability::UniformBufferArrayDynamicIndexing: + case spv::Capability::SampledImageArrayDynamicIndexing: + case spv::Capability::StorageBufferArrayDynamicIndexing: + case spv::Capability::StorageImageArrayDynamicIndexing: + case spv::Capability::ClipDistance: + case spv::Capability::CullDistance: + case spv::Capability::ImageCubeArray: + case spv::Capability::SampleRateShading: + case spv::Capability::SparseResidency: + case spv::Capability::MinLod: + case spv::Capability::SampledCubeArray: + case spv::Capability::ImageMSArray: + case spv::Capability::StorageImageExtendedFormats: + case spv::Capability::InterpolationFunction: + case spv::Capability::StorageImageReadWithoutFormat: + case spv::Capability::StorageImageWriteWithoutFormat: + case spv::Capability::MultiViewport: + case spv::Capability::Int64Atomics: + case spv::Capability::TransformFeedback: + case spv::Capability::GeometryStreams: + case spv::Capability::Float16: + case spv::Capability::Int8: + return true; + default: + break; + } + return false; +} + +bool IsSupportOptionalVulkan_1_1(uint32_t capability) { + if (IsSupportOptionalVulkan_1_0(capability)) return true; + + switch (spv::Capability(capability)) { + case spv::Capability::GroupNonUniform: + case spv::Capability::GroupNonUniformVote: + case spv::Capability::GroupNonUniformArithmetic: + case spv::Capability::GroupNonUniformBallot: + case spv::Capability::GroupNonUniformShuffle: + case spv::Capability::GroupNonUniformShuffleRelative: + case spv::Capability::GroupNonUniformClustered: + case spv::Capability::GroupNonUniformQuad: + case spv::Capability::DrawParameters: + // Alias spv::Capability::StorageBuffer16BitAccess. + case spv::Capability::StorageUniformBufferBlock16: + // Alias spv::Capability::UniformAndStorageBuffer16BitAccess. + case spv::Capability::StorageUniform16: + case spv::Capability::StoragePushConstant16: + case spv::Capability::StorageInputOutput16: + case spv::Capability::DeviceGroup: + case spv::Capability::MultiView: + case spv::Capability::VariablePointersStorageBuffer: + case spv::Capability::VariablePointers: + return true; + default: + break; + } + return false; +} + +bool IsSupportOptionalVulkan_1_2(uint32_t capability) { + if (IsSupportOptionalVulkan_1_1(capability)) return true; + + switch (spv::Capability(capability)) { + case spv::Capability::DenormPreserve: + case spv::Capability::DenormFlushToZero: + case spv::Capability::SignedZeroInfNanPreserve: + case spv::Capability::RoundingModeRTE: + case spv::Capability::RoundingModeRTZ: + case spv::Capability::VulkanMemoryModel: + case spv::Capability::VulkanMemoryModelDeviceScope: + case spv::Capability::StorageBuffer8BitAccess: + case spv::Capability::UniformAndStorageBuffer8BitAccess: + case spv::Capability::StoragePushConstant8: + case spv::Capability::ShaderViewportIndex: + case spv::Capability::ShaderLayer: + case spv::Capability::PhysicalStorageBufferAddresses: + case spv::Capability::RuntimeDescriptorArray: + case spv::Capability::UniformTexelBufferArrayDynamicIndexing: + case spv::Capability::StorageTexelBufferArrayDynamicIndexing: + case spv::Capability::UniformBufferArrayNonUniformIndexing: + case spv::Capability::SampledImageArrayNonUniformIndexing: + case spv::Capability::StorageBufferArrayNonUniformIndexing: + case spv::Capability::StorageImageArrayNonUniformIndexing: + case spv::Capability::InputAttachmentArrayNonUniformIndexing: + case spv::Capability::UniformTexelBufferArrayNonUniformIndexing: + case spv::Capability::StorageTexelBufferArrayNonUniformIndexing: + return true; + default: + break; + } + return false; +} + +bool IsSupportGuaranteedOpenCL_1_2(uint32_t capability, bool embedded_profile) { + switch (spv::Capability(capability)) { + case spv::Capability::Addresses: + case spv::Capability::Float16Buffer: + case spv::Capability::Int16: + case spv::Capability::Int8: + case spv::Capability::Kernel: + case spv::Capability::Linkage: + case spv::Capability::Vector16: + return true; + case spv::Capability::Int64: + return !embedded_profile; + default: + break; + } + return false; +} + +bool IsSupportGuaranteedOpenCL_2_0(uint32_t capability, bool embedded_profile) { + if (IsSupportGuaranteedOpenCL_1_2(capability, embedded_profile)) return true; + + switch (spv::Capability(capability)) { + case spv::Capability::DeviceEnqueue: + case spv::Capability::GenericPointer: + case spv::Capability::Groups: + case spv::Capability::Pipes: + return true; + default: + break; + } + return false; +} + +bool IsSupportGuaranteedOpenCL_2_2(uint32_t capability, bool embedded_profile) { + if (IsSupportGuaranteedOpenCL_2_0(capability, embedded_profile)) return true; + + switch (spv::Capability(capability)) { + case spv::Capability::SubgroupDispatch: + case spv::Capability::PipeStorage: + return true; + default: + break; + } + return false; +} + +bool IsSupportOptionalOpenCL_1_2(uint32_t capability) { + switch (spv::Capability(capability)) { + case spv::Capability::ImageBasic: + case spv::Capability::Float64: + return true; + default: + break; + } + return false; +} + +// Checks if |capability| was enabled by extension. +bool IsEnabledByExtension(ValidationState_t& _, uint32_t capability) { + spv_operand_desc operand_desc = nullptr; + _.grammar().lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, capability, + &operand_desc); + + // operand_desc is expected to be not null, otherwise validator would have + // failed at an earlier stage. This 'assert' is 'just in case'. + assert(operand_desc); + + ExtensionSet operand_exts(operand_desc->numExtensions, + operand_desc->extensions); + if (operand_exts.empty()) return false; + + return _.HasAnyOfExtensions(operand_exts); +} + +bool IsEnabledByCapabilityOpenCL_1_2(ValidationState_t& _, + uint32_t capability) { + if (_.HasCapability(spv::Capability::ImageBasic)) { + switch (spv::Capability(capability)) { + case spv::Capability::LiteralSampler: + case spv::Capability::Sampled1D: + case spv::Capability::Image1D: + case spv::Capability::SampledBuffer: + case spv::Capability::ImageBuffer: + return true; + default: + break; + } + return false; + } + return false; +} + +bool IsEnabledByCapabilityOpenCL_2_0(ValidationState_t& _, + uint32_t capability) { + if (_.HasCapability(spv::Capability::ImageBasic)) { + switch (spv::Capability(capability)) { + case spv::Capability::ImageReadWrite: + case spv::Capability::LiteralSampler: + case spv::Capability::Sampled1D: + case spv::Capability::Image1D: + case spv::Capability::SampledBuffer: + case spv::Capability::ImageBuffer: + return true; + default: + break; + } + return false; + } + return false; +} + +} // namespace + +// Validates that capability declarations use operands allowed in the current +// context. +spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst) { + if (inst->opcode() != spv::Op::OpCapability) return SPV_SUCCESS; + + assert(inst->operands().size() == 1); + + const spv_parsed_operand_t& operand = inst->operand(0); + + assert(operand.num_words == 1); + assert(operand.offset < inst->words().size()); + + const uint32_t capability = inst->word(operand.offset); + const auto capability_str = [&_, capability]() { + spv_operand_desc desc = nullptr; + if (_.grammar().lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, capability, + &desc) != SPV_SUCCESS || + !desc) { + return std::string("Unknown"); + } + return std::string(desc->name); + }; + + const auto env = _.context()->target_env; + const bool opencl_embedded = env == SPV_ENV_OPENCL_EMBEDDED_1_2 || + env == SPV_ENV_OPENCL_EMBEDDED_2_0 || + env == SPV_ENV_OPENCL_EMBEDDED_2_1 || + env == SPV_ENV_OPENCL_EMBEDDED_2_2; + const std::string opencl_profile = opencl_embedded ? "Embedded" : "Full"; + if (env == SPV_ENV_VULKAN_1_0) { + if (!IsSupportGuaranteedVulkan_1_0(capability) && + !IsSupportOptionalVulkan_1_0(capability) && + !IsEnabledByExtension(_, capability)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Capability " << capability_str() + << " is not allowed by Vulkan 1.0 specification" + << " (or requires extension)"; + } + } else if (env == SPV_ENV_VULKAN_1_1) { + if (!IsSupportGuaranteedVulkan_1_1(capability) && + !IsSupportOptionalVulkan_1_1(capability) && + !IsEnabledByExtension(_, capability)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Capability " << capability_str() + << " is not allowed by Vulkan 1.1 specification" + << " (or requires extension)"; + } + } else if (env == SPV_ENV_VULKAN_1_2) { + if (!IsSupportGuaranteedVulkan_1_2(capability) && + !IsSupportOptionalVulkan_1_2(capability) && + !IsEnabledByExtension(_, capability)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Capability " << capability_str() + << " is not allowed by Vulkan 1.2 specification" + << " (or requires extension)"; + } + } else if (env == SPV_ENV_OPENCL_1_2 || env == SPV_ENV_OPENCL_EMBEDDED_1_2) { + if (!IsSupportGuaranteedOpenCL_1_2(capability, opencl_embedded) && + !IsSupportOptionalOpenCL_1_2(capability) && + !IsEnabledByExtension(_, capability) && + !IsEnabledByCapabilityOpenCL_1_2(_, capability)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Capability " << capability_str() + << " is not allowed by OpenCL 1.2 " << opencl_profile + << " Profile specification" + << " (or requires extension or capability)"; + } + } else if (env == SPV_ENV_OPENCL_2_0 || env == SPV_ENV_OPENCL_EMBEDDED_2_0 || + env == SPV_ENV_OPENCL_2_1 || env == SPV_ENV_OPENCL_EMBEDDED_2_1) { + if (!IsSupportGuaranteedOpenCL_2_0(capability, opencl_embedded) && + !IsSupportOptionalOpenCL_1_2(capability) && + !IsEnabledByExtension(_, capability) && + !IsEnabledByCapabilityOpenCL_2_0(_, capability)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Capability " << capability_str() + << " is not allowed by OpenCL 2.0/2.1 " << opencl_profile + << " Profile specification" + << " (or requires extension or capability)"; + } + } else if (env == SPV_ENV_OPENCL_2_2 || env == SPV_ENV_OPENCL_EMBEDDED_2_2) { + if (!IsSupportGuaranteedOpenCL_2_2(capability, opencl_embedded) && + !IsSupportOptionalOpenCL_1_2(capability) && + !IsEnabledByExtension(_, capability) && + !IsEnabledByCapabilityOpenCL_2_0(_, capability)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Capability " << capability_str() + << " is not allowed by OpenCL 2.2 " << opencl_profile + << " Profile specification" + << " (or requires extension or capability)"; + } + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_cfg.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_cfg.cpp new file mode 100644 index 000000000000..9b7161fc4407 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_cfg.cpp @@ -0,0 +1,1270 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/cfa.h" +#include "source/opcode.h" +#include "source/spirv_constant.h" +#include "source/spirv_validator_options.h" +#include "source/val/basic_block.h" +#include "source/val/construct.h" +#include "source/val/function.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) { + auto block = inst->block(); + size_t num_in_ops = inst->words().size() - 3; + if (num_in_ops % 2 != 0) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpPhi does not have an equal number of incoming values and " + "basic blocks."; + } + + if (_.IsVoidType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "OpPhi must not have void result type"; + } + if (_.IsPointerType(inst->type_id()) && + _.addressing_model() == spv::AddressingModel::Logical) { + if (!_.features().variable_pointers) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Using pointers with OpPhi requires capability " + << "VariablePointers or VariablePointersStorageBuffer"; + } + } + + const Instruction* type_inst = _.FindDef(inst->type_id()); + assert(type_inst); + const spv::Op type_opcode = type_inst->opcode(); + + if (!_.options()->before_hlsl_legalization && + !_.HasCapability(spv::Capability::BindlessTextureNV)) { + if (type_opcode == spv::Op::OpTypeSampledImage || + (_.HasCapability(spv::Capability::Shader) && + (type_opcode == spv::Op::OpTypeImage || + type_opcode == spv::Op::OpTypeSampler))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result type cannot be Op" << spvOpcodeString(type_opcode); + } + } + + // Create a uniqued vector of predecessor ids for comparison against + // incoming values. OpBranchConditional %cond %label %label produces two + // predecessors in the CFG. + std::vector pred_ids; + std::transform(block->predecessors()->begin(), block->predecessors()->end(), + std::back_inserter(pred_ids), + [](const BasicBlock* b) { return b->id(); }); + std::sort(pred_ids.begin(), pred_ids.end()); + pred_ids.erase(std::unique(pred_ids.begin(), pred_ids.end()), pred_ids.end()); + + size_t num_edges = num_in_ops / 2; + if (num_edges != pred_ids.size()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpPhi's number of incoming blocks (" << num_edges + << ") does not match block's predecessor count (" + << block->predecessors()->size() << ")."; + } + + std::unordered_set observed_predecessors; + + for (size_t i = 3; i < inst->words().size(); ++i) { + auto inc_id = inst->word(i); + if (i % 2 == 1) { + // Incoming value type must match the phi result type. + auto inc_type_id = _.GetTypeId(inc_id); + if (inst->type_id() != inc_type_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpPhi's result type " << _.getIdName(inst->type_id()) + << " does not match incoming value " << _.getIdName(inc_id) + << " type " << _.getIdName(inc_type_id) << "."; + } + } else { + if (_.GetIdOpcode(inc_id) != spv::Op::OpLabel) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpPhi's incoming basic block " << _.getIdName(inc_id) + << " is not an OpLabel."; + } + + // Incoming basic block must be an immediate predecessor of the phi's + // block. + if (!std::binary_search(pred_ids.begin(), pred_ids.end(), inc_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpPhi's incoming basic block " << _.getIdName(inc_id) + << " is not a predecessor of " << _.getIdName(block->id()) + << "."; + } + + // We must not have already seen this predecessor as one of the phi's + // operands. + if (observed_predecessors.count(inc_id) != 0) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpPhi references incoming basic block " + << _.getIdName(inc_id) << " multiple times."; + } + + // Note the fact that we have now observed this predecessor. + observed_predecessors.insert(inc_id); + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateBranch(ValidationState_t& _, const Instruction* inst) { + // target operands must be OpLabel + const auto id = inst->GetOperandAs(0); + const auto target = _.FindDef(id); + if (!target || spv::Op::OpLabel != target->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "'Target Label' operands for OpBranch must be the ID " + "of an OpLabel instruction"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateBranchConditional(ValidationState_t& _, + const Instruction* inst) { + // num_operands is either 3 or 5 --- if 5, the last two need to be literal + // integers + const auto num_operands = inst->operands().size(); + if (num_operands != 3 && num_operands != 5) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpBranchConditional requires either 3 or 5 parameters"; + } + + // grab the condition operand and check that it is a bool + const auto cond_id = inst->GetOperandAs(0); + const auto cond_op = _.FindDef(cond_id); + if (!cond_op || !cond_op->type_id() || + !_.IsBoolScalarType(cond_op->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) << "Condition operand for " + "OpBranchConditional must be " + "of boolean type"; + } + + // target operands must be OpLabel + // note that we don't need to check that the target labels are in the same + // function, + // PerformCfgChecks already checks for that + const auto true_id = inst->GetOperandAs(1); + const auto true_target = _.FindDef(true_id); + if (!true_target || spv::Op::OpLabel != true_target->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The 'True Label' operand for OpBranchConditional must be the " + "ID of an OpLabel instruction"; + } + + const auto false_id = inst->GetOperandAs(2); + const auto false_target = _.FindDef(false_id); + if (!false_target || spv::Op::OpLabel != false_target->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The 'False Label' operand for OpBranchConditional must be the " + "ID of an OpLabel instruction"; + } + + // A similar requirement for SPV_KHR_maximal_reconvergence is deferred until + // entry point call trees have been reconrded. + if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) && true_id == false_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "In SPIR-V 1.6 or later, True Label and False Label must be " + "different labels"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateSwitch(ValidationState_t& _, const Instruction* inst) { + const auto num_operands = inst->operands().size(); + // At least two operands (selector, default), any more than that are + // literal/target. + + const auto sel_type_id = _.GetOperandTypeId(inst, 0); + if (!_.IsIntScalarType(sel_type_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Selector type must be OpTypeInt"; + } + + const auto default_label = _.FindDef(inst->GetOperandAs(1)); + if (default_label->opcode() != spv::Op::OpLabel) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Default must be an OpLabel instruction"; + } + + // target operands must be OpLabel + for (size_t i = 2; i < num_operands; i += 2) { + // literal, id + const auto id = inst->GetOperandAs(i + 1); + const auto target = _.FindDef(id); + if (!target || spv::Op::OpLabel != target->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "'Target Label' operands for OpSwitch must be IDs of an " + "OpLabel instruction"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateReturnValue(ValidationState_t& _, + const Instruction* inst) { + const auto value_id = inst->GetOperandAs(0); + const auto value = _.FindDef(value_id); + if (!value || !value->type_id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpReturnValue Value " << _.getIdName(value_id) + << " does not represent a value."; + } + auto value_type = _.FindDef(value->type_id()); + if (!value_type || spv::Op::OpTypeVoid == value_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpReturnValue value's type " + << _.getIdName(value->type_id()) << " is missing or void."; + } + + if (_.addressing_model() == spv::AddressingModel::Logical && + spv::Op::OpTypePointer == value_type->opcode() && + !_.features().variable_pointers && !_.options()->relax_logical_pointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpReturnValue value's type " + << _.getIdName(value->type_id()) + << " is a pointer, which is invalid in the Logical addressing " + "model."; + } + + const auto function = inst->function(); + const auto return_type = _.FindDef(function->GetResultTypeId()); + if (!return_type || return_type->id() != value_type->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpReturnValue Value " << _.getIdName(value_id) + << "s type does not match OpFunction's return type."; + } + + return SPV_SUCCESS; +} + +uint32_t operator>>(const spv::LoopControlShift& lhs, + const spv::LoopControlShift& rhs) { + return uint32_t(lhs) >> uint32_t(rhs); +} + +spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { + const auto merge_id = inst->GetOperandAs(0); + const auto merge = _.FindDef(merge_id); + if (!merge || merge->opcode() != spv::Op::OpLabel) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Merge Block " << _.getIdName(merge_id) << " must be an OpLabel"; + } + if (merge_id == inst->block()->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Merge Block may not be the block containing the OpLoopMerge\n"; + } + + const auto continue_id = inst->GetOperandAs(1); + const auto continue_target = _.FindDef(continue_id); + if (!continue_target || continue_target->opcode() != spv::Op::OpLabel) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Continue Target " << _.getIdName(continue_id) + << " must be an OpLabel"; + } + + if (merge_id == continue_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Merge Block and Continue Target must be different ids"; + } + + const auto loop_control = inst->GetOperandAs(2); + if ((loop_control >> spv::LoopControlShift::Unroll) & 0x1 && + (loop_control >> spv::LoopControlShift::DontUnroll) & 0x1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Unroll and DontUnroll loop controls must not both be specified"; + } + if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 && + (loop_control >> spv::LoopControlShift::PeelCount) & 0x1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PeelCount and DontUnroll " + "loop controls must not " + "both be specified"; + } + if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 && + (loop_control >> spv::LoopControlShift::PartialCount) & 0x1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PartialCount and " + "DontUnroll loop controls " + "must not both be specified"; + } + + uint32_t operand = 3; + if ((loop_control >> spv::LoopControlShift::DependencyLength) & 0x1) { + ++operand; + } + if ((loop_control >> spv::LoopControlShift::MinIterations) & 0x1) { + ++operand; + } + if ((loop_control >> spv::LoopControlShift::MaxIterations) & 0x1) { + ++operand; + } + if ((loop_control >> spv::LoopControlShift::IterationMultiple) & 0x1) { + if (inst->operands().size() < operand || + inst->GetOperandAs(operand) == 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "IterationMultiple loop " + "control operand must be " + "greater than zero"; + } + ++operand; + } + if ((loop_control >> spv::LoopControlShift::PeelCount) & 0x1) { + ++operand; + } + if ((loop_control >> spv::LoopControlShift::PartialCount) & 0x1) { + ++operand; + } + + // That the right number of operands is present is checked by the parser. The + // above code tracks operands for expanded validation checking in the future. + + return SPV_SUCCESS; +} + +} // namespace + +void printDominatorList(const BasicBlock& b) { + std::cout << b.id() << " is dominated by: "; + const BasicBlock* bb = &b; + while (bb->immediate_dominator() != bb) { + bb = bb->immediate_dominator(); + std::cout << bb->id() << " "; + } +} + +#define CFG_ASSERT(ASSERT_FUNC, TARGET) \ + if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode + +spv_result_t FirstBlockAssert(ValidationState_t& _, uint32_t target) { + if (_.current_function().IsFirstBlock(target)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(_.current_function().id())) + << "First block " << _.getIdName(target) << " of function " + << _.getIdName(_.current_function().id()) << " is targeted by block " + << _.getIdName(_.current_function().current_block()->id()); + } + return SPV_SUCCESS; +} + +spv_result_t MergeBlockAssert(ValidationState_t& _, uint32_t merge_block) { + if (_.current_function().IsBlockType(merge_block, kBlockTypeMerge)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(_.current_function().id())) + << "Block " << _.getIdName(merge_block) + << " is already a merge block for another header"; + } + return SPV_SUCCESS; +} + +/// Update the continue construct's exit blocks once the backedge blocks are +/// identified in the CFG. +void UpdateContinueConstructExitBlocks( + Function& function, + const std::vector>& back_edges) { + auto& constructs = function.constructs(); + // TODO(umar): Think of a faster way to do this + for (auto& edge : back_edges) { + uint32_t back_edge_block_id; + uint32_t loop_header_block_id; + std::tie(back_edge_block_id, loop_header_block_id) = edge; + auto is_this_header = [=](Construct& c) { + return c.type() == ConstructType::kLoop && + c.entry_block()->id() == loop_header_block_id; + }; + + for (auto construct : constructs) { + if (is_this_header(construct)) { + Construct* continue_construct = + construct.corresponding_constructs().back(); + assert(continue_construct->type() == ConstructType::kContinue); + + BasicBlock* back_edge_block; + std::tie(back_edge_block, std::ignore) = + function.GetBlock(back_edge_block_id); + continue_construct->set_exit(back_edge_block); + } + } + } +} + +std::tuple ConstructNames( + ConstructType type) { + std::string construct_name, header_name, exit_name; + + switch (type) { + case ConstructType::kSelection: + construct_name = "selection"; + header_name = "selection header"; + exit_name = "merge block"; + break; + case ConstructType::kLoop: + construct_name = "loop"; + header_name = "loop header"; + exit_name = "merge block"; + break; + case ConstructType::kContinue: + construct_name = "continue"; + header_name = "continue target"; + exit_name = "back-edge block"; + break; + case ConstructType::kCase: + construct_name = "case"; + header_name = "case entry block"; + exit_name = "case exit block"; + break; + default: + assert(1 == 0 && "Not defined type"); + } + + return std::make_tuple(construct_name, header_name, exit_name); +} + +/// Constructs an error message for construct validation errors +std::string ConstructErrorString(const Construct& construct, + const std::string& header_string, + const std::string& exit_string, + const std::string& dominate_text) { + std::string construct_name, header_name, exit_name; + std::tie(construct_name, header_name, exit_name) = + ConstructNames(construct.type()); + + // TODO(umar): Add header block for continue constructs to error message + return "The " + construct_name + " construct with the " + header_name + " " + + header_string + " " + dominate_text + " the " + exit_name + " " + + exit_string; +} + +// Finds the fall through case construct of |target_block| and records it in +// |case_fall_through|. Returns SPV_ERROR_INVALID_CFG if the case construct +// headed by |target_block| branches to multiple case constructs. +spv_result_t FindCaseFallThrough( + ValidationState_t& _, BasicBlock* target_block, uint32_t* case_fall_through, + const BasicBlock* merge, const std::unordered_set& case_targets, + Function* function) { + std::vector stack; + stack.push_back(target_block); + std::unordered_set visited; + bool target_reachable = target_block->structurally_reachable(); + int target_depth = function->GetBlockDepth(target_block); + while (!stack.empty()) { + auto block = stack.back(); + stack.pop_back(); + + if (block == merge) continue; + + if (!visited.insert(block).second) continue; + + if (target_reachable && block->structurally_reachable() && + target_block->structurally_dominates(*block)) { + // Still in the case construct. + for (auto successor : *block->successors()) { + stack.push_back(successor); + } + } else { + // Exiting the case construct to non-merge block. + if (!case_targets.count(block->id())) { + int depth = function->GetBlockDepth(block); + if ((depth < target_depth) || + (depth == target_depth && block->is_type(kBlockTypeContinue))) { + continue; + } + + return _.diag(SPV_ERROR_INVALID_CFG, target_block->label()) + << "Case construct that targets " + << _.getIdName(target_block->id()) + << " has invalid branch to block " << _.getIdName(block->id()) + << " (not another case construct, corresponding merge, outer " + "loop merge or outer loop continue)"; + } + + if (*case_fall_through == 0u) { + if (target_block != block) { + *case_fall_through = block->id(); + } + } else if (*case_fall_through != block->id()) { + // Case construct has at most one branch to another case construct. + return _.diag(SPV_ERROR_INVALID_CFG, target_block->label()) + << "Case construct that targets " + << _.getIdName(target_block->id()) + << " has branches to multiple other case construct targets " + << _.getIdName(*case_fall_through) << " and " + << _.getIdName(block->id()); + } + } + } + + return SPV_SUCCESS; +} + +spv_result_t StructuredSwitchChecks(ValidationState_t& _, Function* function, + const Instruction* switch_inst, + const BasicBlock* header, + const BasicBlock* merge) { + std::unordered_set case_targets; + for (uint32_t i = 1; i < switch_inst->operands().size(); i += 2) { + uint32_t target = switch_inst->GetOperandAs(i); + if (target != merge->id()) case_targets.insert(target); + } + // Tracks how many times each case construct is targeted by another case + // construct. + std::map num_fall_through_targeted; + uint32_t default_case_fall_through = 0u; + uint32_t default_target = switch_inst->GetOperandAs(1u); + bool default_appears_multiple_times = false; + for (uint32_t i = 3; i < switch_inst->operands().size(); i += 2) { + if (default_target == switch_inst->GetOperandAs(i)) { + default_appears_multiple_times = true; + break; + } + } + std::unordered_map seen_to_fall_through; + for (uint32_t i = 1; i < switch_inst->operands().size(); i += 2) { + uint32_t target = switch_inst->GetOperandAs(i); + if (target == merge->id()) continue; + + uint32_t case_fall_through = 0u; + auto seen_iter = seen_to_fall_through.find(target); + if (seen_iter == seen_to_fall_through.end()) { + const auto target_block = function->GetBlock(target).first; + // OpSwitch must dominate all its case constructs. + if (header->structurally_reachable() && + target_block->structurally_reachable() && + !header->structurally_dominates(*target_block)) { + return _.diag(SPV_ERROR_INVALID_CFG, header->label()) + << "Switch header " << _.getIdName(header->id()) + << " does not structurally dominate its case construct " + << _.getIdName(target); + } + + if (auto error = FindCaseFallThrough(_, target_block, &case_fall_through, + merge, case_targets, function)) { + return error; + } + + // Track how many time the fall through case has been targeted. + if (case_fall_through != 0u) { + auto where = num_fall_through_targeted.lower_bound(case_fall_through); + if (where == num_fall_through_targeted.end() || + where->first != case_fall_through) { + num_fall_through_targeted.insert( + where, std::make_pair(case_fall_through, 1)); + } else { + where->second++; + } + } + seen_to_fall_through.insert(std::make_pair(target, case_fall_through)); + } else { + case_fall_through = seen_iter->second; + } + + if (case_fall_through == default_target && + !default_appears_multiple_times) { + case_fall_through = default_case_fall_through; + } + if (case_fall_through != 0u) { + bool is_default = i == 1; + if (is_default) { + default_case_fall_through = case_fall_through; + } else { + // Allow code like: + // case x: + // case y: + // ... + // case z: + // + // Where x and y target the same block and fall through to z. + uint32_t j = i; + while ((j + 2 < switch_inst->operands().size()) && + target == switch_inst->GetOperandAs(j + 2)) { + j += 2; + } + // If Target T1 branches to Target T2, or if Target T1 branches to the + // Default target and the Default target branches to Target T2, then T1 + // must immediately precede T2 in the list of OpSwitch Target operands. + if ((switch_inst->operands().size() < j + 2) || + (case_fall_through != switch_inst->GetOperandAs(j + 2))) { + return _.diag(SPV_ERROR_INVALID_CFG, switch_inst) + << "Case construct that targets " << _.getIdName(target) + << " has branches to the case construct that targets " + << _.getIdName(case_fall_through) + << ", but does not immediately precede it in the " + "OpSwitch's target list"; + } + } + } + } + + // Each case construct must be branched to by at most one other case + // construct. + for (const auto& pair : num_fall_through_targeted) { + if (pair.second > 1) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(pair.first)) + << "Multiple case constructs have branches to the case construct " + "that targets " + << _.getIdName(pair.first); + } + } + + return SPV_SUCCESS; +} + +// Validates that all CFG divergences (i.e. conditional branch or switch) are +// structured correctly. Either divergence is preceded by a merge instruction +// or the divergence introduces at most one unseen label. +spv_result_t ValidateStructuredSelections( + ValidationState_t& _, const std::vector& postorder) { + std::unordered_set seen; + for (auto iter = postorder.rbegin(); iter != postorder.rend(); ++iter) { + const auto* block = *iter; + const auto* terminator = block->terminator(); + if (!terminator) continue; + const auto index = terminator - &_.ordered_instructions()[0]; + auto* merge = &_.ordered_instructions()[index - 1]; + // Marks merges and continues as seen. + if (merge->opcode() == spv::Op::OpSelectionMerge) { + seen.insert(merge->GetOperandAs(0)); + } else if (merge->opcode() == spv::Op::OpLoopMerge) { + seen.insert(merge->GetOperandAs(0)); + seen.insert(merge->GetOperandAs(1)); + } else { + // Only track the pointer if it is a merge instruction. + merge = nullptr; + } + + // Skip unreachable blocks. + if (!block->structurally_reachable()) continue; + + if (terminator->opcode() == spv::Op::OpBranchConditional) { + const auto true_label = terminator->GetOperandAs(1); + const auto false_label = terminator->GetOperandAs(2); + // Mark the upcoming blocks as seen now, but only error out if this block + // was missing a merge instruction and both labels hadn't been seen + // previously. + const bool true_label_unseen = seen.insert(true_label).second; + const bool false_label_unseen = seen.insert(false_label).second; + if ((!merge || merge->opcode() == spv::Op::OpLoopMerge) && + true_label_unseen && false_label_unseen) { + return _.diag(SPV_ERROR_INVALID_CFG, terminator) + << "Selection must be structured"; + } + } else if (terminator->opcode() == spv::Op::OpSwitch) { + if (!merge) { + return _.diag(SPV_ERROR_INVALID_CFG, terminator) + << "OpSwitch must be preceded by an OpSelectionMerge " + "instruction"; + } + // Mark the targets as seen. + for (uint32_t i = 1; i < terminator->operands().size(); i += 2) { + const auto target = terminator->GetOperandAs(i); + seen.insert(target); + } + } + } + + return SPV_SUCCESS; +} + +spv_result_t StructuredControlFlowChecks( + ValidationState_t& _, Function* function, + const std::vector>& back_edges, + const std::vector& postorder) { + /// Check all backedges target only loop headers and have exactly one + /// back-edge branching to it + + // Map a loop header to blocks with back-edges to the loop header. + std::map> loop_latch_blocks; + for (auto back_edge : back_edges) { + uint32_t back_edge_block; + uint32_t header_block; + std::tie(back_edge_block, header_block) = back_edge; + if (!function->IsBlockType(header_block, kBlockTypeLoop)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(back_edge_block)) + << "Back-edges (" << _.getIdName(back_edge_block) << " -> " + << _.getIdName(header_block) + << ") can only be formed between a block and a loop header."; + } + loop_latch_blocks[header_block].insert(back_edge_block); + } + + // Check the loop headers have exactly one back-edge branching to it + for (BasicBlock* loop_header : function->ordered_blocks()) { + if (!loop_header->structurally_reachable()) continue; + if (!loop_header->is_type(kBlockTypeLoop)) continue; + auto loop_header_id = loop_header->id(); + auto num_latch_blocks = loop_latch_blocks[loop_header_id].size(); + if (num_latch_blocks != 1) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(loop_header_id)) + << "Loop header " << _.getIdName(loop_header_id) + << " is targeted by " << num_latch_blocks + << " back-edge blocks but the standard requires exactly one"; + } + } + + // Check construct rules + for (const Construct& construct : function->constructs()) { + auto header = construct.entry_block(); + if (!header->structurally_reachable()) continue; + auto merge = construct.exit_block(); + + if (!merge) { + std::string construct_name, header_name, exit_name; + std::tie(construct_name, header_name, exit_name) = + ConstructNames(construct.type()); + return _.diag(SPV_ERROR_INTERNAL, _.FindDef(header->id())) + << "Construct " + construct_name + " with " + header_name + " " + + _.getIdName(header->id()) + " does not have a " + + exit_name + ". This may be a bug in the validator."; + } + + // If the header is reachable, the merge is guaranteed to be structurally + // reachable. + if (!header->structurally_dominates(*merge)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(merge->id())) + << ConstructErrorString(construct, _.getIdName(header->id()), + _.getIdName(merge->id()), + "does not structurally dominate"); + } + + // If it's really a merge block for a selection or loop, then it must be + // *strictly* structrually dominated by the header. + if (construct.ExitBlockIsMergeBlock() && (header == merge)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(merge->id())) + << ConstructErrorString(construct, _.getIdName(header->id()), + _.getIdName(merge->id()), + "does not strictly structurally dominate"); + } + + // Check post-dominance for continue constructs. But dominance and + // post-dominance only make sense when the construct is reachable. + if (construct.type() == ConstructType::kContinue) { + if (!merge->structurally_postdominates(*header)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(merge->id())) + << ConstructErrorString(construct, _.getIdName(header->id()), + _.getIdName(merge->id()), + "is not structurally post dominated by"); + } + } + + Construct::ConstructBlockSet construct_blocks = construct.blocks(function); + std::string construct_name, header_name, exit_name; + std::tie(construct_name, header_name, exit_name) = + ConstructNames(construct.type()); + for (auto block : construct_blocks) { + // Check that all exits from the construct are via structured exits. + for (auto succ : *block->successors()) { + if (!construct_blocks.count(succ) && + !construct.IsStructuredExit(_, succ)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) + << "block " << _.getIdName(block->id()) << " exits the " + << construct_name << " headed by " + << _.getIdName(header->id()) + << ", but not via a structured exit"; + } + } + if (block == header) continue; + // Check that for all non-header blocks, all predecessors are within this + // construct. + for (auto pred : *block->predecessors()) { + if (pred->structurally_reachable() && !construct_blocks.count(pred)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(pred->id())) + << "block " << pred->id() << " branches to the " + << construct_name << " construct, but not to the " + << header_name << " " << header->id(); + } + } + + if (block->is_type(BlockType::kBlockTypeSelection) || + block->is_type(BlockType::kBlockTypeLoop)) { + size_t index = (block->terminator() - &_.ordered_instructions()[0]) - 1; + const auto& merge_inst = _.ordered_instructions()[index]; + if (merge_inst.opcode() == spv::Op::OpSelectionMerge || + merge_inst.opcode() == spv::Op::OpLoopMerge) { + uint32_t merge_id = merge_inst.GetOperandAs(0); + auto merge_block = function->GetBlock(merge_id).first; + if (merge_block->structurally_reachable() && + !construct_blocks.count(merge_block)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) + << "Header block " << _.getIdName(block->id()) + << " is contained in the " << construct_name + << " construct headed by " << _.getIdName(header->id()) + << ", but its merge block " << _.getIdName(merge_id) + << " is not"; + } + } + } + } + + if (construct.type() == ConstructType::kLoop) { + // If the continue target differs from the loop header, then check that + // all edges into the continue construct come from within the loop. + const auto index = header->terminator() - &_.ordered_instructions()[0]; + const auto& merge_inst = _.ordered_instructions()[index - 1]; + const auto continue_id = merge_inst.GetOperandAs(1); + const auto* continue_inst = _.FindDef(continue_id); + // OpLabel instructions aren't stored as part of the basic block for + // legacy reaasons. Grab the next instruction and use it's block pointer + // instead. + const auto next_index = + (continue_inst - &_.ordered_instructions()[0]) + 1; + const auto& next_inst = _.ordered_instructions()[next_index]; + const auto* continue_target = next_inst.block(); + if (header->id() != continue_id) { + for (auto pred : *continue_target->predecessors()) { + // Ignore back-edges from within the continue construct. + bool is_back_edge = false; + for (auto back_edge : back_edges) { + uint32_t back_edge_block; + uint32_t header_block; + std::tie(back_edge_block, header_block) = back_edge; + if (header_block == continue_id && back_edge_block == pred->id()) + is_back_edge = true; + } + if (!construct_blocks.count(pred) && !is_back_edge) { + return _.diag(SPV_ERROR_INVALID_CFG, pred->terminator()) + << "Block " << _.getIdName(pred->id()) + << " branches to the loop continue target " + << _.getIdName(continue_id) + << ", but is not contained in the associated loop construct " + << _.getIdName(header->id()); + } + } + } + } + + // Checks rules for case constructs. + if (construct.type() == ConstructType::kSelection && + header->terminator()->opcode() == spv::Op::OpSwitch) { + const auto terminator = header->terminator(); + if (auto error = + StructuredSwitchChecks(_, function, terminator, header, merge)) { + return error; + } + } + } + + if (auto error = ValidateStructuredSelections(_, postorder)) { + return error; + } + + return SPV_SUCCESS; +} + +spv_result_t MaximalReconvergenceChecks(ValidationState_t& _) { + // Find all the entry points with the MaximallyReconvergencesKHR execution + // mode. + std::unordered_set maximal_funcs; + std::unordered_set maximal_entry_points; + for (auto entry_point : _.entry_points()) { + const auto* exec_modes = _.GetExecutionModes(entry_point); + if (exec_modes && + exec_modes->count(spv::ExecutionMode::MaximallyReconvergesKHR)) { + maximal_entry_points.insert(entry_point); + maximal_funcs.insert(entry_point); + } + } + + if (maximal_entry_points.empty()) { + return SPV_SUCCESS; + } + + // Find all the functions reachable from a maximal reconvergence entry point. + for (const auto& func : _.functions()) { + const auto& entry_points = _.EntryPointReferences(func.id()); + for (auto id : entry_points) { + if (maximal_entry_points.count(id)) { + maximal_funcs.insert(func.id()); + break; + } + } + } + + // Check for conditional branches with the same true and false targets. + for (const auto& inst : _.ordered_instructions()) { + if (inst.opcode() == spv::Op::OpBranchConditional) { + const auto true_id = inst.GetOperandAs(1); + const auto false_id = inst.GetOperandAs(2); + if (true_id == false_id && maximal_funcs.count(inst.function()->id())) { + return _.diag(SPV_ERROR_INVALID_ID, &inst) + << "In entry points using the MaximallyReconvergesKHR execution " + "mode, True Label and False Label must be different labels"; + } + } + } + + // Check for invalid multiple predecessors. Only loop headers, continue + // targets, merge targets or switch targets or defaults may have multiple + // unique predecessors. + for (const auto& func : _.functions()) { + if (!maximal_funcs.count(func.id())) continue; + + for (const auto* block : func.ordered_blocks()) { + std::unordered_set unique_preds; + const auto* preds = block->predecessors(); + if (!preds) continue; + + for (const auto* pred : *preds) { + unique_preds.insert(pred->id()); + } + if (unique_preds.size() < 2) continue; + + const auto* terminator = block->terminator(); + const auto index = terminator - &_.ordered_instructions()[0]; + const auto* pre_terminator = &_.ordered_instructions()[index - 1]; + if (pre_terminator->opcode() == spv::Op::OpLoopMerge) continue; + + const auto* label = _.FindDef(block->id()); + bool ok = false; + for (const auto& pair : label->uses()) { + const auto* use_inst = pair.first; + switch (use_inst->opcode()) { + case spv::Op::OpSelectionMerge: + case spv::Op::OpLoopMerge: + case spv::Op::OpSwitch: + ok = true; + break; + default: + break; + } + } + if (!ok) { + return _.diag(SPV_ERROR_INVALID_CFG, label) + << "In entry points using the MaximallyReconvergesKHR " + "execution mode, this basic block must not have multiple " + "unique predecessors"; + } + } + } + + return SPV_SUCCESS; +} + +spv_result_t PerformCfgChecks(ValidationState_t& _) { + for (auto& function : _.functions()) { + // Check all referenced blocks are defined within a function + if (function.undefined_block_count() != 0) { + std::string undef_blocks("{"); + bool first = true; + for (auto undefined_block : function.undefined_blocks()) { + undef_blocks += _.getIdName(undefined_block); + if (!first) { + undef_blocks += " "; + } + first = false; + } + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(function.id())) + << "Block(s) " << undef_blocks << "}" + << " are referenced but not defined in function " + << _.getIdName(function.id()); + } + + // Set each block's immediate dominator. + // + // We want to analyze all the blocks in the function, even in degenerate + // control flow cases including unreachable blocks. So use the augmented + // CFG to ensure we cover all the blocks. + std::vector postorder; + auto ignore_block = [](const BasicBlock*) {}; + auto no_terminal_blocks = [](const BasicBlock*) { return false; }; + if (!function.ordered_blocks().empty()) { + /// calculate dominators + CFA::DepthFirstTraversal( + function.first_block(), function.AugmentedCFGSuccessorsFunction(), + ignore_block, [&](const BasicBlock* b) { postorder.push_back(b); }, + no_terminal_blocks); + auto edges = CFA::CalculateDominators( + postorder, function.AugmentedCFGPredecessorsFunction()); + for (auto edge : edges) { + if (edge.first != edge.second) + edge.first->SetImmediateDominator(edge.second); + } + } + + auto& blocks = function.ordered_blocks(); + if (!blocks.empty()) { + // Check if the order of blocks in the binary appear before the blocks + // they dominate + for (auto block = begin(blocks) + 1; block != end(blocks); ++block) { + if (auto idom = (*block)->immediate_dominator()) { + if (idom != function.pseudo_entry_block() && + block == std::find(begin(blocks), block, idom)) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(idom->id())) + << "Block " << _.getIdName((*block)->id()) + << " appears in the binary before its dominator " + << _.getIdName(idom->id()); + } + } + } + // If we have structured control flow, check that no block has a control + // flow nesting depth larger than the limit. + if (_.HasCapability(spv::Capability::Shader)) { + const int control_flow_nesting_depth_limit = + _.options()->universal_limits_.max_control_flow_nesting_depth; + for (auto block = begin(blocks); block != end(blocks); ++block) { + if (function.GetBlockDepth(*block) > + control_flow_nesting_depth_limit) { + return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef((*block)->id())) + << "Maximum Control Flow nesting depth exceeded."; + } + } + } + } + + /// Structured control flow checks are only required for shader capabilities + if (_.HasCapability(spv::Capability::Shader)) { + // Calculate structural dominance. + postorder.clear(); + std::vector postdom_postorder; + std::vector> back_edges; + if (!function.ordered_blocks().empty()) { + /// calculate dominators + CFA::DepthFirstTraversal( + function.first_block(), + function.AugmentedStructuralCFGSuccessorsFunction(), ignore_block, + [&](const BasicBlock* b) { postorder.push_back(b); }, + no_terminal_blocks); + auto edges = CFA::CalculateDominators( + postorder, function.AugmentedStructuralCFGPredecessorsFunction()); + for (auto edge : edges) { + if (edge.first != edge.second) + edge.first->SetImmediateStructuralDominator(edge.second); + } + + /// calculate post dominators + CFA::DepthFirstTraversal( + function.pseudo_exit_block(), + function.AugmentedStructuralCFGPredecessorsFunction(), ignore_block, + [&](const BasicBlock* b) { postdom_postorder.push_back(b); }, + no_terminal_blocks); + auto postdom_edges = CFA::CalculateDominators( + postdom_postorder, + function.AugmentedStructuralCFGSuccessorsFunction()); + for (auto edge : postdom_edges) { + edge.first->SetImmediateStructuralPostDominator(edge.second); + } + /// calculate back edges. + CFA::DepthFirstTraversal( + function.pseudo_entry_block(), + function.AugmentedStructuralCFGSuccessorsFunction(), ignore_block, + ignore_block, + [&](const BasicBlock* from, const BasicBlock* to) { + // A back edge must be a real edge. Since the augmented successors + // contain structural edges, filter those from consideration. + for (const auto* succ : *(from->successors())) { + if (succ == to) back_edges.emplace_back(from->id(), to->id()); + } + }, + no_terminal_blocks); + } + UpdateContinueConstructExitBlocks(function, back_edges); + + if (auto error = + StructuredControlFlowChecks(_, &function, back_edges, postorder)) + return error; + } + } + + if (auto error = MaximalReconvergenceChecks(_)) { + return error; + } + + return SPV_SUCCESS; +} + +spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { + spv::Op opcode = inst->opcode(); + switch (opcode) { + case spv::Op::OpLabel: + if (auto error = _.current_function().RegisterBlock(inst->id())) + return error; + + // TODO(github:1661) This should be done in the + // ValidationState::RegisterInstruction method but because of the order of + // passes the OpLabel ends up not being part of the basic block it starts. + _.current_function().current_block()->set_label(inst); + break; + case spv::Op::OpLoopMerge: { + uint32_t merge_block = inst->GetOperandAs(0); + uint32_t continue_block = inst->GetOperandAs(1); + CFG_ASSERT(MergeBlockAssert, merge_block); + + if (auto error = _.current_function().RegisterLoopMerge(merge_block, + continue_block)) + return error; + } break; + case spv::Op::OpSelectionMerge: { + uint32_t merge_block = inst->GetOperandAs(0); + CFG_ASSERT(MergeBlockAssert, merge_block); + + if (auto error = _.current_function().RegisterSelectionMerge(merge_block)) + return error; + } break; + case spv::Op::OpBranch: { + uint32_t target = inst->GetOperandAs(0); + CFG_ASSERT(FirstBlockAssert, target); + + _.current_function().RegisterBlockEnd({target}); + } break; + case spv::Op::OpBranchConditional: { + uint32_t tlabel = inst->GetOperandAs(1); + uint32_t flabel = inst->GetOperandAs(2); + CFG_ASSERT(FirstBlockAssert, tlabel); + CFG_ASSERT(FirstBlockAssert, flabel); + + _.current_function().RegisterBlockEnd({tlabel, flabel}); + } break; + + case spv::Op::OpSwitch: { + std::vector cases; + for (size_t i = 1; i < inst->operands().size(); i += 2) { + uint32_t target = inst->GetOperandAs(i); + CFG_ASSERT(FirstBlockAssert, target); + cases.push_back(target); + } + _.current_function().RegisterBlockEnd({cases}); + } break; + case spv::Op::OpReturn: { + const uint32_t return_type = _.current_function().GetResultTypeId(); + const Instruction* return_type_inst = _.FindDef(return_type); + assert(return_type_inst); + if (return_type_inst->opcode() != spv::Op::OpTypeVoid) + return _.diag(SPV_ERROR_INVALID_CFG, inst) + << "OpReturn can only be called from a function with void " + << "return type."; + _.current_function().RegisterBlockEnd(std::vector()); + break; + } + case spv::Op::OpKill: + case spv::Op::OpReturnValue: + case spv::Op::OpUnreachable: + case spv::Op::OpTerminateInvocation: + case spv::Op::OpIgnoreIntersectionKHR: + case spv::Op::OpTerminateRayKHR: + case spv::Op::OpEmitMeshTasksEXT: + _.current_function().RegisterBlockEnd(std::vector()); + // Ops with dedicated passes check for the Execution Model there + if (opcode == spv::Op::OpKill) { + _.current_function().RegisterExecutionModelLimitation( + spv::ExecutionModel::Fragment, + "OpKill requires Fragment execution model"); + } + if (opcode == spv::Op::OpTerminateInvocation) { + _.current_function().RegisterExecutionModelLimitation( + spv::ExecutionModel::Fragment, + "OpTerminateInvocation requires Fragment execution model"); + } + if (opcode == spv::Op::OpIgnoreIntersectionKHR) { + _.current_function().RegisterExecutionModelLimitation( + spv::ExecutionModel::AnyHitKHR, + "OpIgnoreIntersectionKHR requires AnyHitKHR execution model"); + } + if (opcode == spv::Op::OpTerminateRayKHR) { + _.current_function().RegisterExecutionModelLimitation( + spv::ExecutionModel::AnyHitKHR, + "OpTerminateRayKHR requires AnyHitKHR execution model"); + } + + break; + default: + break; + } + return SPV_SUCCESS; +} + +void ReachabilityPass(ValidationState_t& _) { + for (auto& f : _.functions()) { + std::vector stack; + auto entry = f.first_block(); + // Skip function declarations. + if (entry) stack.push_back(entry); + + while (!stack.empty()) { + auto block = stack.back(); + stack.pop_back(); + + if (block->reachable()) continue; + + block->set_reachable(true); + for (auto succ : *block->successors()) { + stack.push_back(succ); + } + } + } + + // Repeat for structural reachability. + for (auto& f : _.functions()) { + std::vector stack; + auto entry = f.first_block(); + // Skip function declarations. + if (entry) stack.push_back(entry); + + while (!stack.empty()) { + auto block = stack.back(); + stack.pop_back(); + + if (block->structurally_reachable()) continue; + + block->set_structurally_reachable(true); + for (auto succ : *block->structural_successors()) { + stack.push_back(succ); + } + } + } +} + +spv_result_t ControlFlowPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpPhi: + if (auto error = ValidatePhi(_, inst)) return error; + break; + case spv::Op::OpBranch: + if (auto error = ValidateBranch(_, inst)) return error; + break; + case spv::Op::OpBranchConditional: + if (auto error = ValidateBranchConditional(_, inst)) return error; + break; + case spv::Op::OpReturnValue: + if (auto error = ValidateReturnValue(_, inst)) return error; + break; + case spv::Op::OpSwitch: + if (auto error = ValidateSwitch(_, inst)) return error; + break; + case spv::Op::OpLoopMerge: + if (auto error = ValidateLoopMerge(_, inst)) return error; + break; + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_composites.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_composites.cpp new file mode 100644 index 000000000000..26486dac70b9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_composites.cpp @@ -0,0 +1,635 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of composite SPIR-V instructions. + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Returns the type of the value accessed by OpCompositeExtract or +// OpCompositeInsert instruction. The function traverses the hierarchy of +// nested data structures (structs, arrays, vectors, matrices) as directed by +// the sequence of indices in the instruction. May return error if traversal +// fails (encountered non-composite, out of bounds, no indices, nesting too +// deep). +spv_result_t GetExtractInsertValueType(ValidationState_t& _, + const Instruction* inst, + uint32_t* member_type) { + const spv::Op opcode = inst->opcode(); + assert(opcode == spv::Op::OpCompositeExtract || + opcode == spv::Op::OpCompositeInsert); + uint32_t word_index = opcode == spv::Op::OpCompositeExtract ? 4 : 5; + const uint32_t num_words = static_cast(inst->words().size()); + const uint32_t composite_id_index = word_index - 1; + const uint32_t num_indices = num_words - word_index; + const uint32_t kCompositeExtractInsertMaxNumIndices = 255; + + if (num_indices == 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected at least one index to Op" + << spvOpcodeString(inst->opcode()) << ", zero found"; + + } else if (num_indices > kCompositeExtractInsertMaxNumIndices) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The number of indexes in Op" << spvOpcodeString(opcode) + << " may not exceed " << kCompositeExtractInsertMaxNumIndices + << ". Found " << num_indices << " indexes."; + } + + *member_type = _.GetTypeId(inst->word(composite_id_index)); + if (*member_type == 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Composite to be an object of composite type"; + } + + for (; word_index < num_words; ++word_index) { + const uint32_t component_index = inst->word(word_index); + const Instruction* const type_inst = _.FindDef(*member_type); + assert(type_inst); + switch (type_inst->opcode()) { + case spv::Op::OpTypeVector: { + *member_type = type_inst->word(2); + const uint32_t vector_size = type_inst->word(3); + if (component_index >= vector_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Vector access is out of bounds, vector size is " + << vector_size << ", but access index is " << component_index; + } + break; + } + case spv::Op::OpTypeMatrix: { + *member_type = type_inst->word(2); + const uint32_t num_cols = type_inst->word(3); + if (component_index >= num_cols) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Matrix access is out of bounds, matrix has " << num_cols + << " columns, but access index is " << component_index; + } + break; + } + case spv::Op::OpTypeArray: { + uint64_t array_size = 0; + auto size = _.FindDef(type_inst->word(3)); + *member_type = type_inst->word(2); + if (spvOpcodeIsSpecConstant(size->opcode())) { + // Cannot verify against the size of this array. + break; + } + + if (!_.EvalConstantValUint64(type_inst->word(3), &array_size)) { + assert(0 && "Array type definition is corrupt"); + } + if (component_index >= array_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Array access is out of bounds, array size is " + << array_size << ", but access index is " << component_index; + } + break; + } + case spv::Op::OpTypeRuntimeArray: { + *member_type = type_inst->word(2); + // Array size is unknown. + break; + } + case spv::Op::OpTypeStruct: { + const size_t num_struct_members = type_inst->words().size() - 2; + if (component_index >= num_struct_members) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Index is out of bounds, can not find index " + << component_index << " in the structure '" + << type_inst->id() << "'. This structure has " + << num_struct_members << " members. Largest valid index is " + << num_struct_members - 1 << "."; + } + *member_type = type_inst->word(component_index + 2); + break; + } + case spv::Op::OpTypeCooperativeMatrixKHR: + case spv::Op::OpTypeCooperativeMatrixNV: { + *member_type = type_inst->word(2); + break; + } + default: + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Reached non-composite type while indexes still remain to " + "be traversed."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _, + const Instruction* inst) { + const uint32_t result_type = inst->type_id(); + const spv::Op result_opcode = _.GetIdOpcode(result_type); + if (!spvOpcodeIsScalarType(result_opcode)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a scalar type"; + } + + const uint32_t vector_type = _.GetOperandTypeId(inst, 2); + const spv::Op vector_opcode = _.GetIdOpcode(vector_type); + if (vector_opcode != spv::Op::OpTypeVector) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Vector type to be OpTypeVector"; + } + + if (_.GetComponentType(vector_type) != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Vector component type to be equal to Result Type"; + } + + const auto index = _.FindDef(inst->GetOperandAs(3)); + if (!index || index->type_id() == 0 || !_.IsIntScalarType(index->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Index to be int scalar"; + } + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cannot extract from a vector of 8- or 16-bit types"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateVectorInsertDyanmic(ValidationState_t& _, + const Instruction* inst) { + const uint32_t result_type = inst->type_id(); + const spv::Op result_opcode = _.GetIdOpcode(result_type); + if (result_opcode != spv::Op::OpTypeVector) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be OpTypeVector"; + } + + const uint32_t vector_type = _.GetOperandTypeId(inst, 2); + if (vector_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Vector type to be equal to Result Type"; + } + + const uint32_t component_type = _.GetOperandTypeId(inst, 3); + if (_.GetComponentType(result_type) != component_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Component type to be equal to Result Type " + << "component type"; + } + + const uint32_t index_type = _.GetOperandTypeId(inst, 4); + if (!_.IsIntScalarType(index_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Index to be int scalar"; + } + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cannot insert into a vector of 8- or 16-bit types"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateCompositeConstruct(ValidationState_t& _, + const Instruction* inst) { + const uint32_t num_operands = static_cast(inst->operands().size()); + const uint32_t result_type = inst->type_id(); + const spv::Op result_opcode = _.GetIdOpcode(result_type); + switch (result_opcode) { + case spv::Op::OpTypeVector: { + const uint32_t num_result_components = _.GetDimension(result_type); + const uint32_t result_component_type = _.GetComponentType(result_type); + uint32_t given_component_count = 0; + + if (num_operands <= 3) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected number of constituents to be at least 2"; + } + + for (uint32_t operand_index = 2; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (operand_type == result_component_type) { + ++given_component_count; + } else { + if (_.GetIdOpcode(operand_type) != spv::Op::OpTypeVector || + _.GetComponentType(operand_type) != result_component_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Constituents to be scalars or vectors of" + << " the same type as Result Type components"; + } + + given_component_count += _.GetDimension(operand_type); + } + } + + if (num_result_components != given_component_count) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected total number of given components to be equal " + << "to the size of Result Type vector"; + } + + break; + } + case spv::Op::OpTypeMatrix: { + uint32_t result_num_rows = 0; + uint32_t result_num_cols = 0; + uint32_t result_col_type = 0; + uint32_t result_component_type = 0; + if (!_.GetMatrixTypeInfo(result_type, &result_num_rows, &result_num_cols, + &result_col_type, &result_component_type)) { + assert(0); + } + + if (result_num_cols + 2 != num_operands) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected total number of Constituents to be equal " + << "to the number of columns of Result Type matrix"; + } + + for (uint32_t operand_index = 2; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (operand_type != result_col_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Constituent type to be equal to the column " + << "type Result Type matrix"; + } + } + + break; + } + case spv::Op::OpTypeArray: { + const Instruction* const array_inst = _.FindDef(result_type); + assert(array_inst); + assert(array_inst->opcode() == spv::Op::OpTypeArray); + + auto size = _.FindDef(array_inst->word(3)); + if (spvOpcodeIsSpecConstant(size->opcode())) { + // Cannot verify against the size of this array. + break; + } + + uint64_t array_size = 0; + if (!_.EvalConstantValUint64(array_inst->word(3), &array_size)) { + assert(0 && "Array type definition is corrupt"); + } + + if (array_size + 2 != num_operands) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected total number of Constituents to be equal " + << "to the number of elements of Result Type array"; + } + + const uint32_t result_component_type = array_inst->word(2); + for (uint32_t operand_index = 2; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (operand_type != result_component_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Constituent type to be equal to the column " + << "type Result Type array"; + } + } + + break; + } + case spv::Op::OpTypeStruct: { + const Instruction* const struct_inst = _.FindDef(result_type); + assert(struct_inst); + assert(struct_inst->opcode() == spv::Op::OpTypeStruct); + + if (struct_inst->operands().size() + 1 != num_operands) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected total number of Constituents to be equal " + << "to the number of members of Result Type struct"; + } + + for (uint32_t operand_index = 2; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + const uint32_t member_type = struct_inst->word(operand_index); + if (operand_type != member_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Constituent type to be equal to the " + << "corresponding member type of Result Type struct"; + } + } + + break; + } + case spv::Op::OpTypeCooperativeMatrixKHR: { + const auto result_type_inst = _.FindDef(result_type); + assert(result_type_inst); + const auto component_type_id = + result_type_inst->GetOperandAs(1); + + if (3 != num_operands) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Must be only one constituent"; + } + + const uint32_t operand_type_id = _.GetOperandTypeId(inst, 2); + + if (operand_type_id != component_type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Constituent type to be equal to the component type"; + } + break; + } + case spv::Op::OpTypeCooperativeMatrixNV: { + const auto result_type_inst = _.FindDef(result_type); + assert(result_type_inst); + const auto component_type_id = + result_type_inst->GetOperandAs(1); + + if (3 != num_operands) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected single constituent"; + } + + const uint32_t operand_type_id = _.GetOperandTypeId(inst, 2); + + if (operand_type_id != component_type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Constituent type to be equal to the component type"; + } + + break; + } + default: { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a composite type"; + } + } + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cannot create a composite containing 8- or 16-bit types"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateCompositeExtract(ValidationState_t& _, + const Instruction* inst) { + uint32_t member_type = 0; + if (spv_result_t error = GetExtractInsertValueType(_, inst, &member_type)) { + return error; + } + + const uint32_t result_type = inst->type_id(); + if (result_type != member_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result type (Op" << spvOpcodeString(_.GetIdOpcode(result_type)) + << ") does not match the type that results from indexing into " + "the composite (Op" + << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; + } + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cannot extract from a composite of 8- or 16-bit types"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateCompositeInsert(ValidationState_t& _, + const Instruction* inst) { + const uint32_t object_type = _.GetOperandTypeId(inst, 2); + const uint32_t composite_type = _.GetOperandTypeId(inst, 3); + const uint32_t result_type = inst->type_id(); + if (result_type != composite_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The Result Type must be the same as Composite type in Op" + << spvOpcodeString(inst->opcode()) << " yielding Result Id " + << result_type << "."; + } + + uint32_t member_type = 0; + if (spv_result_t error = GetExtractInsertValueType(_, inst, &member_type)) { + return error; + } + + if (object_type != member_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The Object type (Op" + << spvOpcodeString(_.GetIdOpcode(object_type)) + << ") does not match the type that results from indexing into the " + "Composite (Op" + << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; + } + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cannot insert into a composite of 8- or 16-bit types"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateCopyObject(ValidationState_t& _, const Instruction* inst) { + const uint32_t result_type = inst->type_id(); + const uint32_t operand_type = _.GetOperandTypeId(inst, 2); + if (operand_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type and Operand type to be the same"; + } + if (_.IsVoidType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "OpCopyObject cannot have void result type"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateTranspose(ValidationState_t& _, const Instruction* inst) { + uint32_t result_num_rows = 0; + uint32_t result_num_cols = 0; + uint32_t result_col_type = 0; + uint32_t result_component_type = 0; + const uint32_t result_type = inst->type_id(); + if (!_.GetMatrixTypeInfo(result_type, &result_num_rows, &result_num_cols, + &result_col_type, &result_component_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a matrix type"; + } + + const uint32_t matrix_type = _.GetOperandTypeId(inst, 2); + uint32_t matrix_num_rows = 0; + uint32_t matrix_num_cols = 0; + uint32_t matrix_col_type = 0; + uint32_t matrix_component_type = 0; + if (!_.GetMatrixTypeInfo(matrix_type, &matrix_num_rows, &matrix_num_cols, + &matrix_col_type, &matrix_component_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Matrix to be of type OpTypeMatrix"; + } + + if (result_component_type != matrix_component_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected component types of Matrix and Result Type to be " + << "identical"; + } + + if (result_num_rows != matrix_num_cols || + result_num_cols != matrix_num_rows) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected number of columns and the column size of Matrix " + << "to be the reverse of those of Result Type"; + } + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cannot transpose matrices of 16-bit floats"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateVectorShuffle(ValidationState_t& _, + const Instruction* inst) { + auto resultType = _.FindDef(inst->type_id()); + if (!resultType || resultType->opcode() != spv::Op::OpTypeVector) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Result Type of OpVectorShuffle must be" + << " OpTypeVector. Found Op" + << spvOpcodeString(static_cast(resultType->opcode())) + << "."; + } + + // The number of components in Result Type must be the same as the number of + // Component operands. + auto componentCount = inst->operands().size() - 4; + auto resultVectorDimension = resultType->GetOperandAs(2); + if (componentCount != resultVectorDimension) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVectorShuffle component literals count does not match " + "Result Type " + << _.getIdName(resultType->id()) << "s vector component count."; + } + + // Vector 1 and Vector 2 must both have vector types, with the same Component + // Type as Result Type. + auto vector1Object = _.FindDef(inst->GetOperandAs(2)); + auto vector1Type = _.FindDef(vector1Object->type_id()); + auto vector2Object = _.FindDef(inst->GetOperandAs(3)); + auto vector2Type = _.FindDef(vector2Object->type_id()); + if (!vector1Type || vector1Type->opcode() != spv::Op::OpTypeVector) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The type of Vector 1 must be OpTypeVector."; + } + if (!vector2Type || vector2Type->opcode() != spv::Op::OpTypeVector) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The type of Vector 2 must be OpTypeVector."; + } + + auto resultComponentType = resultType->GetOperandAs(1); + if (vector1Type->GetOperandAs(1) != resultComponentType) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Component Type of Vector 1 must be the same as ResultType."; + } + if (vector2Type->GetOperandAs(1) != resultComponentType) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Component Type of Vector 2 must be the same as ResultType."; + } + + // All Component literals must either be FFFFFFFF or in [0, N - 1]. + auto vector1ComponentCount = vector1Type->GetOperandAs(2); + auto vector2ComponentCount = vector2Type->GetOperandAs(2); + auto N = vector1ComponentCount + vector2ComponentCount; + auto firstLiteralIndex = 4; + for (size_t i = firstLiteralIndex; i < inst->operands().size(); ++i) { + auto literal = inst->GetOperandAs(i); + if (literal != 0xFFFFFFFF && literal >= N) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Component index " << literal << " is out of bounds for " + << "combined (Vector1 + Vector2) size of " << N << "."; + } + } + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cannot shuffle a vector of 8- or 16-bit types"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateCopyLogical(ValidationState_t& _, + const Instruction* inst) { + const auto result_type = _.FindDef(inst->type_id()); + const auto source = _.FindDef(inst->GetOperandAs(2u)); + const auto source_type = _.FindDef(source->type_id()); + if (!source_type || !result_type || source_type == result_type) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result Type must not equal the Operand type"; + } + + if (!_.LogicallyMatch(source_type, result_type, false)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result Type does not logically match the Operand type"; + } + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cannot copy composites of 8- or 16-bit types"; + } + + return SPV_SUCCESS; +} + +} // anonymous namespace + +// Validates correctness of composite instructions. +spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpVectorExtractDynamic: + return ValidateVectorExtractDynamic(_, inst); + case spv::Op::OpVectorInsertDynamic: + return ValidateVectorInsertDyanmic(_, inst); + case spv::Op::OpVectorShuffle: + return ValidateVectorShuffle(_, inst); + case spv::Op::OpCompositeConstruct: + return ValidateCompositeConstruct(_, inst); + case spv::Op::OpCompositeExtract: + return ValidateCompositeExtract(_, inst); + case spv::Op::OpCompositeInsert: + return ValidateCompositeInsert(_, inst); + case spv::Op::OpCopyObject: + return ValidateCopyObject(_, inst); + case spv::Op::OpTranspose: + return ValidateTranspose(_, inst); + case spv::Op::OpCopyLogical: + return ValidateCopyLogical(_, inst); + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_constants.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_constants.cpp new file mode 100644 index 000000000000..4deaa4968810 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_constants.cpp @@ -0,0 +1,470 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidateConstantBool(ValidationState_t& _, + const Instruction* inst) { + auto type = _.FindDef(inst->type_id()); + if (!type || type->opcode() != spv::Op::OpTypeBool) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Op" << spvOpcodeString(inst->opcode()) << " Result Type " + << _.getIdName(inst->type_id()) << " is not a boolean type."; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateConstantComposite(ValidationState_t& _, + const Instruction* inst) { + std::string opcode_name = std::string("Op") + spvOpcodeString(inst->opcode()); + + const auto result_type = _.FindDef(inst->type_id()); + if (!result_type || !spvOpcodeIsComposite(result_type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Result Type " + << _.getIdName(inst->type_id()) << " is not a composite type."; + } + + const auto constituent_count = inst->words().size() - 3; + switch (result_type->opcode()) { + case spv::Op::OpTypeVector: { + const auto component_count = result_type->GetOperandAs(2); + if (component_count != constituent_count) { + // TODO: Output ID's on diagnostic + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name + << " Constituent count does not match " + "Result Type " + << _.getIdName(result_type->id()) << "s vector component count."; + } + const auto component_type = + _.FindDef(result_type->GetOperandAs(1)); + if (!component_type) { + return _.diag(SPV_ERROR_INVALID_ID, result_type) + << "Component type is not defined."; + } + for (size_t constituent_index = 2; + constituent_index < inst->operands().size(); constituent_index++) { + const auto constituent_id = + inst->GetOperandAs(constituent_index); + const auto constituent = _.FindDef(constituent_id); + if (!constituent || + !spvOpcodeIsConstantOrUndef(constituent->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " is not a constant or undef."; + } + const auto constituent_result_type = _.FindDef(constituent->type_id()); + if (!constituent_result_type || + component_type->id() != constituent_result_type->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << "s type does not match Result Type " + << _.getIdName(result_type->id()) << "s vector element type."; + } + } + } break; + case spv::Op::OpTypeMatrix: { + const auto column_count = result_type->GetOperandAs(2); + if (column_count != constituent_count) { + // TODO: Output ID's on diagnostic + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name + << " Constituent count does not match " + "Result Type " + << _.getIdName(result_type->id()) << "s matrix column count."; + } + + const auto column_type = _.FindDef(result_type->words()[2]); + if (!column_type) { + return _.diag(SPV_ERROR_INVALID_ID, result_type) + << "Column type is not defined."; + } + const auto component_count = column_type->GetOperandAs(2); + const auto component_type = + _.FindDef(column_type->GetOperandAs(1)); + if (!component_type) { + return _.diag(SPV_ERROR_INVALID_ID, column_type) + << "Component type is not defined."; + } + + for (size_t constituent_index = 2; + constituent_index < inst->operands().size(); constituent_index++) { + const auto constituent_id = + inst->GetOperandAs(constituent_index); + const auto constituent = _.FindDef(constituent_id); + if (!constituent || + !spvOpcodeIsConstantOrUndef(constituent->opcode())) { + // The message says "... or undef" because the spec does not say + // undef is a constant. + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " is not a constant or undef."; + } + const auto vector = _.FindDef(constituent->type_id()); + if (!vector) { + return _.diag(SPV_ERROR_INVALID_ID, constituent) + << "Result type is not defined."; + } + if (column_type->opcode() != vector->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " type does not match Result Type " + << _.getIdName(result_type->id()) << "s matrix column type."; + } + const auto vector_component_type = + _.FindDef(vector->GetOperandAs(1)); + if (component_type->id() != vector_component_type->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " component type does not match Result Type " + << _.getIdName(result_type->id()) + << "s matrix column component type."; + } + if (component_count != vector->words()[3]) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " vector component count does not match Result Type " + << _.getIdName(result_type->id()) + << "s vector component count."; + } + } + } break; + case spv::Op::OpTypeArray: { + auto element_type = _.FindDef(result_type->GetOperandAs(1)); + if (!element_type) { + return _.diag(SPV_ERROR_INVALID_ID, result_type) + << "Element type is not defined."; + } + const auto length = _.FindDef(result_type->GetOperandAs(2)); + if (!length) { + return _.diag(SPV_ERROR_INVALID_ID, result_type) + << "Length is not defined."; + } + bool is_int32; + bool is_const; + uint32_t value; + std::tie(is_int32, is_const, value) = _.EvalInt32IfConst(length->id()); + if (is_int32 && is_const && value != constituent_count) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name + << " Constituent count does not match " + "Result Type " + << _.getIdName(result_type->id()) << "s array length."; + } + for (size_t constituent_index = 2; + constituent_index < inst->operands().size(); constituent_index++) { + const auto constituent_id = + inst->GetOperandAs(constituent_index); + const auto constituent = _.FindDef(constituent_id); + if (!constituent || + !spvOpcodeIsConstantOrUndef(constituent->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " is not a constant or undef."; + } + const auto constituent_type = _.FindDef(constituent->type_id()); + if (!constituent_type) { + return _.diag(SPV_ERROR_INVALID_ID, constituent) + << "Result type is not defined."; + } + if (element_type->id() != constituent_type->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << "s type does not match Result Type " + << _.getIdName(result_type->id()) << "s array element type."; + } + } + } break; + case spv::Op::OpTypeStruct: { + const auto member_count = result_type->words().size() - 2; + if (member_count != constituent_count) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(inst->type_id()) + << " count does not match Result Type " + << _.getIdName(result_type->id()) << "s struct member count."; + } + for (uint32_t constituent_index = 2, member_index = 1; + constituent_index < inst->operands().size(); + constituent_index++, member_index++) { + const auto constituent_id = + inst->GetOperandAs(constituent_index); + const auto constituent = _.FindDef(constituent_id); + if (!constituent || + !spvOpcodeIsConstantOrUndef(constituent->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " is not a constant or undef."; + } + const auto constituent_type = _.FindDef(constituent->type_id()); + if (!constituent_type) { + return _.diag(SPV_ERROR_INVALID_ID, constituent) + << "Result type is not defined."; + } + + const auto member_type_id = + result_type->GetOperandAs(member_index); + const auto member_type = _.FindDef(member_type_id); + if (!member_type || member_type->id() != constituent_type->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " type does not match the Result Type " + << _.getIdName(result_type->id()) << "s member type."; + } + } + } break; + case spv::Op::OpTypeCooperativeMatrixKHR: + case spv::Op::OpTypeCooperativeMatrixNV: { + if (1 != constituent_count) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(inst->type_id()) << " count must be one."; + } + const auto constituent_id = inst->GetOperandAs(2); + const auto constituent = _.FindDef(constituent_id); + if (!constituent || !spvOpcodeIsConstantOrUndef(constituent->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) << " is not a constant or undef."; + } + const auto constituent_type = _.FindDef(constituent->type_id()); + if (!constituent_type) { + return _.diag(SPV_ERROR_INVALID_ID, constituent) + << "Result type is not defined."; + } + + const auto component_type_id = result_type->GetOperandAs(1); + const auto component_type = _.FindDef(component_type_id); + if (!component_type || component_type->id() != constituent_type->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opcode_name << " Constituent " + << _.getIdName(constituent_id) + << " type does not match the Result Type " + << _.getIdName(result_type->id()) << "s component type."; + } + } break; + default: + break; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateConstantSampler(ValidationState_t& _, + const Instruction* inst) { + const auto result_type = _.FindDef(inst->type_id()); + if (!result_type || result_type->opcode() != spv::Op::OpTypeSampler) { + return _.diag(SPV_ERROR_INVALID_ID, result_type) + << "OpConstantSampler Result Type " + << _.getIdName(inst->type_id()) << " is not a sampler type."; + } + + return SPV_SUCCESS; +} + +// True if instruction defines a type that can have a null value, as defined by +// the SPIR-V spec. Tracks composite-type components through module to check +// nullability transitively. +bool IsTypeNullable(const std::vector& instruction, + const ValidationState_t& _) { + uint16_t opcode; + uint16_t word_count; + spvOpcodeSplit(instruction[0], &word_count, &opcode); + switch (static_cast(opcode)) { + case spv::Op::OpTypeBool: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeEvent: + case spv::Op::OpTypeDeviceEvent: + case spv::Op::OpTypeReserveId: + case spv::Op::OpTypeQueue: + return true; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + case spv::Op::OpTypeVector: { + auto base_type = _.FindDef(instruction[2]); + return base_type && IsTypeNullable(base_type->words(), _); + } + case spv::Op::OpTypeStruct: { + for (size_t elementIndex = 2; elementIndex < instruction.size(); + ++elementIndex) { + auto element = _.FindDef(instruction[elementIndex]); + if (!element || !IsTypeNullable(element->words(), _)) return false; + } + return true; + } + case spv::Op::OpTypePointer: + if (spv::StorageClass(instruction[2]) == + spv::StorageClass::PhysicalStorageBuffer) { + return false; + } + return true; + default: + return false; + } +} + +spv_result_t ValidateConstantNull(ValidationState_t& _, + const Instruction* inst) { + const auto result_type = _.FindDef(inst->type_id()); + if (!result_type || !IsTypeNullable(result_type->words(), _)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpConstantNull Result Type " << _.getIdName(inst->type_id()) + << " cannot have a null value."; + } + + return SPV_SUCCESS; +} + +// Validates that OpSpecConstant specializes to either int or float type. +spv_result_t ValidateSpecConstant(ValidationState_t& _, + const Instruction* inst) { + // Operand 0 is the of the type that we're specializing to. + auto type_id = inst->GetOperandAs(0); + auto type_instruction = _.FindDef(type_id); + auto type_opcode = type_instruction->opcode(); + if (type_opcode != spv::Op::OpTypeInt && + type_opcode != spv::Op::OpTypeFloat) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Specialization constant " + "must be an integer or " + "floating-point number."; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateSpecConstantOp(ValidationState_t& _, + const Instruction* inst) { + const auto op = inst->GetOperandAs(2); + + // The binary parser already ensures that the op is valid for *some* + // environment. Here we check restrictions. + switch (op) { + case spv::Op::OpQuantizeToF16: + if (!_.HasCapability(spv::Capability::Shader)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Specialization constant operation " << spvOpcodeString(op) + << " requires Shader capability"; + } + break; + + case spv::Op::OpUConvert: + if (!_.features().uconvert_spec_constant_op && + !_.HasCapability(spv::Capability::Kernel)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Prior to SPIR-V 1.4, specialization constant operation " + "UConvert requires Kernel capability or extension " + "SPV_AMD_gpu_shader_int16"; + } + break; + + case spv::Op::OpConvertFToS: + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertFToU: + case spv::Op::OpConvertUToF: + case spv::Op::OpConvertPtrToU: + case spv::Op::OpConvertUToPtr: + case spv::Op::OpGenericCastToPtr: + case spv::Op::OpPtrCastToGeneric: + case spv::Op::OpBitcast: + case spv::Op::OpFNegate: + case spv::Op::OpFAdd: + case spv::Op::OpFSub: + case spv::Op::OpFMul: + case spv::Op::OpFDiv: + case spv::Op::OpFRem: + case spv::Op::OpFMod: + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpPtrAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + if (!_.HasCapability(spv::Capability::Kernel)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Specialization constant operation " << spvOpcodeString(op) + << " requires Kernel capability"; + } + break; + + default: + break; + } + + // TODO(dneto): Validate result type and arguments to the various operations. + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpConstantTrue: + case spv::Op::OpConstantFalse: + case spv::Op::OpSpecConstantTrue: + case spv::Op::OpSpecConstantFalse: + if (auto error = ValidateConstantBool(_, inst)) return error; + break; + case spv::Op::OpConstantComposite: + case spv::Op::OpSpecConstantComposite: + if (auto error = ValidateConstantComposite(_, inst)) return error; + break; + case spv::Op::OpConstantSampler: + if (auto error = ValidateConstantSampler(_, inst)) return error; + break; + case spv::Op::OpConstantNull: + if (auto error = ValidateConstantNull(_, inst)) return error; + break; + case spv::Op::OpSpecConstant: + if (auto error = ValidateSpecConstant(_, inst)) return error; + break; + case spv::Op::OpSpecConstantOp: + if (auto error = ValidateSpecConstantOp(_, inst)) return error; + break; + default: + break; + } + + // Generally disallow creating 8- or 16-bit constants unless the full + // capabilities are present. + if (spvOpcodeIsConstant(inst->opcode()) && + _.HasCapability(spv::Capability::Shader) && + !_.IsPointerType(inst->type_id()) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cannot form constants of 8- or 16-bit types"; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_conversion.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_conversion.cpp new file mode 100644 index 000000000000..b2892a8630bf --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_conversion.cpp @@ -0,0 +1,598 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of conversion instructions. + +#include "source/opcode.h" +#include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +// Validates correctness of conversion instructions. +spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + switch (opcode) { + case spv::Op::OpConvertFToU: { + if (!_.IsUnsignedIntScalarType(result_type) && + !_.IsUnsignedIntVectorType(result_type) && + !_.IsUnsignedIntCooperativeMatrixType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected unsigned int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || (!_.IsFloatScalarType(input_type) && + !_.IsFloatVectorType(input_type) && + !_.IsFloatCooperativeMatrixType(input_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be float scalar or vector: " + << spvOpcodeString(opcode); + + if (_.IsCooperativeMatrixType(result_type) || + _.IsCooperativeMatrixType(input_type)) { + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + if (ret != SPV_SUCCESS) return ret; + } else { + if (_.GetDimension(result_type) != _.GetDimension(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); + } + + break; + } + + case spv::Op::OpConvertFToS: { + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && + !_.IsIntCooperativeMatrixType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || (!_.IsFloatScalarType(input_type) && + !_.IsFloatVectorType(input_type) && + !_.IsFloatCooperativeMatrixType(input_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be float scalar or vector: " + << spvOpcodeString(opcode); + + if (_.IsCooperativeMatrixType(result_type) || + _.IsCooperativeMatrixType(input_type)) { + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + if (ret != SPV_SUCCESS) return ret; + } else { + if (_.GetDimension(result_type) != _.GetDimension(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); + } + + break; + } + + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertUToF: { + if (!_.IsFloatScalarType(result_type) && + !_.IsFloatVectorType(result_type) && + !_.IsFloatCooperativeMatrixType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || + (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) && + !_.IsIntCooperativeMatrixType(input_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be int scalar or vector: " + << spvOpcodeString(opcode); + + if (_.IsCooperativeMatrixType(result_type) || + _.IsCooperativeMatrixType(input_type)) { + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + if (ret != SPV_SUCCESS) return ret; + } else { + if (_.GetDimension(result_type) != _.GetDimension(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); + } + + break; + } + + case spv::Op::OpUConvert: { + if (!_.IsUnsignedIntScalarType(result_type) && + !_.IsUnsignedIntVectorType(result_type) && + !_.IsUnsignedIntCooperativeMatrixType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected unsigned int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || + (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) && + !_.IsIntCooperativeMatrixType(input_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be int scalar or vector: " + << spvOpcodeString(opcode); + + if (_.IsCooperativeMatrixType(result_type) || + _.IsCooperativeMatrixType(input_type)) { + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + if (ret != SPV_SUCCESS) return ret; + } else { + if (_.GetDimension(result_type) != _.GetDimension(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); + } + + if (_.GetBitWidth(result_type) == _.GetBitWidth(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have different bit width from Result " + "Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpSConvert: { + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && + !_.IsIntCooperativeMatrixType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || + (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) && + !_.IsIntCooperativeMatrixType(input_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be int scalar or vector: " + << spvOpcodeString(opcode); + + if (_.IsCooperativeMatrixType(result_type) || + _.IsCooperativeMatrixType(input_type)) { + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + if (ret != SPV_SUCCESS) return ret; + } else { + if (_.GetDimension(result_type) != _.GetDimension(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); + } + + if (_.GetBitWidth(result_type) == _.GetBitWidth(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have different bit width from Result " + "Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpFConvert: { + if (!_.IsFloatScalarType(result_type) && + !_.IsFloatVectorType(result_type) && + !_.IsFloatCooperativeMatrixType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected float scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || (!_.IsFloatScalarType(input_type) && + !_.IsFloatVectorType(input_type) && + !_.IsFloatCooperativeMatrixType(input_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be float scalar or vector: " + << spvOpcodeString(opcode); + + if (_.IsCooperativeMatrixType(result_type) || + _.IsCooperativeMatrixType(input_type)) { + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + if (ret != SPV_SUCCESS) return ret; + } else { + if (_.GetDimension(result_type) != _.GetDimension(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); + } + + if (_.GetBitWidth(result_type) == _.GetBitWidth(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have different bit width from Result " + "Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpQuantizeToF16: { + if ((!_.IsFloatScalarType(result_type) && + !_.IsFloatVectorType(result_type)) || + _.GetBitWidth(result_type) != 32) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit float scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (input_type != result_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input type to be equal to Result Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpConvertPtrToU: { + if (!_.IsUnsignedIntScalarType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected unsigned int scalar type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!_.IsPointerType(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer: " << spvOpcodeString(opcode); + + if (_.addressing_model() == spv::AddressingModel::Logical) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Logical addressing not supported: " + << spvOpcodeString(opcode); + + if (_.addressing_model() == + spv::AddressingModel::PhysicalStorageBuffer64) { + spv::StorageClass input_storage_class; + uint32_t input_data_type = 0; + _.GetPointerTypeInfo(input_type, &input_data_type, + &input_storage_class); + if (input_storage_class != spv::StorageClass::PhysicalStorageBuffer) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Pointer storage class must be PhysicalStorageBuffer: " + << spvOpcodeString(opcode); + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (_.GetBitWidth(result_type) != 64) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4710) + << "PhysicalStorageBuffer64 addressing mode requires the " + "result integer type to have a 64-bit width for Vulkan " + "environment."; + } + } + } + break; + } + + case spv::Op::OpSatConvertSToU: + case spv::Op::OpSatConvertUToS: { + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || + (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar or vector as input: " + << spvOpcodeString(opcode); + + if (_.GetDimension(result_type) != _.GetDimension(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpConvertUToPtr: { + if (!_.IsPointerType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a pointer: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || !_.IsIntScalarType(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected int scalar as input: " << spvOpcodeString(opcode); + + if (_.addressing_model() == spv::AddressingModel::Logical) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Logical addressing not supported: " + << spvOpcodeString(opcode); + + if (_.addressing_model() == + spv::AddressingModel::PhysicalStorageBuffer64) { + spv::StorageClass result_storage_class; + uint32_t result_data_type = 0; + _.GetPointerTypeInfo(result_type, &result_data_type, + &result_storage_class); + if (result_storage_class != spv::StorageClass::PhysicalStorageBuffer) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Pointer storage class must be PhysicalStorageBuffer: " + << spvOpcodeString(opcode); + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (_.GetBitWidth(input_type) != 64) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4710) + << "PhysicalStorageBuffer64 addressing mode requires the " + "input integer to have a 64-bit width for Vulkan " + "environment."; + } + } + } + break; + } + + case spv::Op::OpPtrCastToGeneric: { + spv::StorageClass result_storage_class; + uint32_t result_data_type = 0; + if (!_.GetPointerTypeInfo(result_type, &result_data_type, + &result_storage_class)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a pointer: " + << spvOpcodeString(opcode); + + if (result_storage_class != spv::StorageClass::Generic) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to have storage class Generic: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + spv::StorageClass input_storage_class; + uint32_t input_data_type = 0; + if (!_.GetPointerTypeInfo(input_type, &input_data_type, + &input_storage_class)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer: " << spvOpcodeString(opcode); + + if (input_storage_class != spv::StorageClass::Workgroup && + input_storage_class != spv::StorageClass::CrossWorkgroup && + input_storage_class != spv::StorageClass::Function) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have storage class Workgroup, " + << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); + + if (result_data_type != input_data_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input and Result Type to point to the same type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpGenericCastToPtr: { + spv::StorageClass result_storage_class; + uint32_t result_data_type = 0; + if (!_.GetPointerTypeInfo(result_type, &result_data_type, + &result_storage_class)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a pointer: " + << spvOpcodeString(opcode); + + if (result_storage_class != spv::StorageClass::Workgroup && + result_storage_class != spv::StorageClass::CrossWorkgroup && + result_storage_class != spv::StorageClass::Function) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to have storage class Workgroup, " + << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + spv::StorageClass input_storage_class; + uint32_t input_data_type = 0; + if (!_.GetPointerTypeInfo(input_type, &input_data_type, + &input_storage_class)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer: " << spvOpcodeString(opcode); + + if (input_storage_class != spv::StorageClass::Generic) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have storage class Generic: " + << spvOpcodeString(opcode); + + if (result_data_type != input_data_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input and Result Type to point to the same type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpGenericCastToPtrExplicit: { + spv::StorageClass result_storage_class; + uint32_t result_data_type = 0; + if (!_.GetPointerTypeInfo(result_type, &result_data_type, + &result_storage_class)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a pointer: " + << spvOpcodeString(opcode); + + const auto target_storage_class = + inst->GetOperandAs(3); + if (result_storage_class != target_storage_class) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be of target storage class: " + << spvOpcodeString(opcode); + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + spv::StorageClass input_storage_class; + uint32_t input_data_type = 0; + if (!_.GetPointerTypeInfo(input_type, &input_data_type, + &input_storage_class)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer: " << spvOpcodeString(opcode); + + if (input_storage_class != spv::StorageClass::Generic) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have storage class Generic: " + << spvOpcodeString(opcode); + + if (result_data_type != input_data_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input and Result Type to point to the same type: " + << spvOpcodeString(opcode); + + if (target_storage_class != spv::StorageClass::Workgroup && + target_storage_class != spv::StorageClass::CrossWorkgroup && + target_storage_class != spv::StorageClass::Function) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected target storage class to be Workgroup, " + << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpBitcast: { + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have a type: " << spvOpcodeString(opcode); + + const bool result_is_pointer = _.IsPointerType(result_type); + const bool result_is_int_scalar = _.IsIntScalarType(result_type); + const bool input_is_pointer = _.IsPointerType(input_type); + const bool input_is_int_scalar = _.IsIntScalarType(input_type); + + const bool result_is_coopmat = _.IsCooperativeMatrixType(result_type); + const bool input_is_coopmat = _.IsCooperativeMatrixType(input_type); + + if (!result_is_pointer && !result_is_int_scalar && !result_is_coopmat && + !_.IsIntVectorType(result_type) && + !_.IsFloatScalarType(result_type) && + !_.IsFloatVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a pointer or int or float vector " + << "or scalar type: " << spvOpcodeString(opcode); + + if (!input_is_pointer && !input_is_int_scalar && !input_is_coopmat && + !_.IsIntVectorType(input_type) && !_.IsFloatScalarType(input_type) && + !_.IsFloatVectorType(input_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer or int or float vector " + << "or scalar: " << spvOpcodeString(opcode); + + if (result_is_coopmat != input_is_coopmat) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cooperative matrix can only be cast to another cooperative " + << "matrix: " << spvOpcodeString(opcode); + + if (result_is_coopmat) { + spv_result_t ret = + _.CooperativeMatrixShapesMatch(inst, result_type, input_type); + if (ret != SPV_SUCCESS) return ret; + } + + if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 5) || + _.HasExtension(kSPV_KHR_physical_storage_buffer)) { + const bool result_is_int_vector = _.IsIntVectorType(result_type); + const bool result_has_int32 = + _.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeInt, 32); + const bool input_is_int_vector = _.IsIntVectorType(input_type); + const bool input_has_int32 = + _.ContainsSizedIntOrFloatType(input_type, spv::Op::OpTypeInt, 32); + if (result_is_pointer && !input_is_pointer && !input_is_int_scalar && + !(input_is_int_vector && input_has_int32)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer, int scalar or 32-bit int " + "vector if Result Type is pointer: " + << spvOpcodeString(opcode); + + if (input_is_pointer && !result_is_pointer && !result_is_int_scalar && + !(result_is_int_vector && result_has_int32)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Pointer can only be converted to another pointer, int " + "scalar or 32-bit int vector: " + << spvOpcodeString(opcode); + } else { + if (result_is_pointer && !input_is_pointer && !input_is_int_scalar) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to be a pointer or int scalar if Result " + "Type is pointer: " + << spvOpcodeString(opcode); + + if (input_is_pointer && !result_is_pointer && !result_is_int_scalar) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Pointer can only be converted to another pointer or int " + "scalar: " + << spvOpcodeString(opcode); + } + + if (!result_is_pointer && !input_is_pointer) { + const uint32_t result_size = + _.GetBitWidth(result_type) * _.GetDimension(result_type); + const uint32_t input_size = + _.GetBitWidth(input_type) * _.GetDimension(input_type); + if (result_size != input_size) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected input to have the same total bit width as " + << "Result Type: " << spvOpcodeString(opcode); + } + break; + } + + case spv::Op::OpConvertUToAccelerationStructureKHR: { + if (!_.IsAccelerationStructureType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a Acceleration Structure: " + << spvOpcodeString(opcode); + } + + const uint32_t input_type = _.GetOperandTypeId(inst, 2); + if (!input_type || !_.IsUnsigned64BitHandle(input_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 64-bit uint scalar or 2-component 32-bit uint " + "vector as input: " + << spvOpcodeString(opcode); + } + + break; + } + + default: + break; + } + + if (_.HasCapability(spv::Capability::Shader)) { + switch (inst->opcode()) { + case spv::Op::OpConvertFToU: + case spv::Op::OpConvertFToS: + case spv::Op::OpConvertSToF: + case spv::Op::OpConvertUToF: + case spv::Op::OpBitcast: + if (_.ContainsLimitedUseIntOrFloatType(inst->type_id()) || + _.ContainsLimitedUseIntOrFloatType(_.GetOperandTypeId(inst, 2u))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "8- or 16-bit types can only be used with width-only " + "conversions"; + } + break; + default: + break; + } + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_debug.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_debug.cpp new file mode 100644 index 000000000000..ef537ea02765 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_debug.cpp @@ -0,0 +1,72 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidateMemberName(ValidationState_t& _, const Instruction* inst) { + const auto type_id = inst->GetOperandAs(0); + const auto type = _.FindDef(type_id); + if (!type || spv::Op::OpTypeStruct != type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpMemberName Type " << _.getIdName(type_id) + << " is not a struct type."; + } + const auto member_id = inst->GetOperandAs(1); + const auto member_count = (uint32_t)(type->words().size() - 2); + if (member_count <= member_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpMemberName Member " << _.getIdName(member_id) + << " index is larger than Type " << _.getIdName(type->id()) + << "s member count."; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateLine(ValidationState_t& _, const Instruction* inst) { + const auto file_id = inst->GetOperandAs(0); + const auto file = _.FindDef(file_id); + if (!file || spv::Op::OpString != file->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpLine Target " << _.getIdName(file_id) + << " is not an OpString."; + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t DebugPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpMemberName: + if (auto error = ValidateMemberName(_, inst)) return error; + break; + case spv::Op::OpLine: + if (auto error = ValidateLine(_, inst)) return error; + break; + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_decorations.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_decorations.cpp new file mode 100644 index 000000000000..caa4a6f18424 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_decorations.cpp @@ -0,0 +1,1911 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/diagnostic.h" +#include "source/opcode.h" +#include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/spirv_validator_options.h" +#include "source/util/string_utils.h" +#include "source/val/validate_scopes.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Distinguish between row and column major matrix layouts. +enum MatrixLayout { kRowMajor, kColumnMajor }; + +// A functor for hashing a pair of integers. +struct PairHash { + std::size_t operator()(const std::pair pair) const { + const uint32_t a = pair.first; + const uint32_t b = pair.second; + const uint32_t rotated_b = (b >> 2) | ((b & 3) << 30); + return a ^ rotated_b; + } +}; + +// Struct member layout attributes that are inherited through arrays. +struct LayoutConstraints { + explicit LayoutConstraints( + MatrixLayout the_majorness = MatrixLayout::kColumnMajor, + uint32_t stride = 0) + : majorness(the_majorness), matrix_stride(stride) {} + MatrixLayout majorness; + uint32_t matrix_stride; +}; + +// A type for mapping (struct id, member id) to layout constraints. +using MemberConstraints = std::unordered_map, + LayoutConstraints, PairHash>; + +// Returns the array stride of the given array type. +uint32_t GetArrayStride(uint32_t array_id, ValidationState_t& vstate) { + for (auto& decoration : vstate.id_decorations(array_id)) { + if (spv::Decoration::ArrayStride == decoration.dec_type()) { + return decoration.params()[0]; + } + } + return 0; +} + +// Returns true if the given variable has a BuiltIn decoration. +bool isBuiltInVar(uint32_t var_id, ValidationState_t& vstate) { + const auto& decorations = vstate.id_decorations(var_id); + return std::any_of(decorations.begin(), decorations.end(), + [](const Decoration& d) { + return spv::Decoration::BuiltIn == d.dec_type(); + }); +} + +// Returns true if the given structure type has any members with BuiltIn +// decoration. +bool isBuiltInStruct(uint32_t struct_id, ValidationState_t& vstate) { + const auto& decorations = vstate.id_decorations(struct_id); + return std::any_of( + decorations.begin(), decorations.end(), [](const Decoration& d) { + return spv::Decoration::BuiltIn == d.dec_type() && + Decoration::kInvalidMember != d.struct_member_index(); + }); +} + +// Returns true if the given structure type has a Block decoration. +bool isBlock(uint32_t struct_id, ValidationState_t& vstate) { + const auto& decorations = vstate.id_decorations(struct_id); + return std::any_of(decorations.begin(), decorations.end(), + [](const Decoration& d) { + return spv::Decoration::Block == d.dec_type(); + }); +} + +// Returns true if the given ID has the Import LinkageAttributes decoration. +bool hasImportLinkageAttribute(uint32_t id, ValidationState_t& vstate) { + const auto& decorations = vstate.id_decorations(id); + return std::any_of( + decorations.begin(), decorations.end(), [](const Decoration& d) { + return spv::Decoration::LinkageAttributes == d.dec_type() && + d.params().size() >= 2u && + spv::LinkageType(d.params().back()) == spv::LinkageType::Import; + }); +} + +// Returns a vector of all members of a structure. +std::vector getStructMembers(uint32_t struct_id, + ValidationState_t& vstate) { + const auto inst = vstate.FindDef(struct_id); + return std::vector(inst->words().begin() + 2, inst->words().end()); +} + +// Returns a vector of all members of a structure that have specific type. +std::vector getStructMembers(uint32_t struct_id, spv::Op type, + ValidationState_t& vstate) { + std::vector members; + for (auto id : getStructMembers(struct_id, vstate)) { + if (type == vstate.FindDef(id)->opcode()) { + members.push_back(id); + } + } + return members; +} + +// Returns whether the given structure is missing Offset decoration for any +// member. Handles also nested structures. +bool isMissingOffsetInStruct(uint32_t struct_id, ValidationState_t& vstate) { + const auto* inst = vstate.FindDef(struct_id); + std::vector hasOffset; + std::vector struct_members; + if (inst->opcode() == spv::Op::OpTypeStruct) { + // Check offsets of member decorations. + struct_members = getStructMembers(struct_id, vstate); + hasOffset.resize(struct_members.size(), false); + + for (auto& decoration : vstate.id_decorations(struct_id)) { + if (spv::Decoration::Offset == decoration.dec_type() && + Decoration::kInvalidMember != decoration.struct_member_index()) { + // Offset 0xffffffff is not valid so ignore it for simplicity's sake. + if (decoration.params()[0] == 0xffffffff) return true; + hasOffset[decoration.struct_member_index()] = true; + } + } + } else if (inst->opcode() == spv::Op::OpTypeArray || + inst->opcode() == spv::Op::OpTypeRuntimeArray) { + hasOffset.resize(1, true); + struct_members.push_back(inst->GetOperandAs(1u)); + } + // Look through nested structs (which may be in an array). + bool nestedStructsMissingOffset = false; + for (auto id : struct_members) { + if (isMissingOffsetInStruct(id, vstate)) { + nestedStructsMissingOffset = true; + break; + } + } + return nestedStructsMissingOffset || + !std::all_of(hasOffset.begin(), hasOffset.end(), + [](const bool b) { return b; }); +} + +// Rounds x up to the next alignment. Assumes alignment is a power of two. +uint32_t align(uint32_t x, uint32_t alignment) { + return (x + alignment - 1) & ~(alignment - 1); +} + +// Returns base alignment of struct member. If |roundUp| is true, also +// ensure that structs, arrays, and matrices are aligned at least to a +// multiple of 16 bytes. (That is, when roundUp is true, this function +// returns the *extended* alignment as it's called by the Vulkan spec.) +uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, + const LayoutConstraints& inherited, + MemberConstraints& constraints, + ValidationState_t& vstate) { + const auto inst = vstate.FindDef(member_id); + const auto& words = inst->words(); + // Minimal alignment is byte-aligned. + uint32_t baseAlignment = 1; + switch (inst->opcode()) { + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeImage: + if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) + return baseAlignment = vstate.samplerimage_variable_address_mode() / 8; + assert(0); + return 0; + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + baseAlignment = words[2] / 8; + break; + case spv::Op::OpTypeVector: { + const auto componentId = words[2]; + const auto numComponents = words[3]; + const auto componentAlignment = getBaseAlignment( + componentId, roundUp, inherited, constraints, vstate); + baseAlignment = + componentAlignment * (numComponents == 3 ? 4 : numComponents); + break; + } + case spv::Op::OpTypeMatrix: { + const auto column_type = words[2]; + if (inherited.majorness == kColumnMajor) { + baseAlignment = getBaseAlignment(column_type, roundUp, inherited, + constraints, vstate); + } else { + // A row-major matrix of C columns has a base alignment equal to the + // base alignment of a vector of C matrix components. + const auto num_columns = words[3]; + const auto component_inst = vstate.FindDef(column_type); + const auto component_id = component_inst->words()[2]; + const auto componentAlignment = getBaseAlignment( + component_id, roundUp, inherited, constraints, vstate); + baseAlignment = + componentAlignment * (num_columns == 3 ? 4 : num_columns); + } + if (roundUp) baseAlignment = align(baseAlignment, 16u); + } break; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + baseAlignment = + getBaseAlignment(words[2], roundUp, inherited, constraints, vstate); + if (roundUp) baseAlignment = align(baseAlignment, 16u); + break; + case spv::Op::OpTypeStruct: { + const auto members = getStructMembers(member_id, vstate); + for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); + memberIdx < numMembers; ++memberIdx) { + const auto id = members[memberIdx]; + const auto& constraint = + constraints[std::make_pair(member_id, memberIdx)]; + baseAlignment = std::max( + baseAlignment, + getBaseAlignment(id, roundUp, constraint, constraints, vstate)); + } + if (roundUp) baseAlignment = align(baseAlignment, 16u); + break; + } + case spv::Op::OpTypePointer: + baseAlignment = vstate.pointer_size_and_alignment(); + break; + default: + assert(0); + break; + } + + return baseAlignment; +} + +// Returns scalar alignment of a type. +uint32_t getScalarAlignment(uint32_t type_id, ValidationState_t& vstate) { + const auto inst = vstate.FindDef(type_id); + const auto& words = inst->words(); + switch (inst->opcode()) { + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeImage: + if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) + return vstate.samplerimage_variable_address_mode() / 8; + assert(0); + return 0; + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + return words[2] / 8; + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: { + const auto compositeMemberTypeId = words[2]; + return getScalarAlignment(compositeMemberTypeId, vstate); + } + case spv::Op::OpTypeStruct: { + const auto members = getStructMembers(type_id, vstate); + uint32_t max_member_alignment = 1; + for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); + memberIdx < numMembers; ++memberIdx) { + const auto id = members[memberIdx]; + uint32_t member_alignment = getScalarAlignment(id, vstate); + if (member_alignment > max_member_alignment) { + max_member_alignment = member_alignment; + } + } + return max_member_alignment; + } break; + case spv::Op::OpTypePointer: + return vstate.pointer_size_and_alignment(); + default: + assert(0); + break; + } + + return 1; +} + +// Returns size of a struct member. Doesn't include padding at the end of struct +// or array. Assumes that in the struct case, all members have offsets. +uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, + MemberConstraints& constraints, ValidationState_t& vstate) { + const auto inst = vstate.FindDef(member_id); + const auto& words = inst->words(); + switch (inst->opcode()) { + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeSampler: + case spv::Op::OpTypeImage: + if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) + return vstate.samplerimage_variable_address_mode() / 8; + assert(0); + return 0; + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + return words[2] / 8; + case spv::Op::OpTypeVector: { + const auto componentId = words[2]; + const auto numComponents = words[3]; + const auto componentSize = + getSize(componentId, inherited, constraints, vstate); + const auto size = componentSize * numComponents; + return size; + } + case spv::Op::OpTypeArray: { + const auto sizeInst = vstate.FindDef(words[3]); + if (spvOpcodeIsSpecConstant(sizeInst->opcode())) return 0; + assert(spv::Op::OpConstant == sizeInst->opcode()); + const uint32_t num_elem = sizeInst->words()[3]; + const uint32_t elem_type = words[2]; + const uint32_t elem_size = + getSize(elem_type, inherited, constraints, vstate); + // Account for gaps due to alignments in the first N-1 elements, + // then add the size of the last element. + const auto size = + (num_elem - 1) * GetArrayStride(member_id, vstate) + elem_size; + return size; + } + case spv::Op::OpTypeRuntimeArray: + return 0; + case spv::Op::OpTypeMatrix: { + const auto num_columns = words[3]; + if (inherited.majorness == kColumnMajor) { + return num_columns * inherited.matrix_stride; + } else { + // Row major case. + const auto column_type = words[2]; + const auto component_inst = vstate.FindDef(column_type); + const auto num_rows = component_inst->words()[3]; + const auto scalar_elem_type = component_inst->words()[2]; + const uint32_t scalar_elem_size = + getSize(scalar_elem_type, inherited, constraints, vstate); + return (num_rows - 1) * inherited.matrix_stride + + num_columns * scalar_elem_size; + } + } + case spv::Op::OpTypeStruct: { + const auto& members = getStructMembers(member_id, vstate); + if (members.empty()) return 0; + const auto lastIdx = uint32_t(members.size() - 1); + const auto& lastMember = members.back(); + uint32_t offset = 0xffffffff; + // Find the offset of the last element and add the size. + auto member_decorations = + vstate.id_member_decorations(member_id, lastIdx); + for (auto decoration = member_decorations.begin; + decoration != member_decorations.end; ++decoration) { + assert(decoration->struct_member_index() == (int)lastIdx); + if (spv::Decoration::Offset == decoration->dec_type()) { + offset = decoration->params()[0]; + } + } + // This check depends on the fact that all members have offsets. This + // has been checked earlier in the flow. + assert(offset != 0xffffffff); + const auto& constraint = constraints[std::make_pair(lastMember, lastIdx)]; + return offset + getSize(lastMember, constraint, constraints, vstate); + } + case spv::Op::OpTypePointer: + return vstate.pointer_size_and_alignment(); + default: + assert(0); + return 0; + } +} + +// A member is defined to improperly straddle if either of the following are +// true: +// - It is a vector with total size less than or equal to 16 bytes, and has +// Offset decorations placing its first byte at F and its last byte at L, where +// floor(F / 16) != floor(L / 16). +// - It is a vector with total size greater than 16 bytes and has its Offset +// decorations placing its first byte at a non-integer multiple of 16. +bool hasImproperStraddle(uint32_t id, uint32_t offset, + const LayoutConstraints& inherited, + MemberConstraints& constraints, + ValidationState_t& vstate) { + const auto size = getSize(id, inherited, constraints, vstate); + const auto F = offset; + const auto L = offset + size - 1; + if (size <= 16) { + if ((F >> 4) != (L >> 4)) return true; + } else { + if (F % 16 != 0) return true; + } + return false; +} + +// Returns true if |offset| satsifies an alignment to |alignment|. In the case +// of |alignment| of zero, the |offset| must also be zero. +bool IsAlignedTo(uint32_t offset, uint32_t alignment) { + if (alignment == 0) return offset == 0; + return 0 == (offset % alignment); +} + +// Returns SPV_SUCCESS if the given struct satisfies standard layout rules for +// Block or BufferBlocks in Vulkan. Otherwise emits a diagnostic and returns +// something other than SPV_SUCCESS. Matrices inherit the specified column +// or row major-ness. +spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, + const char* decoration_str, bool blockRules, + bool scalar_block_layout, + uint32_t incoming_offset, + MemberConstraints& constraints, + ValidationState_t& vstate) { + if (vstate.options()->skip_block_layout) return SPV_SUCCESS; + + // blockRules are the same as bufferBlock rules if the uniform buffer + // standard layout extension is being used. + if (vstate.options()->uniform_buffer_standard_layout) blockRules = false; + + // Relaxed layout and scalar layout can both be in effect at the same time. + // For example, relaxed layout is implied by Vulkan 1.1. But scalar layout + // is more permissive than relaxed layout. + const bool relaxed_block_layout = vstate.IsRelaxedBlockLayout(); + + auto fail = [&vstate, struct_id, storage_class_str, decoration_str, + blockRules, relaxed_block_layout, + scalar_block_layout](uint32_t member_idx) -> DiagnosticStream { + DiagnosticStream ds = + std::move(vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(struct_id)) + << "Structure id " << struct_id << " decorated as " + << decoration_str << " for variable in " << storage_class_str + << " storage class must follow " + << (scalar_block_layout + ? "scalar " + : (relaxed_block_layout ? "relaxed " : "standard ")) + << (blockRules ? "uniform buffer" : "storage buffer") + << " layout rules: member " << member_idx << " "); + return ds; + }; + + // If we are checking physical storage buffer pointers, we may not actually + // have a struct here. Instead, pretend we have a struct with a single member + // at offset 0. + const auto& struct_type = vstate.FindDef(struct_id); + std::vector members; + if (struct_type->opcode() == spv::Op::OpTypeStruct) { + members = getStructMembers(struct_id, vstate); + } else { + members.push_back(struct_id); + } + + // To check for member overlaps, we want to traverse the members in + // offset order. + struct MemberOffsetPair { + uint32_t member; + uint32_t offset; + }; + std::vector member_offsets; + + // With physical storage buffers, we might be checking layouts that do not + // originate from a structure. + if (struct_type->opcode() == spv::Op::OpTypeStruct) { + member_offsets.reserve(members.size()); + for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); + memberIdx < numMembers; memberIdx++) { + uint32_t offset = 0xffffffff; + auto member_decorations = + vstate.id_member_decorations(struct_id, memberIdx); + for (auto decoration = member_decorations.begin; + decoration != member_decorations.end; ++decoration) { + assert(decoration->struct_member_index() == (int)memberIdx); + switch (decoration->dec_type()) { + case spv::Decoration::Offset: + offset = decoration->params()[0]; + break; + default: + break; + } + } + member_offsets.push_back( + MemberOffsetPair{memberIdx, incoming_offset + offset}); + } + std::stable_sort( + member_offsets.begin(), member_offsets.end(), + [](const MemberOffsetPair& lhs, const MemberOffsetPair& rhs) { + return lhs.offset < rhs.offset; + }); + } else { + member_offsets.push_back({0, 0}); + } + + // Now scan from lowest offset to highest offset. + uint32_t nextValidOffset = 0; + for (size_t ordered_member_idx = 0; + ordered_member_idx < member_offsets.size(); ordered_member_idx++) { + const auto& member_offset = member_offsets[ordered_member_idx]; + const auto memberIdx = member_offset.member; + const auto offset = member_offset.offset; + auto id = members[member_offset.member]; + const LayoutConstraints& constraint = + constraints[std::make_pair(struct_id, uint32_t(memberIdx))]; + // Scalar layout takes precedence because it's more permissive, and implying + // an alignment that divides evenly into the alignment that would otherwise + // be used. + const auto alignment = + scalar_block_layout + ? getScalarAlignment(id, vstate) + : getBaseAlignment(id, blockRules, constraint, constraints, vstate); + const auto inst = vstate.FindDef(id); + const auto opcode = inst->opcode(); + const auto size = getSize(id, constraint, constraints, vstate); + // Check offset. + if (offset == 0xffffffff) + return fail(memberIdx) << "is missing an Offset decoration"; + if (!scalar_block_layout && relaxed_block_layout && + opcode == spv::Op::OpTypeVector) { + // In relaxed block layout, the vector offset must be aligned to the + // vector's scalar element type. + const auto componentId = inst->words()[2]; + const auto scalar_alignment = getScalarAlignment(componentId, vstate); + if (!IsAlignedTo(offset, scalar_alignment)) { + return fail(memberIdx) + << "at offset " << offset + << " is not aligned to scalar element size " << scalar_alignment; + } + } else { + // Without relaxed block layout, the offset must be divisible by the + // alignment requirement. + if (!IsAlignedTo(offset, alignment)) { + return fail(memberIdx) + << "at offset " << offset << " is not aligned to " << alignment; + } + } + if (offset < nextValidOffset) + return fail(memberIdx) << "at offset " << offset + << " overlaps previous member ending at offset " + << nextValidOffset - 1; + if (!scalar_block_layout && relaxed_block_layout) { + // Check improper straddle of vectors. + if (spv::Op::OpTypeVector == opcode && + hasImproperStraddle(id, offset, constraint, constraints, vstate)) + return fail(memberIdx) + << "is an improperly straddling vector at offset " << offset; + } + // Check struct members recursively. + spv_result_t recursive_status = SPV_SUCCESS; + if (spv::Op::OpTypeStruct == opcode && + SPV_SUCCESS != (recursive_status = checkLayout( + id, storage_class_str, decoration_str, blockRules, + scalar_block_layout, offset, constraints, vstate))) + return recursive_status; + // Check matrix stride. + if (spv::Op::OpTypeMatrix == opcode) { + const auto stride = constraint.matrix_stride; + if (!IsAlignedTo(stride, alignment)) { + return fail(memberIdx) << "is a matrix with stride " << stride + << " not satisfying alignment to " << alignment; + } + } + + // Check arrays and runtime arrays recursively. + auto array_inst = inst; + auto array_alignment = alignment; + while (array_inst->opcode() == spv::Op::OpTypeArray || + array_inst->opcode() == spv::Op::OpTypeRuntimeArray) { + const auto typeId = array_inst->word(2); + const auto element_inst = vstate.FindDef(typeId); + // Check array stride. + uint32_t array_stride = 0; + for (auto& decoration : vstate.id_decorations(array_inst->id())) { + if (spv::Decoration::ArrayStride == decoration.dec_type()) { + array_stride = decoration.params()[0]; + if (array_stride == 0) { + return fail(memberIdx) << "contains an array with stride 0"; + } + if (!IsAlignedTo(array_stride, array_alignment)) + return fail(memberIdx) + << "contains an array with stride " << decoration.params()[0] + << " not satisfying alignment to " << alignment; + } + } + + bool is_int32 = false; + bool is_const = false; + uint32_t num_elements = 0; + if (array_inst->opcode() == spv::Op::OpTypeArray) { + std::tie(is_int32, is_const, num_elements) = + vstate.EvalInt32IfConst(array_inst->word(3)); + } + num_elements = std::max(1u, num_elements); + // Check each element recursively if it is a struct. There is a + // limitation to this check if the array size is a spec constant or is a + // runtime array then we will only check a single element. This means + // some improper straddles might be missed. + if (spv::Op::OpTypeStruct == element_inst->opcode()) { + std::vector seen(16, false); + for (uint32_t i = 0; i < num_elements; ++i) { + uint32_t next_offset = i * array_stride + offset; + // Stop checking if offsets repeat in terms of 16-byte multiples. + if (seen[next_offset % 16]) { + break; + } + + if (SPV_SUCCESS != + (recursive_status = checkLayout( + typeId, storage_class_str, decoration_str, blockRules, + scalar_block_layout, next_offset, constraints, vstate))) + return recursive_status; + + seen[next_offset % 16] = true; + } + } + + // Proceed to the element in case it is an array. + array_inst = element_inst; + array_alignment = scalar_block_layout + ? getScalarAlignment(array_inst->id(), vstate) + : getBaseAlignment(array_inst->id(), blockRules, + constraint, constraints, vstate); + + const auto element_size = + getSize(element_inst->id(), constraint, constraints, vstate); + if (element_size > array_stride) { + return fail(memberIdx) + << "contains an array with stride " << array_stride + << ", but with an element size of " << element_size; + } + } + nextValidOffset = offset + size; + if (!scalar_block_layout && + (spv::Op::OpTypeArray == opcode || spv::Op::OpTypeStruct == opcode)) { + // Non-scalar block layout rules don't permit anything in the padding of + // a struct or array. + nextValidOffset = align(nextValidOffset, alignment); + } + } + return SPV_SUCCESS; +} + +// Returns true if variable or structure id has given decoration. Handles also +// nested structures. +bool hasDecoration(uint32_t id, spv::Decoration decoration, + ValidationState_t& vstate) { + for (auto& dec : vstate.id_decorations(id)) { + if (decoration == dec.dec_type()) return true; + } + if (spv::Op::OpTypeStruct != vstate.FindDef(id)->opcode()) { + return false; + } + for (auto member_id : getStructMembers(id, spv::Op::OpTypeStruct, vstate)) { + if (hasDecoration(member_id, decoration, vstate)) { + return true; + } + } + return false; +} + +// Returns true if all ids of given type have a specified decoration. +bool checkForRequiredDecoration(uint32_t struct_id, + std::function checker, + spv::Op type, ValidationState_t& vstate) { + const auto& members = getStructMembers(struct_id, vstate); + for (size_t memberIdx = 0; memberIdx < members.size(); memberIdx++) { + const auto id = members[memberIdx]; + if (type != vstate.FindDef(id)->opcode()) continue; + bool found = false; + for (auto& dec : vstate.id_decorations(id)) { + if (checker(dec.dec_type())) found = true; + } + for (auto& dec : vstate.id_decorations(struct_id)) { + if (checker(dec.dec_type()) && + (int)memberIdx == dec.struct_member_index()) { + found = true; + } + } + if (!found) { + return false; + } + } + for (auto id : getStructMembers(struct_id, spv::Op::OpTypeStruct, vstate)) { + if (!checkForRequiredDecoration(id, checker, type, vstate)) { + return false; + } + } + return true; +} + +spv_result_t CheckLinkageAttrOfFunctions(ValidationState_t& vstate) { + for (const auto& function : vstate.functions()) { + if (function.block_count() == 0u) { + // A function declaration (an OpFunction with no basic blocks), must have + // a Linkage Attributes Decoration with the Import Linkage Type. + if (!hasImportLinkageAttribute(function.id(), vstate)) { + return vstate.diag(SPV_ERROR_INVALID_BINARY, + vstate.FindDef(function.id())) + << "Function declaration (id " << function.id() + << ") must have a LinkageAttributes decoration with the Import " + "Linkage type."; + } + } else { + if (hasImportLinkageAttribute(function.id(), vstate)) { + return vstate.diag(SPV_ERROR_INVALID_BINARY, + vstate.FindDef(function.id())) + << "Function definition (id " << function.id() + << ") may not be decorated with Import Linkage type."; + } + } + } + return SPV_SUCCESS; +} + +// Checks whether an imported variable is initialized by this module. +spv_result_t CheckImportedVariableInitialization(ValidationState_t& vstate) { + // According the SPIR-V Spec 2.16.1, it is illegal to initialize an imported + // variable. This means that a module-scope OpVariable with initialization + // value cannot be marked with the Import Linkage Type (import type id = 1). + for (auto global_var_id : vstate.global_vars()) { + // Initializer is an optional argument for OpVariable. If initializer + // is present, the instruction will have 5 words. + auto variable_instr = vstate.FindDef(global_var_id); + if (variable_instr->words().size() == 5u && + hasImportLinkageAttribute(global_var_id, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, variable_instr) + << "A module-scope OpVariable with initialization value " + "cannot be marked with the Import Linkage Type."; + } + } + return SPV_SUCCESS; +} + +// Checks whether a builtin variable is valid. +spv_result_t CheckBuiltInVariable(uint32_t var_id, ValidationState_t& vstate) { + const auto& decorations = vstate.id_decorations(var_id); + for (const auto& d : decorations) { + if (spvIsVulkanEnv(vstate.context()->target_env)) { + if (d.dec_type() == spv::Decoration::Location || + d.dec_type() == spv::Decoration::Component) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) + << vstate.VkErrorID(4915) << "A BuiltIn variable (id " << var_id + << ") cannot have any Location or Component decorations"; + } + } + } + return SPV_SUCCESS; +} + +// Checks whether proper decorations have been applied to the entry points. +spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { + for (uint32_t entry_point : vstate.entry_points()) { + const auto& descs = vstate.entry_point_descriptions(entry_point); + int num_builtin_block_inputs = 0; + int num_builtin_block_outputs = 0; + int num_workgroup_variables = 0; + int num_workgroup_variables_with_block = 0; + int num_workgroup_variables_with_aliased = 0; + for (const auto& desc : descs) { + std::unordered_set seen_vars; + for (auto interface : desc.interfaces) { + Instruction* var_instr = vstate.FindDef(interface); + if (!var_instr || spv::Op::OpVariable != var_instr->opcode()) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << "Interfaces passed to OpEntryPoint must be of type " + "OpTypeVariable. Found Op" + << spvOpcodeString(var_instr->opcode()) << "."; + } + const spv::StorageClass storage_class = + var_instr->GetOperandAs(2); + if (vstate.version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // Starting in 1.4, OpEntryPoint must list all global variables + // it statically uses and those interfaces must be unique. + if (storage_class == spv::StorageClass::Function) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << "OpEntryPoint interfaces should only list global " + "variables"; + } + + if (!seen_vars.insert(var_instr).second) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << "Non-unique OpEntryPoint interface " + << vstate.getIdName(interface) << " is disallowed"; + } + } else { + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << "OpEntryPoint interfaces must be OpVariables with " + "Storage Class of Input(1) or Output(3). Found Storage " + "Class " + << uint32_t(storage_class) << " for Entry Point id " + << entry_point << "."; + } + } + + const uint32_t ptr_id = var_instr->word(1); + Instruction* ptr_instr = vstate.FindDef(ptr_id); + // It is guaranteed (by validator ID checks) that ptr_instr is + // OpTypePointer. Word 3 of this instruction is the type being pointed + // to. + const uint32_t type_id = ptr_instr->word(3); + Instruction* type_instr = vstate.FindDef(type_id); + if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode() && + isBuiltInStruct(type_id, vstate)) { + if (!isBlock(type_id, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_DATA, vstate.FindDef(type_id)) + << vstate.VkErrorID(4919) + << "Interface struct has no Block decoration but has " + "BuiltIn members. " + "Location decorations must be used on each member of " + "OpVariable with a structure type that is a block not " + "decorated with Location."; + } + if (storage_class == spv::StorageClass::Input) + ++num_builtin_block_inputs; + if (storage_class == spv::StorageClass::Output) + ++num_builtin_block_outputs; + if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1) + break; + if (auto error = CheckBuiltInVariable(interface, vstate)) + return error; + } else if (isBuiltInVar(interface, vstate)) { + if (auto error = CheckBuiltInVariable(interface, vstate)) + return error; + } + + if (storage_class == spv::StorageClass::Workgroup) { + ++num_workgroup_variables; + if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode()) { + if (hasDecoration(type_id, spv::Decoration::Block, vstate)) + ++num_workgroup_variables_with_block; + if (hasDecoration(var_instr->id(), spv::Decoration::Aliased, + vstate)) + ++num_workgroup_variables_with_aliased; + } + } + + if (spvIsVulkanEnv(vstate.context()->target_env)) { + const auto* models = vstate.GetExecutionModels(entry_point); + const bool has_frag = + models->find(spv::ExecutionModel::Fragment) != models->end(); + const bool has_vert = + models->find(spv::ExecutionModel::Vertex) != models->end(); + for (const auto& decoration : + vstate.id_decorations(var_instr->id())) { + if (decoration == spv::Decoration::Flat || + decoration == spv::Decoration::NoPerspective || + decoration == spv::Decoration::Sample || + decoration == spv::Decoration::Centroid) { + // VUID 04670 already validates these decorations are input/output + if (storage_class == spv::StorageClass::Input && + (models->size() > 1 || has_vert)) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << vstate.VkErrorID(6202) + << vstate.SpvDecorationString(decoration.dec_type()) + << " decorated variable must not be used in vertex " + "execution model as an Input storage class for Entry " + "Point id " + << entry_point << "."; + } else if (storage_class == spv::StorageClass::Output && + (models->size() > 1 || has_frag)) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << vstate.VkErrorID(6201) + << vstate.SpvDecorationString(decoration.dec_type()) + << " decorated variable must not be used in fragment " + "execution model as an Output storage class for " + "Entry Point id " + << entry_point << "."; + } + } + } + + const bool has_flat = + hasDecoration(var_instr->id(), spv::Decoration::Flat, vstate); + if (has_frag && storage_class == spv::StorageClass::Input && + !has_flat && + ((vstate.IsFloatScalarType(type_id) && + vstate.GetBitWidth(type_id) == 64) || + vstate.IsIntScalarOrVectorType(type_id))) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << vstate.VkErrorID(4744) + << "Fragment OpEntryPoint operand " + << interface << " with Input interfaces with integer or " + "float type must have a Flat decoration " + "for Entry Point id " + << entry_point << "."; + } + } + } + if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1) { + return vstate.diag(SPV_ERROR_INVALID_BINARY, + vstate.FindDef(entry_point)) + << "There must be at most one object per Storage Class that can " + "contain a structure type containing members decorated with " + "BuiltIn, consumed per entry-point. Entry Point id " + << entry_point << " does not meet this requirement."; + } + // The LinkageAttributes Decoration cannot be applied to functions + // targeted by an OpEntryPoint instruction + for (auto& decoration : vstate.id_decorations(entry_point)) { + if (spv::Decoration::LinkageAttributes == decoration.dec_type()) { + const std::string linkage_name = + spvtools::utils::MakeString(decoration.params()); + return vstate.diag(SPV_ERROR_INVALID_BINARY, + vstate.FindDef(entry_point)) + << "The LinkageAttributes Decoration (Linkage name: " + << linkage_name << ") cannot be applied to function id " + << entry_point + << " because it is targeted by an OpEntryPoint instruction."; + } + } + + const bool workgroup_blocks_allowed = vstate.HasCapability( + spv::Capability::WorkgroupMemoryExplicitLayoutKHR); + if (workgroup_blocks_allowed && num_workgroup_variables > 0 && + num_workgroup_variables_with_block > 0) { + if (num_workgroup_variables != num_workgroup_variables_with_block) { + return vstate.diag(SPV_ERROR_INVALID_BINARY, vstate.FindDef(entry_point)) + << "When declaring WorkgroupMemoryExplicitLayoutKHR, " + "either all or none of the Workgroup Storage Class variables " + "in the entry point interface must point to struct types " + "decorated with Block. Entry point id " + << entry_point << " does not meet this requirement."; + } + if (num_workgroup_variables_with_block > 1 && + num_workgroup_variables_with_block != + num_workgroup_variables_with_aliased) { + return vstate.diag(SPV_ERROR_INVALID_BINARY, vstate.FindDef(entry_point)) + << "When declaring WorkgroupMemoryExplicitLayoutKHR, " + "if more than one Workgroup Storage Class variable in " + "the entry point interface point to a type decorated " + "with Block, all of them must be decorated with Aliased. " + "Entry point id " + << entry_point << " does not meet this requirement."; + } + } else if (!workgroup_blocks_allowed && + num_workgroup_variables_with_block > 0) { + return vstate.diag(SPV_ERROR_INVALID_BINARY, + vstate.FindDef(entry_point)) + << "Workgroup Storage Class variables can't be decorated with " + "Block unless declaring the WorkgroupMemoryExplicitLayoutKHR " + "capability."; + } + } + } + return SPV_SUCCESS; +} + +// Load |constraints| with all the member constraints for structs contained +// within the given array type. +void ComputeMemberConstraintsForArray(MemberConstraints* constraints, + uint32_t array_id, + const LayoutConstraints& inherited, + ValidationState_t& vstate); + +// Load |constraints| with all the member constraints for the given struct, +// and all its contained structs. +void ComputeMemberConstraintsForStruct(MemberConstraints* constraints, + uint32_t struct_id, + const LayoutConstraints& inherited, + ValidationState_t& vstate) { + assert(constraints); + const auto& members = getStructMembers(struct_id, vstate); + for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); + memberIdx < numMembers; memberIdx++) { + LayoutConstraints& constraint = + (*constraints)[std::make_pair(struct_id, memberIdx)]; + constraint = inherited; + auto member_decorations = + vstate.id_member_decorations(struct_id, memberIdx); + for (auto decoration = member_decorations.begin; + decoration != member_decorations.end; ++decoration) { + assert(decoration->struct_member_index() == (int)memberIdx); + switch (decoration->dec_type()) { + case spv::Decoration::RowMajor: + constraint.majorness = kRowMajor; + break; + case spv::Decoration::ColMajor: + constraint.majorness = kColumnMajor; + break; + case spv::Decoration::MatrixStride: + constraint.matrix_stride = decoration->params()[0]; + break; + default: + break; + } + } + + // Now recurse + auto member_type_id = members[memberIdx]; + const auto member_type_inst = vstate.FindDef(member_type_id); + const auto opcode = member_type_inst->opcode(); + switch (opcode) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + ComputeMemberConstraintsForArray(constraints, member_type_id, inherited, + vstate); + break; + case spv::Op::OpTypeStruct: + ComputeMemberConstraintsForStruct(constraints, member_type_id, + inherited, vstate); + break; + default: + break; + } + } +} + +void ComputeMemberConstraintsForArray(MemberConstraints* constraints, + uint32_t array_id, + const LayoutConstraints& inherited, + ValidationState_t& vstate) { + assert(constraints); + auto elem_type_id = vstate.FindDef(array_id)->words()[2]; + const auto elem_type_inst = vstate.FindDef(elem_type_id); + const auto opcode = elem_type_inst->opcode(); + switch (opcode) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + ComputeMemberConstraintsForArray(constraints, elem_type_id, inherited, + vstate); + break; + case spv::Op::OpTypeStruct: + ComputeMemberConstraintsForStruct(constraints, elem_type_id, inherited, + vstate); + break; + default: + break; + } +} + +spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { + // Set of entry points that are known to use a push constant. + std::unordered_set uses_push_constant; + for (const auto& inst : vstate.ordered_instructions()) { + const auto& words = inst.words(); + auto type_id = inst.type_id(); + const Instruction* type_inst = vstate.FindDef(type_id); + if (spv::Op::OpVariable == inst.opcode()) { + const auto var_id = inst.id(); + // For storage class / decoration combinations, see Vulkan 14.5.4 "Offset + // and Stride Assignment". + const auto storageClass = inst.GetOperandAs(2); + const bool uniform = storageClass == spv::StorageClass::Uniform; + const bool uniform_constant = + storageClass == spv::StorageClass::UniformConstant; + const bool push_constant = + storageClass == spv::StorageClass::PushConstant; + const bool storage_buffer = + storageClass == spv::StorageClass::StorageBuffer; + + if (spvIsVulkanEnv(vstate.context()->target_env)) { + // Vulkan: There must be no more than one PushConstant block per entry + // point. + if (push_constant) { + auto entry_points = vstate.EntryPointReferences(var_id); + for (auto ep_id : entry_points) { + const bool already_used = !uses_push_constant.insert(ep_id).second; + if (already_used) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) + << vstate.VkErrorID(6674) << "Entry point id '" << ep_id + << "' uses more than one PushConstant interface.\n" + << "From Vulkan spec:\n" + << "There must be no more than one push constant block " + << "statically used per shader entry point."; + } + } + } + // Vulkan: Check DescriptorSet and Binding decoration for + // UniformConstant which cannot be a struct. + if (uniform_constant) { + auto entry_points = vstate.EntryPointReferences(var_id); + if (!entry_points.empty() && + !hasDecoration(var_id, spv::Decoration::DescriptorSet, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) + << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id + << "' is missing DescriptorSet decoration.\n" + << "From Vulkan spec:\n" + << "These variables must have DescriptorSet and Binding " + "decorations specified"; + } + if (!entry_points.empty() && + !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) + << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id + << "' is missing Binding decoration.\n" + << "From Vulkan spec:\n" + << "These variables must have DescriptorSet and Binding " + "decorations specified"; + } + } + } + + if (spvIsOpenGLEnv(vstate.context()->target_env)) { + bool has_block = hasDecoration(var_id, spv::Decoration::Block, vstate); + bool has_buffer_block = + hasDecoration(var_id, spv::Decoration::BufferBlock, vstate); + if ((uniform && (has_block || has_buffer_block)) || + (storage_buffer && has_block)) { + auto entry_points = vstate.EntryPointReferences(var_id); + if (!entry_points.empty() && + !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) + << (uniform ? "Uniform" : "Storage Buffer") << " id '" + << var_id << "' is missing Binding decoration.\n" + << "From ARB_gl_spirv extension:\n" + << "Uniform and shader storage block variables must " + << "also be decorated with a *Binding*."; + } + } + } + + const bool phys_storage_buffer = + storageClass == spv::StorageClass::PhysicalStorageBuffer; + const bool workgroup = + storageClass == spv::StorageClass::Workgroup && + vstate.HasCapability( + spv::Capability::WorkgroupMemoryExplicitLayoutKHR); + if (uniform || push_constant || storage_buffer || phys_storage_buffer || + workgroup) { + const auto ptrInst = vstate.FindDef(words[1]); + assert(spv::Op::OpTypePointer == ptrInst->opcode()); + auto id = ptrInst->words()[3]; + auto id_inst = vstate.FindDef(id); + // Jump through one level of arraying. + if (!workgroup && (id_inst->opcode() == spv::Op::OpTypeArray || + id_inst->opcode() == spv::Op::OpTypeRuntimeArray)) { + id = id_inst->GetOperandAs(1u); + id_inst = vstate.FindDef(id); + } + // Struct requirement is checked on variables so just move on here. + if (spv::Op::OpTypeStruct != id_inst->opcode()) continue; + MemberConstraints constraints; + ComputeMemberConstraintsForStruct(&constraints, id, LayoutConstraints(), + vstate); + // Prepare for messages + const char* sc_str = + uniform ? "Uniform" + : (push_constant ? "PushConstant" + : (workgroup ? "Workgroup" + : "StorageBuffer")); + + if (spvIsVulkanEnv(vstate.context()->target_env)) { + const bool block = hasDecoration(id, spv::Decoration::Block, vstate); + const bool buffer_block = + hasDecoration(id, spv::Decoration::BufferBlock, vstate); + if (storage_buffer && buffer_block) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) + << vstate.VkErrorID(6675) << "Storage buffer id '" << var_id + << " In Vulkan, BufferBlock is disallowed on variables in " + "the StorageBuffer storage class"; + } + // Vulkan: Check Block decoration for PushConstant, Uniform + // and StorageBuffer variables. Uniform can also use BufferBlock. + if (push_constant && !block) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << vstate.VkErrorID(6675) << "PushConstant id '" << id + << "' is missing Block decoration.\n" + << "From Vulkan spec:\n" + << "Such variables must be identified with a Block " + "decoration"; + } + if (storage_buffer && !block) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << vstate.VkErrorID(6675) << "StorageBuffer id '" << id + << "' is missing Block decoration.\n" + << "From Vulkan spec:\n" + << "Such variables must be identified with a Block " + "decoration"; + } + if (uniform && !block && !buffer_block) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << vstate.VkErrorID(6676) << "Uniform id '" << id + << "' is missing Block or BufferBlock decoration.\n" + << "From Vulkan spec:\n" + << "Such variables must be identified with a Block or " + "BufferBlock decoration"; + } + // Vulkan: Check DescriptorSet and Binding decoration for + // Uniform and StorageBuffer variables. + if (uniform || storage_buffer) { + auto entry_points = vstate.EntryPointReferences(var_id); + if (!entry_points.empty() && + !hasDecoration(var_id, spv::Decoration::DescriptorSet, + vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) + << vstate.VkErrorID(6677) << sc_str << " id '" << var_id + << "' is missing DescriptorSet decoration.\n" + << "From Vulkan spec:\n" + << "These variables must have DescriptorSet and Binding " + "decorations specified"; + } + if (!entry_points.empty() && + !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) + << vstate.VkErrorID(6677) << sc_str << " id '" << var_id + << "' is missing Binding decoration.\n" + << "From Vulkan spec:\n" + << "These variables must have DescriptorSet and Binding " + "decorations specified"; + } + } + } + + for (const auto& dec : vstate.id_decorations(id)) { + const bool blockDeco = spv::Decoration::Block == dec.dec_type(); + const bool bufferDeco = + spv::Decoration::BufferBlock == dec.dec_type(); + const bool blockRules = uniform && blockDeco; + const bool bufferRules = + (uniform && bufferDeco) || + ((push_constant || storage_buffer || + phys_storage_buffer || workgroup) && blockDeco); + if (uniform && blockDeco) { + vstate.RegisterPointerToUniformBlock(ptrInst->id()); + vstate.RegisterStructForUniformBlock(id); + } + if ((uniform && bufferDeco) || + ((storage_buffer || phys_storage_buffer) && blockDeco)) { + vstate.RegisterPointerToStorageBuffer(ptrInst->id()); + vstate.RegisterStructForStorageBuffer(id); + } + + if (blockRules || bufferRules) { + const char* deco_str = blockDeco ? "Block" : "BufferBlock"; + spv_result_t recursive_status = SPV_SUCCESS; + const bool scalar_block_layout = workgroup ? + vstate.options()->workgroup_scalar_block_layout : + vstate.options()->scalar_block_layout; + + if (isMissingOffsetInStruct(id, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "Structure id " << id << " decorated as " << deco_str + << " must be explicitly laid out with Offset " + "decorations."; + } + + if (!checkForRequiredDecoration( + id, + [](spv::Decoration d) { + return d == spv::Decoration::ArrayStride; + }, + spv::Op::OpTypeArray, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "Structure id " << id << " decorated as " << deco_str + << " must be explicitly laid out with ArrayStride " + "decorations."; + } + + if (!checkForRequiredDecoration( + id, + [](spv::Decoration d) { + return d == spv::Decoration::MatrixStride; + }, + spv::Op::OpTypeMatrix, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "Structure id " << id << " decorated as " << deco_str + << " must be explicitly laid out with MatrixStride " + "decorations."; + } + + if (!checkForRequiredDecoration( + id, + [](spv::Decoration d) { + return d == spv::Decoration::RowMajor || + d == spv::Decoration::ColMajor; + }, + spv::Op::OpTypeMatrix, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "Structure id " << id << " decorated as " << deco_str + << " must be explicitly laid out with RowMajor or " + "ColMajor decorations."; + } + + if (spvIsVulkanEnv(vstate.context()->target_env)) { + if (blockRules && (SPV_SUCCESS != (recursive_status = checkLayout( + id, sc_str, deco_str, true, + scalar_block_layout, 0, + constraints, vstate)))) { + return recursive_status; + } else if (bufferRules && + (SPV_SUCCESS != + (recursive_status = checkLayout( + id, sc_str, deco_str, false, scalar_block_layout, + 0, constraints, vstate)))) { + return recursive_status; + } + } + } + } + } + } else if (type_inst && type_inst->opcode() == spv::Op::OpTypePointer && + type_inst->GetOperandAs(1u) == + spv::StorageClass::PhysicalStorageBuffer) { + const bool scalar_block_layout = vstate.options()->scalar_block_layout; + MemberConstraints constraints; + const bool buffer = true; + const auto data_type_id = type_inst->GetOperandAs(2u); + const auto* data_type_inst = vstate.FindDef(data_type_id); + if (data_type_inst->opcode() == spv::Op::OpTypeStruct) { + ComputeMemberConstraintsForStruct(&constraints, data_type_id, + LayoutConstraints(), vstate); + } + if (auto res = checkLayout(data_type_id, "PhysicalStorageBuffer", "Block", + !buffer, scalar_block_layout, 0, constraints, + vstate)) { + return res; + } + } + } + return SPV_SUCCESS; +} + +// Returns true if |decoration| cannot be applied to the same id more than once. +bool AtMostOncePerId(spv::Decoration decoration) { + return decoration == spv::Decoration::ArrayStride; +} + +// Returns true if |decoration| cannot be applied to the same member more than +// once. +bool AtMostOncePerMember(spv::Decoration decoration) { + switch (decoration) { + case spv::Decoration::Offset: + case spv::Decoration::MatrixStride: + case spv::Decoration::RowMajor: + case spv::Decoration::ColMajor: + return true; + default: + return false; + } +} + +spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { + using PerIDKey = std::tuple; + using PerMemberKey = std::tuple; + + // An Array of pairs where the decorations in the pair cannot both be applied + // to the same id. + static const spv::Decoration mutually_exclusive_per_id[][2] = { + {spv::Decoration::Block, spv::Decoration::BufferBlock}, + {spv::Decoration::Restrict, spv::Decoration::Aliased}}; + static const auto num_mutually_exclusive_per_id_pairs = + sizeof(mutually_exclusive_per_id) / (2 * sizeof(spv::Decoration)); + + // An Array of pairs where the decorations in the pair cannot both be applied + // to the same member. + static const spv::Decoration mutually_exclusive_per_member[][2] = { + {spv::Decoration::RowMajor, spv::Decoration::ColMajor}}; + static const auto num_mutually_exclusive_per_mem_pairs = + sizeof(mutually_exclusive_per_member) / (2 * sizeof(spv::Decoration)); + + std::set seen_per_id; + std::set seen_per_member; + + for (const auto& inst : vstate.ordered_instructions()) { + const auto& words = inst.words(); + if (spv::Op::OpDecorate == inst.opcode()) { + const auto id = words[1]; + const auto dec_type = static_cast(words[2]); + const auto k = PerIDKey(dec_type, id); + const auto already_used = !seen_per_id.insert(k).second; + if (already_used && AtMostOncePerId(dec_type)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "ID '" << id << "' decorated with " + << vstate.SpvDecorationString(dec_type) + << " multiple times is not allowed."; + } + // Verify certain mutually exclusive decorations are not both applied on + // an ID. + for (uint32_t pair_idx = 0; + pair_idx < num_mutually_exclusive_per_id_pairs; ++pair_idx) { + spv::Decoration excl_dec_type = spv::Decoration::Max; + if (mutually_exclusive_per_id[pair_idx][0] == dec_type) { + excl_dec_type = mutually_exclusive_per_id[pair_idx][1]; + } else if (mutually_exclusive_per_id[pair_idx][1] == dec_type) { + excl_dec_type = mutually_exclusive_per_id[pair_idx][0]; + } else { + continue; + } + + const auto excl_k = PerIDKey(excl_dec_type, id); + if (seen_per_id.find(excl_k) != seen_per_id.end()) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "ID '" << id << "' decorated with both " + << vstate.SpvDecorationString(dec_type) << " and " + << vstate.SpvDecorationString(excl_dec_type) + << " is not allowed."; + } + } + } else if (spv::Op::OpMemberDecorate == inst.opcode()) { + const auto id = words[1]; + const auto member_id = words[2]; + const auto dec_type = static_cast(words[3]); + const auto k = PerMemberKey(dec_type, id, member_id); + const auto already_used = !seen_per_member.insert(k).second; + if (already_used && AtMostOncePerMember(dec_type)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "ID '" << id << "', member '" << member_id + << "' decorated with " << vstate.SpvDecorationString(dec_type) + << " multiple times is not allowed."; + } + // Verify certain mutually exclusive decorations are not both applied on + // a (ID, member) tuple. + for (uint32_t pair_idx = 0; + pair_idx < num_mutually_exclusive_per_mem_pairs; ++pair_idx) { + spv::Decoration excl_dec_type = spv::Decoration::Max; + if (mutually_exclusive_per_member[pair_idx][0] == dec_type) { + excl_dec_type = mutually_exclusive_per_member[pair_idx][1]; + } else if (mutually_exclusive_per_member[pair_idx][1] == dec_type) { + excl_dec_type = mutually_exclusive_per_member[pair_idx][0]; + } else { + continue; + } + + const auto excl_k = PerMemberKey(excl_dec_type, id, member_id); + if (seen_per_member.find(excl_k) != seen_per_member.end()) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "ID '" << id << "', member '" << member_id + << "' decorated with both " + << vstate.SpvDecorationString(dec_type) << " and " + << vstate.SpvDecorationString(excl_dec_type) + << " is not allowed."; + } + } + } + } + return SPV_SUCCESS; +} + +spv_result_t CheckVulkanMemoryModelDeprecatedDecorations( + ValidationState_t& vstate) { + if (vstate.memory_model() != spv::MemoryModel::VulkanKHR) return SPV_SUCCESS; + + std::string msg; + std::ostringstream str(msg); + for (const auto& def : vstate.all_definitions()) { + const auto inst = def.second; + const auto id = inst->id(); + for (const auto& dec : vstate.id_decorations(id)) { + const auto member = dec.struct_member_index(); + if (dec.dec_type() == spv::Decoration::Coherent || + dec.dec_type() == spv::Decoration::Volatile) { + str << (dec.dec_type() == spv::Decoration::Coherent ? "Coherent" + : "Volatile"); + str << " decoration targeting " << vstate.getIdName(id); + if (member != Decoration::kInvalidMember) { + str << " (member index " << member << ")"; + } + str << " is banned when using the Vulkan memory model."; + return vstate.diag(SPV_ERROR_INVALID_ID, inst) << str.str(); + } + } + } + return SPV_SUCCESS; +} + +// Returns SPV_SUCCESS if validation rules are satisfied for FPRoundingMode +// decorations. Otherwise emits a diagnostic and returns something other than +// SPV_SUCCESS. +spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, + const Instruction& inst, + const Decoration& decoration) { + // Validates width-only conversion instruction for floating-point object + // i.e., OpFConvert + if (inst.opcode() != spv::Op::OpFConvert) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "FPRoundingMode decoration can be applied only to a " + "width-only conversion instruction for floating-point " + "object."; + } + + if (spvIsVulkanEnv(vstate.context()->target_env)) { + const auto mode = spv::FPRoundingMode(decoration.params()[0]); + if ((mode != spv::FPRoundingMode::RTE) && + (mode != spv::FPRoundingMode::RTZ)) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4675) + << "In Vulkan, the FPRoundingMode mode must only by RTE or RTZ."; + } + } + + // Validates Object operand of an OpStore + for (const auto& use : inst.uses()) { + const auto store = use.first; + if (store->opcode() == spv::Op::OpFConvert) continue; + if (spvOpcodeIsDebug(store->opcode())) continue; + if (store->IsNonSemantic()) continue; + if (spvOpcodeIsDecoration(store->opcode())) continue; + if (store->opcode() != spv::Op::OpStore) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "FPRoundingMode decoration can be applied only to the " + "Object operand of an OpStore."; + } + + if (use.second != 2) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "FPRoundingMode decoration can be applied only to the " + "Object operand of an OpStore."; + } + + const auto ptr_inst = vstate.FindDef(store->GetOperandAs(0)); + const auto ptr_type = vstate.FindDef(ptr_inst->GetOperandAs(0)); + + const auto half_float_id = ptr_type->GetOperandAs(2); + if (!vstate.IsFloatScalarOrVectorType(half_float_id) || + vstate.GetBitWidth(half_float_id) != 16) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "FPRoundingMode decoration can be applied only to the " + "Object operand of an OpStore storing through a pointer " + "to " + "a 16-bit floating-point scalar or vector object."; + } + + // Validates storage class of the pointer to the OpStore + const auto storage = ptr_type->GetOperandAs(1); + if (storage != spv::StorageClass::StorageBuffer && + storage != spv::StorageClass::Uniform && + storage != spv::StorageClass::PushConstant && + storage != spv::StorageClass::Input && + storage != spv::StorageClass::Output && + storage != spv::StorageClass::PhysicalStorageBuffer) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "FPRoundingMode decoration can be applied only to the " + "Object operand of an OpStore in the StorageBuffer, " + "PhysicalStorageBuffer, Uniform, PushConstant, Input, or " + "Output Storage Classes."; + } + } + return SPV_SUCCESS; +} + +// Returns SPV_SUCCESS if validation rules are satisfied for the NonWritable +// decoration. Otherwise emits a diagnostic and returns something other than +// SPV_SUCCESS. The |inst| parameter is the object being decorated. This must +// be called after TypePass and AnnotateCheckDecorationsOfBuffers are called. +spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate, + const Instruction& inst, + const Decoration& decoration) { + assert(inst.id() && "Parser ensures the target of the decoration has an ID"); + + if (decoration.struct_member_index() == Decoration::kInvalidMember) { + // The target must be a memory object declaration. + // First, it must be a variable or function parameter. + const auto opcode = inst.opcode(); + const auto type_id = inst.type_id(); + if (opcode != spv::Op::OpVariable && + opcode != spv::Op::OpFunctionParameter) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "Target of NonWritable decoration must be a memory object " + "declaration (a variable or a function parameter)"; + } + const auto var_storage_class = opcode == spv::Op::OpVariable + ? inst.GetOperandAs(2) + : spv::StorageClass::Max; + if ((var_storage_class == spv::StorageClass::Function || + var_storage_class == spv::StorageClass::Private) && + vstate.features().nonwritable_var_in_function_or_private) { + // New permitted feature in SPIR-V 1.4. + } else if ( + // It may point to a UBO, SSBO, or storage image. + vstate.IsPointerToUniformBlock(type_id) || + vstate.IsPointerToStorageBuffer(type_id) || + vstate.IsPointerToStorageImage(type_id)) { + } else { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "Target of NonWritable decoration is invalid: must point to a " + "storage image, uniform block, " + << (vstate.features().nonwritable_var_in_function_or_private + ? "storage buffer, or variable in Private or Function " + "storage class" + : "or storage buffer"); + } + } + + return SPV_SUCCESS; +} + +// Returns SPV_SUCCESS if validation rules are satisfied for Uniform or +// UniformId decorations. Otherwise emits a diagnostic and returns something +// other than SPV_SUCCESS. Assumes each decoration on a group has been +// propagated down to the group members. The |inst| parameter is the object +// being decorated. +spv_result_t CheckUniformDecoration(ValidationState_t& vstate, + const Instruction& inst, + const Decoration& decoration) { + const char* const dec_name = decoration.dec_type() == spv::Decoration::Uniform + ? "Uniform" + : "UniformId"; + + // Uniform or UniformId must decorate an "object" + // - has a result ID + // - is an instantiation of a non-void type. So it has a type ID, and that + // type is not void. + + // We already know the result ID is non-zero. + + if (inst.type_id() == 0) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << dec_name << " decoration applied to a non-object"; + } + if (Instruction* type_inst = vstate.FindDef(inst.type_id())) { + if (type_inst->opcode() == spv::Op::OpTypeVoid) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << dec_name << " decoration applied to a value with void type"; + } + } else { + // We might never get here because this would have been rejected earlier in + // the flow. + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << dec_name << " decoration applied to an object with invalid type"; + } + + // Use of Uniform with OpDecorate is checked elsewhere. + // Use of UniformId with OpDecorateId is checked elsewhere. + + if (decoration.dec_type() == spv::Decoration::UniformId) { + assert(decoration.params().size() == 1 && + "Grammar ensures UniformId has one parameter"); + + // The scope id is an execution scope. + if (auto error = + ValidateExecutionScope(vstate, &inst, decoration.params()[0])) + return error; + } + + return SPV_SUCCESS; +} + +// Returns SPV_SUCCESS if validation rules are satisfied for NoSignedWrap or +// NoUnsignedWrap decorations. Otherwise emits a diagnostic and returns +// something other than SPV_SUCCESS. Assumes each decoration on a group has been +// propagated down to the group members. +spv_result_t CheckIntegerWrapDecoration(ValidationState_t& vstate, + const Instruction& inst, + const Decoration& decoration) { + switch (inst.opcode()) { + case spv::Op::OpIAdd: + case spv::Op::OpISub: + case spv::Op::OpIMul: + case spv::Op::OpShiftLeftLogical: + case spv::Op::OpSNegate: + return SPV_SUCCESS; + case spv::Op::OpExtInst: + // TODO(dneto): Only certain extended instructions allow these + // decorations. For now allow anything. + return SPV_SUCCESS; + default: + break; + } + + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << (decoration.dec_type() == spv::Decoration::NoSignedWrap + ? "NoSignedWrap" + : "NoUnsignedWrap") + << " decoration may not be applied to " + << spvOpcodeString(inst.opcode()); +} + +// Returns SPV_SUCCESS if validation rules are satisfied for the Component +// decoration. Otherwise emits a diagnostic and returns something other than +// SPV_SUCCESS. +spv_result_t CheckComponentDecoration(ValidationState_t& vstate, + const Instruction& inst, + const Decoration& decoration) { + assert(inst.id() && "Parser ensures the target of the decoration has an ID"); + assert(decoration.params().size() == 1 && + "Grammar ensures Component has one parameter"); + + uint32_t type_id; + if (decoration.struct_member_index() == Decoration::kInvalidMember) { + // The target must be a memory object declaration. + const auto opcode = inst.opcode(); + if (opcode != spv::Op::OpVariable && + opcode != spv::Op::OpFunctionParameter) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "Target of Component decoration must be a memory object " + "declaration (a variable or a function parameter)"; + } + + // Only valid for the Input and Output Storage Classes. + const auto storage_class = opcode == spv::Op::OpVariable + ? inst.GetOperandAs(2) + : spv::StorageClass::Max; + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output && + storage_class != spv::StorageClass::Max) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "Target of Component decoration is invalid: must point to a " + "Storage Class of Input(1) or Output(3). Found Storage " + "Class " + << uint32_t(storage_class); + } + + type_id = inst.type_id(); + if (vstate.IsPointerType(type_id)) { + const auto pointer = vstate.FindDef(type_id); + type_id = pointer->GetOperandAs(2); + } + } else { + if (inst.opcode() != spv::Op::OpTypeStruct) { + return vstate.diag(SPV_ERROR_INVALID_DATA, &inst) + << "Attempted to get underlying data type via member index for " + "non-struct type."; + } + type_id = inst.word(decoration.struct_member_index() + 2); + } + + if (spvIsVulkanEnv(vstate.context()->target_env)) { + // Strip the array, if present. + if (vstate.GetIdOpcode(type_id) == spv::Op::OpTypeArray) { + type_id = vstate.FindDef(type_id)->word(2u); + } + + if (!vstate.IsIntScalarOrVectorType(type_id) && + !vstate.IsFloatScalarOrVectorType(type_id)) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4924) + << "Component decoration specified for type " + << vstate.getIdName(type_id) << " that is not a scalar or vector"; + } + + const auto component = decoration.params()[0]; + if (component > 3) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4920) + << "Component decoration value must not be greater than 3"; + } + + const auto dimension = vstate.GetDimension(type_id); + const auto bit_width = vstate.GetBitWidth(type_id); + if (bit_width == 16 || bit_width == 32) { + const auto sum_component = component + dimension; + if (sum_component > 4) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4921) + << "Sequence of components starting with " << component + << " and ending with " << (sum_component - 1) + << " gets larger than 3"; + } + } else if (bit_width == 64) { + if (dimension > 2) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(7703) + << "Component decoration only allowed on 64-bit scalar and " + "2-component vector"; + } + if (component == 1 || component == 3) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4923) + << "Component decoration value must not be 1 or 3 for 64-bit " + "data types"; + } + // 64-bit is double per component dimension + const auto sum_component = component + (2 * dimension); + if (sum_component > 4) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4922) + << "Sequence of components starting with " << component + << " and ending with " << (sum_component - 1) + << " gets larger than 3"; + } + } + } + + return SPV_SUCCESS; +} + +// Returns SPV_SUCCESS if validation rules are satisfied for the Block +// decoration. Otherwise emits a diagnostic and returns something other than +// SPV_SUCCESS. +spv_result_t CheckBlockDecoration(ValidationState_t& vstate, + const Instruction& inst, + const Decoration& decoration) { + assert(inst.id() && "Parser ensures the target of the decoration has an ID"); + if (inst.opcode() != spv::Op::OpTypeStruct) { + const char* const dec_name = decoration.dec_type() == spv::Decoration::Block + ? "Block" + : "BufferBlock"; + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << dec_name << " decoration on a non-struct type."; + } + return SPV_SUCCESS; +} + +spv_result_t CheckLocationDecoration(ValidationState_t& vstate, + const Instruction& inst, + const Decoration& decoration) { + if (inst.opcode() == spv::Op::OpVariable) return SPV_SUCCESS; + + if (decoration.struct_member_index() != Decoration::kInvalidMember && + inst.opcode() == spv::Op::OpTypeStruct) { + return SPV_SUCCESS; + } + + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "Location decoration can only be applied to a variable or member " + "of a structure type"; +} + +spv_result_t CheckRelaxPrecisionDecoration(ValidationState_t& vstate, + const Instruction& inst, + const Decoration& decoration) { + // This is not the most precise check, but the rules for RelaxPrecision are + // very general, and it will be difficult to implement precisely. For now, + // I will only check for the cases that cause problems for the optimizer. + if (!spvOpcodeGeneratesType(inst.opcode())) { + return SPV_SUCCESS; + } + + if (decoration.struct_member_index() != Decoration::kInvalidMember && + inst.opcode() == spv::Op::OpTypeStruct) { + return SPV_SUCCESS; + } + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "RelaxPrecision decoration cannot be applied to a type"; +} + +#define PASS_OR_BAIL_AT_LINE(X, LINE) \ + { \ + spv_result_t e##LINE = (X); \ + if (e##LINE != SPV_SUCCESS) return e##LINE; \ + } static_assert(true, "require extra semicolon") +#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__) + +// Check rules for decorations where we start from the decoration rather +// than the decorated object. Assumes each decoration on a group have been +// propagated down to the group members. +spv_result_t CheckDecorationsFromDecoration(ValidationState_t& vstate) { + // Some rules are only checked for shaders. + const bool is_shader = vstate.HasCapability(spv::Capability::Shader); + + for (const auto& kv : vstate.id_decorations()) { + const uint32_t id = kv.first; + const auto& decorations = kv.second; + if (decorations.empty()) continue; + + const Instruction* inst = vstate.FindDef(id); + assert(inst); + + // We assume the decorations applied to a decoration group have already + // been propagated down to the group members. + if (inst->opcode() == spv::Op::OpDecorationGroup) continue; + + for (const auto& decoration : decorations) { + switch (decoration.dec_type()) { + case spv::Decoration::Component: + PASS_OR_BAIL(CheckComponentDecoration(vstate, *inst, decoration)); + break; + case spv::Decoration::FPRoundingMode: + if (is_shader) + PASS_OR_BAIL( + CheckFPRoundingModeForShaders(vstate, *inst, decoration)); + break; + case spv::Decoration::NonWritable: + PASS_OR_BAIL(CheckNonWritableDecoration(vstate, *inst, decoration)); + break; + case spv::Decoration::Uniform: + case spv::Decoration::UniformId: + PASS_OR_BAIL(CheckUniformDecoration(vstate, *inst, decoration)); + break; + case spv::Decoration::NoSignedWrap: + case spv::Decoration::NoUnsignedWrap: + PASS_OR_BAIL(CheckIntegerWrapDecoration(vstate, *inst, decoration)); + break; + case spv::Decoration::Block: + case spv::Decoration::BufferBlock: + PASS_OR_BAIL(CheckBlockDecoration(vstate, *inst, decoration)); + break; + case spv::Decoration::Location: + PASS_OR_BAIL(CheckLocationDecoration(vstate, *inst, decoration)); + break; + case spv::Decoration::RelaxedPrecision: + PASS_OR_BAIL( + CheckRelaxPrecisionDecoration(vstate, *inst, decoration)); + break; + default: + break; + } + } + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t ValidateDecorations(ValidationState_t& vstate) { + if (auto error = CheckImportedVariableInitialization(vstate)) return error; + if (auto error = CheckDecorationsOfEntryPoints(vstate)) return error; + if (auto error = CheckDecorationsOfBuffers(vstate)) return error; + if (auto error = CheckDecorationsCompatibility(vstate)) return error; + if (auto error = CheckLinkageAttrOfFunctions(vstate)) return error; + if (auto error = CheckVulkanMemoryModelDeprecatedDecorations(vstate)) + return error; + if (auto error = CheckDecorationsFromDecoration(vstate)) return error; + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_derivatives.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_derivatives.cpp new file mode 100644 index 000000000000..90cf6645c413 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_derivatives.cpp @@ -0,0 +1,111 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of derivative SPIR-V instructions. + +#include + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +// Validates correctness of derivative instructions. +spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + switch (opcode) { + case spv::Op::OpDPdx: + case spv::Op::OpDPdy: + case spv::Op::OpFwidth: + case spv::Op::OpDPdxFine: + case spv::Op::OpDPdyFine: + case spv::Op::OpFwidthFine: + case spv::Op::OpDPdxCoarse: + case spv::Op::OpDPdyCoarse: + case spv::Op::OpFwidthCoarse: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be float scalar or vector type: " + << spvOpcodeString(opcode); + } + if (!_.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeFloat, + 32)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result type component width must be 32 bits"; + } + + const uint32_t p_type = _.GetOperandTypeId(inst, 2); + if (p_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected P type and Result Type to be the same: " + << spvOpcodeString(opcode); + } + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::Fragment && + model != spv::ExecutionModel::GLCompute) { + if (message) { + *message = + std::string( + "Derivative instructions require Fragment or GLCompute " + "execution model: ") + + spvOpcodeString(opcode); + } + return false; + } + return true; + }); + _.function(inst->function()->id()) + ->RegisterLimitation([opcode](const ValidationState_t& state, + const Function* entry_point, + std::string* message) { + const auto* models = state.GetExecutionModels(entry_point->id()); + const auto* modes = state.GetExecutionModes(entry_point->id()); + if (models && + models->find(spv::ExecutionModel::GLCompute) != models->end() && + (!modes || + (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == + modes->end() && + modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == + modes->end()))) { + if (message) { + *message = std::string( + "Derivative instructions require " + "DerivativeGroupQuadsNV " + "or DerivativeGroupLinearNV execution mode for " + "GLCompute execution model: ") + + spvOpcodeString(opcode); + } + return false; + } + return true; + }); + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_execution_limitations.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_execution_limitations.cpp new file mode 100644 index 000000000000..0221d7ef20a7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_execution_limitations.cpp @@ -0,0 +1,69 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +spv_result_t ValidateExecutionLimitations(ValidationState_t& _, + const Instruction* inst) { + if (inst->opcode() != spv::Op::OpFunction) { + return SPV_SUCCESS; + } + + const auto func = _.function(inst->id()); + if (!func) { + return _.diag(SPV_ERROR_INTERNAL, inst) + << "Internal error: missing function id " << inst->id() << "."; + } + + for (uint32_t entry_id : _.FunctionEntryPoints(inst->id())) { + const auto* models = _.GetExecutionModels(entry_id); + if (models) { + if (models->empty()) { + return _.diag(SPV_ERROR_INTERNAL, inst) + << "Internal error: empty execution models for function id " + << entry_id << "."; + } + for (const auto model : *models) { + std::string reason; + if (!func->IsCompatibleWithExecutionModel(model, &reason)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpEntryPoint Entry Point " << _.getIdName(entry_id) + << "s callgraph contains function " + << _.getIdName(inst->id()) + << ", which cannot be used with the current execution " + "model:\n" + << reason; + } + } + } + + std::string reason; + if (!func->CheckLimitations(_, _.function(entry_id), &reason)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpEntryPoint Entry Point " << _.getIdName(entry_id) + << "s callgraph contains function " << _.getIdName(inst->id()) + << ", which cannot be used with the current execution " + "modes:\n" + << reason; + } + } + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_extensions.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_extensions.cpp new file mode 100644 index 000000000000..7b73c9c6e27e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_extensions.cpp @@ -0,0 +1,3715 @@ +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of extension SPIR-V instructions. +#include +#include +#include +#include + +#include "NonSemanticShaderDebugInfo100.h" +#include "OpenCLDebugInfo100.h" +#include "source/common_debug_info.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" +#include "source/latest_version_glsl_std_450_header.h" +#include "source/latest_version_opencl_std_header.h" +#include "source/spirv_constant.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" +#include "spirv/unified1/NonSemanticClspvReflection.h" + +namespace spvtools { +namespace val { +namespace { + +std::string ReflectionInstructionName(ValidationState_t& _, + const Instruction* inst) { + spv_ext_inst_desc desc = nullptr; + if (_.grammar().lookupExtInst(SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION, + inst->word(4), &desc) != SPV_SUCCESS || + !desc) { + return std::string("Unknown ExtInst"); + } + std::ostringstream ss; + ss << desc->name; + + return ss.str(); +} + +uint32_t GetSizeTBitWidth(const ValidationState_t& _) { + if (_.addressing_model() == spv::AddressingModel::Physical32) return 32; + + if (_.addressing_model() == spv::AddressingModel::Physical64) return 64; + + return 0; +} + +bool IsIntScalar(ValidationState_t& _, uint32_t id, bool must_len32, + bool must_unsigned) { + auto type = _.FindDef(id); + if (!type || type->opcode() != spv::Op::OpTypeInt) { + return false; + } + + if (must_len32 && type->GetOperandAs(1) != 32) { + return false; + } + + return !must_unsigned || type->GetOperandAs(2) == 0; +} + +bool IsUint32Constant(ValidationState_t& _, uint32_t id) { + auto inst = _.FindDef(id); + if (!inst || inst->opcode() != spv::Op::OpConstant) { + return false; + } + + return IsIntScalar(_, inst->type_id(), true, true); +} + +uint32_t GetUint32Constant(ValidationState_t& _, uint32_t id) { + auto inst = _.FindDef(id); + return inst->word(3); +} + +// Check that the operand of a debug info instruction |inst| at |word_index| +// is a result id of an instruction with |expected_opcode|. +spv_result_t ValidateOperandForDebugInfo( + ValidationState_t& _, const std::string& operand_name, + spv::Op expected_opcode, const Instruction* inst, uint32_t word_index, + const std::function& ext_inst_name) { + auto* operand = _.FindDef(inst->word(word_index)); + if (operand->opcode() != expected_opcode) { + spv_opcode_desc desc = nullptr; + if (_.grammar().lookupOpcode(expected_opcode, &desc) != SPV_SUCCESS || + !desc) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand " << operand_name << " is invalid"; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand " << operand_name << " must be a result id of " + << "Op" << desc->name; + } + return SPV_SUCCESS; +} + +// For NonSemantic.Shader.DebugInfo.100 check that the operand of a debug info +// instruction |inst| at |word_index| is a result id of a 32-bit integer +// OpConstant instruction. For OpenCL.DebugInfo.100 the parameter is a literal +// word so cannot be validated. +spv_result_t ValidateUint32ConstantOperandForDebugInfo( + ValidationState_t& _, const std::string& operand_name, + const Instruction* inst, uint32_t word_index, + const std::function& ext_inst_name) { + if (!IsUint32Constant(_, inst->word(word_index))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": expected operand " << operand_name + << " must be a result id of 32-bit unsigned OpConstant"; + } + return SPV_SUCCESS; +} + +#define CHECK_OPERAND(NAME, opcode, index) \ + do { \ + auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \ + ext_inst_name); \ + if (result != SPV_SUCCESS) return result; \ + } while (0) + +#define CHECK_CONST_UINT_OPERAND(NAME, index) \ + if (vulkanDebugInfo) { \ + auto result = ValidateUint32ConstantOperandForDebugInfo( \ + _, NAME, inst, index, ext_inst_name); \ + if (result != SPV_SUCCESS) return result; \ + } + +// True if the operand of a debug info instruction |inst| at |word_index| +// satisfies |expectation| that is given as a function. Otherwise, +// returns false. +bool DoesDebugInfoOperandMatchExpectation( + const ValidationState_t& _, + const std::function& expectation, + const Instruction* inst, uint32_t word_index) { + if (inst->words().size() <= word_index) return false; + auto* debug_inst = _.FindDef(inst->word(word_index)); + if (debug_inst->opcode() != spv::Op::OpExtInst || + (debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 && + debug_inst->ext_inst_type() != + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) || + !expectation(CommonDebugInfoInstructions(debug_inst->word(4)))) { + return false; + } + return true; +} + +// Overload for NonSemanticShaderDebugInfo100Instructions. +bool DoesDebugInfoOperandMatchExpectation( + const ValidationState_t& _, + const std::function& + expectation, + const Instruction* inst, uint32_t word_index) { + if (inst->words().size() <= word_index) return false; + auto* debug_inst = _.FindDef(inst->word(word_index)); + if (debug_inst->opcode() != spv::Op::OpExtInst || + (debug_inst->ext_inst_type() != + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) || + !expectation( + NonSemanticShaderDebugInfo100Instructions(debug_inst->word(4)))) { + return false; + } + return true; +} + +// Check that the operand of a debug info instruction |inst| at |word_index| +// is a result id of an debug info instruction whose debug instruction type +// is |expected_debug_inst|. +spv_result_t ValidateDebugInfoOperand( + ValidationState_t& _, const std::string& debug_inst_name, + CommonDebugInfoInstructions expected_debug_inst, const Instruction* inst, + uint32_t word_index, const std::function& ext_inst_name) { + std::function expectation = + [expected_debug_inst](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == expected_debug_inst; + }; + if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index)) + return SPV_SUCCESS; + + spv_ext_inst_desc desc = nullptr; + if (_.grammar().lookupExtInst(inst->ext_inst_type(), expected_debug_inst, + &desc) != SPV_SUCCESS || + !desc) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand " << debug_inst_name << " is invalid"; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand " << debug_inst_name << " must be a result id of " + << desc->name; +} + +#define CHECK_DEBUG_OPERAND(NAME, debug_opcode, index) \ + do { \ + auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \ + ext_inst_name); \ + if (result != SPV_SUCCESS) return result; \ + } while (0) + +// Check that the operand of a debug info instruction |inst| at |word_index| +// is a result id of an debug info instruction with DebugTypeBasic. +spv_result_t ValidateOperandBaseType( + ValidationState_t& _, const Instruction* inst, uint32_t word_index, + const std::function& ext_inst_name) { + return ValidateDebugInfoOperand(_, "Base Type", CommonDebugInfoDebugTypeBasic, + inst, word_index, ext_inst_name); +} + +// Check that the operand of a debug info instruction |inst| at |word_index| +// is a result id of a debug lexical scope instruction which is one of +// DebugCompilationUnit, DebugFunction, DebugLexicalBlock, or +// DebugTypeComposite. +spv_result_t ValidateOperandLexicalScope( + ValidationState_t& _, const std::string& debug_inst_name, + const Instruction* inst, uint32_t word_index, + const std::function& ext_inst_name) { + std::function expectation = + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == CommonDebugInfoDebugCompilationUnit || + dbg_inst == CommonDebugInfoDebugFunction || + dbg_inst == CommonDebugInfoDebugLexicalBlock || + dbg_inst == CommonDebugInfoDebugTypeComposite; + }; + if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index)) + return SPV_SUCCESS; + + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand " << debug_inst_name + << " must be a result id of a lexical scope"; +} + +// Check that the operand of a debug info instruction |inst| at |word_index| +// is a result id of a debug type instruction (See DebugTypeXXX in +// "4.3. Type instructions" section of OpenCL.DebugInfo.100 spec. +spv_result_t ValidateOperandDebugType( + ValidationState_t& _, const std::string& debug_inst_name, + const Instruction* inst, uint32_t word_index, + const std::function& ext_inst_name, + bool allow_template_param) { + // Check for NonSemanticShaderDebugInfo100 specific types. + if (inst->ext_inst_type() == + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { + std::function expectation = + [](NonSemanticShaderDebugInfo100Instructions dbg_inst) { + return dbg_inst == NonSemanticShaderDebugInfo100DebugTypeMatrix; + }; + if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index)) + return SPV_SUCCESS; + } + + // Check for common types. + std::function expectation = + [&allow_template_param](CommonDebugInfoInstructions dbg_inst) { + if (allow_template_param && + (dbg_inst == CommonDebugInfoDebugTypeTemplateParameter || + dbg_inst == CommonDebugInfoDebugTypeTemplateTemplateParameter)) { + return true; + } + return CommonDebugInfoDebugTypeBasic <= dbg_inst && + dbg_inst <= CommonDebugInfoDebugTypeTemplate; + }; + if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index)) + return SPV_SUCCESS; + + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand " << debug_inst_name + << " is not a valid debug type"; +} + +spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _, + const Instruction* inst, + uint32_t version) { + const auto inst_name = ReflectionInstructionName(_, inst); + const auto kernel_id = inst->GetOperandAs(4); + const auto kernel = _.FindDef(kernel_id); + if (kernel->opcode() != spv::Op::OpFunction) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << inst_name << " does not reference a function"; + } + + bool found_kernel = false; + for (auto entry_point : _.entry_points()) { + if (entry_point == kernel_id) { + found_kernel = true; + break; + } + } + if (!found_kernel) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << inst_name << " does not reference an entry-point"; + } + + const auto* exec_models = _.GetExecutionModels(kernel_id); + if (!exec_models || exec_models->empty()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << inst_name << " does not reference an entry-point"; + } + for (auto exec_model : *exec_models) { + if (exec_model != spv::ExecutionModel::GLCompute) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << inst_name << " must refer only to GLCompute entry-points"; + } + } + + auto name = _.FindDef(inst->GetOperandAs(5)); + if (!name || name->opcode() != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString"; + } + + const std::string name_str = name->GetOperandAs(1); + bool found = false; + for (auto& desc : _.entry_point_descriptions(kernel_id)) { + if (name_str == desc.name) { + found = true; + break; + } + } + if (!found) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Name must match an entry-point for Kernel"; + } + + const auto num_operands = inst->operands().size(); + if (version < 5 && num_operands > 6) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Version " << version << " of the " << inst_name + << " instruction can only have 2 additional operands"; + } + + if (num_operands > 6) { + const auto num_args_id = inst->GetOperandAs(6); + if (!IsUint32Constant(_, num_args_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "NumArguments must be a 32-bit unsigned integer OpConstant"; + } + } + + if (num_operands > 7) { + const auto flags_id = inst->GetOperandAs(7); + if (!IsUint32Constant(_, flags_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Flags must be a 32-bit unsigned integer OpConstant"; + } + } + + if (num_operands > 8) { + const auto atts_id = inst->GetOperandAs(8); + if (_.GetIdOpcode(atts_id) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Attributes must be an OpString"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _, + const Instruction* inst) { + const auto num_operands = inst->operands().size(); + if (_.GetIdOpcode(inst->GetOperandAs(4)) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString"; + } + if (num_operands > 5) { + if (_.GetIdOpcode(inst->GetOperandAs(5)) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "TypeName must be an OpString"; + } + } + if (num_operands > 6) { + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "AddressQualifier must be a 32-bit unsigned integer " + "OpConstant"; + } + } + if (num_operands > 7) { + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "AccessQualifier must be a 32-bit unsigned integer " + "OpConstant"; + } + } + if (num_operands > 8) { + if (!IsUint32Constant(_, inst->GetOperandAs(8))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "TypeQualifier must be a 32-bit unsigned integer " + "OpConstant"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) { + const auto decl_id = inst->GetOperandAs(4); + const auto decl = _.FindDef(decl_id); + if (!decl || decl->opcode() != spv::Op::OpExtInst) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Kernel must be a Kernel extended instruction"; + } + + if (decl->GetOperandAs(2) != inst->GetOperandAs(2)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Kernel must be from the same extended instruction import"; + } + + const auto ext_inst = + decl->GetOperandAs(3); + if (ext_inst != NonSemanticClspvReflectionKernel) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Kernel must be a Kernel extended instruction"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateArgInfo(ValidationState_t& _, const Instruction* inst, + uint32_t info_index) { + auto info = _.FindDef(inst->GetOperandAs(info_index)); + if (!info || info->opcode() != spv::Op::OpExtInst) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ArgInfo must be an ArgumentInfo extended instruction"; + } + + if (info->GetOperandAs(2) != inst->GetOperandAs(2)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ArgInfo must be from the same extended instruction import"; + } + + auto ext_inst = info->GetOperandAs(3); + if (ext_inst != NonSemanticClspvReflectionArgumentInfo) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ArgInfo must be an ArgumentInfo extended instruction"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionArgumentBuffer(ValidationState_t& _, + const Instruction* inst) { + const auto num_operands = inst->operands().size(); + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Ordinal must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Binding must be a 32-bit unsigned integer OpConstant"; + } + + if (num_operands == 9) { + if (auto error = ValidateArgInfo(_, inst, 8)) { + return error; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionArgumentOffsetBuffer( + ValidationState_t& _, const Instruction* inst) { + const auto num_operands = inst->operands().size(); + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Ordinal must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Binding must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(8))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(9))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + if (num_operands == 11) { + if (auto error = ValidateArgInfo(_, inst, 10)) { + return error; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionArgumentPushConstant( + ValidationState_t& _, const Instruction* inst) { + const auto num_operands = inst->operands().size(); + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Ordinal must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + if (num_operands == 9) { + if (auto error = ValidateArgInfo(_, inst, 8)) { + return error; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionArgumentWorkgroup(ValidationState_t& _, + const Instruction* inst) { + const auto num_operands = inst->operands().size(); + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Ordinal must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "SpecId must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ElemSize must be a 32-bit unsigned integer OpConstant"; + } + + if (num_operands == 9) { + if (auto error = ValidateArgInfo(_, inst, 8)) { + return error; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionSpecConstantTriple( + ValidationState_t& _, const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "X must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Y must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Z must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionSpecConstantWorkDim( + ValidationState_t& _, const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Dim must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPushConstant(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionInitializedData(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Binding must be a 32-bit unsigned integer OpConstant"; + } + + if (_.GetIdOpcode(inst->GetOperandAs(6)) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionSampler(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Binding must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Mask must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPropertyRequiredWorkgroupSize( + ValidationState_t& _, const Instruction* inst) { + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "X must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Y must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Z must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionSubgroupMaxSize(ValidationState_t& _, + const Instruction* inst) { + const auto size_id = inst->GetOperandAs(4); + if (!IsUint32Constant(_, size_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPointerRelocation(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ObjectOffset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "PointerOffset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "PointerSize must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionImageMetadataPushConstant( + ValidationState_t& _, const Instruction* inst) { + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Ordinal must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionImageMetadataUniform( + ValidationState_t& _, const Instruction* inst) { + if (auto error = ValidateKernelDecl(_, inst)) { + return error; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Ordinal must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(7))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Binding must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(8))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(9))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPushConstantData(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + if (_.GetIdOpcode(inst->GetOperandAs(6)) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPrintfInfo(ValidationState_t& _, + const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "PrintfID must be a 32-bit unsigned integer OpConstant"; + } + + if (_.GetIdOpcode(inst->GetOperandAs(5)) != spv::Op::OpString) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "FormatString must be an OpString"; + } + + for (size_t i = 6; i < inst->operands().size(); ++i) { + if (!IsUint32Constant(_, inst->GetOperandAs(i))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ArgumentSizes must be a 32-bit unsigned integer OpConstant"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPrintfStorageBuffer( + ValidationState_t& _, const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Binding must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionPrintfPushConstant( + ValidationState_t& _, const Instruction* inst) { + if (!IsUint32Constant(_, inst->GetOperandAs(4))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Offset must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(5))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size must be a 32-bit unsigned integer OpConstant"; + } + + if (!IsUint32Constant(_, inst->GetOperandAs(6))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "BufferSize must be a 32-bit unsigned integer OpConstant"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, + const Instruction* inst, + uint32_t version) { + if (!_.IsVoidType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Return Type must be OpTypeVoid"; + } + + uint32_t required_version = 0; + const auto ext_inst = + inst->GetOperandAs(3); + switch (ext_inst) { + case NonSemanticClspvReflectionKernel: + case NonSemanticClspvReflectionArgumentInfo: + case NonSemanticClspvReflectionArgumentStorageBuffer: + case NonSemanticClspvReflectionArgumentUniform: + case NonSemanticClspvReflectionArgumentPodStorageBuffer: + case NonSemanticClspvReflectionArgumentPodUniform: + case NonSemanticClspvReflectionArgumentPodPushConstant: + case NonSemanticClspvReflectionArgumentSampledImage: + case NonSemanticClspvReflectionArgumentStorageImage: + case NonSemanticClspvReflectionArgumentSampler: + case NonSemanticClspvReflectionArgumentWorkgroup: + case NonSemanticClspvReflectionSpecConstantWorkgroupSize: + case NonSemanticClspvReflectionSpecConstantGlobalOffset: + case NonSemanticClspvReflectionSpecConstantWorkDim: + case NonSemanticClspvReflectionPushConstantGlobalOffset: + case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize: + case NonSemanticClspvReflectionPushConstantGlobalSize: + case NonSemanticClspvReflectionPushConstantRegionOffset: + case NonSemanticClspvReflectionPushConstantNumWorkgroups: + case NonSemanticClspvReflectionPushConstantRegionGroupOffset: + case NonSemanticClspvReflectionConstantDataStorageBuffer: + case NonSemanticClspvReflectionConstantDataUniform: + case NonSemanticClspvReflectionLiteralSampler: + case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize: + required_version = 1; + break; + case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize: + required_version = 2; + break; + case NonSemanticClspvReflectionArgumentPointerPushConstant: + case NonSemanticClspvReflectionArgumentPointerUniform: + case NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer: + case NonSemanticClspvReflectionProgramScopeVariablePointerRelocation: + case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant: + case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant: + case NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform: + case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform: + required_version = 3; + break; + case NonSemanticClspvReflectionArgumentStorageTexelBuffer: + case NonSemanticClspvReflectionArgumentUniformTexelBuffer: + required_version = 4; + break; + case NonSemanticClspvReflectionConstantDataPointerPushConstant: + case NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant: + case NonSemanticClspvReflectionPrintfInfo: + case NonSemanticClspvReflectionPrintfBufferStorageBuffer: + case NonSemanticClspvReflectionPrintfBufferPointerPushConstant: + required_version = 5; + break; + default: + break; + } + if (version < required_version) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << ReflectionInstructionName(_, inst) << " requires version " + << required_version << ", but parsed version is " << version; + } + + switch (ext_inst) { + case NonSemanticClspvReflectionKernel: + return ValidateClspvReflectionKernel(_, inst, version); + case NonSemanticClspvReflectionArgumentInfo: + return ValidateClspvReflectionArgumentInfo(_, inst); + case NonSemanticClspvReflectionArgumentStorageBuffer: + case NonSemanticClspvReflectionArgumentUniform: + case NonSemanticClspvReflectionArgumentSampledImage: + case NonSemanticClspvReflectionArgumentStorageImage: + case NonSemanticClspvReflectionArgumentSampler: + case NonSemanticClspvReflectionArgumentStorageTexelBuffer: + case NonSemanticClspvReflectionArgumentUniformTexelBuffer: + return ValidateClspvReflectionArgumentBuffer(_, inst); + case NonSemanticClspvReflectionArgumentPodStorageBuffer: + case NonSemanticClspvReflectionArgumentPodUniform: + case NonSemanticClspvReflectionArgumentPointerUniform: + return ValidateClspvReflectionArgumentOffsetBuffer(_, inst); + case NonSemanticClspvReflectionArgumentPodPushConstant: + case NonSemanticClspvReflectionArgumentPointerPushConstant: + return ValidateClspvReflectionArgumentPushConstant(_, inst); + case NonSemanticClspvReflectionArgumentWorkgroup: + return ValidateClspvReflectionArgumentWorkgroup(_, inst); + case NonSemanticClspvReflectionSpecConstantWorkgroupSize: + case NonSemanticClspvReflectionSpecConstantGlobalOffset: + return ValidateClspvReflectionSpecConstantTriple(_, inst); + case NonSemanticClspvReflectionSpecConstantWorkDim: + return ValidateClspvReflectionSpecConstantWorkDim(_, inst); + case NonSemanticClspvReflectionPushConstantGlobalOffset: + case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize: + case NonSemanticClspvReflectionPushConstantGlobalSize: + case NonSemanticClspvReflectionPushConstantRegionOffset: + case NonSemanticClspvReflectionPushConstantNumWorkgroups: + case NonSemanticClspvReflectionPushConstantRegionGroupOffset: + return ValidateClspvReflectionPushConstant(_, inst); + case NonSemanticClspvReflectionConstantDataStorageBuffer: + case NonSemanticClspvReflectionConstantDataUniform: + case NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer: + return ValidateClspvReflectionInitializedData(_, inst); + case NonSemanticClspvReflectionLiteralSampler: + return ValidateClspvReflectionSampler(_, inst); + case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize: + return ValidateClspvReflectionPropertyRequiredWorkgroupSize(_, inst); + case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize: + return ValidateClspvReflectionSubgroupMaxSize(_, inst); + case NonSemanticClspvReflectionProgramScopeVariablePointerRelocation: + return ValidateClspvReflectionPointerRelocation(_, inst); + case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant: + case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant: + return ValidateClspvReflectionImageMetadataPushConstant(_, inst); + case NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform: + case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform: + return ValidateClspvReflectionImageMetadataUniform(_, inst); + case NonSemanticClspvReflectionConstantDataPointerPushConstant: + case NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant: + return ValidateClspvReflectionPushConstantData(_, inst); + case NonSemanticClspvReflectionPrintfInfo: + return ValidateClspvReflectionPrintfInfo(_, inst); + case NonSemanticClspvReflectionPrintfBufferStorageBuffer: + return ValidateClspvReflectionPrintfStorageBuffer(_, inst); + case NonSemanticClspvReflectionPrintfBufferPointerPushConstant: + return ValidateClspvReflectionPrintfPushConstant(_, inst); + default: + break; + } + + return SPV_SUCCESS; +} + +bool IsConstIntScalarTypeWith32Or64Bits(ValidationState_t& _, + Instruction* instr) { + if (instr->opcode() != spv::Op::OpConstant) return false; + if (!_.IsIntScalarType(instr->type_id())) return false; + uint32_t size_in_bits = _.GetBitWidth(instr->type_id()); + return size_in_bits == 32 || size_in_bits == 64; +} + +bool IsConstWithIntScalarType(ValidationState_t& _, const Instruction* inst, + uint32_t word_index) { + auto* int_scalar_const = _.FindDef(inst->word(word_index)); + if (int_scalar_const->opcode() == spv::Op::OpConstant && + _.IsIntScalarType(int_scalar_const->type_id())) { + return true; + } + return false; +} + +bool IsDebugVariableWithIntScalarType(ValidationState_t& _, + const Instruction* inst, + uint32_t word_index) { + auto* dbg_int_scalar_var = _.FindDef(inst->word(word_index)); + if (CommonDebugInfoInstructions(dbg_int_scalar_var->word(4)) == + CommonDebugInfoDebugLocalVariable || + CommonDebugInfoInstructions(dbg_int_scalar_var->word(4)) == + CommonDebugInfoDebugGlobalVariable) { + auto* dbg_type = _.FindDef(dbg_int_scalar_var->word(6)); + if (CommonDebugInfoInstructions(dbg_type->word(4)) == + CommonDebugInfoDebugTypeBasic) { + const spv_ext_inst_type_t ext_inst_type = + spv_ext_inst_type_t(inst->ext_inst_type()); + const bool vulkanDebugInfo = + ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100; + uint32_t encoding = dbg_type->word(7); + if (!vulkanDebugInfo || IsUint32Constant(_, encoding)) { + auto ocl_encoding = OpenCLDebugInfo100DebugBaseTypeAttributeEncoding( + vulkanDebugInfo ? GetUint32Constant(_, encoding) : encoding); + if (ocl_encoding == OpenCLDebugInfo100Signed || + ocl_encoding == OpenCLDebugInfo100Unsigned) { + return true; + } + } + } + } + return false; +} + +} // anonymous namespace + +spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) { + if (_.version() < SPV_SPIRV_VERSION_WORD(1, 4)) { + std::string extension = GetExtensionString(&(inst->c_inst())); + if (extension == + ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) || + extension == ExtensionToString(kSPV_EXT_mesh_shader) || + extension == ExtensionToString(kSPV_NV_shader_invocation_reorder)) { + return _.diag(SPV_ERROR_WRONG_VERSION, inst) + << extension << " extension requires SPIR-V version 1.4 or later."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateExtInstImport(ValidationState_t& _, + const Instruction* inst) { + const auto name_id = 1; + if (_.version() <= SPV_SPIRV_VERSION_WORD(1, 5) && + !_.HasExtension(kSPV_KHR_non_semantic_info)) { + const std::string name = inst->GetOperandAs(name_id); + if (name.find("NonSemantic.") == 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "NonSemantic extended instruction sets cannot be declared " + "without SPV_KHR_non_semantic_info."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { + const uint32_t result_type = inst->type_id(); + const uint32_t num_operands = static_cast(inst->operands().size()); + + const uint32_t ext_inst_set = inst->word(3); + const uint32_t ext_inst_index = inst->word(4); + const spv_ext_inst_type_t ext_inst_type = + spv_ext_inst_type_t(inst->ext_inst_type()); + + auto ext_inst_name = [&_, ext_inst_set, ext_inst_type, ext_inst_index]() { + spv_ext_inst_desc desc = nullptr; + if (_.grammar().lookupExtInst(ext_inst_type, ext_inst_index, &desc) != + SPV_SUCCESS || + !desc) { + return std::string("Unknown ExtInst"); + } + + auto* import_inst = _.FindDef(ext_inst_set); + assert(import_inst); + + std::ostringstream ss; + ss << import_inst->GetOperandAs(1); + ss << " "; + ss << desc->name; + + return ss.str(); + }; + + if (ext_inst_type == SPV_EXT_INST_TYPE_GLSL_STD_450) { + const GLSLstd450 ext_inst_key = GLSLstd450(ext_inst_index); + switch (ext_inst_key) { + case GLSLstd450Round: + case GLSLstd450RoundEven: + case GLSLstd450FAbs: + case GLSLstd450Trunc: + case GLSLstd450FSign: + case GLSLstd450Floor: + case GLSLstd450Ceil: + case GLSLstd450Fract: + case GLSLstd450Sqrt: + case GLSLstd450InverseSqrt: + case GLSLstd450FMin: + case GLSLstd450FMax: + case GLSLstd450FClamp: + case GLSLstd450FMix: + case GLSLstd450Step: + case GLSLstd450SmoothStep: + case GLSLstd450Fma: + case GLSLstd450Normalize: + case GLSLstd450FaceForward: + case GLSLstd450Reflect: + case GLSLstd450NMin: + case GLSLstd450NMax: + case GLSLstd450NClamp: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar or vector type"; + } + + for (uint32_t operand_index = 4; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (result_type != operand_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected types of all operands to be equal to Result " + "Type"; + } + } + break; + } + + case GLSLstd450SAbs: + case GLSLstd450SSign: + case GLSLstd450UMin: + case GLSLstd450SMin: + case GLSLstd450UMax: + case GLSLstd450SMax: + case GLSLstd450UClamp: + case GLSLstd450SClamp: + case GLSLstd450FindILsb: + case GLSLstd450FindUMsb: + case GLSLstd450FindSMsb: { + if (!_.IsIntScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be an int scalar or vector type"; + } + + const uint32_t result_type_bit_width = _.GetBitWidth(result_type); + const uint32_t result_type_dimension = _.GetDimension(result_type); + + for (uint32_t operand_index = 4; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (!operand_type || !_.IsIntScalarOrVectorType(operand_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected all operands to be int scalars or vectors"; + } + + if (result_type_dimension != _.GetDimension(operand_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected all operands to have the same dimension as " + << "Result Type"; + } + + if (result_type_bit_width != _.GetBitWidth(operand_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected all operands to have the same bit width as " + << "Result Type"; + } + + if (ext_inst_key == GLSLstd450FindUMsb || + ext_inst_key == GLSLstd450FindSMsb) { + if (result_type_bit_width != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "this instruction is currently limited to 32-bit width " + << "components"; + } + } + } + break; + } + + case GLSLstd450Radians: + case GLSLstd450Degrees: + case GLSLstd450Sin: + case GLSLstd450Cos: + case GLSLstd450Tan: + case GLSLstd450Asin: + case GLSLstd450Acos: + case GLSLstd450Atan: + case GLSLstd450Sinh: + case GLSLstd450Cosh: + case GLSLstd450Tanh: + case GLSLstd450Asinh: + case GLSLstd450Acosh: + case GLSLstd450Atanh: + case GLSLstd450Exp: + case GLSLstd450Exp2: + case GLSLstd450Log: + case GLSLstd450Log2: + case GLSLstd450Atan2: + case GLSLstd450Pow: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 16 or 32-bit scalar or " + "vector float type"; + } + + const uint32_t result_type_bit_width = _.GetBitWidth(result_type); + if (result_type_bit_width != 16 && result_type_bit_width != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 16 or 32-bit scalar or " + "vector float type"; + } + + for (uint32_t operand_index = 4; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (result_type != operand_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected types of all operands to be equal to Result " + "Type"; + } + } + break; + } + + case GLSLstd450Determinant: { + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + uint32_t num_rows = 0; + uint32_t num_cols = 0; + uint32_t col_type = 0; + uint32_t component_type = 0; + if (!_.GetMatrixTypeInfo(x_type, &num_rows, &num_cols, &col_type, + &component_type) || + num_rows != num_cols) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X to be a square matrix"; + } + + if (result_type != component_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X component type to be equal to " + << "Result Type"; + } + break; + } + + case GLSLstd450MatrixInverse: { + uint32_t num_rows = 0; + uint32_t num_cols = 0; + uint32_t col_type = 0; + uint32_t component_type = 0; + if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type, + &component_type) || + num_rows != num_cols) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a square matrix"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + if (result_type != x_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X type to be equal to Result Type"; + } + break; + } + + case GLSLstd450Modf: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or vector float type"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + const uint32_t i_type = _.GetOperandTypeId(inst, 5); + + if (x_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X type to be equal to Result Type"; + } + + spv::StorageClass i_storage_class; + uint32_t i_data_type = 0; + if (!_.GetPointerTypeInfo(i_type, &i_data_type, &i_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand I to be a pointer"; + } + + if (i_data_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand I data type to be equal to Result Type"; + } + + break; + } + + case GLSLstd450ModfStruct: { + std::vector result_types; + if (!_.GetStructMemberTypes(result_type, &result_types) || + result_types.size() != 2 || + !_.IsFloatScalarOrVectorType(result_types[0]) || + result_types[1] != result_types[0]) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a struct with two identical " + << "scalar or vector float type members"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + if (x_type != result_types[0]) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X type to be equal to members of " + << "Result Type struct"; + } + break; + } + + case GLSLstd450Frexp: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or vector float type"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + const uint32_t exp_type = _.GetOperandTypeId(inst, 5); + + if (x_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X type to be equal to Result Type"; + } + + spv::StorageClass exp_storage_class; + uint32_t exp_data_type = 0; + if (!_.GetPointerTypeInfo(exp_type, &exp_data_type, + &exp_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Exp to be a pointer"; + } + + if (!_.IsIntScalarOrVectorType(exp_data_type) || + (!_.HasExtension(kSPV_AMD_gpu_shader_int16) && + _.GetBitWidth(exp_data_type) != 32) || + (_.HasExtension(kSPV_AMD_gpu_shader_int16) && + _.GetBitWidth(exp_data_type) != 16 && + _.GetBitWidth(exp_data_type) != 32)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Exp data type to be a " + << (_.HasExtension(kSPV_AMD_gpu_shader_int16) + ? "16-bit or 32-bit " + : "32-bit ") + << "int scalar or vector type"; + } + + if (_.GetDimension(result_type) != _.GetDimension(exp_data_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Exp data type to have the same component " + << "number as Result Type"; + } + + break; + } + + case GLSLstd450Ldexp: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or vector float type"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + const uint32_t exp_type = _.GetOperandTypeId(inst, 5); + + if (x_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X type to be equal to Result Type"; + } + + if (!_.IsIntScalarOrVectorType(exp_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Exp to be a 32-bit int scalar " + << "or vector type"; + } + + if (_.GetDimension(result_type) != _.GetDimension(exp_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Exp to have the same component " + << "number as Result Type"; + } + + break; + } + + case GLSLstd450FrexpStruct: { + std::vector result_types; + if (!_.GetStructMemberTypes(result_type, &result_types) || + result_types.size() != 2 || + !_.IsFloatScalarOrVectorType(result_types[0]) || + !_.IsIntScalarOrVectorType(result_types[1]) || + (!_.HasExtension(kSPV_AMD_gpu_shader_int16) && + _.GetBitWidth(result_types[1]) != 32) || + (_.HasExtension(kSPV_AMD_gpu_shader_int16) && + _.GetBitWidth(result_types[1]) != 16 && + _.GetBitWidth(result_types[1]) != 32) || + _.GetDimension(result_types[0]) != + _.GetDimension(result_types[1])) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a struct with two members, " + << "first member a float scalar or vector, second member a " + << (_.HasExtension(kSPV_AMD_gpu_shader_int16) + ? "16-bit or 32-bit " + : "32-bit ") + << "int scalar or vector with the same number of " + << "components as the first member"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + if (x_type != result_types[0]) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X type to be equal to the first member " + << "of Result Type struct"; + } + break; + } + + case GLSLstd450PackSnorm4x8: + case GLSLstd450PackUnorm4x8: { + if (!_.IsIntScalarType(result_type) || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be 32-bit int scalar type"; + } + + const uint32_t v_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatVectorType(v_type) || _.GetDimension(v_type) != 4 || + _.GetBitWidth(v_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand V to be a 32-bit float vector of size 4"; + } + break; + } + + case GLSLstd450PackSnorm2x16: + case GLSLstd450PackUnorm2x16: + case GLSLstd450PackHalf2x16: { + if (!_.IsIntScalarType(result_type) || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be 32-bit int scalar type"; + } + + const uint32_t v_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatVectorType(v_type) || _.GetDimension(v_type) != 2 || + _.GetBitWidth(v_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand V to be a 32-bit float vector of size 2"; + } + break; + } + + case GLSLstd450PackDouble2x32: { + if (!_.IsFloatScalarType(result_type) || + _.GetBitWidth(result_type) != 64) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be 64-bit float scalar type"; + } + + const uint32_t v_type = _.GetOperandTypeId(inst, 4); + if (!_.IsIntVectorType(v_type) || _.GetDimension(v_type) != 2 || + _.GetBitWidth(v_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand V to be a 32-bit int vector of size 2"; + } + break; + } + + case GLSLstd450UnpackSnorm4x8: + case GLSLstd450UnpackUnorm4x8: { + if (!_.IsFloatVectorType(result_type) || + _.GetDimension(result_type) != 4 || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 32-bit float vector of size " + "4"; + } + + const uint32_t v_type = _.GetOperandTypeId(inst, 4); + if (!_.IsIntScalarType(v_type) || _.GetBitWidth(v_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to be a 32-bit int scalar"; + } + break; + } + + case GLSLstd450UnpackSnorm2x16: + case GLSLstd450UnpackUnorm2x16: + case GLSLstd450UnpackHalf2x16: { + if (!_.IsFloatVectorType(result_type) || + _.GetDimension(result_type) != 2 || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 32-bit float vector of size " + "2"; + } + + const uint32_t v_type = _.GetOperandTypeId(inst, 4); + if (!_.IsIntScalarType(v_type) || _.GetBitWidth(v_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to be a 32-bit int scalar"; + } + break; + } + + case GLSLstd450UnpackDouble2x32: { + if (!_.IsIntVectorType(result_type) || + _.GetDimension(result_type) != 2 || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 32-bit int vector of size " + "2"; + } + + const uint32_t v_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatScalarType(v_type) || _.GetBitWidth(v_type) != 64) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand V to be a 64-bit float scalar"; + } + break; + } + + case GLSLstd450Length: { + if (!_.IsFloatScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar type"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatScalarOrVectorType(x_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X to be of float scalar or vector type"; + } + + if (result_type != _.GetComponentType(x_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X component type to be equal to Result " + "Type"; + } + break; + } + + case GLSLstd450Distance: { + if (!_.IsFloatScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar type"; + } + + const uint32_t p0_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatScalarOrVectorType(p0_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P0 to be of float scalar or vector type"; + } + + if (result_type != _.GetComponentType(p0_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P0 component type to be equal to " + << "Result Type"; + } + + const uint32_t p1_type = _.GetOperandTypeId(inst, 5); + if (!_.IsFloatScalarOrVectorType(p1_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P1 to be of float scalar or vector type"; + } + + if (result_type != _.GetComponentType(p1_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P1 component type to be equal to " + << "Result Type"; + } + + if (_.GetDimension(p0_type) != _.GetDimension(p1_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operands P0 and P1 to have the same number of " + << "components"; + } + break; + } + + case GLSLstd450Cross: { + if (!_.IsFloatVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float vector type"; + } + + if (_.GetDimension(result_type) != 3) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to have 3 components"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + const uint32_t y_type = _.GetOperandTypeId(inst, 5); + + if (x_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X type to be equal to Result Type"; + } + + if (y_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Y type to be equal to Result Type"; + } + break; + } + + case GLSLstd450Refract: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar or vector type"; + } + + const uint32_t i_type = _.GetOperandTypeId(inst, 4); + const uint32_t n_type = _.GetOperandTypeId(inst, 5); + const uint32_t eta_type = _.GetOperandTypeId(inst, 6); + + if (result_type != i_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand I to be of type equal to Result Type"; + } + + if (result_type != n_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand N to be of type equal to Result Type"; + } + + if (!_.IsFloatScalarType(eta_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Eta to be a float scalar"; + } + break; + } + + case GLSLstd450InterpolateAtCentroid: + case GLSLstd450InterpolateAtSample: + case GLSLstd450InterpolateAtOffset: { + if (!_.HasCapability(spv::Capability::InterpolationFunction)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << ext_inst_name() + << " requires capability InterpolationFunction"; + } + + if (!_.IsFloatScalarOrVectorType(result_type) || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 32-bit float scalar " + << "or vector type"; + } + + // If HLSL legalization and first operand is an OpLoad, use load + // pointer as the interpolant lvalue. Else use interpolate first + // operand. + uint32_t interp_id = inst->GetOperandAs(4); + auto* interp_inst = _.FindDef(interp_id); + uint32_t interpolant_type = (_.options()->before_hlsl_legalization && + interp_inst->opcode() == spv::Op::OpLoad) + ? _.GetOperandTypeId(interp_inst, 2) + : _.GetOperandTypeId(inst, 4); + + spv::StorageClass interpolant_storage_class; + uint32_t interpolant_data_type = 0; + if (!_.GetPointerTypeInfo(interpolant_type, &interpolant_data_type, + &interpolant_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Interpolant to be a pointer"; + } + + if (result_type != interpolant_data_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Interpolant data type to be equal to Result Type"; + } + + if (interpolant_storage_class != spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Interpolant storage class to be Input"; + } + + if (ext_inst_key == GLSLstd450InterpolateAtSample) { + const uint32_t sample_type = _.GetOperandTypeId(inst, 5); + if (!_.IsIntScalarType(sample_type) || + _.GetBitWidth(sample_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Sample to be 32-bit integer"; + } + } + + if (ext_inst_key == GLSLstd450InterpolateAtOffset) { + const uint32_t offset_type = _.GetOperandTypeId(inst, 5); + if (!_.IsFloatVectorType(offset_type) || + _.GetDimension(offset_type) != 2 || + _.GetBitWidth(offset_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Offset to be a vector of 2 32-bit floats"; + } + } + + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + spv::ExecutionModel::Fragment, + ext_inst_name() + + std::string(" requires Fragment execution model")); + break; + } + + case GLSLstd450IMix: { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Extended instruction GLSLstd450IMix is not supported"; + } + + case GLSLstd450Bad: { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Encountered extended instruction GLSLstd450Bad"; + } + + case GLSLstd450Count: { + assert(0); + break; + } + } + } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_STD) { + const OpenCLLIB::Entrypoints ext_inst_key = + OpenCLLIB::Entrypoints(ext_inst_index); + switch (ext_inst_key) { + case OpenCLLIB::Acos: + case OpenCLLIB::Acosh: + case OpenCLLIB::Acospi: + case OpenCLLIB::Asin: + case OpenCLLIB::Asinh: + case OpenCLLIB::Asinpi: + case OpenCLLIB::Atan: + case OpenCLLIB::Atan2: + case OpenCLLIB::Atanh: + case OpenCLLIB::Atanpi: + case OpenCLLIB::Atan2pi: + case OpenCLLIB::Cbrt: + case OpenCLLIB::Ceil: + case OpenCLLIB::Copysign: + case OpenCLLIB::Cos: + case OpenCLLIB::Cosh: + case OpenCLLIB::Cospi: + case OpenCLLIB::Erfc: + case OpenCLLIB::Erf: + case OpenCLLIB::Exp: + case OpenCLLIB::Exp2: + case OpenCLLIB::Exp10: + case OpenCLLIB::Expm1: + case OpenCLLIB::Fabs: + case OpenCLLIB::Fdim: + case OpenCLLIB::Floor: + case OpenCLLIB::Fma: + case OpenCLLIB::Fmax: + case OpenCLLIB::Fmin: + case OpenCLLIB::Fmod: + case OpenCLLIB::Hypot: + case OpenCLLIB::Lgamma: + case OpenCLLIB::Log: + case OpenCLLIB::Log2: + case OpenCLLIB::Log10: + case OpenCLLIB::Log1p: + case OpenCLLIB::Logb: + case OpenCLLIB::Mad: + case OpenCLLIB::Maxmag: + case OpenCLLIB::Minmag: + case OpenCLLIB::Nextafter: + case OpenCLLIB::Pow: + case OpenCLLIB::Powr: + case OpenCLLIB::Remainder: + case OpenCLLIB::Rint: + case OpenCLLIB::Round: + case OpenCLLIB::Rsqrt: + case OpenCLLIB::Sin: + case OpenCLLIB::Sinh: + case OpenCLLIB::Sinpi: + case OpenCLLIB::Sqrt: + case OpenCLLIB::Tan: + case OpenCLLIB::Tanh: + case OpenCLLIB::Tanpi: + case OpenCLLIB::Tgamma: + case OpenCLLIB::Trunc: + case OpenCLLIB::Half_cos: + case OpenCLLIB::Half_divide: + case OpenCLLIB::Half_exp: + case OpenCLLIB::Half_exp2: + case OpenCLLIB::Half_exp10: + case OpenCLLIB::Half_log: + case OpenCLLIB::Half_log2: + case OpenCLLIB::Half_log10: + case OpenCLLIB::Half_powr: + case OpenCLLIB::Half_recip: + case OpenCLLIB::Half_rsqrt: + case OpenCLLIB::Half_sin: + case OpenCLLIB::Half_sqrt: + case OpenCLLIB::Half_tan: + case OpenCLLIB::Native_cos: + case OpenCLLIB::Native_divide: + case OpenCLLIB::Native_exp: + case OpenCLLIB::Native_exp2: + case OpenCLLIB::Native_exp10: + case OpenCLLIB::Native_log: + case OpenCLLIB::Native_log2: + case OpenCLLIB::Native_log10: + case OpenCLLIB::Native_powr: + case OpenCLLIB::Native_recip: + case OpenCLLIB::Native_rsqrt: + case OpenCLLIB::Native_sin: + case OpenCLLIB::Native_sqrt: + case OpenCLLIB::Native_tan: + case OpenCLLIB::FClamp: + case OpenCLLIB::Degrees: + case OpenCLLIB::FMax_common: + case OpenCLLIB::FMin_common: + case OpenCLLIB::Mix: + case OpenCLLIB::Radians: + case OpenCLLIB::Step: + case OpenCLLIB::Smoothstep: + case OpenCLLIB::Sign: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar or vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + for (uint32_t operand_index = 4; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (result_type != operand_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected types of all operands to be equal to Result " + "Type"; + } + } + break; + } + + case OpenCLLIB::Fract: + case OpenCLLIB::Modf: + case OpenCLLIB::Sincos: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar or vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + if (result_type != x_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected type of operand X to be equal to Result Type"; + } + + const uint32_t p_type = _.GetOperandTypeId(inst, 5); + spv::StorageClass p_storage_class; + uint32_t p_data_type = 0; + if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected the last operand to be a pointer"; + } + + if (p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected storage class of the pointer to be Generic, " + "CrossWorkgroup, Workgroup or Function"; + } + + if (result_type != p_data_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected data type of the pointer to be equal to Result " + "Type"; + } + break; + } + + case OpenCLLIB::Frexp: + case OpenCLLIB::Lgamma_r: + case OpenCLLIB::Remquo: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar or vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + uint32_t operand_index = 4; + const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++); + if (result_type != x_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected type of operand X to be equal to Result Type"; + } + + if (ext_inst_key == OpenCLLIB::Remquo) { + const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++); + if (result_type != y_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected type of operand Y to be equal to Result Type"; + } + } + + const uint32_t p_type = _.GetOperandTypeId(inst, operand_index++); + spv::StorageClass p_storage_class; + uint32_t p_data_type = 0; + if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected the last operand to be a pointer"; + } + + if (p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected storage class of the pointer to be Generic, " + "CrossWorkgroup, Workgroup or Function"; + } + + if (!_.IsIntScalarOrVectorType(p_data_type) || + _.GetBitWidth(p_data_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected data type of the pointer to be a 32-bit int " + "scalar or vector type"; + } + + if (_.GetDimension(p_data_type) != num_components) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected data type of the pointer to have the same number " + "of components as Result Type"; + } + break; + } + + case OpenCLLIB::Ilogb: { + if (!_.IsIntScalarOrVectorType(result_type) || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 32-bit int scalar or vector " + "type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatScalarOrVectorType(x_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X to be a float scalar or vector"; + } + + if (_.GetDimension(x_type) != num_components) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X to have the same number of components " + "as Result Type"; + } + break; + } + + case OpenCLLIB::Ldexp: + case OpenCLLIB::Pown: + case OpenCLLIB::Rootn: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar or vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + if (result_type != x_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected type of operand X to be equal to Result Type"; + } + + const uint32_t exp_type = _.GetOperandTypeId(inst, 5); + if (!_.IsIntScalarOrVectorType(exp_type) || + _.GetBitWidth(exp_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected the exponent to be a 32-bit int scalar or vector"; + } + + if (_.GetDimension(exp_type) != num_components) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected the exponent to have the same number of " + "components as Result Type"; + } + break; + } + + case OpenCLLIB::Nan: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar or vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + const uint32_t nancode_type = _.GetOperandTypeId(inst, 4); + if (!_.IsIntScalarOrVectorType(nancode_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Nancode to be an int scalar or vector type"; + } + + if (_.GetDimension(nancode_type) != num_components) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Nancode to have the same number of components as " + "Result Type"; + } + + if (_.GetBitWidth(result_type) != _.GetBitWidth(nancode_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Nancode to have the same bit width as Result " + "Type"; + } + break; + } + + case OpenCLLIB::SAbs: + case OpenCLLIB::SAbs_diff: + case OpenCLLIB::SAdd_sat: + case OpenCLLIB::UAdd_sat: + case OpenCLLIB::SHadd: + case OpenCLLIB::UHadd: + case OpenCLLIB::SRhadd: + case OpenCLLIB::URhadd: + case OpenCLLIB::SClamp: + case OpenCLLIB::UClamp: + case OpenCLLIB::Clz: + case OpenCLLIB::Ctz: + case OpenCLLIB::SMad_hi: + case OpenCLLIB::UMad_sat: + case OpenCLLIB::SMad_sat: + case OpenCLLIB::SMax: + case OpenCLLIB::UMax: + case OpenCLLIB::SMin: + case OpenCLLIB::UMin: + case OpenCLLIB::SMul_hi: + case OpenCLLIB::Rotate: + case OpenCLLIB::SSub_sat: + case OpenCLLIB::USub_sat: + case OpenCLLIB::Popcount: + case OpenCLLIB::UAbs: + case OpenCLLIB::UAbs_diff: + case OpenCLLIB::UMul_hi: + case OpenCLLIB::UMad_hi: { + if (!_.IsIntScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be an int scalar or vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + for (uint32_t operand_index = 4; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (result_type != operand_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected types of all operands to be equal to Result " + "Type"; + } + } + break; + } + + case OpenCLLIB::U_Upsample: + case OpenCLLIB::S_Upsample: { + if (!_.IsIntScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be an int scalar or vector " + "type"; + } + + const uint32_t result_num_components = _.GetDimension(result_type); + if (result_num_components > 4 && result_num_components != 8 && + result_num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + const uint32_t result_bit_width = _.GetBitWidth(result_type); + if (result_bit_width != 16 && result_bit_width != 32 && + result_bit_width != 64) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected bit width of Result Type components to be 16, 32 " + "or 64"; + } + + const uint32_t hi_type = _.GetOperandTypeId(inst, 4); + const uint32_t lo_type = _.GetOperandTypeId(inst, 5); + + if (hi_type != lo_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Hi and Lo operands to have the same type"; + } + + if (result_num_components != _.GetDimension(hi_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Hi and Lo operands to have the same number of " + "components as Result Type"; + } + + if (result_bit_width != 2 * _.GetBitWidth(hi_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected bit width of components of Hi and Lo operands to " + "be half of the bit width of components of Result Type"; + } + break; + } + + case OpenCLLIB::SMad24: + case OpenCLLIB::UMad24: + case OpenCLLIB::SMul24: + case OpenCLLIB::UMul24: { + if (!_.IsIntScalarOrVectorType(result_type) || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 32-bit int scalar or vector " + "type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + for (uint32_t operand_index = 4; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (result_type != operand_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected types of all operands to be equal to Result " + "Type"; + } + } + break; + } + + case OpenCLLIB::Cross: { + if (!_.IsFloatVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components != 3 && num_components != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to have 3 or 4 components"; + } + + const uint32_t x_type = _.GetOperandTypeId(inst, 4); + const uint32_t y_type = _.GetOperandTypeId(inst, 5); + + if (x_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X type to be equal to Result Type"; + } + + if (y_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Y type to be equal to Result Type"; + } + break; + } + + case OpenCLLIB::Distance: + case OpenCLLIB::Fast_distance: { + if (!_.IsFloatScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar type"; + } + + const uint32_t p0_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatScalarOrVectorType(p0_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P0 to be of float scalar or vector type"; + } + + const uint32_t num_components = _.GetDimension(p0_type); + if (num_components > 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P0 to have no more than 4 components"; + } + + if (result_type != _.GetComponentType(p0_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P0 component type to be equal to " + << "Result Type"; + } + + const uint32_t p1_type = _.GetOperandTypeId(inst, 5); + if (p0_type != p1_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operands P0 and P1 to be of the same type"; + } + break; + } + + case OpenCLLIB::Length: + case OpenCLLIB::Fast_length: { + if (!_.IsFloatScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar type"; + } + + const uint32_t p_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatScalarOrVectorType(p_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to be a float scalar or vector"; + } + + const uint32_t num_components = _.GetDimension(p_type); + if (num_components > 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to have no more than 4 components"; + } + + if (result_type != _.GetComponentType(p_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P component type to be equal to Result " + "Type"; + } + break; + } + + case OpenCLLIB::Normalize: + case OpenCLLIB::Fast_normalize: { + if (!_.IsFloatScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar or vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to have no more than 4 components"; + } + + const uint32_t p_type = _.GetOperandTypeId(inst, 4); + if (p_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P type to be equal to Result Type"; + } + break; + } + + case OpenCLLIB::Bitselect: { + if (!_.IsFloatScalarOrVectorType(result_type) && + !_.IsIntScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be an int or float scalar or " + "vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + for (uint32_t operand_index = 4; operand_index < num_operands; + ++operand_index) { + const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index); + if (result_type != operand_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected types of all operands to be equal to Result " + "Type"; + } + } + break; + } + + case OpenCLLIB::Select: { + if (!_.IsFloatScalarOrVectorType(result_type) && + !_.IsIntScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be an int or float scalar or " + "vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + const uint32_t a_type = _.GetOperandTypeId(inst, 4); + const uint32_t b_type = _.GetOperandTypeId(inst, 5); + const uint32_t c_type = _.GetOperandTypeId(inst, 6); + + if (result_type != a_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand A type to be equal to Result Type"; + } + + if (result_type != b_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand B type to be equal to Result Type"; + } + + if (!_.IsIntScalarOrVectorType(c_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand C to be an int scalar or vector"; + } + + if (num_components != _.GetDimension(c_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand C to have the same number of components " + "as Result Type"; + } + + if (_.GetBitWidth(result_type) != _.GetBitWidth(c_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand C to have the same bit width as Result " + "Type"; + } + break; + } + + case OpenCLLIB::Vloadn: { + if (!_.IsFloatVectorType(result_type) && + !_.IsIntVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be an int or float vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to have 2, 3, 4, 8 or 16 components"; + } + + const uint32_t offset_type = _.GetOperandTypeId(inst, 4); + const uint32_t p_type = _.GetOperandTypeId(inst, 5); + + const uint32_t size_t_bit_width = GetSizeTBitWidth(_); + if (!size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << " can only be used with physical addressing models"; + } + + if (!_.IsIntScalarType(offset_type) || + _.GetBitWidth(offset_type) != size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Offset to be of type size_t (" + << size_t_bit_width + << "-bit integer for the addressing model used in the module)"; + } + + spv::StorageClass p_storage_class; + uint32_t p_data_type = 0; + if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to be a pointer"; + } + + if (p_storage_class != spv::StorageClass::UniformConstant && + p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P storage class to be UniformConstant, " + "Generic, CrossWorkgroup, Workgroup or Function"; + } + + if (_.GetComponentType(result_type) != p_data_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P data type to be equal to component " + "type of Result Type"; + } + + const uint32_t n_value = inst->word(7); + if (num_components != n_value) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected literal N to be equal to the number of " + "components of Result Type"; + } + break; + } + + case OpenCLLIB::Vstoren: { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": expected Result Type to be void"; + } + + const uint32_t data_type = _.GetOperandTypeId(inst, 4); + const uint32_t offset_type = _.GetOperandTypeId(inst, 5); + const uint32_t p_type = _.GetOperandTypeId(inst, 6); + + if (!_.IsFloatVectorType(data_type) && !_.IsIntVectorType(data_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Data to be an int or float vector"; + } + + const uint32_t num_components = _.GetDimension(data_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Data to have 2, 3, 4, 8 or 16 components"; + } + + const uint32_t size_t_bit_width = GetSizeTBitWidth(_); + if (!size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << " can only be used with physical addressing models"; + } + + if (!_.IsIntScalarType(offset_type) || + _.GetBitWidth(offset_type) != size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Offset to be of type size_t (" + << size_t_bit_width + << "-bit integer for the addressing model used in the module)"; + } + + spv::StorageClass p_storage_class; + uint32_t p_data_type = 0; + if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to be a pointer"; + } + + if (p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P storage class to be Generic, " + "CrossWorkgroup, Workgroup or Function"; + } + + if (_.GetComponentType(data_type) != p_data_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P data type to be equal to the type of " + "operand Data components"; + } + break; + } + + case OpenCLLIB::Vload_half: { + if (!_.IsFloatScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float scalar type"; + } + + const uint32_t offset_type = _.GetOperandTypeId(inst, 4); + const uint32_t p_type = _.GetOperandTypeId(inst, 5); + + const uint32_t size_t_bit_width = GetSizeTBitWidth(_); + if (!size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << " can only be used with physical addressing models"; + } + + if (!_.IsIntScalarType(offset_type) || + _.GetBitWidth(offset_type) != size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Offset to be of type size_t (" + << size_t_bit_width + << "-bit integer for the addressing model used in the module)"; + } + + spv::StorageClass p_storage_class; + uint32_t p_data_type = 0; + if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to be a pointer"; + } + + if (p_storage_class != spv::StorageClass::UniformConstant && + p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P storage class to be UniformConstant, " + "Generic, CrossWorkgroup, Workgroup or Function"; + } + + if (!_.IsFloatScalarType(p_data_type) || + _.GetBitWidth(p_data_type) != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P data type to be 16-bit float scalar"; + } + break; + } + + case OpenCLLIB::Vload_halfn: + case OpenCLLIB::Vloada_halfn: { + if (!_.IsFloatVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a float vector type"; + } + + const uint32_t num_components = _.GetDimension(result_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to have 2, 3, 4, 8 or 16 components"; + } + + const uint32_t offset_type = _.GetOperandTypeId(inst, 4); + const uint32_t p_type = _.GetOperandTypeId(inst, 5); + + const uint32_t size_t_bit_width = GetSizeTBitWidth(_); + if (!size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << " can only be used with physical addressing models"; + } + + if (!_.IsIntScalarType(offset_type) || + _.GetBitWidth(offset_type) != size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Offset to be of type size_t (" + << size_t_bit_width + << "-bit integer for the addressing model used in the module)"; + } + + spv::StorageClass p_storage_class; + uint32_t p_data_type = 0; + if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to be a pointer"; + } + + if (p_storage_class != spv::StorageClass::UniformConstant && + p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P storage class to be UniformConstant, " + "Generic, CrossWorkgroup, Workgroup or Function"; + } + + if (!_.IsFloatScalarType(p_data_type) || + _.GetBitWidth(p_data_type) != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P data type to be 16-bit float scalar"; + } + + const uint32_t n_value = inst->word(7); + if (num_components != n_value) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected literal N to be equal to the number of " + "components of Result Type"; + } + break; + } + + case OpenCLLIB::Vstore_half: + case OpenCLLIB::Vstore_half_r: + case OpenCLLIB::Vstore_halfn: + case OpenCLLIB::Vstore_halfn_r: + case OpenCLLIB::Vstorea_halfn: + case OpenCLLIB::Vstorea_halfn_r: { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": expected Result Type to be void"; + } + + const uint32_t data_type = _.GetOperandTypeId(inst, 4); + const uint32_t offset_type = _.GetOperandTypeId(inst, 5); + const uint32_t p_type = _.GetOperandTypeId(inst, 6); + const uint32_t data_type_bit_width = _.GetBitWidth(data_type); + + if (ext_inst_key == OpenCLLIB::Vstore_half || + ext_inst_key == OpenCLLIB::Vstore_half_r) { + if (!_.IsFloatScalarType(data_type) || + (data_type_bit_width != 32 && data_type_bit_width != 64)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Data to be a 32 or 64-bit float scalar"; + } + } else { + if (!_.IsFloatVectorType(data_type) || + (data_type_bit_width != 32 && data_type_bit_width != 64)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Data to be a 32 or 64-bit float vector"; + } + + const uint32_t num_components = _.GetDimension(data_type); + if (num_components > 4 && num_components != 8 && + num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Data to have 2, 3, 4, 8 or 16 components"; + } + } + + const uint32_t size_t_bit_width = GetSizeTBitWidth(_); + if (!size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << " can only be used with physical addressing models"; + } + + if (!_.IsIntScalarType(offset_type) || + _.GetBitWidth(offset_type) != size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Offset to be of type size_t (" + << size_t_bit_width + << "-bit integer for the addressing model used in the module)"; + } + + spv::StorageClass p_storage_class; + uint32_t p_data_type = 0; + if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P to be a pointer"; + } + + if (p_storage_class != spv::StorageClass::Generic && + p_storage_class != spv::StorageClass::CrossWorkgroup && + p_storage_class != spv::StorageClass::Workgroup && + p_storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P storage class to be Generic, " + "CrossWorkgroup, Workgroup or Function"; + } + + if (!_.IsFloatScalarType(p_data_type) || + _.GetBitWidth(p_data_type) != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand P data type to be 16-bit float scalar"; + } + + // Rounding mode enum is checked by assembler. + break; + } + + case OpenCLLIB::Shuffle: + case OpenCLLIB::Shuffle2: { + if (!_.IsFloatVectorType(result_type) && + !_.IsIntVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be an int or float vector type"; + } + + const uint32_t result_num_components = _.GetDimension(result_type); + if (result_num_components != 2 && result_num_components != 4 && + result_num_components != 8 && result_num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to have 2, 4, 8 or 16 components"; + } + + uint32_t operand_index = 4; + const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++); + + if (ext_inst_key == OpenCLLIB::Shuffle2) { + const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++); + if (x_type != y_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operands X and Y to be of the same type"; + } + } + + const uint32_t shuffle_mask_type = + _.GetOperandTypeId(inst, operand_index++); + + if (!_.IsFloatVectorType(x_type) && !_.IsIntVectorType(x_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X to be an int or float vector"; + } + + const uint32_t x_num_components = _.GetDimension(x_type); + if (x_num_components != 2 && x_num_components != 4 && + x_num_components != 8 && x_num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X to have 2, 4, 8 or 16 components"; + } + + const uint32_t result_component_type = _.GetComponentType(result_type); + + if (result_component_type != _.GetComponentType(x_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand X and Result Type to have equal " + "component types"; + } + + if (!_.IsIntVectorType(shuffle_mask_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Shuffle Mask to be an int vector"; + } + + if (result_num_components != _.GetDimension(shuffle_mask_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Shuffle Mask to have the same number of " + "components as Result Type"; + } + + if (_.GetBitWidth(result_component_type) != + _.GetBitWidth(shuffle_mask_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Shuffle Mask components to have the same " + "bit width as Result Type components"; + } + break; + } + + case OpenCLLIB::Printf: { + if (!_.IsIntScalarType(result_type) || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a 32-bit int type"; + } + + const uint32_t format_type = _.GetOperandTypeId(inst, 4); + spv::StorageClass format_storage_class; + uint32_t format_data_type = 0; + if (!_.GetPointerTypeInfo(format_type, &format_data_type, + &format_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Format to be a pointer"; + } + + if (format_storage_class != spv::StorageClass::UniformConstant) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Format storage class to be UniformConstant"; + } + + if (!_.IsIntScalarType(format_data_type) || + _.GetBitWidth(format_data_type) != 8) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Format data type to be 8-bit int"; + } + break; + } + + case OpenCLLIB::Prefetch: { + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": expected Result Type to be void"; + } + + const uint32_t p_type = _.GetOperandTypeId(inst, 4); + const uint32_t num_elements_type = _.GetOperandTypeId(inst, 5); + + spv::StorageClass p_storage_class; + uint32_t p_data_type = 0; + if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Ptr to be a pointer"; + } + + if (p_storage_class != spv::StorageClass::CrossWorkgroup) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Ptr storage class to be CrossWorkgroup"; + } + + if (!_.IsFloatScalarOrVectorType(p_data_type) && + !_.IsIntScalarOrVectorType(p_data_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Ptr data type to be int or float scalar or " + "vector"; + } + + const uint32_t num_components = _.GetDimension(p_data_type); + if (num_components > 4 && num_components != 8 && num_components != 16) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected Result Type to be a scalar or a vector with 2, " + "3, 4, 8 or 16 components"; + } + + const uint32_t size_t_bit_width = GetSizeTBitWidth(_); + if (!size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << " can only be used with physical addressing models"; + } + + if (!_.IsIntScalarType(num_elements_type) || + _.GetBitWidth(num_elements_type) != size_t_bit_width) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Num Elements to be of type size_t (" + << size_t_bit_width + << "-bit integer for the addressing model used in the module)"; + } + break; + } + } + } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 || + ext_inst_type == + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { + if (!_.IsVoidType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected result type must be a result id of " + << "OpTypeVoid"; + } + + const bool vulkanDebugInfo = + ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100; + + auto num_words = inst->words().size(); + + // Handle any non-common NonSemanticShaderDebugInfo instructions. + if (vulkanDebugInfo) { + const NonSemanticShaderDebugInfo100Instructions ext_inst_key = + NonSemanticShaderDebugInfo100Instructions(ext_inst_index); + switch (ext_inst_key) { + // The following block of instructions will be handled by the common + // validation. + case NonSemanticShaderDebugInfo100DebugInfoNone: + case NonSemanticShaderDebugInfo100DebugCompilationUnit: + case NonSemanticShaderDebugInfo100DebugTypeBasic: + case NonSemanticShaderDebugInfo100DebugTypePointer: + case NonSemanticShaderDebugInfo100DebugTypeQualifier: + case NonSemanticShaderDebugInfo100DebugTypeArray: + case NonSemanticShaderDebugInfo100DebugTypeVector: + case NonSemanticShaderDebugInfo100DebugTypedef: + case NonSemanticShaderDebugInfo100DebugTypeFunction: + case NonSemanticShaderDebugInfo100DebugTypeEnum: + case NonSemanticShaderDebugInfo100DebugTypeComposite: + case NonSemanticShaderDebugInfo100DebugTypeMember: + case NonSemanticShaderDebugInfo100DebugTypeInheritance: + case NonSemanticShaderDebugInfo100DebugTypePtrToMember: + case NonSemanticShaderDebugInfo100DebugTypeTemplate: + case NonSemanticShaderDebugInfo100DebugTypeTemplateParameter: + case NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter: + case NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack: + case NonSemanticShaderDebugInfo100DebugGlobalVariable: + case NonSemanticShaderDebugInfo100DebugFunctionDeclaration: + case NonSemanticShaderDebugInfo100DebugFunction: + case NonSemanticShaderDebugInfo100DebugLexicalBlock: + case NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator: + case NonSemanticShaderDebugInfo100DebugScope: + case NonSemanticShaderDebugInfo100DebugNoScope: + case NonSemanticShaderDebugInfo100DebugInlinedAt: + case NonSemanticShaderDebugInfo100DebugLocalVariable: + case NonSemanticShaderDebugInfo100DebugInlinedVariable: + case NonSemanticShaderDebugInfo100DebugDeclare: + case NonSemanticShaderDebugInfo100DebugValue: + case NonSemanticShaderDebugInfo100DebugOperation: + case NonSemanticShaderDebugInfo100DebugExpression: + case NonSemanticShaderDebugInfo100DebugMacroDef: + case NonSemanticShaderDebugInfo100DebugMacroUndef: + case NonSemanticShaderDebugInfo100DebugImportedEntity: + case NonSemanticShaderDebugInfo100DebugSource: + break; + case NonSemanticShaderDebugInfo100DebugTypeMatrix: { + CHECK_DEBUG_OPERAND("Vector Type", CommonDebugInfoDebugTypeVector, 5); + + CHECK_CONST_UINT_OPERAND("Vector Count", 6); + + uint32_t vector_count = inst->word(6); + uint64_t const_val; + if (!_.EvalConstantValUint64(vector_count, &const_val)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << ": Vector Count must be 32-bit integer OpConstant"; + } + + vector_count = const_val & 0xffffffff; + if (!vector_count || vector_count > 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": Vector Count must be positive " + << "integer less than or equal to 4"; + } + break; + } + // TODO: Add validation rules for remaining cases as well. + case NonSemanticShaderDebugInfo100DebugFunctionDefinition: + case NonSemanticShaderDebugInfo100DebugSourceContinued: + case NonSemanticShaderDebugInfo100DebugLine: + case NonSemanticShaderDebugInfo100DebugNoLine: + case NonSemanticShaderDebugInfo100DebugBuildIdentifier: + case NonSemanticShaderDebugInfo100DebugStoragePath: + case NonSemanticShaderDebugInfo100DebugEntryPoint: + break; + case NonSemanticShaderDebugInfo100InstructionsMax: + assert(0); + break; + } + } + + // Handle any non-common OpenCL insts, then common + if (ext_inst_type != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 || + OpenCLDebugInfo100Instructions(ext_inst_index) != + OpenCLDebugInfo100DebugModuleINTEL) { + const CommonDebugInfoInstructions ext_inst_key = + CommonDebugInfoInstructions(ext_inst_index); + switch (ext_inst_key) { + case CommonDebugInfoDebugInfoNone: + case CommonDebugInfoDebugNoScope: + break; + // The binary parser validates the opcode for DebugInfoNone, + // DebugNoScope, DebugOperation. We just check the parameters to + // DebugOperation are properly constants for vulkan debug info. + case CommonDebugInfoDebugOperation: { + CHECK_CONST_UINT_OPERAND("Operation", 5); + for (uint32_t i = 6; i < num_words; ++i) { + CHECK_CONST_UINT_OPERAND("Operand", i); + } + break; + } + case CommonDebugInfoDebugCompilationUnit: { + CHECK_CONST_UINT_OPERAND("Version", 5); + CHECK_CONST_UINT_OPERAND("DWARF Version", 6); + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Language", 8); + break; + } + case CommonDebugInfoDebugSource: { + CHECK_OPERAND("File", spv::Op::OpString, 5); + if (num_words == 7) CHECK_OPERAND("Text", spv::Op::OpString, 6); + break; + } + case CommonDebugInfoDebugTypeBasic: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Size", spv::Op::OpConstant, 6); + CHECK_CONST_UINT_OPERAND("Encoding", 7); + break; + } + case CommonDebugInfoDebugTypePointer: { + auto validate_base_type = ValidateOperandDebugType( + _, "Base Type", inst, 5, ext_inst_name, false); + if (validate_base_type != SPV_SUCCESS) return validate_base_type; + CHECK_CONST_UINT_OPERAND("Storage Class", 6); + CHECK_CONST_UINT_OPERAND("Flags", 7); + break; + } + case CommonDebugInfoDebugTypeQualifier: { + auto validate_base_type = ValidateOperandDebugType( + _, "Base Type", inst, 5, ext_inst_name, false); + if (validate_base_type != SPV_SUCCESS) return validate_base_type; + CHECK_CONST_UINT_OPERAND("Type Qualifier", 6); + break; + } + case CommonDebugInfoDebugTypeVector: { + auto validate_base_type = + ValidateOperandBaseType(_, inst, 5, ext_inst_name); + if (validate_base_type != SPV_SUCCESS) return validate_base_type; + + CHECK_CONST_UINT_OPERAND("Component Count", 6); + uint32_t component_count = inst->word(6); + if (vulkanDebugInfo) { + uint64_t const_val; + if (!_.EvalConstantValUint64(component_count, &const_val)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() + << ": Component Count must be 32-bit integer OpConstant"; + } + component_count = const_val & 0xffffffff; + } + + if (!component_count || component_count > 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": Component Count must be positive " + << "integer less than or equal to 4"; + } + break; + } + case CommonDebugInfoDebugTypeArray: { + auto validate_base_type = ValidateOperandDebugType( + _, "Base Type", inst, 5, ext_inst_name, false); + if (validate_base_type != SPV_SUCCESS) return validate_base_type; + for (uint32_t i = 6; i < num_words; ++i) { + bool invalid = false; + auto* component_count = _.FindDef(inst->word(i)); + if (IsConstIntScalarTypeWith32Or64Bits(_, component_count)) { + // TODO: We need a spec discussion for the runtime array for + // OpenCL. + if (!vulkanDebugInfo && !component_count->word(3)) { + invalid = true; + } + } else if (component_count->words().size() > 6 && + (CommonDebugInfoInstructions(component_count->word(4)) == + CommonDebugInfoDebugLocalVariable || + CommonDebugInfoInstructions(component_count->word(4)) == + CommonDebugInfoDebugGlobalVariable)) { + auto* component_count_type = _.FindDef(component_count->word(6)); + if (component_count_type->words().size() > 7) { + uint32_t encoding = component_count_type->word(7); + if (CommonDebugInfoInstructions(component_count_type->word( + 4)) != CommonDebugInfoDebugTypeBasic || + (vulkanDebugInfo && !IsUint32Constant(_, encoding)) || + OpenCLDebugInfo100DebugBaseTypeAttributeEncoding( + vulkanDebugInfo + ? GetUint32Constant(_, encoding) + : encoding) != OpenCLDebugInfo100Unsigned) { + invalid = true; + } else { + // DebugTypeBasic for DebugLocalVariable/DebugGlobalVariable + // must have Unsigned encoding and 32 or 64 as its size in + // bits. + Instruction* size_in_bits = + _.FindDef(component_count_type->word(6)); + if (!_.IsIntScalarType(size_in_bits->type_id()) || + (size_in_bits->word(3) != 32 && + size_in_bits->word(3) != 64)) { + invalid = true; + } + } + } else { + invalid = true; + } + } else { + invalid = true; + } + if (invalid) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": Component Count must be " + << "OpConstant with a 32- or 64-bits integer scalar type " + "or " + << "DebugGlobalVariable or DebugLocalVariable with a 32- " + "or " + << "64-bits unsigned integer scalar type"; + } + } + break; + } + case CommonDebugInfoDebugTypedef: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + auto validate_base_type = + ValidateOperandBaseType(_, inst, 6, ext_inst_name); + if (validate_base_type != SPV_SUCCESS) return validate_base_type; + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Line", 8); + CHECK_CONST_UINT_OPERAND("Column", 9); + auto validate_parent = + ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); + if (validate_parent != SPV_SUCCESS) return validate_parent; + break; + } + case CommonDebugInfoDebugTypeFunction: { + CHECK_CONST_UINT_OPERAND("Flags", 5); + auto* return_type = _.FindDef(inst->word(6)); + // TODO: We need a spec discussion that we have to allow return and + // parameter types of a DebugTypeFunction to have template parameter. + if (return_type->opcode() != spv::Op::OpTypeVoid) { + auto validate_return = ValidateOperandDebugType( + _, "Return Type", inst, 6, ext_inst_name, true); + if (validate_return != SPV_SUCCESS) return validate_return; + } + for (uint32_t word_index = 7; word_index < num_words; ++word_index) { + auto validate_param = ValidateOperandDebugType( + _, "Parameter Types", inst, word_index, ext_inst_name, true); + if (validate_param != SPV_SUCCESS) return validate_param; + } + break; + } + case CommonDebugInfoDebugTypeEnum: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + if (!DoesDebugInfoOperandMatchExpectation( + _, + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == CommonDebugInfoDebugInfoNone; + }, + inst, 6)) { + auto validate_underlying_type = ValidateOperandDebugType( + _, "Underlying Types", inst, 6, ext_inst_name, false); + if (validate_underlying_type != SPV_SUCCESS) + return validate_underlying_type; + } + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Line", 8); + CHECK_CONST_UINT_OPERAND("Column", 9); + auto validate_parent = + ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); + if (validate_parent != SPV_SUCCESS) return validate_parent; + CHECK_OPERAND("Size", spv::Op::OpConstant, 11); + auto* size = _.FindDef(inst->word(11)); + if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": expected operand Size is a " + << "positive integer"; + } + CHECK_CONST_UINT_OPERAND("Flags", 12); + for (uint32_t word_index = 13; word_index + 1 < num_words; + word_index += 2) { + CHECK_OPERAND("Value", spv::Op::OpConstant, word_index); + CHECK_OPERAND("Name", spv::Op::OpString, word_index + 1); + } + break; + } + case CommonDebugInfoDebugTypeComposite: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Line", 8); + CHECK_CONST_UINT_OPERAND("Column", 9); + auto validate_parent = + ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); + if (validate_parent != SPV_SUCCESS) return validate_parent; + CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); + if (!DoesDebugInfoOperandMatchExpectation( + _, + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == CommonDebugInfoDebugInfoNone; + }, + inst, 12)) { + CHECK_OPERAND("Size", spv::Op::OpConstant, 12); + } + CHECK_CONST_UINT_OPERAND("Flags", 13); + for (uint32_t word_index = 14; word_index < num_words; ++word_index) { + if (!DoesDebugInfoOperandMatchExpectation( + _, + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == CommonDebugInfoDebugTypeMember || + dbg_inst == CommonDebugInfoDebugFunction || + dbg_inst == CommonDebugInfoDebugTypeInheritance; + }, + inst, word_index)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Members " + << "must be DebugTypeMember, DebugFunction, or " + "DebugTypeInheritance"; + } + } + break; + } + case CommonDebugInfoDebugTypeMember: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + // TODO: We need a spec discussion that we have to allow member types + // to have template parameter. + auto validate_type = + ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true); + if (validate_type != SPV_SUCCESS) return validate_type; + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Line", 8); + CHECK_CONST_UINT_OPERAND("Column", 9); + // NonSemantic.Shader.DebugInfo doesn't have the Parent operand + if (vulkanDebugInfo) { + CHECK_OPERAND("Offset", spv::Op::OpConstant, 10); + CHECK_OPERAND("Size", spv::Op::OpConstant, 11); + CHECK_CONST_UINT_OPERAND("Flags", 12); + if (num_words == 14) + CHECK_OPERAND("Value", spv::Op::OpConstant, 13); + } else { + CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite, + 10); + CHECK_OPERAND("Offset", spv::Op::OpConstant, 11); + CHECK_OPERAND("Size", spv::Op::OpConstant, 12); + CHECK_CONST_UINT_OPERAND("Flags", 13); + if (num_words == 15) + CHECK_OPERAND("Value", spv::Op::OpConstant, 14); + } + break; + } + case CommonDebugInfoDebugTypeInheritance: { + CHECK_DEBUG_OPERAND("Child", CommonDebugInfoDebugTypeComposite, 5); + auto* debug_inst = _.FindDef(inst->word(5)); + auto composite_type = + OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6)); + if (composite_type != OpenCLDebugInfo100Class && + composite_type != OpenCLDebugInfo100Structure) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Child must be class or struct debug " + "type"; + } + CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite, 6); + debug_inst = _.FindDef(inst->word(6)); + composite_type = + OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6)); + if (composite_type != OpenCLDebugInfo100Class && + composite_type != OpenCLDebugInfo100Structure) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Parent must be class or struct debug " + "type"; + } + CHECK_OPERAND("Offset", spv::Op::OpConstant, 7); + CHECK_OPERAND("Size", spv::Op::OpConstant, 8); + CHECK_CONST_UINT_OPERAND("Flags", 9); + break; + } + case CommonDebugInfoDebugFunction: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, + ext_inst_name, false); + if (validate_type != SPV_SUCCESS) return validate_type; + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Line", 8); + CHECK_CONST_UINT_OPERAND("Column", 9); + auto validate_parent = + ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); + if (validate_parent != SPV_SUCCESS) return validate_parent; + CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); + CHECK_CONST_UINT_OPERAND("Flags", 12); + CHECK_CONST_UINT_OPERAND("Scope Line", 13); + // NonSemantic.Shader.DebugInfo.100 doesn't include a reference to the + // OpFunction + if (vulkanDebugInfo) { + if (num_words == 15) { + CHECK_DEBUG_OPERAND("Declaration", + CommonDebugInfoDebugFunctionDeclaration, 14); + } + } else { + if (!DoesDebugInfoOperandMatchExpectation( + _, + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == CommonDebugInfoDebugInfoNone; + }, + inst, 14)) { + CHECK_OPERAND("Function", spv::Op::OpFunction, 14); + } + if (num_words == 16) { + CHECK_DEBUG_OPERAND("Declaration", + CommonDebugInfoDebugFunctionDeclaration, 15); + } + } + break; + } + case CommonDebugInfoDebugFunctionDeclaration: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, + ext_inst_name, false); + if (validate_type != SPV_SUCCESS) return validate_type; + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Line", 8); + CHECK_CONST_UINT_OPERAND("Column", 9); + auto validate_parent = + ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); + if (validate_parent != SPV_SUCCESS) return validate_parent; + CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); + CHECK_CONST_UINT_OPERAND("Flags", 12); + break; + } + case CommonDebugInfoDebugLexicalBlock: { + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 5); + CHECK_CONST_UINT_OPERAND("Line", 6); + CHECK_CONST_UINT_OPERAND("Column", 7); + auto validate_parent = + ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name); + if (validate_parent != SPV_SUCCESS) return validate_parent; + if (num_words == 10) CHECK_OPERAND("Name", spv::Op::OpString, 9); + break; + } + case CommonDebugInfoDebugScope: { + auto validate_scope = + ValidateOperandLexicalScope(_, "Scope", inst, 5, ext_inst_name); + if (validate_scope != SPV_SUCCESS) return validate_scope; + if (num_words == 7) { + CHECK_DEBUG_OPERAND("Inlined At", CommonDebugInfoDebugInlinedAt, 6); + } + break; + } + case CommonDebugInfoDebugLocalVariable: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + // TODO: We need a spec discussion that we have to allow local + // variable types to have template parameter. + auto validate_type = + ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true); + if (validate_type != SPV_SUCCESS) return validate_type; + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Line", 8); + CHECK_CONST_UINT_OPERAND("Column", 9); + auto validate_parent = + ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); + if (validate_parent != SPV_SUCCESS) return validate_parent; + CHECK_CONST_UINT_OPERAND("Flags", 11); + if (num_words == 13) { + CHECK_CONST_UINT_OPERAND("ArgNumber", 12); + } + break; + } + case CommonDebugInfoDebugDeclare: { + CHECK_DEBUG_OPERAND("Local Variable", + CommonDebugInfoDebugLocalVariable, 5); + auto* operand = _.FindDef(inst->word(6)); + if (operand->opcode() != spv::Op::OpVariable && + operand->opcode() != spv::Op::OpFunctionParameter) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Variable must be a result id of " + "OpVariable or OpFunctionParameter"; + } + + CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7); + + if (vulkanDebugInfo) { + for (uint32_t word_index = 8; word_index < num_words; + ++word_index) { + auto index_inst = _.FindDef(inst->word(word_index)); + auto type_id = index_inst != nullptr ? index_inst->type_id() : 0; + if (type_id == 0 || !IsIntScalar(_, type_id, false, false)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected index must be scalar integer"; + } + } + break; + } + case CommonDebugInfoDebugExpression: { + for (uint32_t word_index = 5; word_index < num_words; ++word_index) { + CHECK_DEBUG_OPERAND("Operation", CommonDebugInfoDebugOperation, + word_index); + } + break; + } + case CommonDebugInfoDebugTypeTemplate: { + if (!DoesDebugInfoOperandMatchExpectation( + _, + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == CommonDebugInfoDebugTypeComposite || + dbg_inst == CommonDebugInfoDebugFunction; + }, + inst, 5)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Target must be DebugTypeComposite " + << "or DebugFunction"; + } + for (uint32_t word_index = 6; word_index < num_words; ++word_index) { + if (!DoesDebugInfoOperandMatchExpectation( + _, + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == + CommonDebugInfoDebugTypeTemplateParameter || + dbg_inst == + CommonDebugInfoDebugTypeTemplateTemplateParameter; + }, + inst, word_index)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Parameters must be " + << "DebugTypeTemplateParameter or " + << "DebugTypeTemplateTemplateParameter"; + } + } + break; + } + case CommonDebugInfoDebugTypeTemplateParameter: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + auto validate_actual_type = ValidateOperandDebugType( + _, "Actual Type", inst, 6, ext_inst_name, false); + if (validate_actual_type != SPV_SUCCESS) return validate_actual_type; + if (!DoesDebugInfoOperandMatchExpectation( + _, + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == CommonDebugInfoDebugInfoNone; + }, + inst, 7)) { + CHECK_OPERAND("Value", spv::Op::OpConstant, 7); + } + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 8); + CHECK_CONST_UINT_OPERAND("Line", 9); + CHECK_CONST_UINT_OPERAND("Column", 10); + break; + } + case CommonDebugInfoDebugGlobalVariable: { + CHECK_OPERAND("Name", spv::Op::OpString, 5); + auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, + ext_inst_name, false); + if (validate_type != SPV_SUCCESS) return validate_type; + CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); + CHECK_CONST_UINT_OPERAND("Line", 8); + CHECK_CONST_UINT_OPERAND("Column", 9); + auto validate_scope = + ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name); + if (validate_scope != SPV_SUCCESS) return validate_scope; + CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); + if (!DoesDebugInfoOperandMatchExpectation( + _, + [](CommonDebugInfoInstructions dbg_inst) { + return dbg_inst == CommonDebugInfoDebugInfoNone; + }, + inst, 12)) { + auto* operand = _.FindDef(inst->word(12)); + if (operand->opcode() != spv::Op::OpVariable && + operand->opcode() != spv::Op::OpConstant) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": " + << "expected operand Variable must be a result id of " + "OpVariable or OpConstant or DebugInfoNone"; + } + } + if (num_words == 15) { + CHECK_DEBUG_OPERAND("Static Member Declaration", + CommonDebugInfoDebugTypeMember, 14); + } + break; + } + case CommonDebugInfoDebugInlinedAt: { + CHECK_CONST_UINT_OPERAND("Line", 5); + auto validate_scope = + ValidateOperandLexicalScope(_, "Scope", inst, 6, ext_inst_name); + if (validate_scope != SPV_SUCCESS) return validate_scope; + if (num_words == 8) { + CHECK_DEBUG_OPERAND("Inlined", CommonDebugInfoDebugInlinedAt, 7); + } + break; + } + case CommonDebugInfoDebugValue: { + CHECK_DEBUG_OPERAND("Local Variable", + CommonDebugInfoDebugLocalVariable, 5); + CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7); + + for (uint32_t word_index = 8; word_index < num_words; ++word_index) { + // TODO: The following code simply checks if it is a const int + // scalar or a DebugLocalVariable or DebugGlobalVariable, but we + // have to check it using the same validation for Indexes of + // OpAccessChain. + if (!IsConstWithIntScalarType(_, inst, word_index) && + !IsDebugVariableWithIntScalarType(_, inst, word_index)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << ext_inst_name() << ": expected operand Indexes is " + << "OpConstant, DebugGlobalVariable, or " + << "type is OpConstant with an integer scalar type"; + } + } + break; + } + + // TODO: Add validation rules for remaining cases as well. + case CommonDebugInfoDebugTypePtrToMember: + case CommonDebugInfoDebugTypeTemplateTemplateParameter: + case CommonDebugInfoDebugTypeTemplateParameterPack: + case CommonDebugInfoDebugLexicalBlockDiscriminator: + case CommonDebugInfoDebugInlinedVariable: + case CommonDebugInfoDebugMacroDef: + case CommonDebugInfoDebugMacroUndef: + case CommonDebugInfoDebugImportedEntity: + break; + case CommonDebugInfoInstructionsMax: + assert(0); + break; + } + } + } else if (ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) { + auto import_inst = _.FindDef(inst->GetOperandAs(2)); + const std::string name = import_inst->GetOperandAs(1); + const std::string reflection = "NonSemantic.ClspvReflection."; + char* end_ptr; + auto version_string = name.substr(reflection.size()); + if (version_string.empty()) { + return _.diag(SPV_ERROR_INVALID_DATA, import_inst) + << "Missing NonSemantic.ClspvReflection import version"; + } + uint32_t version = static_cast( + std::strtoul(version_string.c_str(), &end_ptr, 10)); + if (end_ptr && *end_ptr != '\0') { + return _.diag(SPV_ERROR_INVALID_DATA, import_inst) + << "NonSemantic.ClspvReflection import does not encode the " + "version correctly"; + } + if (version == 0 || version > NonSemanticClspvReflectionRevision) { + return _.diag(SPV_ERROR_INVALID_DATA, import_inst) + << "Unknown NonSemantic.ClspvReflection import version"; + } + + return ValidateClspvReflectionInstruction(_, inst, version); + } + + return SPV_SUCCESS; +} + +spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + if (opcode == spv::Op::OpExtension) return ValidateExtension(_, inst); + if (opcode == spv::Op::OpExtInstImport) return ValidateExtInstImport(_, inst); + if (opcode == spv::Op::OpExtInst) return ValidateExtInst(_, inst); + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_function.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_function.cpp new file mode 100644 index 000000000000..639817fef442 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_function.cpp @@ -0,0 +1,360 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "source/enum_string_mapping.h" +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Returns true if |a| and |b| are instructions defining pointers that point to +// types logically match and the decorations that apply to |b| are a subset +// of the decorations that apply to |a|. +bool DoPointeesLogicallyMatch(val::Instruction* a, val::Instruction* b, + ValidationState_t& _) { + if (a->opcode() != spv::Op::OpTypePointer || + b->opcode() != spv::Op::OpTypePointer) { + return false; + } + + const auto& dec_a = _.id_decorations(a->id()); + const auto& dec_b = _.id_decorations(b->id()); + for (const auto& dec : dec_b) { + if (std::find(dec_a.begin(), dec_a.end(), dec) == dec_a.end()) { + return false; + } + } + + uint32_t a_type = a->GetOperandAs(2); + uint32_t b_type = b->GetOperandAs(2); + + if (a_type == b_type) { + return true; + } + + Instruction* a_type_inst = _.FindDef(a_type); + Instruction* b_type_inst = _.FindDef(b_type); + + return _.LogicallyMatch(a_type_inst, b_type_inst, true); +} + +spv_result_t ValidateFunction(ValidationState_t& _, const Instruction* inst) { + const auto function_type_id = inst->GetOperandAs(3); + const auto function_type = _.FindDef(function_type_id); + if (!function_type || spv::Op::OpTypeFunction != function_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunction Function Type " << _.getIdName(function_type_id) + << " is not a function type."; + } + + const auto return_id = function_type->GetOperandAs(1); + if (return_id != inst->type_id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunction Result Type " << _.getIdName(inst->type_id()) + << " does not match the Function Type's return type " + << _.getIdName(return_id) << "."; + } + + const std::vector acceptable = { + spv::Op::OpGroupDecorate, + spv::Op::OpDecorate, + spv::Op::OpEnqueueKernel, + spv::Op::OpEntryPoint, + spv::Op::OpExecutionMode, + spv::Op::OpExecutionModeId, + spv::Op::OpFunctionCall, + spv::Op::OpGetKernelNDrangeSubGroupCount, + spv::Op::OpGetKernelNDrangeMaxSubGroupSize, + spv::Op::OpGetKernelWorkGroupSize, + spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple, + spv::Op::OpGetKernelLocalSizeForSubgroupCount, + spv::Op::OpGetKernelMaxNumSubgroups, + spv::Op::OpName}; + for (auto& pair : inst->uses()) { + const auto* use = pair.first; + if (std::find(acceptable.begin(), acceptable.end(), use->opcode()) == + acceptable.end() && + !use->IsNonSemantic() && !use->IsDebugInfo()) { + return _.diag(SPV_ERROR_INVALID_ID, use) + << "Invalid use of function result id " << _.getIdName(inst->id()) + << "."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateFunctionParameter(ValidationState_t& _, + const Instruction* inst) { + // NOTE: Find OpFunction & ensure OpFunctionParameter is not out of place. + size_t param_index = 0; + size_t inst_num = inst->LineNum() - 1; + if (inst_num == 0) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Function parameter cannot be the first instruction."; + } + + auto func_inst = &_.ordered_instructions()[inst_num]; + while (--inst_num) { + func_inst = &_.ordered_instructions()[inst_num]; + if (func_inst->opcode() == spv::Op::OpFunction) { + break; + } else if (func_inst->opcode() == spv::Op::OpFunctionParameter) { + ++param_index; + } + } + + if (func_inst->opcode() != spv::Op::OpFunction) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Function parameter must be preceded by a function."; + } + + const auto function_type_id = func_inst->GetOperandAs(3); + const auto function_type = _.FindDef(function_type_id); + if (!function_type) { + return _.diag(SPV_ERROR_INVALID_ID, func_inst) + << "Missing function type definition."; + } + if (param_index >= function_type->words().size() - 3) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Too many OpFunctionParameters for " << func_inst->id() + << ": expected " << function_type->words().size() - 3 + << " based on the function's type"; + } + + const auto param_type = + _.FindDef(function_type->GetOperandAs(param_index + 2)); + if (!param_type || inst->type_id() != param_type->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionParameter Result Type " + << _.getIdName(inst->type_id()) + << " does not match the OpTypeFunction parameter " + "type of the same index."; + } + + // Validate that PhysicalStorageBuffer have one of Restrict, Aliased, + // RestrictPointer, or AliasedPointer. + auto param_nonarray_type_id = param_type->id(); + while (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypeArray) { + param_nonarray_type_id = + _.FindDef(param_nonarray_type_id)->GetOperandAs(1u); + } + if (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypePointer) { + auto param_nonarray_type = _.FindDef(param_nonarray_type_id); + if (param_nonarray_type->GetOperandAs(1u) == + spv::StorageClass::PhysicalStorageBuffer) { + // check for Aliased or Restrict + const auto& decorations = _.id_decorations(inst->id()); + + bool foundAliased = std::any_of( + decorations.begin(), decorations.end(), [](const Decoration& d) { + return spv::Decoration::Aliased == d.dec_type(); + }); + + bool foundRestrict = std::any_of( + decorations.begin(), decorations.end(), [](const Decoration& d) { + return spv::Decoration::Restrict == d.dec_type(); + }); + + if (!foundAliased && !foundRestrict) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionParameter " << inst->id() + << ": expected Aliased or Restrict for PhysicalStorageBuffer " + "pointer."; + } + if (foundAliased && foundRestrict) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionParameter " << inst->id() + << ": can't specify both Aliased and Restrict for " + "PhysicalStorageBuffer pointer."; + } + } else { + const auto pointee_type_id = + param_nonarray_type->GetOperandAs(2); + const auto pointee_type = _.FindDef(pointee_type_id); + if (spv::Op::OpTypePointer == pointee_type->opcode() && + pointee_type->GetOperandAs(1u) == + spv::StorageClass::PhysicalStorageBuffer) { + // check for AliasedPointer/RestrictPointer + const auto& decorations = _.id_decorations(inst->id()); + + bool foundAliased = std::any_of( + decorations.begin(), decorations.end(), [](const Decoration& d) { + return spv::Decoration::AliasedPointer == d.dec_type(); + }); + + bool foundRestrict = std::any_of( + decorations.begin(), decorations.end(), [](const Decoration& d) { + return spv::Decoration::RestrictPointer == d.dec_type(); + }); + + if (!foundAliased && !foundRestrict) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionParameter " << inst->id() + << ": expected AliasedPointer or RestrictPointer for " + "PhysicalStorageBuffer pointer."; + } + if (foundAliased && foundRestrict) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionParameter " << inst->id() + << ": can't specify both AliasedPointer and " + "RestrictPointer for PhysicalStorageBuffer pointer."; + } + } + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateFunctionCall(ValidationState_t& _, + const Instruction* inst) { + const auto function_id = inst->GetOperandAs(2); + const auto function = _.FindDef(function_id); + if (!function || spv::Op::OpFunction != function->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionCall Function " << _.getIdName(function_id) + << " is not a function."; + } + + auto return_type = _.FindDef(function->type_id()); + if (!return_type || return_type->id() != inst->type_id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionCall Result Type " << _.getIdName(inst->type_id()) + << "s type does not match Function " + << _.getIdName(return_type->id()) << "s return type."; + } + + const auto function_type_id = function->GetOperandAs(3); + const auto function_type = _.FindDef(function_type_id); + if (!function_type || function_type->opcode() != spv::Op::OpTypeFunction) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Missing function type definition."; + } + + const auto function_call_arg_count = inst->words().size() - 4; + const auto function_param_count = function_type->words().size() - 3; + if (function_param_count != function_call_arg_count) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionCall Function 's parameter count does not match " + "the argument count."; + } + + for (size_t argument_index = 3, param_index = 2; + argument_index < inst->operands().size(); + argument_index++, param_index++) { + const auto argument_id = inst->GetOperandAs(argument_index); + const auto argument = _.FindDef(argument_id); + if (!argument) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Missing argument " << argument_index - 3 << " definition."; + } + + const auto argument_type = _.FindDef(argument->type_id()); + if (!argument_type) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Missing argument " << argument_index - 3 + << " type definition."; + } + + const auto parameter_type_id = + function_type->GetOperandAs(param_index); + const auto parameter_type = _.FindDef(parameter_type_id); + if (!parameter_type || argument_type->id() != parameter_type->id()) { + if (!_.options()->before_hlsl_legalization || + !DoPointeesLogicallyMatch(argument_type, parameter_type, _)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpFunctionCall Argument " << _.getIdName(argument_id) + << "s type does not match Function " + << _.getIdName(parameter_type_id) << "s parameter type."; + } + } + + if (_.addressing_model() == spv::AddressingModel::Logical) { + if (parameter_type->opcode() == spv::Op::OpTypePointer && + !_.options()->relax_logical_pointer) { + spv::StorageClass sc = + parameter_type->GetOperandAs(1u); + // Validate which storage classes can be pointer operands. + switch (sc) { + case spv::StorageClass::UniformConstant: + case spv::StorageClass::Function: + case spv::StorageClass::Private: + case spv::StorageClass::Workgroup: + case spv::StorageClass::AtomicCounter: + // These are always allowed. + break; + case spv::StorageClass::StorageBuffer: + if (!_.features().variable_pointers) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "StorageBuffer pointer operand " + << _.getIdName(argument_id) + << " requires a variable pointers capability"; + } + break; + default: + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Invalid storage class for pointer operand " + << _.getIdName(argument_id); + } + + // Validate memory object declaration requirements. + if (argument->opcode() != spv::Op::OpVariable && + argument->opcode() != spv::Op::OpFunctionParameter) { + const bool ssbo_vptr = _.features().variable_pointers && + sc == spv::StorageClass::StorageBuffer; + const bool wg_vptr = + _.HasCapability(spv::Capability::VariablePointers) && + sc == spv::StorageClass::Workgroup; + const bool uc_ptr = sc == spv::StorageClass::UniformConstant; + if (!ssbo_vptr && !wg_vptr && !uc_ptr) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Pointer operand " << _.getIdName(argument_id) + << " must be a memory object declaration"; + } + } + } + } + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t FunctionPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpFunction: + if (auto error = ValidateFunction(_, inst)) return error; + break; + case spv::Op::OpFunctionParameter: + if (auto error = ValidateFunctionParameter(_, inst)) return error; + break; + case spv::Op::OpFunctionCall: + if (auto error = ValidateFunctionCall(_, inst)) return error; + break; + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_id.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_id.cpp new file mode 100644 index 000000000000..bcfeb5915e04 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_id.cpp @@ -0,0 +1,244 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "source/instruction.h" +#include "source/opcode.h" +#include "source/operand.h" +#include "source/val/function.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace val { + +spv_result_t UpdateIdUse(ValidationState_t& _, const Instruction* inst) { + for (auto& operand : inst->operands()) { + const spv_operand_type_t& type = operand.type; + const uint32_t operand_id = inst->word(operand.offset); + if (spvIsIdType(type) && type != SPV_OPERAND_TYPE_RESULT_ID) { + if (auto def = _.FindDef(operand_id)) + def->RegisterUse(inst, operand.offset); + } + } + + return SPV_SUCCESS; +} + +/// This function checks all ID definitions dominate their use in the CFG. +/// +/// This function will iterate over all ID definitions that are defined in the +/// functions of a module and make sure that the definitions appear in a +/// block that dominates their use. +/// +/// NOTE: This function does NOT check module scoped functions which are +/// checked during the initial binary parse in the IdPass below +spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) { + std::vector phi_instructions; + std::unordered_set phi_ids; + for (const auto& inst : _.ordered_instructions()) { + if (inst.id() == 0) continue; + if (const Function* func = inst.function()) { + if (const BasicBlock* block = inst.block()) { + // If the Id is defined within a block then make sure all references to + // that Id appear in a blocks that are dominated by the defining block + for (auto& use_index_pair : inst.uses()) { + const Instruction* use = use_index_pair.first; + if (const BasicBlock* use_block = use->block()) { + if (use_block->reachable() == false) continue; + if (use->opcode() == spv::Op::OpPhi) { + if (phi_ids.insert(use->id()).second) { + phi_instructions.push_back(use); + } + } else if (!block->dominates(*use->block())) { + return _.diag(SPV_ERROR_INVALID_ID, use_block->label()) + << "ID " << _.getIdName(inst.id()) << " defined in block " + << _.getIdName(block->id()) + << " does not dominate its use in block " + << _.getIdName(use_block->id()); + } + } + } + } else { + // If the Ids defined within a function but not in a block(i.e. function + // parameters, block ids), then make sure all references to that Id + // appear within the same function + for (auto use : inst.uses()) { + const Instruction* user = use.first; + if (user->function() && user->function() != func) { + return _.diag(SPV_ERROR_INVALID_ID, _.FindDef(func->id())) + << "ID " << _.getIdName(inst.id()) << " used in function " + << _.getIdName(user->function()->id()) + << " is used outside of it's defining function " + << _.getIdName(func->id()); + } + } + } + } + // NOTE: Ids defined outside of functions must appear before they are used + // This check is being performed in the IdPass function + } + + // Check all OpPhi parent blocks are dominated by the variable's defining + // blocks + for (const Instruction* phi : phi_instructions) { + if (phi->block()->reachable() == false) continue; + for (size_t i = 3; i < phi->operands().size(); i += 2) { + const Instruction* variable = _.FindDef(phi->word(i)); + const BasicBlock* parent = + phi->function()->GetBlock(phi->word(i + 1)).first; + if (variable->block() && parent->reachable() && + !variable->block()->dominates(*parent)) { + return _.diag(SPV_ERROR_INVALID_ID, phi) + << "In OpPhi instruction " << _.getIdName(phi->id()) << ", ID " + << _.getIdName(variable->id()) + << " definition does not dominate its parent " + << _.getIdName(parent->id()); + } + } + } + + return SPV_SUCCESS; +} + +// Performs SSA validation on the IDs of an instruction. The +// can_have_forward_declared_ids functor should return true if the +// instruction operand's ID can be forward referenced. +spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { + auto can_have_forward_declared_ids = + inst->opcode() == spv::Op::OpExtInst && + spvExtInstIsDebugInfo(inst->ext_inst_type()) + ? spvDbgInfoExtOperandCanBeForwardDeclaredFunction( + inst->ext_inst_type(), inst->word(4)) + : spvOperandCanBeForwardDeclaredFunction(inst->opcode()); + + // Keep track of a result id defined by this instruction. 0 means it + // does not define an id. + uint32_t result_id = 0; + + for (unsigned i = 0; i < inst->operands().size(); i++) { + const spv_parsed_operand_t& operand = inst->operand(i); + const spv_operand_type_t& type = operand.type; + // We only care about Id operands, which are a single word. + const uint32_t operand_word = inst->word(operand.offset); + + auto ret = SPV_ERROR_INTERNAL; + switch (type) { + case SPV_OPERAND_TYPE_RESULT_ID: + // NOTE: Multiple Id definitions are being checked by the binary parser. + // + // Defer undefined-forward-reference removal until after we've analyzed + // the remaining operands to this instruction. Deferral only matters + // for OpPhi since it's the only case where it defines its own forward + // reference. Other instructions that can have forward references + // either don't define a value or the forward reference is to a function + // Id (and hence defined outside of a function body). + result_id = operand_word; + // NOTE: The result Id is added (in RegisterInstruction) *after* all of + // the other Ids have been checked to avoid premature use in the same + // instruction. + ret = SPV_SUCCESS; + break; + case SPV_OPERAND_TYPE_ID: + case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: + case SPV_OPERAND_TYPE_SCOPE_ID: + if (const auto def = _.FindDef(operand_word)) { + const auto opcode = inst->opcode(); + if (spvOpcodeGeneratesType(def->opcode()) && + !spvOpcodeGeneratesType(opcode) && !spvOpcodeIsDebug(opcode) && + !inst->IsDebugInfo() && !inst->IsNonSemantic() && + !spvOpcodeIsDecoration(opcode) && opcode != spv::Op::OpFunction && + opcode != spv::Op::OpCooperativeMatrixLengthNV && + opcode != spv::Op::OpCooperativeMatrixLengthKHR && + !(opcode == spv::Op::OpSpecConstantOp && + (spv::Op(inst->word(3)) == + spv::Op::OpCooperativeMatrixLengthNV || + spv::Op(inst->word(3)) == + spv::Op::OpCooperativeMatrixLengthKHR))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Operand " << _.getIdName(operand_word) + << " cannot be a type"; + } else if (def->type_id() == 0 && !spvOpcodeGeneratesType(opcode) && + !spvOpcodeIsDebug(opcode) && !inst->IsDebugInfo() && + !inst->IsNonSemantic() && !spvOpcodeIsDecoration(opcode) && + !spvOpcodeIsBranch(opcode) && opcode != spv::Op::OpPhi && + opcode != spv::Op::OpExtInst && + opcode != spv::Op::OpExtInstImport && + opcode != spv::Op::OpSelectionMerge && + opcode != spv::Op::OpLoopMerge && + opcode != spv::Op::OpFunction && + opcode != spv::Op::OpCooperativeMatrixLengthNV && + opcode != spv::Op::OpCooperativeMatrixLengthKHR && + !(opcode == spv::Op::OpSpecConstantOp && + (spv::Op(inst->word(3)) == + spv::Op::OpCooperativeMatrixLengthNV || + spv::Op(inst->word(3)) == + spv::Op::OpCooperativeMatrixLengthKHR))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Operand " << _.getIdName(operand_word) + << " requires a type"; + } else if (def->IsNonSemantic() && !inst->IsNonSemantic()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Operand " << _.getIdName(operand_word) + << " in semantic instruction cannot be a non-semantic " + "instruction"; + } else { + ret = SPV_SUCCESS; + } + } else if (can_have_forward_declared_ids(i)) { + if (spvOpcodeGeneratesType(inst->opcode()) && + !_.IsForwardPointer(operand_word)) { + ret = _.diag(SPV_ERROR_INVALID_ID, inst) + << "Operand " << _.getIdName(operand_word) + << " requires a previous definition"; + } else { + ret = _.ForwardDeclareId(operand_word); + } + } else { + ret = _.diag(SPV_ERROR_INVALID_ID, inst) + << "ID " << _.getIdName(operand_word) + << " has not been defined"; + } + break; + case SPV_OPERAND_TYPE_TYPE_ID: + if (_.IsDefinedId(operand_word)) { + auto* def = _.FindDef(operand_word); + if (!spvOpcodeGeneratesType(def->opcode())) { + ret = _.diag(SPV_ERROR_INVALID_ID, inst) + << "ID " << _.getIdName(operand_word) << " is not a type id"; + } else { + ret = SPV_SUCCESS; + } + } else { + ret = _.diag(SPV_ERROR_INVALID_ID, inst) + << "ID " << _.getIdName(operand_word) + << " has not been defined"; + } + break; + default: + ret = SPV_SUCCESS; + break; + } + if (SPV_SUCCESS != ret) return ret; + } + if (result_id) _.RemoveIfForwardDeclared(result_id); + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_image.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_image.cpp new file mode 100644 index 000000000000..543f345ecd96 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_image.cpp @@ -0,0 +1,2423 @@ +// Copyright (c) 2017 Google Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of image instructions. + +#include + +#include "source/opcode.h" +#include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/util/bitutils.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validate_scopes.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Performs compile time check that all spv::ImageOperandsMask::XXX cases are +// handled in this module. If spv::ImageOperandsMask::XXX list changes, this +// function will fail the build. For all other purposes this is a placeholder +// function. +bool CheckAllImageOperandsHandled() { + spv::ImageOperandsMask enum_val = spv::ImageOperandsMask::Bias; + + // Some improvised code to prevent the compiler from considering enum_val + // constant and optimizing the switch away. + uint32_t stack_var = 0; + if (reinterpret_cast(&stack_var) % 256) + enum_val = spv::ImageOperandsMask::Lod; + + switch (enum_val) { + // Please update the validation rules in this module if you are changing + // the list of image operands, and add new enum values to this switch. + case spv::ImageOperandsMask::MaskNone: + return false; + case spv::ImageOperandsMask::Bias: + case spv::ImageOperandsMask::Lod: + case spv::ImageOperandsMask::Grad: + case spv::ImageOperandsMask::ConstOffset: + case spv::ImageOperandsMask::Offset: + case spv::ImageOperandsMask::ConstOffsets: + case spv::ImageOperandsMask::Sample: + case spv::ImageOperandsMask::MinLod: + + // TODO(dneto): Support image operands related to the Vulkan memory model. + // https://gitlab.khronos.org/spirv/spirv-tools/issues/32 + case spv::ImageOperandsMask::MakeTexelAvailableKHR: + case spv::ImageOperandsMask::MakeTexelVisibleKHR: + case spv::ImageOperandsMask::NonPrivateTexelKHR: + case spv::ImageOperandsMask::VolatileTexelKHR: + case spv::ImageOperandsMask::SignExtend: + case spv::ImageOperandsMask::ZeroExtend: + // TODO(jaebaek): Move this line properly after handling image offsets + // operand. This line temporarily fixes CI failure that + // blocks other PRs. + // https://github.com/KhronosGroup/SPIRV-Tools/issues/4565 + case spv::ImageOperandsMask::Offsets: + case spv::ImageOperandsMask::Nontemporal: + return true; + } + return false; +} + +// Used by GetImageTypeInfo. See OpTypeImage spec for more information. +struct ImageTypeInfo { + uint32_t sampled_type = 0; + spv::Dim dim = spv::Dim::Max; + uint32_t depth = 0; + uint32_t arrayed = 0; + uint32_t multisampled = 0; + uint32_t sampled = 0; + spv::ImageFormat format = spv::ImageFormat::Max; + spv::AccessQualifier access_qualifier = spv::AccessQualifier::Max; +}; + +// Provides information on image type. |id| should be object of either +// OpTypeImage or OpTypeSampledImage type. Returns false in case of failure +// (not a valid id, failed to parse the instruction, etc). +bool GetImageTypeInfo(const ValidationState_t& _, uint32_t id, + ImageTypeInfo* info) { + if (!id || !info) return false; + + const Instruction* inst = _.FindDef(id); + assert(inst); + + if (inst->opcode() == spv::Op::OpTypeSampledImage) { + inst = _.FindDef(inst->word(2)); + assert(inst); + } + + if (inst->opcode() != spv::Op::OpTypeImage) return false; + + const size_t num_words = inst->words().size(); + if (num_words != 9 && num_words != 10) return false; + + info->sampled_type = inst->word(2); + info->dim = static_cast(inst->word(3)); + info->depth = inst->word(4); + info->arrayed = inst->word(5); + info->multisampled = inst->word(6); + info->sampled = inst->word(7); + info->format = static_cast(inst->word(8)); + info->access_qualifier = + num_words < 10 ? spv::AccessQualifier::Max + : static_cast(inst->word(9)); + return true; +} + +bool IsImplicitLod(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + return true; + default: + break; + } + return false; +} + +bool IsExplicitLod(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + return true; + default: + break; + } + return false; +} + +bool IsValidLodOperand(const ValidationState_t& _, spv::Op opcode) { + switch (opcode) { + case spv::Op::OpImageRead: + case spv::Op::OpImageWrite: + case spv::Op::OpImageSparseRead: + return _.HasCapability(spv::Capability::ImageReadWriteLodAMD); + default: + return IsExplicitLod(opcode); + } +} + +bool IsValidGatherLodBiasAMD(const ValidationState_t& _, spv::Op opcode) { + switch (opcode) { + case spv::Op::OpImageGather: + case spv::Op::OpImageSparseGather: + return _.HasCapability(spv::Capability::ImageGatherBiasLodAMD); + default: + break; + } + return false; +} + +// Returns true if the opcode is a Image instruction which applies +// homogenous projection to the coordinates. +bool IsProj(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + return true; + default: + break; + } + return false; +} + +// Returns the number of components in a coordinate used to access a texel in +// a single plane of an image with the given parameters. +uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) { + uint32_t plane_size = 0; + // If this switch breaks your build, please add new values below. + switch (info.dim) { + case spv::Dim::Dim1D: + case spv::Dim::Buffer: + plane_size = 1; + break; + case spv::Dim::Dim2D: + case spv::Dim::Rect: + case spv::Dim::SubpassData: + case spv::Dim::TileImageDataEXT: + plane_size = 2; + break; + case spv::Dim::Dim3D: + case spv::Dim::Cube: + // For Cube direction vector is used instead of UV. + plane_size = 3; + break; + case spv::Dim::Max: + default: + assert(0); + break; + } + + return plane_size; +} + +// Returns minimal number of coordinates based on image dim, arrayed and whether +// the instruction uses projection coordinates. +uint32_t GetMinCoordSize(spv::Op opcode, const ImageTypeInfo& info) { + if (info.dim == spv::Dim::Cube && + (opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite || + opcode == spv::Op::OpImageSparseRead)) { + // These opcodes use UV for Cube, not direction vector. + return 3; + } + + return GetPlaneCoordSize(info) + info.arrayed + (IsProj(opcode) ? 1 : 0); +} + +// Checks ImageOperand bitfield and respective operands. +// word_index is the index of the first word after the image-operand mask word. +spv_result_t ValidateImageOperands(ValidationState_t& _, + const Instruction* inst, + const ImageTypeInfo& info, + uint32_t word_index) { + static const bool kAllImageOperandsHandled = CheckAllImageOperandsHandled(); + (void)kAllImageOperandsHandled; + + const spv::Op opcode = inst->opcode(); + const size_t num_words = inst->words().size(); + + const bool have_explicit_mask = (word_index - 1 < num_words); + const uint32_t mask = have_explicit_mask ? inst->word(word_index - 1) : 0u; + + if (have_explicit_mask) { + // NonPrivate, Volatile, SignExtend, ZeroExtend take no operand words. + const uint32_t mask_bits_having_operands = + mask & ~uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR | + spv::ImageOperandsMask::VolatileTexelKHR | + spv::ImageOperandsMask::SignExtend | + spv::ImageOperandsMask::ZeroExtend | + spv::ImageOperandsMask::Nontemporal); + size_t expected_num_image_operand_words = + spvtools::utils::CountSetBits(mask_bits_having_operands); + if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { + // Grad uses two words. + ++expected_num_image_operand_words; + } + + if (expected_num_image_operand_words != num_words - word_index) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Number of image operand ids doesn't correspond to the bit " + "mask"; + } + } else if (num_words != word_index - 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Number of image operand ids doesn't correspond to the bit mask"; + } + + if (info.multisampled & + (0 == (mask & uint32_t(spv::ImageOperandsMask::Sample)))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Sample is required for operation on " + "multi-sampled image"; + } + + // After this point, only set bits in the image operands mask can cause + // the module to be invalid. + if (mask == 0) return SPV_SUCCESS; + + if (spvtools::utils::CountSetBits( + mask & uint32_t(spv::ImageOperandsMask::Offset | + spv::ImageOperandsMask::ConstOffset | + spv::ImageOperandsMask::ConstOffsets | + spv::ImageOperandsMask::Offsets)) > 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operands Offset, ConstOffset, ConstOffsets, Offsets " + "cannot be used together"; + } + + const bool is_implicit_lod = IsImplicitLod(opcode); + const bool is_explicit_lod = IsExplicitLod(opcode); + const bool is_valid_lod_operand = IsValidLodOperand(_, opcode); + const bool is_valid_gather_lod_bias_amd = IsValidGatherLodBiasAMD(_, opcode); + + // The checks should be done in the order of definition of OperandImage. + + if (mask & uint32_t(spv::ImageOperandsMask::Bias)) { + if (!is_implicit_lod && !is_valid_gather_lod_bias_amd) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Bias can only be used with ImplicitLod opcodes"; + } + + const uint32_t type_id = _.GetTypeId(inst->word(word_index++)); + if (!_.IsFloatScalarType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand Bias to be float scalar"; + } + + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Bias requires 'Dim' parameter to be 1D, 2D, 3D " + "or Cube"; + } + + // Multisampled is already checked. + } + + if (mask & uint32_t(spv::ImageOperandsMask::Lod)) { + if (!is_valid_lod_operand && opcode != spv::Op::OpImageFetch && + opcode != spv::Op::OpImageSparseFetch && + !is_valid_gather_lod_bias_amd) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Lod can only be used with ExplicitLod opcodes " + << "and OpImageFetch"; + } + + if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand bits Lod and Grad cannot be set at the same " + "time"; + } + + const uint32_t type_id = _.GetTypeId(inst->word(word_index++)); + if (is_explicit_lod || is_valid_gather_lod_bias_amd) { + if (!_.IsFloatScalarType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand Lod to be float scalar when used " + << "with ExplicitLod"; + } + } else { + if (!_.IsIntScalarType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand Lod to be int scalar when used with " + << "OpImageFetch"; + } + } + + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Lod requires 'Dim' parameter to be 1D, 2D, 3D " + "or Cube"; + } + + // Multisampled is already checked. + } + + if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { + if (!is_explicit_lod) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Grad can only be used with ExplicitLod opcodes"; + } + + const uint32_t dx_type_id = _.GetTypeId(inst->word(word_index++)); + const uint32_t dy_type_id = _.GetTypeId(inst->word(word_index++)); + if (!_.IsFloatScalarOrVectorType(dx_type_id) || + !_.IsFloatScalarOrVectorType(dy_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected both Image Operand Grad ids to be float scalars or " + << "vectors"; + } + + const uint32_t plane_size = GetPlaneCoordSize(info); + const uint32_t dx_size = _.GetDimension(dx_type_id); + const uint32_t dy_size = _.GetDimension(dy_type_id); + if (plane_size != dx_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand Grad dx to have " << plane_size + << " components, but given " << dx_size; + } + + if (plane_size != dy_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand Grad dy to have " << plane_size + << " components, but given " << dy_size; + } + + // Multisampled is already checked. + } + + if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { + if (info.dim == spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand ConstOffset cannot be used with Cube Image " + "'Dim'"; + } + + const uint32_t id = inst->word(word_index++); + const uint32_t type_id = _.GetTypeId(id); + if (!_.IsIntScalarOrVectorType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand ConstOffset to be int scalar or " + << "vector"; + } + + if (!spvOpcodeIsConstant(_.GetIdOpcode(id))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand ConstOffset to be a const object"; + } + + const uint32_t plane_size = GetPlaneCoordSize(info); + const uint32_t offset_size = _.GetDimension(type_id); + if (plane_size != offset_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand ConstOffset to have " << plane_size + << " components, but given " << offset_size; + } + } + + if (mask & uint32_t(spv::ImageOperandsMask::Offset)) { + if (info.dim == spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Offset cannot be used with Cube Image 'Dim'"; + } + + const uint32_t id = inst->word(word_index++); + const uint32_t type_id = _.GetTypeId(id); + if (!_.IsIntScalarOrVectorType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand Offset to be int scalar or " + << "vector"; + } + + const uint32_t plane_size = GetPlaneCoordSize(info); + const uint32_t offset_size = _.GetDimension(type_id); + if (plane_size != offset_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand Offset to have " << plane_size + << " components, but given " << offset_size; + } + + if (!_.options()->before_hlsl_legalization && + spvIsVulkanEnv(_.context()->target_env)) { + if (opcode != spv::Op::OpImageGather && + opcode != spv::Op::OpImageDrefGather && + opcode != spv::Op::OpImageSparseGather && + opcode != spv::Op::OpImageSparseDrefGather) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4663) + << "Image Operand Offset can only be used with " + "OpImage*Gather operations"; + } + } + } + + if (mask & uint32_t(spv::ImageOperandsMask::ConstOffsets)) { + if (opcode != spv::Op::OpImageGather && + opcode != spv::Op::OpImageDrefGather && + opcode != spv::Op::OpImageSparseGather && + opcode != spv::Op::OpImageSparseDrefGather) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand ConstOffsets can only be used with " + "OpImageGather and OpImageDrefGather"; + } + + if (info.dim == spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand ConstOffsets cannot be used with Cube Image " + "'Dim'"; + } + + const uint32_t id = inst->word(word_index++); + const uint32_t type_id = _.GetTypeId(id); + const Instruction* type_inst = _.FindDef(type_id); + assert(type_inst); + + if (type_inst->opcode() != spv::Op::OpTypeArray) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand ConstOffsets to be an array of size 4"; + } + + uint64_t array_size = 0; + if (!_.EvalConstantValUint64(type_inst->word(3), &array_size)) { + assert(0 && "Array type definition is corrupt"); + } + + if (array_size != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand ConstOffsets to be an array of size 4"; + } + + const uint32_t component_type = type_inst->word(2); + if (!_.IsIntVectorType(component_type) || + _.GetDimension(component_type) != 2) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand ConstOffsets array components to be " + "int vectors of size 2"; + } + + if (!spvOpcodeIsConstant(_.GetIdOpcode(id))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand ConstOffsets to be a const object"; + } + } + + if (mask & uint32_t(spv::ImageOperandsMask::Sample)) { + if (opcode != spv::Op::OpImageFetch && opcode != spv::Op::OpImageRead && + opcode != spv::Op::OpImageWrite && + opcode != spv::Op::OpImageSparseFetch && + opcode != spv::Op::OpImageSparseRead) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Sample can only be used with OpImageFetch, " + << "OpImageRead, OpImageWrite, OpImageSparseFetch and " + << "OpImageSparseRead"; + } + + if (info.multisampled == 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand Sample requires non-zero 'MS' parameter"; + } + + const uint32_t type_id = _.GetTypeId(inst->word(word_index++)); + if (!_.IsIntScalarType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand Sample to be int scalar"; + } + } + + if (mask & uint32_t(spv::ImageOperandsMask::MinLod)) { + if (!is_implicit_lod && !(mask & uint32_t(spv::ImageOperandsMask::Grad))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand MinLod can only be used with ImplicitLod " + << "opcodes or together with Image Operand Grad"; + } + + const uint32_t type_id = _.GetTypeId(inst->word(word_index++)); + if (!_.IsFloatScalarType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image Operand MinLod to be float scalar"; + } + + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand MinLod requires 'Dim' parameter to be 1D, 2D, " + "3D or Cube"; + } + + if (info.multisampled != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand MinLod requires 'MS' parameter to be 0"; + } + } + + if (mask & uint32_t(spv::ImageOperandsMask::MakeTexelAvailableKHR)) { + // Checked elsewhere: capability and memory model are correct. + if (opcode != spv::Op::OpImageWrite) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand MakeTexelAvailableKHR can only be used with Op" + << spvOpcodeString(spv::Op::OpImageWrite) << ": Op" + << spvOpcodeString(opcode); + } + + if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand MakeTexelAvailableKHR requires " + "NonPrivateTexelKHR is also specified: Op" + << spvOpcodeString(opcode); + } + + const auto available_scope = inst->word(word_index++); + if (auto error = ValidateMemoryScope(_, inst, available_scope)) + return error; + } + + if (mask & uint32_t(spv::ImageOperandsMask::MakeTexelVisibleKHR)) { + // Checked elsewhere: capability and memory model are correct. + if (opcode != spv::Op::OpImageRead && + opcode != spv::Op::OpImageSparseRead) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand MakeTexelVisibleKHR can only be used with Op" + << spvOpcodeString(spv::Op::OpImageRead) << " or Op" + << spvOpcodeString(spv::Op::OpImageSparseRead) << ": Op" + << spvOpcodeString(opcode); + } + + if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Operand MakeTexelVisibleKHR requires NonPrivateTexelKHR " + "is also specified: Op" + << spvOpcodeString(opcode); + } + + const auto visible_scope = inst->word(word_index++); + if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error; + } + + if (mask & uint32_t(spv::ImageOperandsMask::SignExtend)) { + // Checked elsewhere: SPIR-V 1.4 version or later. + + // "The texel value is converted to the target value via sign extension. + // Only valid when the texel type is a scalar or vector of integer type." + // + // We don't have enough information to know what the texel type is. + // In OpenCL, knowledge is deferred until runtime: the image SampledType is + // void, and the Format is Unknown. + // In Vulkan, the texel type is only known in all cases by the pipeline + // setup. + } + + if (mask & uint32_t(spv::ImageOperandsMask::ZeroExtend)) { + // Checked elsewhere: SPIR-V 1.4 version or later. + + // "The texel value is converted to the target value via zero extension. + // Only valid when the texel type is a scalar or vector of integer type." + // + // We don't have enough information to know what the texel type is. + // In OpenCL, knowledge is deferred until runtime: the image SampledType is + // void, and the Format is Unknown. + // In Vulkan, the texel type is only known in all cases by the pipeline + // setup. + } + + if (mask & uint32_t(spv::ImageOperandsMask::Offsets)) { + // TODO: add validation + } + + if (mask & uint32_t(spv::ImageOperandsMask::Nontemporal)) { + // Checked elsewhere: SPIR-V 1.6 version or later. + } + + return SPV_SUCCESS; +} + +// Validate OpImage*Proj* instructions +spv_result_t ValidateImageProj(ValidationState_t& _, const Instruction* inst, + const ImageTypeInfo& info) { + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Rect) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Dim' parameter to be 1D, 2D, 3D or Rect"; + } + + if (info.multisampled != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'MS' parameter to be 0"; + } + + if (info.arrayed != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'arrayed' parameter to be 0"; + } + + return SPV_SUCCESS; +} + +// Validate OpImage*Read and OpImage*Write instructions +spv_result_t ValidateImageReadWrite(ValidationState_t& _, + const Instruction* inst, + const ImageTypeInfo& info) { + if (info.sampled == 2) { + if (info.dim == spv::Dim::Dim1D && + !_.HasCapability(spv::Capability::Image1D)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability Image1D is required to access storage image"; + } else if (info.dim == spv::Dim::Rect && + !_.HasCapability(spv::Capability::ImageRect)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability ImageRect is required to access storage image"; + } else if (info.dim == spv::Dim::Buffer && + !_.HasCapability(spv::Capability::ImageBuffer)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability ImageBuffer is required to access storage image"; + } else if (info.dim == spv::Dim::Cube && info.arrayed == 1 && + !_.HasCapability(spv::Capability::ImageCubeArray)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability ImageCubeArray is required to access " + << "storage image"; + } + + if (info.multisampled == 1 && info.arrayed == 1 && info.sampled == 2 && + !_.HasCapability(spv::Capability::ImageMSArray)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability ImageMSArray is required to access storage " + << "image"; + } + } else if (info.sampled != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled' parameter to be 0 or 2"; + } + + return SPV_SUCCESS; +} + +// Returns true if opcode is *ImageSparse*, false otherwise. +bool IsSparse(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpImageSparseTexelsResident: + case spv::Op::OpImageSparseRead: { + return true; + } + + default: { return false; } + } + + return false; +} + +// Checks sparse image opcode result type and returns the second struct member. +// Returns inst.type_id for non-sparse image opcodes. +// Not valid for sparse image opcodes which do not return a struct. +spv_result_t GetActualResultType(ValidationState_t& _, const Instruction* inst, + uint32_t* actual_result_type) { + const spv::Op opcode = inst->opcode(); + + if (IsSparse(opcode)) { + const Instruction* const type_inst = _.FindDef(inst->type_id()); + assert(type_inst); + + if (!type_inst || type_inst->opcode() != spv::Op::OpTypeStruct) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be OpTypeStruct"; + } + + if (type_inst->words().size() != 4 || + !_.IsIntScalarType(type_inst->word(2))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a struct containing an int " + "scalar and a texel"; + } + + *actual_result_type = type_inst->word(3); + } else { + *actual_result_type = inst->type_id(); + } + + return SPV_SUCCESS; +} + +// Returns a string describing actual result type of an opcode. +// Not valid for sparse image opcodes which do not return a struct. +const char* GetActualResultTypeStr(spv::Op opcode) { + if (IsSparse(opcode)) return "Result Type's second member"; + return "Result Type"; +} + +spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { + assert(inst->type_id() == 0); + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, inst->word(1), &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (_.IsIntScalarType(info.sampled_type) && + (64 == _.GetBitWidth(info.sampled_type)) && + !_.HasCapability(spv::Capability::Int64ImageEXT)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability Int64ImageEXT is required when using Sampled Type of " + "64-bit int"; + } + + const auto target_env = _.context()->target_env; + if (spvIsVulkanEnv(target_env)) { + if ((!_.IsFloatScalarType(info.sampled_type) && + !_.IsIntScalarType(info.sampled_type)) || + ((32 != _.GetBitWidth(info.sampled_type)) && + (64 != _.GetBitWidth(info.sampled_type))) || + ((64 == _.GetBitWidth(info.sampled_type)) && + _.IsFloatScalarType(info.sampled_type))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4656) + << "Expected Sampled Type to be a 32-bit int, 64-bit int or " + "32-bit float scalar type for Vulkan environment"; + } + } else if (spvIsOpenCLEnv(target_env)) { + if (!_.IsVoidType(info.sampled_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Sampled Type must be OpTypeVoid in the OpenCL environment."; + } + } else { + const spv::Op sampled_type_opcode = _.GetIdOpcode(info.sampled_type); + if (sampled_type_opcode != spv::Op::OpTypeVoid && + sampled_type_opcode != spv::Op::OpTypeInt && + sampled_type_opcode != spv::Op::OpTypeFloat) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sampled Type to be either void or" + << " numerical scalar type"; + } + } + + // Universal checks on image type operands + // Dim and Format and Access Qualifier are checked elsewhere. + + if (info.depth > 2) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Invalid Depth " << info.depth << " (must be 0, 1 or 2)"; + } + + if (info.arrayed > 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)"; + } + + if (info.multisampled > 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Invalid MS " << info.multisampled << " (must be 0 or 1)"; + } + + if (info.sampled > 2) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)"; + } + + if (info.dim == spv::Dim::SubpassData) { + if (info.sampled != 2) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(6214) << "Dim SubpassData requires Sampled to be 2"; + } + + if (info.format != spv::ImageFormat::Unknown) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Dim SubpassData requires format Unknown"; + } + } else if (info.dim == spv::Dim::TileImageDataEXT) { + if (_.IsVoidType(info.sampled_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Dim TileImageDataEXT requires Sampled Type to be not " + "OpTypeVoid"; + } + if (info.sampled != 2) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Dim TileImageDataEXT requires Sampled to be 2"; + } + if (info.format != spv::ImageFormat::Unknown) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Dim TileImageDataEXT requires format Unknown"; + } + if (info.depth != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Dim TileImageDataEXT requires Depth to be 0"; + } + if (info.arrayed != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Dim TileImageDataEXT requires Arrayed to be 0"; + } + } else { + if (info.multisampled && (info.sampled == 2) && + !_.HasCapability(spv::Capability::StorageImageMultisample)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability StorageImageMultisample is required when using " + "multisampled storage image"; + } + } + + if (spvIsOpenCLEnv(target_env)) { + if ((info.arrayed == 1) && (info.dim != spv::Dim::Dim1D) && + (info.dim != spv::Dim::Dim2D)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "In the OpenCL environment, Arrayed may only be set to 1 " + << "when Dim is either 1D or 2D."; + } + + if (info.multisampled != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "MS must be 0 in the OpenCL environment."; + } + + if (info.sampled != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Sampled must be 0 in the OpenCL environment."; + } + + if (info.access_qualifier == spv::AccessQualifier::Max) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "In the OpenCL environment, the optional Access Qualifier" + << " must be present."; + } + } + + if (spvIsVulkanEnv(target_env)) { + if (info.sampled == 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4657) + << "Sampled must be 1 or 2 in the Vulkan environment."; + } + + if (info.dim == spv::Dim::SubpassData && info.arrayed != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(6214) << "Dim SubpassData requires Arrayed to be 0"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeSampledImage(ValidationState_t& _, + const Instruction* inst) { + const uint32_t image_type = inst->word(2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be of type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + // OpenCL requires Sampled=0, checked elsewhere. + // Vulkan uses the Sampled=1 case. + // If Dim is TileImageDataEXT, Sampled must be 2 and this is validated + // elsewhere. + if ((info.sampled != 0) && (info.sampled != 1)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4657) + << "Sampled image type requires an image type with \"Sampled\" " + "operand set to 0 or 1"; + } + + // This covers both OpTypeSampledImage and OpSampledImage. + if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) && + info.dim == spv::Dim::Buffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "In SPIR-V 1.6 or later, sampled image dimension must not be " + "Buffer"; + } + + return SPV_SUCCESS; +} + +bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) { + switch (opcode) { + case spv::Op::OpSampledImage: + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImage: + case spv::Op::OpImageQueryLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpCopyObject: + case spv::Op::OpImageSampleWeightedQCOM: + case spv::Op::OpImageBoxFilterQCOM: + case spv::Op::OpImageBlockMatchSSDQCOM: + case spv::Op::OpImageBlockMatchSADQCOM: + return true; + case spv::Op::OpStore: + if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true; + return false; + default: + return false; + } +} + +spv_result_t ValidateSampledImage(ValidationState_t& _, + const Instruction* inst) { + if (_.GetIdOpcode(inst->type_id()) != spv::Op::OpTypeSampledImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be OpTypeSampledImage."; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be of type OpTypeImage."; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + // TODO(atgoo@github.com) Check compatibility of result type and received + // image. + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (info.sampled != 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(6671) + << "Expected Image 'Sampled' parameter to be 1 for Vulkan " + "environment."; + } + } else { + if (info.sampled != 0 && info.sampled != 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled' parameter to be 0 or 1"; + } + } + + if (info.dim == spv::Dim::SubpassData) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Dim' parameter to be not SubpassData."; + } + + if (_.GetIdOpcode(_.GetOperandTypeId(inst, 3)) != spv::Op::OpTypeSampler) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sampler to be of type OpTypeSampler"; + } + + // We need to validate 2 things: + // * All OpSampledImage instructions must be in the same block in which their + // Result are consumed. + // * Result from OpSampledImage instructions must not appear as operands + // to OpPhi instructions or OpSelect instructions, or any instructions other + // than the image lookup and query instructions specified to take an operand + // whose type is OpTypeSampledImage. + std::vector consumers = _.getSampledImageConsumers(inst->id()); + if (!consumers.empty()) { + for (auto consumer_instr : consumers) { + const auto consumer_opcode = consumer_instr->opcode(); + if (consumer_instr->block() != inst->block()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "All OpSampledImage instructions must be in the same block " + "in " + "which their Result are consumed. OpSampledImage Result " + "Type " + << _.getIdName(inst->id()) + << " has a consumer in a different basic " + "block. The consumer instruction is " + << _.getIdName(consumer_instr->id()) << "."; + } + + if (consumer_opcode == spv::Op::OpPhi || + consumer_opcode == spv::Op::OpSelect) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result from OpSampledImage instruction must not appear " + "as " + "operands of Op" + << spvOpcodeString(static_cast(consumer_opcode)) << "." + << " Found result " << _.getIdName(inst->id()) + << " as an operand of " << _.getIdName(consumer_instr->id()) + << "."; + } + + if (!IsAllowedSampledImageOperand(consumer_opcode, _)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result from OpSampledImage instruction must not appear " + "as operand for Op" + << spvOpcodeString(static_cast(consumer_opcode)) + << ", since it is not specified as taking an " + << "OpTypeSampledImage." + << " Found result " << _.getIdName(inst->id()) + << " as an operand of " << _.getIdName(consumer_instr->id()) + << "."; + } + } + } + + const Instruction* ld_inst; + { + int t_idx = inst->GetOperandAs(2); + ld_inst = _.FindDef(t_idx); + } + + if (ld_inst->opcode() == spv::Op::OpLoad) { + int texture_id = ld_inst->GetOperandAs(2); // variable to load + _.RegisterQCOMImageProcessingTextureConsumer(texture_id, ld_inst, inst); + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageTexelPointer(ValidationState_t& _, + const Instruction* inst) { + const auto result_type = _.FindDef(inst->type_id()); + if (result_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be OpTypePointer"; + } + + const auto storage_class = result_type->GetOperandAs(1); + if (storage_class != spv::StorageClass::Image) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be OpTypePointer whose Storage Class " + "operand is Image"; + } + + const auto ptr_type = result_type->GetOperandAs(2); + const auto ptr_opcode = _.GetIdOpcode(ptr_type); + if (ptr_opcode != spv::Op::OpTypeInt && ptr_opcode != spv::Op::OpTypeFloat && + ptr_opcode != spv::Op::OpTypeVoid && + !(ptr_opcode == spv::Op::OpTypeVector && + _.HasCapability(spv::Capability::AtomicFloat16VectorNV) && + _.IsFloat16Vector2Or4Type(ptr_type))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be OpTypePointer whose Type operand " + "must be a scalar numerical type or OpTypeVoid"; + } + + const auto image_ptr = _.FindDef(_.GetOperandTypeId(inst, 2)); + if (!image_ptr || image_ptr->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be OpTypePointer"; + } + + const auto image_type = image_ptr->GetOperandAs(2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be OpTypePointer with Type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (info.sampled_type != ptr_type && + !(_.HasCapability(spv::Capability::AtomicFloat16VectorNV) && + _.IsFloat16Vector2Or4Type(ptr_type) && + _.GetIdOpcode(info.sampled_type) == spv::Op::OpTypeFloat && + ((_.GetDimension(ptr_type) == 2 && + info.format == spv::ImageFormat::Rg16f) || + (_.GetDimension(ptr_type) == 4 && + info.format == spv::ImageFormat::Rgba16f)))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled Type' to be the same as the Type " + "pointed to by Result Type"; + } + + if (info.dim == spv::Dim::SubpassData) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Dim SubpassData cannot be used with OpImageTexelPointer"; + } + + if (info.dim == spv::Dim::TileImageDataEXT) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Dim TileImageDataEXT cannot be used with " + "OpImageTexelPointer"; + } + + const uint32_t coord_type = _.GetOperandTypeId(inst, 3); + if (!coord_type || !_.IsIntScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be integer scalar or vector"; + } + + uint32_t expected_coord_size = 0; + if (info.arrayed == 0) { + expected_coord_size = GetPlaneCoordSize(info); + } else if (info.arrayed == 1) { + switch (info.dim) { + case spv::Dim::Dim1D: + expected_coord_size = 2; + break; + case spv::Dim::Cube: + case spv::Dim::Dim2D: + expected_coord_size = 3; + break; + default: + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Dim' must be one of 1D, 2D, or Cube when " + "Arrayed is 1"; + break; + } + } + + const uint32_t actual_coord_size = _.GetDimension(coord_type); + if (expected_coord_size != actual_coord_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to have " << expected_coord_size + << " components, but given " << actual_coord_size; + } + + const uint32_t sample_type = _.GetOperandTypeId(inst, 4); + if (!sample_type || !_.IsIntScalarType(sample_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sample to be integer scalar"; + } + + if (info.multisampled == 0) { + uint64_t ms = 0; + if (!_.EvalConstantValUint64(inst->GetOperandAs(4), &ms) || + ms != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sample for Image with MS 0 to be a valid for " + "the value 0"; + } + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if ((info.format != spv::ImageFormat::R64i) && + (info.format != spv::ImageFormat::R64ui) && + (info.format != spv::ImageFormat::R32f) && + (info.format != spv::ImageFormat::R32i) && + (info.format != spv::ImageFormat::R32ui) && + !((info.format == spv::ImageFormat::Rg16f || + info.format == spv::ImageFormat::Rgba16f) && + _.HasCapability(spv::Capability::AtomicFloat16VectorNV))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4658) + << "Expected the Image Format in Image to be R64i, R64ui, R32f, " + "R32i, or R32ui for Vulkan environment"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + uint32_t actual_result_type = 0; + if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { + return error; + } + + if (!_.IsIntVectorType(actual_result_type) && + !_.IsFloatVectorType(actual_result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to be int or float vector type"; + } + + if (_.GetDimension(actual_result_type) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to have 4 components"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sampled Image to be of type OpTypeSampledImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (IsProj(opcode)) { + if (spv_result_t result = ValidateImageProj(_, inst, info)) return result; + } + + if (info.multisampled) { + // When using image operands, the Sample image operand is required if and + // only if the image is multisampled (MS=1). The Sample image operand is + // only allowed for fetch, read, and write. + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Sampling operation is invalid for multisample image"; + } + + if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + const uint32_t texel_component_type = + _.GetComponentType(actual_result_type); + if (texel_component_type != info.sampled_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled Type' to be the same as " + << GetActualResultTypeStr(opcode) << " components"; + } + } + + const uint32_t coord_type = _.GetOperandTypeId(inst, 3); + if ((opcode == spv::Op::OpImageSampleExplicitLod || + opcode == spv::Op::OpImageSparseSampleExplicitLod) && + _.HasCapability(spv::Capability::Kernel)) { + if (!_.IsFloatScalarOrVectorType(coord_type) && + !_.IsIntScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be int or float scalar or vector"; + } + } else { + if (!_.IsFloatScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be float scalar or vector"; + } + } + + const uint32_t min_coord_size = GetMinCoordSize(opcode, info); + const uint32_t actual_coord_size = _.GetDimension(coord_type); + if (min_coord_size > actual_coord_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to have at least " << min_coord_size + << " components, but given only " << actual_coord_size; + } + + const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5); + + if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { + if (spvIsOpenCLEnv(_.context()->target_env)) { + if (opcode == spv::Op::OpImageSampleExplicitLod) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ConstOffset image operand not allowed " + << "in the OpenCL environment."; + } + } + } + + if (spv_result_t result = + ValidateImageOperands(_, inst, info, /* word_index = */ 6)) + return result; + + return SPV_SUCCESS; +} + +// Validates anything OpImage*Dref* instruction +spv_result_t ValidateImageDref(ValidationState_t& _, const Instruction* inst, + const ImageTypeInfo& info) { + const uint32_t dref_type = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Dref to be of 32-bit float type"; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (info.dim == spv::Dim::Dim3D) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4777) + << "In Vulkan, OpImage*Dref* instructions must not use images " + "with a 3D Dim"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageDrefLod(ValidationState_t& _, + const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + uint32_t actual_result_type = 0; + if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { + return error; + } + + if (!_.IsIntScalarType(actual_result_type) && + !_.IsFloatScalarType(actual_result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to be int or float scalar type"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sampled Image to be of type OpTypeSampledImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (IsProj(opcode)) { + if (spv_result_t result = ValidateImageProj(_, inst, info)) return result; + } + + if (info.multisampled) { + // When using image operands, the Sample image operand is required if and + // only if the image is multisampled (MS=1). The Sample image operand is + // only allowed for fetch, read, and write. + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Dref sampling operation is invalid for multisample image"; + } + + if (actual_result_type != info.sampled_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled Type' to be the same as " + << GetActualResultTypeStr(opcode); + } + + const uint32_t coord_type = _.GetOperandTypeId(inst, 3); + if (!_.IsFloatScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be float scalar or vector"; + } + + const uint32_t min_coord_size = GetMinCoordSize(opcode, info); + const uint32_t actual_coord_size = _.GetDimension(coord_type); + if (min_coord_size > actual_coord_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to have at least " << min_coord_size + << " components, but given only " << actual_coord_size; + } + + if (spv_result_t result = ValidateImageDref(_, inst, info)) return result; + + if (spv_result_t result = + ValidateImageOperands(_, inst, info, /* word_index = */ 7)) + return result; + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { + uint32_t actual_result_type = 0; + if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { + return error; + } + + const spv::Op opcode = inst->opcode(); + if (!_.IsIntVectorType(actual_result_type) && + !_.IsFloatVectorType(actual_result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to be int or float vector type"; + } + + if (_.GetDimension(actual_result_type) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to have 4 components"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be of type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + const uint32_t result_component_type = + _.GetComponentType(actual_result_type); + if (result_component_type != info.sampled_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled Type' to be the same as " + << GetActualResultTypeStr(opcode) << " components"; + } + } + + if (info.dim == spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' cannot be Cube"; + } + + if (info.sampled != 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled' parameter to be 1"; + } + + const uint32_t coord_type = _.GetOperandTypeId(inst, 3); + if (!_.IsIntScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be int scalar or vector"; + } + + const uint32_t min_coord_size = GetMinCoordSize(opcode, info); + const uint32_t actual_coord_size = _.GetDimension(coord_type); + if (min_coord_size > actual_coord_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to have at least " << min_coord_size + << " components, but given only " << actual_coord_size; + } + + if (spv_result_t result = + ValidateImageOperands(_, inst, info, /* word_index = */ 6)) + return result; + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageGather(ValidationState_t& _, + const Instruction* inst) { + uint32_t actual_result_type = 0; + if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) + return error; + + const spv::Op opcode = inst->opcode(); + if (!_.IsIntVectorType(actual_result_type) && + !_.IsFloatVectorType(actual_result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to be int or float vector type"; + } + + if (_.GetDimension(actual_result_type) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to have 4 components"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sampled Image to be of type OpTypeSampledImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (info.multisampled) { + // When using image operands, the Sample image operand is required if and + // only if the image is multisampled (MS=1). The Sample image operand is + // only allowed for fetch, read, and write. + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Gather operation is invalid for multisample image"; + } + + if (opcode == spv::Op::OpImageDrefGather || + opcode == spv::Op::OpImageSparseDrefGather || + _.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + const uint32_t result_component_type = + _.GetComponentType(actual_result_type); + if (result_component_type != info.sampled_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled Type' to be the same as " + << GetActualResultTypeStr(opcode) << " components"; + } + } + + if (info.dim != spv::Dim::Dim2D && info.dim != spv::Dim::Cube && + info.dim != spv::Dim::Rect) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4777) + << "Expected Image 'Dim' to be 2D, Cube, or Rect"; + } + + const uint32_t coord_type = _.GetOperandTypeId(inst, 3); + if (!_.IsFloatScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be float scalar or vector"; + } + + const uint32_t min_coord_size = GetMinCoordSize(opcode, info); + const uint32_t actual_coord_size = _.GetDimension(coord_type); + if (min_coord_size > actual_coord_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to have at least " << min_coord_size + << " components, but given only " << actual_coord_size; + } + + if (opcode == spv::Op::OpImageGather || + opcode == spv::Op::OpImageSparseGather) { + const uint32_t component = inst->GetOperandAs(4); + const uint32_t component_index_type = _.GetTypeId(component); + if (!_.IsIntScalarType(component_index_type) || + _.GetBitWidth(component_index_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Component to be 32-bit int scalar"; + } + if (spvIsVulkanEnv(_.context()->target_env)) { + if (!spvOpcodeIsConstant(_.GetIdOpcode(component))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4664) + << "Expected Component Operand to be a const object for Vulkan " + "environment"; + } + } + } else { + assert(opcode == spv::Op::OpImageDrefGather || + opcode == spv::Op::OpImageSparseDrefGather); + if (spv_result_t result = ValidateImageDref(_, inst, info)) return result; + } + + if (spv_result_t result = + ValidateImageOperands(_, inst, info, /* word_index = */ 7)) + return result; + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + uint32_t actual_result_type = 0; + if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { + return error; + } + + if (!_.IsIntScalarOrVectorType(actual_result_type) && + !_.IsFloatScalarOrVectorType(actual_result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to be int or float scalar or vector type"; + } + + const auto target_env = _.context()->target_env; + // Vulkan requires the result to be a 4-element int or float + // vector. + if (spvIsVulkanEnv(target_env)) { + if (_.GetDimension(actual_result_type) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4780) << "Expected " + << GetActualResultTypeStr(opcode) << " to have 4 components"; + } + } // Check OpenCL below, after we get the image info. + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be of type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (spvIsOpenCLEnv(target_env)) { + // In OpenCL, a read from a depth image returns a scalar float. In other + // cases, the result is always a 4-element vector. + // https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Env.html#_data_format_for_reading_and_writing_images + // https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_C.html#image-read-and-write-functions + // The builtins for reading depth images are: + // float read_imagef(aQual image2d_depth_t image, int2 coord) + // float read_imagef(aQual image2d_array_depth_t image, int4 coord) + if (info.depth) { + if (!_.IsFloatScalarType(actual_result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " from a depth image read to result in a scalar float value"; + } + } else { + if (_.GetDimension(actual_result_type) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected " << GetActualResultTypeStr(opcode) + << " to have 4 components"; + } + } + + const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5); + if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ConstOffset image operand not allowed " + << "in the OpenCL environment."; + } + } + + if (info.dim == spv::Dim::SubpassData) { + if (opcode == spv::Op::OpImageSparseRead) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Dim SubpassData cannot be used with ImageSparseRead"; + } + + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + spv::ExecutionModel::Fragment, + std::string("Dim SubpassData requires Fragment execution model: ") + + spvOpcodeString(opcode)); + } + + if (info.dim == spv::Dim::TileImageDataEXT) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image Dim TileImageDataEXT cannot be used with " + << spvOpcodeString(opcode); + } + + if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + const uint32_t result_component_type = + _.GetComponentType(actual_result_type); + if (result_component_type != info.sampled_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled Type' to be the same as " + << GetActualResultTypeStr(opcode) << " components"; + } + } + + if (spv_result_t result = ValidateImageReadWrite(_, inst, info)) + return result; + + const uint32_t coord_type = _.GetOperandTypeId(inst, 3); + if (!_.IsIntScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be int scalar or vector"; + } + + const uint32_t min_coord_size = GetMinCoordSize(opcode, info); + const uint32_t actual_coord_size = _.GetDimension(coord_type); + if (min_coord_size > actual_coord_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to have at least " << min_coord_size + << " components, but given only " << actual_coord_size; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (info.format == spv::ImageFormat::Unknown && + info.dim != spv::Dim::SubpassData && + !_.HasCapability(spv::Capability::StorageImageReadWithoutFormat)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability StorageImageReadWithoutFormat is required to " + << "read storage image"; + } + } + + if (spv_result_t result = + ValidateImageOperands(_, inst, info, /* word_index = */ 6)) + return result; + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { + const uint32_t image_type = _.GetOperandTypeId(inst, 0); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be of type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (info.dim == spv::Dim::SubpassData) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image 'Dim' cannot be SubpassData"; + } + + if (info.dim == spv::Dim::TileImageDataEXT) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image 'Dim' cannot be TileImageDataEXT"; + } + + if (spv_result_t result = ValidateImageReadWrite(_, inst, info)) + return result; + + const uint32_t coord_type = _.GetOperandTypeId(inst, 1); + if (!_.IsIntScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be int scalar or vector"; + } + + const uint32_t min_coord_size = GetMinCoordSize(inst->opcode(), info); + const uint32_t actual_coord_size = _.GetDimension(coord_type); + if (min_coord_size > actual_coord_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to have at least " << min_coord_size + << " components, but given only " << actual_coord_size; + } + + // because it needs to match with 'Sampled Type' the Texel can't be a boolean + const uint32_t texel_type = _.GetOperandTypeId(inst, 2); + if (!_.IsIntScalarOrVectorType(texel_type) && + !_.IsFloatScalarOrVectorType(texel_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Texel to be int or float vector or scalar"; + } + + if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + const uint32_t texel_component_type = _.GetComponentType(texel_type); + if (texel_component_type != info.sampled_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image 'Sampled Type' to be the same as Texel " + << "components"; + } + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (info.format == spv::ImageFormat::Unknown && + info.dim != spv::Dim::SubpassData && + !_.HasCapability(spv::Capability::StorageImageWriteWithoutFormat)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Capability StorageImageWriteWithoutFormat is required to " + "write " + << "to storage image"; + } + } + + if (inst->words().size() > 4) { + if (spvIsOpenCLEnv(_.context()->target_env)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Optional Image Operands are not allowed in the OpenCL " + << "environment."; + } + } + + if (spv_result_t result = + ValidateImageOperands(_, inst, info, /* word_index = */ 5)) + return result; + + return SPV_SUCCESS; +} + +spv_result_t ValidateImage(ValidationState_t& _, const Instruction* inst) { + const uint32_t result_type = inst->type_id(); + if (_.GetIdOpcode(result_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be OpTypeImage"; + } + + const uint32_t sampled_image_type = _.GetOperandTypeId(inst, 2); + const Instruction* sampled_image_type_inst = _.FindDef(sampled_image_type); + assert(sampled_image_type_inst); + + if (sampled_image_type_inst->opcode() != spv::Op::OpTypeSampledImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sample Image to be of type OpTypeSampleImage"; + } + + if (sampled_image_type_inst->word(2) != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Sample Image image type to be equal to Result Type"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageQuerySizeLod(ValidationState_t& _, + const Instruction* inst) { + const uint32_t result_type = inst->type_id(); + if (!_.IsIntScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be int scalar or vector type"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be of type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + uint32_t expected_num_components = info.arrayed; + switch (info.dim) { + case spv::Dim::Dim1D: + expected_num_components += 1; + break; + case spv::Dim::Dim2D: + case spv::Dim::Cube: + expected_num_components += 2; + break; + case spv::Dim::Dim3D: + expected_num_components += 3; + break; + default: + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image 'Dim' must be 1D, 2D, 3D or Cube"; + } + + if (info.multisampled != 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'MS' must be 0"; + } + + const auto target_env = _.context()->target_env; + if (spvIsVulkanEnv(target_env)) { + if (info.sampled != 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4659) + << "OpImageQuerySizeLod must only consume an \"Image\" operand " + "whose type has its \"Sampled\" operand set to 1"; + } + } + + uint32_t result_num_components = _.GetDimension(result_type); + if (result_num_components != expected_num_components) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type has " << result_num_components << " components, " + << "but " << expected_num_components << " expected"; + } + + const uint32_t lod_type = _.GetOperandTypeId(inst, 3); + if (!_.IsIntScalarType(lod_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Level of Detail to be int scalar"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateImageQuerySize(ValidationState_t& _, + const Instruction* inst) { + const uint32_t result_type = inst->type_id(); + if (!_.IsIntScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be int scalar or vector type"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be of type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + uint32_t expected_num_components = info.arrayed; + switch (info.dim) { + case spv::Dim::Dim1D: + case spv::Dim::Buffer: + expected_num_components += 1; + break; + case spv::Dim::Dim2D: + case spv::Dim::Cube: + case spv::Dim::Rect: + expected_num_components += 2; + break; + case spv::Dim::Dim3D: + expected_num_components += 3; + break; + default: + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"; + } + + if (info.dim == spv::Dim::Dim1D || info.dim == spv::Dim::Dim2D || + info.dim == spv::Dim::Dim3D || info.dim == spv::Dim::Cube) { + if (info.multisampled != 1 && info.sampled != 0 && info.sampled != 2) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"; + } + } + + uint32_t result_num_components = _.GetDimension(result_type); + if (result_num_components != expected_num_components) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type has " << result_num_components << " components, " + << "but " << expected_num_components << " expected"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageQueryFormatOrOrder(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsIntScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be int scalar type"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operand to be of type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (info.dim == spv::Dim::TileImageDataEXT) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image 'Dim' cannot be TileImageDataEXT"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateImageQueryLod(ValidationState_t& _, + const Instruction* inst) { + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [&](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::Fragment && + model != spv::ExecutionModel::GLCompute) { + if (message) { + *message = std::string( + "OpImageQueryLod requires Fragment or GLCompute execution " + "model"); + } + return false; + } + return true; + }); + _.function(inst->function()->id()) + ->RegisterLimitation([](const ValidationState_t& state, + const Function* entry_point, + std::string* message) { + const auto* models = state.GetExecutionModels(entry_point->id()); + const auto* modes = state.GetExecutionModes(entry_point->id()); + if (models->find(spv::ExecutionModel::GLCompute) != models->end() && + modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == + modes->end() && + modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == + modes->end()) { + if (message) { + *message = std::string( + "OpImageQueryLod requires DerivativeGroupQuadsNV " + "or DerivativeGroupLinearNV execution mode for GLCompute " + "execution model"); + } + return false; + } + return true; + }); + + const uint32_t result_type = inst->type_id(); + if (!_.IsFloatVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be float vector type"; + } + + if (_.GetDimension(result_type) != 2) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to have 2 components"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image operand to be of type OpTypeSampledImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image 'Dim' must be 1D, 2D, 3D or Cube"; + } + + const uint32_t coord_type = _.GetOperandTypeId(inst, 3); + if (_.HasCapability(spv::Capability::Kernel)) { + if (!_.IsFloatScalarOrVectorType(coord_type) && + !_.IsIntScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be int or float scalar or vector"; + } + } else { + if (!_.IsFloatScalarOrVectorType(coord_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to be float scalar or vector"; + } + } + + const uint32_t min_coord_size = GetPlaneCoordSize(info); + const uint32_t actual_coord_size = _.GetDimension(coord_type); + if (min_coord_size > actual_coord_size) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Coordinate to have at least " << min_coord_size + << " components, but given only " << actual_coord_size; + } + + // The operand is a sampled image. + // The sampled image type is already checked to be parameterized by an image + // type with Sampled=0 or Sampled=1. Vulkan bans Sampled=0, and so we have + // Sampled=1. So the validator already enforces Vulkan VUID 4659: + // OpImageQuerySizeLod must only consume an "Image" operand whose type has + // its "Sampled" operand set to 1 + return SPV_SUCCESS; +} + +spv_result_t ValidateImageSparseLod(ValidationState_t& _, + const Instruction* inst) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Instruction reserved for future use, use of this instruction " + << "is invalid"; +} + +spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsIntScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be int scalar type"; + } + + const uint32_t image_type = _.GetOperandTypeId(inst, 2); + if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Image to be of type OpTypeImage"; + } + + ImageTypeInfo info; + if (!GetImageTypeInfo(_, image_type, &info)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Corrupt image type definition"; + } + + const spv::Op opcode = inst->opcode(); + if (opcode == spv::Op::OpImageQueryLevels) { + if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && + info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Image 'Dim' must be 1D, 2D, 3D or Cube"; + } + const auto target_env = _.context()->target_env; + if (spvIsVulkanEnv(target_env)) { + if (info.sampled != 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4659) + << "OpImageQueryLevels must only consume an \"Image\" operand " + "whose type has its \"Sampled\" operand set to 1"; + } + } + } else { + assert(opcode == spv::Op::OpImageQuerySamples); + if (info.dim != spv::Dim::Dim2D) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 2D"; + } + + if (info.multisampled != 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'MS' must be 1"; + } + } + return SPV_SUCCESS; +} + +spv_result_t ValidateImageSparseTexelsResident(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsBoolScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be bool scalar type"; + } + + const uint32_t resident_code_type = _.GetOperandTypeId(inst, 2); + if (!_.IsIntScalarType(resident_code_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Resident Code to be int scalar"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageProcessingQCOMDecoration(ValidationState_t& _, int id, + spv::Decoration decor) { + const Instruction* si_inst = nullptr; + const Instruction* ld_inst = _.FindDef(id); + if (ld_inst->opcode() == spv::Op::OpSampledImage) { + si_inst = ld_inst; + int t_idx = si_inst->GetOperandAs(2); // texture + ld_inst = _.FindDef(t_idx); + } + if (ld_inst->opcode() != spv::Op::OpLoad) { + return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) << "Expect to see OpLoad"; + } + int texture_id = ld_inst->GetOperandAs(2); // variable to load + if (!_.HasDecoration(texture_id, decor)) { + return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) + << "Missing decoration WeightTextureQCOM/BlockMatchTextureQCOM"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageProcessingQCOM(ValidationState_t& _, + const Instruction* inst) { + spv_result_t res = SPV_SUCCESS; + const spv::Op opcode = inst->opcode(); + switch (opcode) { + case spv::Op::OpImageSampleWeightedQCOM: { + int wi_idx = inst->GetOperandAs(4); // weight + res = ValidateImageProcessingQCOMDecoration( + _, wi_idx, spv::Decoration::WeightTextureQCOM); + break; + } + case spv::Op::OpImageBlockMatchSSDQCOM: + case spv::Op::OpImageBlockMatchSADQCOM: { + int tgt_idx = inst->GetOperandAs(2); // target + res = ValidateImageProcessingQCOMDecoration( + _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM); + if (res != SPV_SUCCESS) break; + int ref_idx = inst->GetOperandAs(4); // reference + res = ValidateImageProcessingQCOMDecoration( + _, ref_idx, spv::Decoration::BlockMatchTextureQCOM); + break; + } + default: + break; + } + + return res; +} + +} // namespace + +// Validates correctness of image instructions. +spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + if (IsImplicitLod(opcode)) { + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::Fragment && + model != spv::ExecutionModel::GLCompute) { + if (message) { + *message = + std::string( + "ImplicitLod instructions require Fragment or GLCompute " + "execution model: ") + + spvOpcodeString(opcode); + } + return false; + } + return true; + }); + _.function(inst->function()->id()) + ->RegisterLimitation([opcode](const ValidationState_t& state, + const Function* entry_point, + std::string* message) { + const auto* models = state.GetExecutionModels(entry_point->id()); + const auto* modes = state.GetExecutionModes(entry_point->id()); + if (models && + models->find(spv::ExecutionModel::GLCompute) != models->end() && + (!modes || + (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == + modes->end() && + modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == + modes->end()))) { + if (message) { + *message = + std::string( + "ImplicitLod instructions require DerivativeGroupQuadsNV " + "or DerivativeGroupLinearNV execution mode for GLCompute " + "execution model: ") + + spvOpcodeString(opcode); + } + return false; + } + return true; + }); + } + + switch (opcode) { + case spv::Op::OpTypeImage: + return ValidateTypeImage(_, inst); + case spv::Op::OpTypeSampledImage: + return ValidateTypeSampledImage(_, inst); + case spv::Op::OpSampledImage: + return ValidateSampledImage(_, inst); + case spv::Op::OpImageTexelPointer: + return ValidateImageTexelPointer(_, inst); + + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + return ValidateImageLod(_, inst); + + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + return ValidateImageDrefLod(_, inst); + + case spv::Op::OpImageFetch: + case spv::Op::OpImageSparseFetch: + return ValidateImageFetch(_, inst); + + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + return ValidateImageGather(_, inst); + + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseRead: + return ValidateImageRead(_, inst); + + case spv::Op::OpImageWrite: + return ValidateImageWrite(_, inst); + + case spv::Op::OpImage: + return ValidateImage(_, inst); + + case spv::Op::OpImageQueryFormat: + case spv::Op::OpImageQueryOrder: + return ValidateImageQueryFormatOrOrder(_, inst); + + case spv::Op::OpImageQuerySizeLod: + return ValidateImageQuerySizeLod(_, inst); + case spv::Op::OpImageQuerySize: + return ValidateImageQuerySize(_, inst); + case spv::Op::OpImageQueryLod: + return ValidateImageQueryLod(_, inst); + + case spv::Op::OpImageQueryLevels: + case spv::Op::OpImageQuerySamples: + return ValidateImageQueryLevelsOrSamples(_, inst); + + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + return ValidateImageSparseLod(_, inst); + + case spv::Op::OpImageSparseTexelsResident: + return ValidateImageSparseTexelsResident(_, inst); + + case spv::Op::OpImageSampleWeightedQCOM: + case spv::Op::OpImageBoxFilterQCOM: + case spv::Op::OpImageBlockMatchSSDQCOM: + case spv::Op::OpImageBlockMatchSADQCOM: + return ValidateImageProcessingQCOM(_, inst); + + default: + break; + } + + return SPV_SUCCESS; +} + +bool IsImageInstruction(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpImageSampleImplicitLod: + case spv::Op::OpImageSampleDrefImplicitLod: + case spv::Op::OpImageSampleProjImplicitLod: + case spv::Op::OpImageSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleImplicitLod: + case spv::Op::OpImageSparseSampleDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + + case spv::Op::OpImageSampleExplicitLod: + case spv::Op::OpImageSampleDrefExplicitLod: + case spv::Op::OpImageSampleProjExplicitLod: + case spv::Op::OpImageSampleProjDrefExplicitLod: + case spv::Op::OpImageSparseSampleExplicitLod: + case spv::Op::OpImageSparseSampleDrefExplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + + case spv::Op::OpImage: + case spv::Op::OpImageFetch: + case spv::Op::OpImageSparseFetch: + case spv::Op::OpImageGather: + case spv::Op::OpImageDrefGather: + case spv::Op::OpImageSparseGather: + case spv::Op::OpImageSparseDrefGather: + case spv::Op::OpImageRead: + case spv::Op::OpImageSparseRead: + case spv::Op::OpImageWrite: + + case spv::Op::OpImageQueryFormat: + case spv::Op::OpImageQueryOrder: + case spv::Op::OpImageQuerySizeLod: + case spv::Op::OpImageQuerySize: + case spv::Op::OpImageQueryLod: + case spv::Op::OpImageQueryLevels: + case spv::Op::OpImageQuerySamples: + + case spv::Op::OpImageSampleWeightedQCOM: + case spv::Op::OpImageBoxFilterQCOM: + case spv::Op::OpImageBlockMatchSSDQCOM: + case spv::Op::OpImageBlockMatchSADQCOM: + return true; + default: + break; + } + return false; +} + +spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _, + const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + if (!IsImageInstruction(opcode)) return SPV_SUCCESS; + + switch (opcode) { + case spv::Op::OpImageSampleWeightedQCOM: + case spv::Op::OpImageBoxFilterQCOM: + case spv::Op::OpImageBlockMatchSSDQCOM: + case spv::Op::OpImageBlockMatchSADQCOM: + break; + default: + for (size_t i = 0; i < inst->operands().size(); ++i) { + int id = inst->GetOperandAs(i); + const Instruction* operand_inst = _.FindDef(id); + if (operand_inst == nullptr) continue; + if (operand_inst->opcode() == spv::Op::OpLoad) { + if (_.IsQCOMImageProcessingTextureConsumer(id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Illegal use of QCOM image processing decorated texture"; + } + } + if (operand_inst->opcode() == spv::Op::OpSampledImage) { + if (_.IsQCOMImageProcessingTextureConsumer(id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Illegal use of QCOM image processing decorated texture"; + } + } + } + break; + } + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_instruction.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_instruction.cpp new file mode 100644 index 000000000000..5bc4d2cef4c0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_instruction.cpp @@ -0,0 +1,513 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Performs validation on instructions that appear inside of a SPIR-V block. + +#include +#include +#include +#include + +#include "source/enum_set.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" +#include "source/opcode.h" +#include "source/operand.h" +#include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/spirv_validator_options.h" +#include "source/util/string_utils.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +std::string ToString(const CapabilitySet& capabilities, + const AssemblyGrammar& grammar) { + std::stringstream ss; + for (auto capability : capabilities) { + spv_operand_desc desc; + if (SPV_SUCCESS == grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, + uint32_t(capability), &desc)) + ss << desc->name << " "; + else + ss << uint32_t(capability) << " "; + } + return ss.str(); +} + +// Returns capabilities that enable an opcode. An empty result is interpreted +// as no prohibition of use of the opcode. If the result is non-empty, then +// the opcode may only be used if at least one of the capabilities is specified +// by the module. +CapabilitySet EnablingCapabilitiesForOp(const ValidationState_t& state, + spv::Op opcode) { + // Exceptions for SPV_AMD_shader_ballot + switch (opcode) { + // Normally these would require Group capability + case spv::Op::OpGroupIAddNonUniformAMD: + case spv::Op::OpGroupFAddNonUniformAMD: + case spv::Op::OpGroupFMinNonUniformAMD: + case spv::Op::OpGroupUMinNonUniformAMD: + case spv::Op::OpGroupSMinNonUniformAMD: + case spv::Op::OpGroupFMaxNonUniformAMD: + case spv::Op::OpGroupUMaxNonUniformAMD: + case spv::Op::OpGroupSMaxNonUniformAMD: + if (state.HasExtension(kSPV_AMD_shader_ballot)) return CapabilitySet(); + break; + default: + break; + } + // Look it up in the grammar + spv_opcode_desc opcode_desc = {}; + if (SPV_SUCCESS == state.grammar().lookupOpcode(opcode, &opcode_desc)) { + return state.grammar().filterCapsAgainstTargetEnv( + opcode_desc->capabilities, opcode_desc->numCapabilities); + } + return CapabilitySet(); +} + +// Returns SPV_SUCCESS if, for the given operand, the target environment +// satsifies minimum version requirements, or if the module declares an +// enabling extension for the operand. Otherwise emit a diagnostic and +// return an error code. +spv_result_t OperandVersionExtensionCheck( + ValidationState_t& _, const Instruction* inst, size_t which_operand, + const spv_operand_desc_t& operand_desc, uint32_t word) { + const uint32_t module_version = _.version(); + const uint32_t operand_min_version = operand_desc.minVersion; + const uint32_t operand_last_version = operand_desc.lastVersion; + const bool reserved = operand_min_version == 0xffffffffu; + const bool version_satisfied = !reserved && + (operand_min_version <= module_version) && + (module_version <= operand_last_version); + + if (version_satisfied) { + return SPV_SUCCESS; + } + + if (operand_last_version < module_version) { + return _.diag(SPV_ERROR_WRONG_VERSION, inst) + << spvtools::utils::CardinalToOrdinal(which_operand) + << " operand of " << spvOpcodeString(inst->opcode()) << ": operand " + << operand_desc.name << "(" << word << ") requires SPIR-V version " + << SPV_SPIRV_VERSION_MAJOR_PART(operand_last_version) << "." + << SPV_SPIRV_VERSION_MINOR_PART(operand_last_version) + << " or earlier"; + } + + if (!reserved && operand_desc.numExtensions == 0) { + return _.diag(SPV_ERROR_WRONG_VERSION, inst) + << spvtools::utils::CardinalToOrdinal(which_operand) + << " operand of " << spvOpcodeString(inst->opcode()) << ": operand " + << operand_desc.name << "(" << word << ") requires SPIR-V version " + << SPV_SPIRV_VERSION_MAJOR_PART(operand_min_version) << "." + << SPV_SPIRV_VERSION_MINOR_PART(operand_min_version) << " or later"; + } else { + ExtensionSet required_extensions(operand_desc.numExtensions, + operand_desc.extensions); + if (!_.HasAnyOfExtensions(required_extensions)) { + return _.diag(SPV_ERROR_MISSING_EXTENSION, inst) + << spvtools::utils::CardinalToOrdinal(which_operand) + << " operand of " << spvOpcodeString(inst->opcode()) + << ": operand " << operand_desc.name << "(" << word + << ") requires one of these extensions: " + << ExtensionSetToString(required_extensions); + } + } + return SPV_SUCCESS; +} + +// Returns SPV_SUCCESS if the given operand is enabled by capabilities declared +// in the module. Otherwise issues an error message and returns +// SPV_ERROR_INVALID_CAPABILITY. +spv_result_t CheckRequiredCapabilities(ValidationState_t& state, + const Instruction* inst, + size_t which_operand, + const spv_parsed_operand_t& operand, + uint32_t word) { + // Mere mention of PointSize, ClipDistance, or CullDistance in a Builtin + // decoration does not require the associated capability. The use of such + // a variable value should trigger the capability requirement, but that's + // not implemented yet. This rule is independent of target environment. + // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365 + if (operand.type == SPV_OPERAND_TYPE_BUILT_IN) { + switch (spv::BuiltIn(word)) { + case spv::BuiltIn::PointSize: + case spv::BuiltIn::ClipDistance: + case spv::BuiltIn::CullDistance: + return SPV_SUCCESS; + default: + break; + } + } else if (operand.type == SPV_OPERAND_TYPE_FP_ROUNDING_MODE) { + // Allow all FP rounding modes if requested + if (state.features().free_fp_rounding_mode) { + return SPV_SUCCESS; + } + } else if (operand.type == SPV_OPERAND_TYPE_GROUP_OPERATION && + state.features().group_ops_reduce_and_scans && + (word <= uint32_t(spv::GroupOperation::ExclusiveScan))) { + // Allow certain group operations if requested. + return SPV_SUCCESS; + } + + CapabilitySet enabling_capabilities; + spv_operand_desc operand_desc = nullptr; + const auto lookup_result = + state.grammar().lookupOperand(operand.type, word, &operand_desc); + if (lookup_result == SPV_SUCCESS) { + // Allow FPRoundingMode decoration if requested. + if (operand.type == SPV_OPERAND_TYPE_DECORATION && + spv::Decoration(operand_desc->value) == + spv::Decoration::FPRoundingMode) { + if (state.features().free_fp_rounding_mode) return SPV_SUCCESS; + + // Vulkan API requires more capabilities on rounding mode. + if (spvIsVulkanEnv(state.context()->target_env)) { + enabling_capabilities.insert( + spv::Capability::StorageUniformBufferBlock16); + enabling_capabilities.insert(spv::Capability::StorageUniform16); + enabling_capabilities.insert(spv::Capability::StoragePushConstant16); + enabling_capabilities.insert(spv::Capability::StorageInputOutput16); + } + } else { + enabling_capabilities = state.grammar().filterCapsAgainstTargetEnv( + operand_desc->capabilities, operand_desc->numCapabilities); + } + + // When encountering an OpCapability instruction, the instruction pass + // registers a capability with the module *before* checking capabilities. + // So in the case of an OpCapability instruction, don't bother checking + // enablement by another capability. + if (inst->opcode() != spv::Op::OpCapability) { + const bool enabled_by_cap = + state.HasAnyOfCapabilities(enabling_capabilities); + if (!enabling_capabilities.empty() && !enabled_by_cap) { + return state.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Operand " << which_operand << " of " + << spvOpcodeString(inst->opcode()) + << " requires one of these capabilities: " + << ToString(enabling_capabilities, state.grammar()); + } + } + return OperandVersionExtensionCheck(state, inst, which_operand, + *operand_desc, word); + } + return SPV_SUCCESS; +} + +// Returns SPV_ERROR_INVALID_BINARY and emits a diagnostic if the instruction +// is explicitly reserved in the SPIR-V core spec. Otherwise return +// SPV_SUCCESS. +spv_result_t ReservedCheck(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + switch (opcode) { + // These instructions are enabled by a capability, but should never + // be used anyway. + case spv::Op::OpImageSparseSampleProjImplicitLod: + case spv::Op::OpImageSparseSampleProjExplicitLod: + case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case spv::Op::OpImageSparseSampleProjDrefExplicitLod: { + spv_opcode_desc inst_desc; + _.grammar().lookupOpcode(opcode, &inst_desc); + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << "Invalid Opcode name 'Op" << inst_desc->name << "'"; + } + default: + break; + } + return SPV_SUCCESS; +} + +// Returns SPV_ERROR_INVALID_CAPABILITY and emits a diagnostic if the +// instruction is invalid because the required capability isn't declared +// in the module. +spv_result_t CapabilityCheck(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + CapabilitySet opcode_caps = EnablingCapabilitiesForOp(_, opcode); + if (!_.HasAnyOfCapabilities(opcode_caps)) { + return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) + << "Opcode " << spvOpcodeString(opcode) + << " requires one of these capabilities: " + << ToString(opcode_caps, _.grammar()); + } + for (size_t i = 0; i < inst->operands().size(); ++i) { + const auto& operand = inst->operand(i); + const auto word = inst->word(operand.offset); + if (spvOperandIsConcreteMask(operand.type)) { + // Check for required capabilities for each bit position of the mask. + for (uint32_t mask_bit = 0x80000000; mask_bit; mask_bit >>= 1) { + if (word & mask_bit) { + spv_result_t status = + CheckRequiredCapabilities(_, inst, i + 1, operand, mask_bit); + if (status != SPV_SUCCESS) return status; + } + } + } else if (spvIsIdType(operand.type)) { + // TODO(dneto): Check the value referenced by this Id, if we can compute + // it. For now, just punt, to fix issue 248: + // https://github.com/KhronosGroup/SPIRV-Tools/issues/248 + } else { + // Check the operand word as a whole. + spv_result_t status = + CheckRequiredCapabilities(_, inst, i + 1, operand, word); + if (status != SPV_SUCCESS) return status; + } + } + return SPV_SUCCESS; +} + +// Checks that the instruction can be used in this target environment's base +// version. Assumes that CapabilityCheck has checked direct capability +// dependencies for the opcode. +spv_result_t VersionCheck(ValidationState_t& _, const Instruction* inst) { + const auto opcode = inst->opcode(); + spv_opcode_desc inst_desc; + const spv_result_t r = _.grammar().lookupOpcode(opcode, &inst_desc); + assert(r == SPV_SUCCESS); + (void)r; + + const auto min_version = inst_desc->minVersion; + const auto last_version = inst_desc->lastVersion; + const auto module_version = _.version(); + + if (last_version < module_version) { + return _.diag(SPV_ERROR_WRONG_VERSION, inst) + << spvOpcodeString(opcode) << " requires SPIR-V version " + << SPV_SPIRV_VERSION_MAJOR_PART(last_version) << "." + << SPV_SPIRV_VERSION_MINOR_PART(last_version) << " or earlier"; + } + + // OpTerminateInvocation is special because it is enabled by Shader + // capability, but also requires an extension and/or version check. + const bool capability_check_is_sufficient = + inst->opcode() != spv::Op::OpTerminateInvocation; + + if (capability_check_is_sufficient && (inst_desc->numCapabilities > 0u)) { + // We already checked that the direct capability dependency has been + // satisfied. We don't need to check any further. + return SPV_SUCCESS; + } + + ExtensionSet exts(inst_desc->numExtensions, inst_desc->extensions); + if (exts.empty()) { + // If no extensions can enable this instruction, then emit error + // messages only concerning core SPIR-V versions if errors happen. + if (min_version == ~0u) { + return _.diag(SPV_ERROR_WRONG_VERSION, inst) + << spvOpcodeString(opcode) << " is reserved for future use."; + } + + if (module_version < min_version) { + return _.diag(SPV_ERROR_WRONG_VERSION, inst) + << spvOpcodeString(opcode) << " requires SPIR-V version " + << SPV_SPIRV_VERSION_MAJOR_PART(min_version) << "." + << SPV_SPIRV_VERSION_MINOR_PART(min_version) << " at minimum."; + } + } else if (!_.HasAnyOfExtensions(exts)) { + // Otherwise, we only error out when no enabling extensions are + // registered. + if (min_version == ~0u) { + return _.diag(SPV_ERROR_MISSING_EXTENSION, inst) + << spvOpcodeString(opcode) + << " requires one of the following extensions: " + << ExtensionSetToString(exts); + } + + if (module_version < min_version) { + return _.diag(SPV_ERROR_WRONG_VERSION, inst) + << spvOpcodeString(opcode) << " requires SPIR-V version " + << SPV_SPIRV_VERSION_MAJOR_PART(min_version) << "." + << SPV_SPIRV_VERSION_MINOR_PART(min_version) + << " at minimum or one of the following extensions: " + << ExtensionSetToString(exts); + } + } + + return SPV_SUCCESS; +} + +// Checks that the Resuld is within the valid bound. +spv_result_t LimitCheckIdBound(ValidationState_t& _, const Instruction* inst) { + if (inst->id() >= _.getIdBound()) { + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << "Result '" << inst->id() + << "' must be less than the ID bound '" << _.getIdBound() << "'."; + } + return SPV_SUCCESS; +} + +// Checks that the number of OpTypeStruct members is within the limit. +spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) { + if (spv::Op::OpTypeStruct != inst->opcode()) { + return SPV_SUCCESS; + } + + // Number of members is the number of operands of the instruction minus 1. + // One operand is the result ID. + const uint16_t limit = + static_cast(_.options()->universal_limits_.max_struct_members); + if (inst->operands().size() - 1 > limit) { + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << "Number of OpTypeStruct members (" << inst->operands().size() - 1 + << ") has exceeded the limit (" << limit << ")."; + } + + // Section 2.17 of SPIRV Spec specifies that the "Structure Nesting Depth" + // must be less than or equal to 255. + // This is interpreted as structures including other structures as + // members. The code does not follow pointers or look into arrays to see + // if we reach a structure downstream. The nesting depth of a struct is + // 1+(largest depth of any member). Scalars are at depth 0. + uint32_t max_member_depth = 0; + // Struct members start at word 2 of OpTypeStruct instruction. + for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) { + auto member = inst->word(word_i); + auto memberTypeInstr = _.FindDef(member); + if (memberTypeInstr && spv::Op::OpTypeStruct == memberTypeInstr->opcode()) { + max_member_depth = std::max( + max_member_depth, _.struct_nesting_depth(memberTypeInstr->id())); + } + } + + const uint32_t depth_limit = _.options()->universal_limits_.max_struct_depth; + const uint32_t cur_depth = 1 + max_member_depth; + _.set_struct_nesting_depth(inst->id(), cur_depth); + if (cur_depth > depth_limit) { + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << "Structure Nesting Depth may not be larger than " << depth_limit + << ". Found " << cur_depth << "."; + } + return SPV_SUCCESS; +} + +// Checks that the number of (literal, label) pairs in OpSwitch is within +// the limit. +spv_result_t LimitCheckSwitch(ValidationState_t& _, const Instruction* inst) { + if (spv::Op::OpSwitch == inst->opcode()) { + // The instruction syntax is as follows: + // OpSwitch literal label literal label ... + // literal,label pairs come after the first 2 operands. + // It is guaranteed at this point that num_operands is an even number. + size_t num_pairs = (inst->operands().size() - 2) / 2; + const unsigned int num_pairs_limit = + _.options()->universal_limits_.max_switch_branches; + if (num_pairs > num_pairs_limit) { + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << "Number of (literal, label) pairs in OpSwitch (" << num_pairs + << ") exceeds the limit (" << num_pairs_limit << ")."; + } + } + return SPV_SUCCESS; +} + +// Ensure the number of variables of the given class does not exceed the +// limit. +spv_result_t LimitCheckNumVars(ValidationState_t& _, const uint32_t var_id, + const spv::StorageClass storage_class) { + if (spv::StorageClass::Function == storage_class) { + _.registerLocalVariable(var_id); + const uint32_t num_local_vars_limit = + _.options()->universal_limits_.max_local_variables; + if (_.num_local_vars() > num_local_vars_limit) { + return _.diag(SPV_ERROR_INVALID_BINARY, nullptr) + << "Number of local variables ('Function' Storage Class) " + "exceeded the valid limit (" + << num_local_vars_limit << ")."; + } + } else { + _.registerGlobalVariable(var_id); + const uint32_t num_global_vars_limit = + _.options()->universal_limits_.max_global_variables; + if (_.num_global_vars() > num_global_vars_limit) { + return _.diag(SPV_ERROR_INVALID_BINARY, nullptr) + << "Number of Global Variables (Storage Class other than " + "'Function') exceeded the valid limit (" + << num_global_vars_limit << ")."; + } + } + return SPV_SUCCESS; +} + +// Parses OpExtension instruction and logs warnings if unsuccessful. +spv_result_t CheckIfKnownExtension(ValidationState_t& _, + const Instruction* inst) { + const std::string extension_str = GetExtensionString(&(inst->c_inst())); + Extension extension; + if (!GetExtensionFromString(extension_str.c_str(), &extension)) { + return _.diag(SPV_WARNING, inst) + << "Found unrecognized extension " << extension_str; + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + if (opcode == spv::Op::OpExtension) { + CheckIfKnownExtension(_, inst); + } else if (opcode == spv::Op::OpCapability) { + _.RegisterCapability(inst->GetOperandAs(0)); + } else if (opcode == spv::Op::OpMemoryModel) { + if (_.has_memory_model_specified()) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "OpMemoryModel should only be provided once."; + } + _.set_addressing_model(inst->GetOperandAs(0)); + _.set_memory_model(inst->GetOperandAs(1)); + } else if (opcode == spv::Op::OpExecutionMode || + opcode == spv::Op::OpExecutionModeId) { + const uint32_t entry_point = inst->word(1); + _.RegisterExecutionModeForEntryPoint(entry_point, + spv::ExecutionMode(inst->word(2))); + } else if (opcode == spv::Op::OpVariable) { + const auto storage_class = inst->GetOperandAs(2); + if (auto error = LimitCheckNumVars(_, inst->id(), storage_class)) { + return error; + } + } else if (opcode == spv::Op::OpSamplerImageAddressingModeNV) { + if (!_.HasCapability(spv::Capability::BindlessTextureNV)) { + return _.diag(SPV_ERROR_MISSING_EXTENSION, inst) + << "OpSamplerImageAddressingModeNV supported only with extension " + "SPV_NV_bindless_texture"; + } + uint32_t bitwidth = inst->GetOperandAs(0); + if (_.samplerimage_variable_address_mode() != 0) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "OpSamplerImageAddressingModeNV should only be provided once"; + } + if (bitwidth != 32 && bitwidth != 64) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "OpSamplerImageAddressingModeNV bitwidth should be 64 or 32"; + } + _.set_samplerimage_variable_address_mode(bitwidth); + } + + if (auto error = ReservedCheck(_, inst)) return error; + if (auto error = CapabilityCheck(_, inst)) return error; + if (auto error = LimitCheckIdBound(_, inst)) return error; + if (auto error = LimitCheckStruct(_, inst)) return error; + if (auto error = LimitCheckSwitch(_, inst)) return error; + if (auto error = VersionCheck(_, inst)) return error; + + // All instruction checks have passed. + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_interfaces.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_interfaces.cpp new file mode 100644 index 000000000000..54ebfd788530 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_interfaces.cpp @@ -0,0 +1,649 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/val/function.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Limit the number of checked locations to 4096. Multiplied by 4 to represent +// all the components. This limit is set to be well beyond practical use cases. +const uint32_t kMaxLocations = 4096 * 4; + +// Returns true if \c inst is an input or output variable. +bool is_interface_variable(const Instruction* inst, bool is_spv_1_4) { + if (is_spv_1_4) { + // Starting in SPIR-V 1.4, all global variables are interface variables. + return inst->opcode() == spv::Op::OpVariable && + inst->GetOperandAs(2u) != + spv::StorageClass::Function; + } else { + return inst->opcode() == spv::Op::OpVariable && + (inst->GetOperandAs(2u) == + spv::StorageClass::Input || + inst->GetOperandAs(2u) == + spv::StorageClass::Output); + } +} + +// Checks that \c var is listed as an interface in all the entry points that use +// it. +spv_result_t check_interface_variable(ValidationState_t& _, + const Instruction* var) { + std::vector functions; + std::vector uses; + for (auto use : var->uses()) { + uses.push_back(use.first); + } + for (uint32_t i = 0; i < uses.size(); ++i) { + const auto user = uses[i]; + if (const Function* func = user->function()) { + functions.push_back(func); + } else { + // In the rare case that the variable is used by another instruction in + // the global scope, continue searching for an instruction used in a + // function. + for (auto use : user->uses()) { + uses.push_back(use.first); + } + } + } + + std::sort(functions.begin(), functions.end(), + [](const Function* lhs, const Function* rhs) { + return lhs->id() < rhs->id(); + }); + functions.erase(std::unique(functions.begin(), functions.end()), + functions.end()); + + std::vector entry_points; + for (const auto func : functions) { + for (auto id : _.FunctionEntryPoints(func->id())) { + entry_points.push_back(id); + } + } + + std::sort(entry_points.begin(), entry_points.end()); + entry_points.erase(std::unique(entry_points.begin(), entry_points.end()), + entry_points.end()); + + for (auto id : entry_points) { + for (const auto& desc : _.entry_point_descriptions(id)) { + bool found = false; + for (auto interface : desc.interfaces) { + if (var->id() == interface) { + found = true; + break; + } + } + if (!found) { + return _.diag(SPV_ERROR_INVALID_ID, var) + << "Interface variable id <" << var->id() + << "> is used by entry point '" << desc.name << "' id <" << id + << ">, but is not listed as an interface"; + } + } + } + + return SPV_SUCCESS; +} + +// This function assumes a base location has been determined already. As such +// any further location decorations are invalid. +// TODO: if this code turns out to be slow, there is an opportunity to cache +// the result for a given type id. +spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type, + uint32_t* num_locations) { + *num_locations = 0; + switch (type->opcode()) { + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + // Scalars always consume a single location. + *num_locations = 1; + break; + case spv::Op::OpTypeVector: + // 3- and 4-component 64-bit vectors consume two locations. + if ((_.ContainsSizedIntOrFloatType(type->id(), spv::Op::OpTypeInt, 64) || + _.ContainsSizedIntOrFloatType(type->id(), spv::Op::OpTypeFloat, + 64)) && + (type->GetOperandAs(2) > 2)) { + *num_locations = 2; + } else { + *num_locations = 1; + } + break; + case spv::Op::OpTypeMatrix: + // Matrices consume locations equal to the underlying vector type for + // each column. + NumConsumedLocations(_, _.FindDef(type->GetOperandAs(1)), + num_locations); + *num_locations *= type->GetOperandAs(2); + break; + case spv::Op::OpTypeArray: { + // Arrays consume locations equal to the underlying type times the number + // of elements in the vector. + NumConsumedLocations(_, _.FindDef(type->GetOperandAs(1)), + num_locations); + bool is_int = false; + bool is_const = false; + uint32_t value = 0; + // Attempt to evaluate the number of array elements. + std::tie(is_int, is_const, value) = + _.EvalInt32IfConst(type->GetOperandAs(2)); + if (is_int && is_const) *num_locations *= value; + break; + } + case spv::Op::OpTypeStruct: { + // Members cannot have location decorations at this point. + if (_.HasDecoration(type->id(), spv::Decoration::Location)) { + return _.diag(SPV_ERROR_INVALID_DATA, type) + << _.VkErrorID(4918) << "Members cannot be assigned a location"; + } + + // Structs consume locations equal to the sum of the locations consumed + // by the members. + for (uint32_t i = 1; i < type->operands().size(); ++i) { + uint32_t member_locations = 0; + if (auto error = NumConsumedLocations( + _, _.FindDef(type->GetOperandAs(i)), + &member_locations)) { + return error; + } + *num_locations += member_locations; + } + break; + } + case spv::Op::OpTypePointer: { + if (_.addressing_model() == + spv::AddressingModel::PhysicalStorageBuffer64 && + type->GetOperandAs(1) == + spv::StorageClass::PhysicalStorageBuffer) { + *num_locations = 1; + break; + } + [[fallthrough]]; + } + default: + return _.diag(SPV_ERROR_INVALID_DATA, type) + << "Invalid type to assign a location"; + } + + return SPV_SUCCESS; +} + +// Returns the number of components consumed by types that support a component +// decoration. +uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) { + uint32_t num_components = 0; + switch (type->opcode()) { + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: + // 64-bit types consume two components. + if (type->GetOperandAs(1) == 64) { + num_components = 2; + } else { + num_components = 1; + } + break; + case spv::Op::OpTypeVector: + // Vectors consume components equal to the underlying type's consumption + // times the number of elements in the vector. Note that 3- and 4-element + // vectors cannot have a component decoration (i.e. assumed to be zero). + num_components = + NumConsumedComponents(_, _.FindDef(type->GetOperandAs(1))); + num_components *= type->GetOperandAs(2); + break; + case spv::Op::OpTypeArray: + // Skip the array. + return NumConsumedComponents(_, + _.FindDef(type->GetOperandAs(1))); + case spv::Op::OpTypePointer: + if (_.addressing_model() == + spv::AddressingModel::PhysicalStorageBuffer64 && + type->GetOperandAs(1) == + spv::StorageClass::PhysicalStorageBuffer) { + return 2; + } + break; + default: + // This is an error that is validated elsewhere. + break; + } + + return num_components; +} + +// Populates |locations| (and/or |output_index1_locations|) with the use +// location and component coordinates for |variable|. Indices are calculated as +// 4 * location + component. +spv_result_t GetLocationsForVariable( + ValidationState_t& _, const Instruction* entry_point, + const Instruction* variable, std::unordered_set* locations, + std::unordered_set* output_index1_locations) { + const bool is_fragment = entry_point->GetOperandAs(0) == + spv::ExecutionModel::Fragment; + const bool is_output = + variable->GetOperandAs(2) == spv::StorageClass::Output; + auto ptr_type_id = variable->GetOperandAs(0); + auto ptr_type = _.FindDef(ptr_type_id); + auto type_id = ptr_type->GetOperandAs(2); + auto type = _.FindDef(type_id); + + // Check for Location, Component and Index decorations on the variable. The + // validator allows duplicate decorations if the location/component/index are + // equal. Also track Patch and PerTaskNV decorations. + bool has_location = false; + uint32_t location = 0; + bool has_component = false; + uint32_t component = 0; + bool has_index = false; + uint32_t index = 0; + bool has_patch = false; + bool has_per_task_nv = false; + bool has_per_vertex_khr = false; + for (auto& dec : _.id_decorations(variable->id())) { + if (dec.dec_type() == spv::Decoration::Location) { + if (has_location && dec.params()[0] != location) { + return _.diag(SPV_ERROR_INVALID_DATA, variable) + << "Variable has conflicting location decorations"; + } + has_location = true; + location = dec.params()[0]; + } else if (dec.dec_type() == spv::Decoration::Component) { + if (has_component && dec.params()[0] != component) { + return _.diag(SPV_ERROR_INVALID_DATA, variable) + << "Variable has conflicting component decorations"; + } + has_component = true; + component = dec.params()[0]; + } else if (dec.dec_type() == spv::Decoration::Index) { + if (!is_output || !is_fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, variable) + << "Index can only be applied to Fragment output variables"; + } + if (has_index && dec.params()[0] != index) { + return _.diag(SPV_ERROR_INVALID_DATA, variable) + << "Variable has conflicting index decorations"; + } + has_index = true; + index = dec.params()[0]; + } else if (dec.dec_type() == spv::Decoration::BuiltIn) { + // Don't check built-ins. + return SPV_SUCCESS; + } else if (dec.dec_type() == spv::Decoration::Patch) { + has_patch = true; + } else if (dec.dec_type() == spv::Decoration::PerTaskNV) { + has_per_task_nv = true; + } else if (dec.dec_type() == spv::Decoration::PerVertexKHR) { + if (!is_fragment) { + return _.diag(SPV_ERROR_INVALID_DATA, variable) + << _.VkErrorID(6777) + << "PerVertexKHR can only be applied to Fragment Execution " + "Models"; + } + if (type->opcode() != spv::Op::OpTypeArray && + type->opcode() != spv::Op::OpTypeRuntimeArray) { + return _.diag(SPV_ERROR_INVALID_DATA, variable) + << _.VkErrorID(6778) + << "PerVertexKHR must be declared as arrays"; + } + has_per_vertex_khr = true; + } + } + + // Vulkan 14.1.3: Tessellation control and mesh per-vertex outputs and + // tessellation control, evaluation and geometry per-vertex inputs have a + // layer of arraying that is not included in interface matching. + bool is_arrayed = false; + switch (entry_point->GetOperandAs(0)) { + case spv::ExecutionModel::TessellationControl: + if (!has_patch) { + is_arrayed = true; + } + break; + case spv::ExecutionModel::TessellationEvaluation: + if (!is_output && !has_patch) { + is_arrayed = true; + } + break; + case spv::ExecutionModel::Geometry: + if (!is_output) { + is_arrayed = true; + } + break; + case spv::ExecutionModel::Fragment: + if (!is_output && has_per_vertex_khr) { + is_arrayed = true; + } + break; + case spv::ExecutionModel::MeshNV: + if (is_output && !has_per_task_nv) { + is_arrayed = true; + } + break; + default: + break; + } + + // Unpack arrayness. + if (is_arrayed && (type->opcode() == spv::Op::OpTypeArray || + type->opcode() == spv::Op::OpTypeRuntimeArray)) { + type_id = type->GetOperandAs(1); + type = _.FindDef(type_id); + } + + if (type->opcode() == spv::Op::OpTypeStruct) { + // Don't check built-ins. + if (_.HasDecoration(type_id, spv::Decoration::BuiltIn)) return SPV_SUCCESS; + } + + // Only block-decorated structs don't need a location on the variable. + const bool is_block = _.HasDecoration(type_id, spv::Decoration::Block); + if (!has_location && !is_block) { + const auto vuid = (type->opcode() == spv::Op::OpTypeStruct) ? 4917 : 4916; + return _.diag(SPV_ERROR_INVALID_DATA, variable) + << _.VkErrorID(vuid) << "Variable must be decorated with a location"; + } + + const std::string storage_class = is_output ? "output" : "input"; + if (has_location) { + auto sub_type = type; + bool is_int = false; + bool is_const = false; + uint32_t array_size = 1; + // If the variable is still arrayed, mark the locations/components per + // index. + if (type->opcode() == spv::Op::OpTypeArray) { + // Determine the array size if possible and get the element type. + std::tie(is_int, is_const, array_size) = + _.EvalInt32IfConst(type->GetOperandAs(2)); + if (!is_int || !is_const) array_size = 1; + auto sub_type_id = type->GetOperandAs(1); + sub_type = _.FindDef(sub_type_id); + } + + uint32_t num_locations = 0; + if (auto error = NumConsumedLocations(_, sub_type, &num_locations)) + return error; + uint32_t num_components = NumConsumedComponents(_, sub_type); + + for (uint32_t array_idx = 0; array_idx < array_size; ++array_idx) { + uint32_t array_location = location + (num_locations * array_idx); + uint32_t start = array_location * 4; + if (kMaxLocations <= start) { + // Too many locations, give up. + break; + } + + uint32_t end = (array_location + num_locations) * 4; + if (num_components != 0) { + start += component; + end = array_location * 4 + component + num_components; + } + + auto locs = locations; + if (has_index && index == 1) locs = output_index1_locations; + + for (uint32_t i = start; i < end; ++i) { + if (!locs->insert(i).second) { + return _.diag(SPV_ERROR_INVALID_DATA, entry_point) + << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721)) + << "Entry-point has conflicting " << storage_class + << " location assignment at location " << i / 4 + << ", component " << i % 4; + } + } + } + } else { + // For Block-decorated structs with no location assigned to the variable, + // each member of the block must be assigned a location. Also record any + // member component assignments. The validator allows duplicate decorations + // if they agree on the location/component. + std::unordered_map member_locations; + std::unordered_map member_components; + for (auto& dec : _.id_decorations(type_id)) { + if (dec.dec_type() == spv::Decoration::Location) { + auto where = member_locations.find(dec.struct_member_index()); + if (where == member_locations.end()) { + member_locations[dec.struct_member_index()] = dec.params()[0]; + } else if (where->second != dec.params()[0]) { + return _.diag(SPV_ERROR_INVALID_DATA, type) + << "Member index " << dec.struct_member_index() + << " has conflicting location assignments"; + } + } else if (dec.dec_type() == spv::Decoration::Component) { + auto where = member_components.find(dec.struct_member_index()); + if (where == member_components.end()) { + member_components[dec.struct_member_index()] = dec.params()[0]; + } else if (where->second != dec.params()[0]) { + return _.diag(SPV_ERROR_INVALID_DATA, type) + << "Member index " << dec.struct_member_index() + << " has conflicting component assignments"; + } + } + } + + for (uint32_t i = 1; i < type->operands().size(); ++i) { + auto where = member_locations.find(i - 1); + if (where == member_locations.end()) { + return _.diag(SPV_ERROR_INVALID_DATA, type) + << _.VkErrorID(4919) << "Member index " << i - 1 + << " is missing a location assignment"; + } + + location = where->second; + auto member = _.FindDef(type->GetOperandAs(i)); + uint32_t num_locations = 0; + if (auto error = NumConsumedLocations(_, member, &num_locations)) + return error; + + // If the component is not specified, it is assumed to be zero. + uint32_t num_components = NumConsumedComponents(_, member); + component = 0; + if (member_components.count(i - 1)) { + component = member_components[i - 1]; + } + + uint32_t start = location * 4; + if (kMaxLocations <= start) { + // Too many locations, give up. + continue; + } + + if (member->opcode() == spv::Op::OpTypeArray && num_components >= 1 && + num_components < 4) { + // When an array has an element that takes less than a location in + // size, calculate the used locations in a strided manner. + for (uint32_t l = location; l < num_locations + location; ++l) { + for (uint32_t c = component; c < component + num_components; ++c) { + uint32_t check = 4 * l + c; + if (!locations->insert(check).second) { + return _.diag(SPV_ERROR_INVALID_DATA, entry_point) + << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721)) + << "Entry-point has conflicting " << storage_class + << " location assignment at location " << l + << ", component " << c; + } + } + } + } else { + // TODO: There is a hole here is the member is an array of 3- or + // 4-element vectors of 64-bit types. + uint32_t end = (location + num_locations) * 4; + if (num_components != 0) { + start += component; + end = location * 4 + component + num_components; + } + for (uint32_t l = start; l < end; ++l) { + if (!locations->insert(l).second) { + return _.diag(SPV_ERROR_INVALID_DATA, entry_point) + << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721)) + << "Entry-point has conflicting " << storage_class + << " location assignment at location " << l / 4 + << ", component " << l % 4; + } + } + } + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateLocations(ValidationState_t& _, + const Instruction* entry_point) { + // According to Vulkan 14.1 only the following execution models have + // locations assigned. + // TODO(dneto): SPV_NV_ray_tracing also uses locations on interface variables, + // in other shader stages. Similarly, the *provisional* version of + // SPV_KHR_ray_tracing did as well, but not the final version. + switch (entry_point->GetOperandAs(0)) { + case spv::ExecutionModel::Vertex: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::Fragment: + break; + default: + return SPV_SUCCESS; + } + + // Locations are stored as a combined location and component values. + std::unordered_set input_locations; + std::unordered_set output_locations_index0; + std::unordered_set output_locations_index1; + std::unordered_set seen; + for (uint32_t i = 3; i < entry_point->operands().size(); ++i) { + auto interface_id = entry_point->GetOperandAs(i); + auto interface_var = _.FindDef(interface_id); + auto storage_class = interface_var->GetOperandAs(2); + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + continue; + } + if (!seen.insert(interface_id).second) { + // Pre-1.4 an interface variable could be listed multiple times in an + // entry point. Validation for 1.4 or later is done elsewhere. + continue; + } + + auto locations = (storage_class == spv::StorageClass::Input) + ? &input_locations + : &output_locations_index0; + if (auto error = GetLocationsForVariable( + _, entry_point, interface_var, locations, &output_locations_index1)) + return error; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateStorageClass(ValidationState_t& _, + const Instruction* entry_point) { + bool has_push_constant = false; + bool has_ray_payload = false; + bool has_hit_attribute = false; + bool has_callable_data = false; + for (uint32_t i = 3; i < entry_point->operands().size(); ++i) { + auto interface_id = entry_point->GetOperandAs(i); + auto interface_var = _.FindDef(interface_id); + auto storage_class = interface_var->GetOperandAs(2); + switch (storage_class) { + case spv::StorageClass::PushConstant: { + if (has_push_constant) { + return _.diag(SPV_ERROR_INVALID_DATA, entry_point) + << _.VkErrorID(6673) + << "Entry-point has more than one variable with the " + "PushConstant storage class in the interface"; + } + has_push_constant = true; + break; + } + case spv::StorageClass::IncomingRayPayloadKHR: { + if (has_ray_payload) { + return _.diag(SPV_ERROR_INVALID_DATA, entry_point) + << _.VkErrorID(4700) + << "Entry-point has more than one variable with the " + "IncomingRayPayloadKHR storage class in the interface"; + } + has_ray_payload = true; + break; + } + case spv::StorageClass::HitAttributeKHR: { + if (has_hit_attribute) { + return _.diag(SPV_ERROR_INVALID_DATA, entry_point) + << _.VkErrorID(4702) + << "Entry-point has more than one variable with the " + "HitAttributeKHR storage class in the interface"; + } + has_hit_attribute = true; + break; + } + case spv::StorageClass::IncomingCallableDataKHR: { + if (has_callable_data) { + return _.diag(SPV_ERROR_INVALID_DATA, entry_point) + << _.VkErrorID(4706) + << "Entry-point has more than one variable with the " + "IncomingCallableDataKHR storage class in the interface"; + } + has_callable_data = true; + break; + } + default: + break; + } + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t ValidateInterfaces(ValidationState_t& _) { + bool is_spv_1_4 = _.version() >= SPV_SPIRV_VERSION_WORD(1, 4); + for (auto& inst : _.ordered_instructions()) { + if (is_interface_variable(&inst, is_spv_1_4)) { + if (auto error = check_interface_variable(_, &inst)) { + return error; + } + } + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + for (auto& inst : _.ordered_instructions()) { + if (inst.opcode() == spv::Op::OpEntryPoint) { + if (auto error = ValidateLocations(_, &inst)) { + return error; + } + if (auto error = ValidateStorageClass(_, &inst)) { + return error; + } + } + if (inst.opcode() == spv::Op::OpTypeVoid) break; + } + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_layout.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_layout.cpp new file mode 100644 index 000000000000..dbc1f1e5dee5 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_layout.cpp @@ -0,0 +1,385 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Source code for logical layout validation as described in section 2.4 + +#include "DebugInfo.h" +#include "NonSemanticShaderDebugInfo100.h" +#include "OpenCLDebugInfo100.h" +#include "source/opcode.h" +#include "source/operand.h" +#include "source/val/function.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Module scoped instructions are processed by determining if the opcode +// is part of the current layout section. If it is not then the next sections is +// checked. +spv_result_t ModuleScopedInstructions(ValidationState_t& _, + const Instruction* inst, spv::Op opcode) { + switch (opcode) { + case spv::Op::OpExtInst: + if (spvExtInstIsDebugInfo(inst->ext_inst_type())) { + const uint32_t ext_inst_index = inst->word(4); + bool local_debug_info = false; + if (inst->ext_inst_type() == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) { + const OpenCLDebugInfo100Instructions ext_inst_key = + OpenCLDebugInfo100Instructions(ext_inst_index); + if (ext_inst_key == OpenCLDebugInfo100DebugScope || + ext_inst_key == OpenCLDebugInfo100DebugNoScope || + ext_inst_key == OpenCLDebugInfo100DebugDeclare || + ext_inst_key == OpenCLDebugInfo100DebugValue) { + local_debug_info = true; + } + } else if (inst->ext_inst_type() == + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { + const NonSemanticShaderDebugInfo100Instructions ext_inst_key = + NonSemanticShaderDebugInfo100Instructions(ext_inst_index); + if (ext_inst_key == NonSemanticShaderDebugInfo100DebugScope || + ext_inst_key == NonSemanticShaderDebugInfo100DebugNoScope || + ext_inst_key == NonSemanticShaderDebugInfo100DebugDeclare || + ext_inst_key == NonSemanticShaderDebugInfo100DebugValue || + ext_inst_key == NonSemanticShaderDebugInfo100DebugLine || + ext_inst_key == NonSemanticShaderDebugInfo100DebugNoLine || + ext_inst_key == + NonSemanticShaderDebugInfo100DebugFunctionDefinition) { + local_debug_info = true; + } + } else { + const DebugInfoInstructions ext_inst_key = + DebugInfoInstructions(ext_inst_index); + if (ext_inst_key == DebugInfoDebugScope || + ext_inst_key == DebugInfoDebugNoScope || + ext_inst_key == DebugInfoDebugDeclare || + ext_inst_key == DebugInfoDebugValue) { + local_debug_info = true; + } + } + + if (local_debug_info) { + if (_.in_function_body() == false) { + // DebugScope, DebugNoScope, DebugDeclare, DebugValue must + // appear in a function body. + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "DebugScope, DebugNoScope, DebugDeclare, DebugValue " + << "of debug info extension must appear in a function " + << "body"; + } + } else { + // Debug info extinst opcodes other than DebugScope, DebugNoScope, + // DebugDeclare, DebugValue must be placed between section 9 (types, + // constants, global variables) and section 10 (function + // declarations). + if (_.current_layout_section() < kLayoutTypes || + _.current_layout_section() >= kLayoutFunctionDeclarations) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Debug info extension instructions other than " + << "DebugScope, DebugNoScope, DebugDeclare, DebugValue " + << "must appear between section 9 (types, constants, " + << "global variables) and section 10 (function " + << "declarations)"; + } + } + } else if (spvExtInstIsNonSemantic(inst->ext_inst_type())) { + // non-semantic extinst opcodes are allowed beginning in the types + // section, but since they must name a return type they cannot be the + // first instruction in the types section. Therefore check that we are + // already in it. + if (_.current_layout_section() < kLayoutTypes) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Non-semantic OpExtInst must not appear before types " + << "section"; + } + } else { + // otherwise they must be used in a block + if (_.current_layout_section() < kLayoutFunctionDefinitions) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << spvOpcodeString(opcode) << " must appear in a block"; + } + } + break; + default: + break; + } + + while (_.IsOpcodeInCurrentLayoutSection(opcode) == false) { + if (_.IsOpcodeInPreviousLayoutSection(opcode)) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << spvOpcodeString(opcode) << " is in an invalid layout section"; + } + + _.ProgressToNextLayoutSectionOrder(); + + switch (_.current_layout_section()) { + case kLayoutMemoryModel: + if (opcode != spv::Op::OpMemoryModel) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << spvOpcodeString(opcode) + << " cannot appear before the memory model instruction"; + } + break; + case kLayoutFunctionDeclarations: + // All module sections have been processed. Recursively call + // ModuleLayoutPass to process the next section of the module + return ModuleLayoutPass(_, inst); + default: + break; + } + } + return SPV_SUCCESS; +} + +// Function declaration validation is performed by making sure that the +// FunctionParameter and FunctionEnd instructions only appear inside of +// functions. It also ensures that the Function instruction does not appear +// inside of another function. This stage ends when the first label is +// encountered inside of a function. +spv_result_t FunctionScopedInstructions(ValidationState_t& _, + const Instruction* inst, + spv::Op opcode) { + // Make sure we advance into the function definitions when we hit + // non-function declaration instructions. + if (_.current_layout_section() == kLayoutFunctionDeclarations && + !_.IsOpcodeInCurrentLayoutSection(opcode)) { + _.ProgressToNextLayoutSectionOrder(); + + if (_.in_function_body()) { + if (auto error = _.current_function().RegisterSetFunctionDeclType( + FunctionDecl::kFunctionDeclDefinition)) { + return error; + } + } + } + + if (_.IsOpcodeInCurrentLayoutSection(opcode)) { + switch (opcode) { + case spv::Op::OpFunction: { + if (_.in_function_body()) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Cannot declare a function in a function body"; + } + auto control_mask = inst->GetOperandAs(2); + if (auto error = + _.RegisterFunction(inst->id(), inst->type_id(), control_mask, + inst->GetOperandAs(3))) + return error; + if (_.current_layout_section() == kLayoutFunctionDefinitions) { + if (auto error = _.current_function().RegisterSetFunctionDeclType( + FunctionDecl::kFunctionDeclDefinition)) + return error; + } + } break; + + case spv::Op::OpFunctionParameter: + if (_.in_function_body() == false) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Function parameter instructions must be in a " + "function body"; + } + if (_.current_function().block_count() != 0) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Function parameters must only appear immediately after " + "the function definition"; + } + if (auto error = _.current_function().RegisterFunctionParameter( + inst->id(), inst->type_id())) + return error; + break; + + case spv::Op::OpFunctionEnd: + if (_.in_function_body() == false) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Function end instructions must be in a function body"; + } + if (_.in_block()) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Function end cannot be called in blocks"; + } + if (_.current_function().block_count() == 0 && + _.current_layout_section() == kLayoutFunctionDefinitions) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Function declarations must appear before " + "function definitions."; + } + if (_.current_layout_section() == kLayoutFunctionDeclarations) { + if (auto error = _.current_function().RegisterSetFunctionDeclType( + FunctionDecl::kFunctionDeclDeclaration)) + return error; + } + if (auto error = _.RegisterFunctionEnd()) return error; + break; + + case spv::Op::OpLine: + case spv::Op::OpNoLine: + break; + case spv::Op::OpLabel: + // If the label is encountered then the current function is a + // definition so set the function to a declaration and update the + // module section + if (_.in_function_body() == false) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Label instructions must be in a function body"; + } + if (_.in_block()) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "A block must end with a branch instruction."; + } + break; + + case spv::Op::OpExtInst: + if (spvExtInstIsDebugInfo(inst->ext_inst_type())) { + const uint32_t ext_inst_index = inst->word(4); + bool local_debug_info = false; + if (inst->ext_inst_type() == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) { + const OpenCLDebugInfo100Instructions ext_inst_key = + OpenCLDebugInfo100Instructions(ext_inst_index); + if (ext_inst_key == OpenCLDebugInfo100DebugScope || + ext_inst_key == OpenCLDebugInfo100DebugNoScope || + ext_inst_key == OpenCLDebugInfo100DebugDeclare || + ext_inst_key == OpenCLDebugInfo100DebugValue) { + local_debug_info = true; + } + } else if (inst->ext_inst_type() == + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { + const NonSemanticShaderDebugInfo100Instructions ext_inst_key = + NonSemanticShaderDebugInfo100Instructions(ext_inst_index); + if (ext_inst_key == NonSemanticShaderDebugInfo100DebugScope || + ext_inst_key == NonSemanticShaderDebugInfo100DebugNoScope || + ext_inst_key == NonSemanticShaderDebugInfo100DebugDeclare || + ext_inst_key == NonSemanticShaderDebugInfo100DebugValue || + ext_inst_key == NonSemanticShaderDebugInfo100DebugLine || + ext_inst_key == NonSemanticShaderDebugInfo100DebugNoLine || + ext_inst_key == + NonSemanticShaderDebugInfo100DebugFunctionDefinition) { + local_debug_info = true; + } + } else { + const DebugInfoInstructions ext_inst_key = + DebugInfoInstructions(ext_inst_index); + if (ext_inst_key == DebugInfoDebugScope || + ext_inst_key == DebugInfoDebugNoScope || + ext_inst_key == DebugInfoDebugDeclare || + ext_inst_key == DebugInfoDebugValue) { + local_debug_info = true; + } + } + + if (local_debug_info) { + if (_.in_function_body() == false) { + // DebugScope, DebugNoScope, DebugDeclare, DebugValue must + // appear in a function body. + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "DebugScope, DebugNoScope, DebugDeclare, DebugValue " + << "of debug info extension must appear in a function " + << "body"; + } + } else { + // Debug info extinst opcodes other than DebugScope, DebugNoScope, + // DebugDeclare, DebugValue must be placed between section 9 (types, + // constants, global variables) and section 10 (function + // declarations). + if (_.current_layout_section() < kLayoutTypes || + _.current_layout_section() >= kLayoutFunctionDeclarations) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Debug info extension instructions other than " + << "DebugScope, DebugNoScope, DebugDeclare, DebugValue " + << "must appear between section 9 (types, constants, " + << "global variables) and section 10 (function " + << "declarations)"; + } + } + } else if (spvExtInstIsNonSemantic(inst->ext_inst_type())) { + // non-semantic extinst opcodes are allowed beginning in the types + // section, but must either be placed outside a function declaration, + // or inside a block. + if (_.current_layout_section() < kLayoutTypes) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Non-semantic OpExtInst must not appear before types " + << "section"; + } else if (_.in_function_body() && _.in_block() == false) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Non-semantic OpExtInst within function definition must " + "appear in a block"; + } + } else { + // otherwise they must be used in a block + if (_.in_block() == false) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << spvOpcodeString(opcode) << " must appear in a block"; + } + } + break; + + default: + if (_.current_layout_section() == kLayoutFunctionDeclarations && + _.in_function_body()) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "A function must begin with a label"; + } else { + if (_.in_block() == false) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << spvOpcodeString(opcode) << " must appear in a block"; + } + } + break; + } + } else { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << spvOpcodeString(opcode) + << " cannot appear in a function declaration"; + } + return SPV_SUCCESS; +} + +} // namespace + +// TODO(umar): Check linkage capabilities for function declarations +// TODO(umar): Better error messages +// NOTE: This function does not handle CFG related validation +// Performs logical layout validation. See Section 2.4 +spv_result_t ModuleLayoutPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + + switch (_.current_layout_section()) { + case kLayoutCapabilities: + case kLayoutExtensions: + case kLayoutExtInstImport: + case kLayoutMemoryModel: + case kLayoutSamplerImageAddressMode: + case kLayoutEntryPoint: + case kLayoutExecutionMode: + case kLayoutDebug1: + case kLayoutDebug2: + case kLayoutDebug3: + case kLayoutAnnotations: + case kLayoutTypes: + if (auto error = ModuleScopedInstructions(_, inst, opcode)) return error; + break; + case kLayoutFunctionDeclarations: + case kLayoutFunctionDefinitions: + if (auto error = FunctionScopedInstructions(_, inst, opcode)) { + return error; + } + break; + } + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_literals.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_literals.cpp new file mode 100644 index 000000000000..15cc27a92f20 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_literals.cpp @@ -0,0 +1,96 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates literal numbers. + +#include + +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Returns true if the operand holds a literal number +bool IsLiteralNumber(const spv_parsed_operand_t& operand) { + switch (operand.number_kind) { + case SPV_NUMBER_SIGNED_INT: + case SPV_NUMBER_UNSIGNED_INT: + case SPV_NUMBER_FLOATING: + return true; + default: + return false; + } +} + +// Verifies that the upper bits of the given upper |word| with given +// lower |width| are zero- or sign-extended when |signed_int| is true +bool VerifyUpperBits(uint32_t word, uint32_t width, bool signed_int) { + assert(width < 32); + assert(0 < width); + const uint32_t upper_mask = 0xFFFFFFFFu << width; + const uint32_t upper_bits = word & upper_mask; + + bool result = false; + if (signed_int) { + const uint32_t sign_bit = word & (1u << (width - 1)); + if (sign_bit) { + result = upper_bits == upper_mask; + } else { + result = upper_bits == 0; + } + } else { + result = upper_bits == 0; + } + return result; +} + +} // namespace + +// Validates that literal numbers are represented according to the spec +spv_result_t LiteralsPass(ValidationState_t& _, const Instruction* inst) { + // For every operand that is a literal number + for (size_t i = 0; i < inst->operands().size(); i++) { + const spv_parsed_operand_t& operand = inst->operand(i); + if (!IsLiteralNumber(operand)) continue; + + // The upper bits are always in the last word (little-endian) + int last_index = operand.offset + operand.num_words - 1; + const uint32_t upper_word = inst->word(last_index); + + // TODO(jcaraban): is the |word size| defined in some header? + const uint32_t word_size = 32; + uint32_t bit_width = operand.number_bit_width; + + // Bit widths that are a multiple of the word size have no upper bits + const auto remaining_value_bits = bit_width % word_size; + if (remaining_value_bits == 0) continue; + + const bool signedness = operand.number_kind == SPV_NUMBER_SIGNED_INT; + + if (!VerifyUpperBits(upper_word, remaining_value_bits, signedness)) { + return _.diag(SPV_ERROR_INVALID_VALUE, inst) + << "The high-order bits of a literal number in instruction " + << inst->id() << " must be 0 for a floating-point type, " + << "or 0 for an integer type with Signedness of 0, " + << "or sign extended when Signedness is 1"; + } + } + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_logicals.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_logicals.cpp new file mode 100644 index 000000000000..4479e43958ae --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_logicals.cpp @@ -0,0 +1,293 @@ +// Copyright (c) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of logical SPIR-V instructions. + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +// Validates correctness of logical instructions. +spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + switch (opcode) { + case spv::Op::OpAny: + case spv::Op::OpAll: { + if (!_.IsBoolScalarType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected bool scalar type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t vector_type = _.GetOperandTypeId(inst, 2); + if (!vector_type || !_.IsBoolVectorType(vector_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operand to be vector bool: " + << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpIsNan: + case spv::Op::OpIsInf: + case spv::Op::OpIsFinite: + case spv::Op::OpIsNormal: + case spv::Op::OpSignBitSet: { + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t operand_type = _.GetOperandTypeId(inst, 2); + if (!operand_type || (!_.IsFloatScalarType(operand_type) && + !_.IsFloatVectorType(operand_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operand to be scalar or vector float: " + << spvOpcodeString(opcode); + + if (_.GetDimension(result_type) != _.GetDimension(operand_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected vector sizes of Result Type and the operand to be " + "equal: " + << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpFOrdEqual: + case spv::Op::OpFUnordEqual: + case spv::Op::OpFOrdNotEqual: + case spv::Op::OpFUnordNotEqual: + case spv::Op::OpFOrdLessThan: + case spv::Op::OpFUnordLessThan: + case spv::Op::OpFOrdGreaterThan: + case spv::Op::OpFUnordGreaterThan: + case spv::Op::OpFOrdLessThanEqual: + case spv::Op::OpFUnordLessThanEqual: + case spv::Op::OpFOrdGreaterThanEqual: + case spv::Op::OpFUnordGreaterThanEqual: + case spv::Op::OpLessOrGreater: + case spv::Op::OpOrdered: + case spv::Op::OpUnordered: { + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t left_operand_type = _.GetOperandTypeId(inst, 2); + if (!left_operand_type || (!_.IsFloatScalarType(left_operand_type) && + !_.IsFloatVectorType(left_operand_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operands to be scalar or vector float: " + << spvOpcodeString(opcode); + + if (_.GetDimension(result_type) != _.GetDimension(left_operand_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected vector sizes of Result Type and the operands to be " + "equal: " + << spvOpcodeString(opcode); + + if (left_operand_type != _.GetOperandTypeId(inst, 3)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected left and right operands to have the same type: " + << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpLogicalEqual: + case spv::Op::OpLogicalNotEqual: + case spv::Op::OpLogicalOr: + case spv::Op::OpLogicalAnd: { + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + if (result_type != _.GetOperandTypeId(inst, 2) || + result_type != _.GetOperandTypeId(inst, 3)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected both operands to be of Result Type: " + << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpLogicalNot: { + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + if (result_type != _.GetOperandTypeId(inst, 2)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operand to be of Result Type: " + << spvOpcodeString(opcode); + + break; + } + + case spv::Op::OpSelect: { + uint32_t dimension = 1; + { + const Instruction* type_inst = _.FindDef(result_type); + assert(type_inst); + + const auto composites = _.features().select_between_composites; + auto fail = [&_, composites, inst, opcode]() -> spv_result_t { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected scalar or " + << (composites ? "composite" : "vector") + << " type as Result Type: " << spvOpcodeString(opcode); + }; + + const spv::Op type_opcode = type_inst->opcode(); + switch (type_opcode) { + case spv::Op::OpTypePointer: { + if (_.addressing_model() == spv::AddressingModel::Logical && + !_.features().variable_pointers) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Using pointers with OpSelect requires capability " + << "VariablePointers or VariablePointersStorageBuffer"; + break; + } + + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampler: { + if (!_.HasCapability(spv::Capability::BindlessTextureNV)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Using image/sampler with OpSelect requires capability " + << "BindlessTextureNV"; + break; + } + + case spv::Op::OpTypeVector: { + dimension = type_inst->word(3); + break; + } + + case spv::Op::OpTypeBool: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeFloat: { + break; + } + + // Not RuntimeArray because of other rules. + case spv::Op::OpTypeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeStruct: { + if (!composites) return fail(); + break; + } + + default: + return fail(); + } + + const uint32_t condition_type = _.GetOperandTypeId(inst, 2); + const uint32_t left_type = _.GetOperandTypeId(inst, 3); + const uint32_t right_type = _.GetOperandTypeId(inst, 4); + + if (!condition_type || (!_.IsBoolScalarType(condition_type) && + !_.IsBoolVectorType(condition_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected bool scalar or vector type as condition: " + << spvOpcodeString(opcode); + + if (_.GetDimension(condition_type) != dimension) { + // If the condition is a vector type, then the result must also be a + // vector with matching dimensions. In SPIR-V 1.4, a scalar condition + // can be used to select between vector types. |composites| is a + // proxy for SPIR-V 1.4 functionality. + if (!composites || _.IsBoolVectorType(condition_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected vector sizes of Result Type and the condition " + "to be equal: " + << spvOpcodeString(opcode); + } + } + + if (result_type != left_type || result_type != right_type) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected both objects to be of Result Type: " + << spvOpcodeString(opcode); + + break; + } + } + + case spv::Op::OpIEqual: + case spv::Op::OpINotEqual: + case spv::Op::OpUGreaterThan: + case spv::Op::OpUGreaterThanEqual: + case spv::Op::OpULessThan: + case spv::Op::OpULessThanEqual: + case spv::Op::OpSGreaterThan: + case spv::Op::OpSGreaterThanEqual: + case spv::Op::OpSLessThan: + case spv::Op::OpSLessThanEqual: { + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); + + const uint32_t left_type = _.GetOperandTypeId(inst, 2); + const uint32_t right_type = _.GetOperandTypeId(inst, 3); + + if (!left_type || + (!_.IsIntScalarType(left_type) && !_.IsIntVectorType(left_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operands to be scalar or vector int: " + << spvOpcodeString(opcode); + + if (_.GetDimension(result_type) != _.GetDimension(left_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected vector sizes of Result Type and the operands to be" + << " equal: " << spvOpcodeString(opcode); + + if (!right_type || + (!_.IsIntScalarType(right_type) && !_.IsIntVectorType(right_type))) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected operands to be scalar or vector int: " + << spvOpcodeString(opcode); + + if (_.GetDimension(result_type) != _.GetDimension(right_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected vector sizes of Result Type and the operands to be" + << " equal: " << spvOpcodeString(opcode); + + if (_.GetBitWidth(left_type) != _.GetBitWidth(right_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected both operands to have the same component bit " + "width: " + << spvOpcodeString(opcode); + + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_memory.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_memory.cpp new file mode 100644 index 000000000000..c9ecf51a1e40 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_memory.cpp @@ -0,0 +1,1900 @@ +// Copyright (c) 2018 Google LLC. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validate_scopes.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +bool AreLayoutCompatibleStructs(ValidationState_t&, const Instruction*, + const Instruction*); +bool HaveLayoutCompatibleMembers(ValidationState_t&, const Instruction*, + const Instruction*); +bool HaveSameLayoutDecorations(ValidationState_t&, const Instruction*, + const Instruction*); +bool HasConflictingMemberOffsets(const std::set&, + const std::set&); + +bool IsAllowedTypeOrArrayOfSame(ValidationState_t& _, const Instruction* type, + std::initializer_list allowed) { + if (std::find(allowed.begin(), allowed.end(), type->opcode()) != + allowed.end()) { + return true; + } + if (type->opcode() == spv::Op::OpTypeArray || + type->opcode() == spv::Op::OpTypeRuntimeArray) { + auto elem_type = _.FindDef(type->word(2)); + return std::find(allowed.begin(), allowed.end(), elem_type->opcode()) != + allowed.end(); + } + return false; +} + +// Returns true if the two instructions represent structs that, as far as the +// validator can tell, have the exact same data layout. +bool AreLayoutCompatibleStructs(ValidationState_t& _, const Instruction* type1, + const Instruction* type2) { + if (type1->opcode() != spv::Op::OpTypeStruct) { + return false; + } + if (type2->opcode() != spv::Op::OpTypeStruct) { + return false; + } + + if (!HaveLayoutCompatibleMembers(_, type1, type2)) return false; + + return HaveSameLayoutDecorations(_, type1, type2); +} + +// Returns true if the operands to the OpTypeStruct instruction defining the +// types are the same or are layout compatible types. |type1| and |type2| must +// be OpTypeStruct instructions. +bool HaveLayoutCompatibleMembers(ValidationState_t& _, const Instruction* type1, + const Instruction* type2) { + assert(type1->opcode() == spv::Op::OpTypeStruct && + "type1 must be an OpTypeStruct instruction."); + assert(type2->opcode() == spv::Op::OpTypeStruct && + "type2 must be an OpTypeStruct instruction."); + const auto& type1_operands = type1->operands(); + const auto& type2_operands = type2->operands(); + if (type1_operands.size() != type2_operands.size()) { + return false; + } + + for (size_t operand = 2; operand < type1_operands.size(); ++operand) { + if (type1->word(operand) != type2->word(operand)) { + auto def1 = _.FindDef(type1->word(operand)); + auto def2 = _.FindDef(type2->word(operand)); + if (!AreLayoutCompatibleStructs(_, def1, def2)) { + return false; + } + } + } + return true; +} + +// Returns true if all decorations that affect the data layout of the struct +// (like Offset), are the same for the two types. |type1| and |type2| must be +// OpTypeStruct instructions. +bool HaveSameLayoutDecorations(ValidationState_t& _, const Instruction* type1, + const Instruction* type2) { + assert(type1->opcode() == spv::Op::OpTypeStruct && + "type1 must be an OpTypeStruct instruction."); + assert(type2->opcode() == spv::Op::OpTypeStruct && + "type2 must be an OpTypeStruct instruction."); + const std::set& type1_decorations = _.id_decorations(type1->id()); + const std::set& type2_decorations = _.id_decorations(type2->id()); + + // TODO: Will have to add other check for arrays an matricies if we want to + // handle them. + if (HasConflictingMemberOffsets(type1_decorations, type2_decorations)) { + return false; + } + + return true; +} + +bool HasConflictingMemberOffsets( + const std::set& type1_decorations, + const std::set& type2_decorations) { + { + // We are interested in conflicting decoration. If a decoration is in one + // list but not the other, then we will assume the code is correct. We are + // looking for things we know to be wrong. + // + // We do not have to traverse type2_decoration because, after traversing + // type1_decorations, anything new will not be found in + // type1_decoration. Therefore, it cannot lead to a conflict. + for (const Decoration& decoration : type1_decorations) { + switch (decoration.dec_type()) { + case spv::Decoration::Offset: { + // Since these affect the layout of the struct, they must be present + // in both structs. + auto compare = [&decoration](const Decoration& rhs) { + if (rhs.dec_type() != spv::Decoration::Offset) return false; + return decoration.struct_member_index() == + rhs.struct_member_index(); + }; + auto i = std::find_if(type2_decorations.begin(), + type2_decorations.end(), compare); + if (i != type2_decorations.end() && + decoration.params().front() != i->params().front()) { + return true; + } + } break; + default: + // This decoration does not affect the layout of the structure, so + // just moving on. + break; + } + } + } + return false; +} + +// If |skip_builtin| is true, returns true if |storage| contains bool within +// it and no storage that contains the bool is builtin. +// If |skip_builtin| is false, returns true if |storage| contains bool within +// it. +bool ContainsInvalidBool(ValidationState_t& _, const Instruction* storage, + bool skip_builtin) { + if (skip_builtin) { + for (const Decoration& decoration : _.id_decorations(storage->id())) { + if (decoration.dec_type() == spv::Decoration::BuiltIn) return false; + } + } + + const size_t elem_type_index = 1; + uint32_t elem_type_id; + Instruction* elem_type; + + switch (storage->opcode()) { + case spv::Op::OpTypeBool: + return true; + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + elem_type_id = storage->GetOperandAs(elem_type_index); + elem_type = _.FindDef(elem_type_id); + return ContainsInvalidBool(_, elem_type, skip_builtin); + case spv::Op::OpTypeStruct: + for (size_t member_type_index = 1; + member_type_index < storage->operands().size(); + ++member_type_index) { + auto member_type_id = + storage->GetOperandAs(member_type_index); + auto member_type = _.FindDef(member_type_id); + if (ContainsInvalidBool(_, member_type, skip_builtin)) return true; + } + default: + break; + } + return false; +} + +bool ContainsCooperativeMatrix(ValidationState_t& _, + const Instruction* storage) { + const size_t elem_type_index = 1; + uint32_t elem_type_id; + Instruction* elem_type; + + switch (storage->opcode()) { + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + return true; + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + elem_type_id = storage->GetOperandAs(elem_type_index); + elem_type = _.FindDef(elem_type_id); + return ContainsCooperativeMatrix(_, elem_type); + case spv::Op::OpTypeStruct: + for (size_t member_type_index = 1; + member_type_index < storage->operands().size(); + ++member_type_index) { + auto member_type_id = + storage->GetOperandAs(member_type_index); + auto member_type = _.FindDef(member_type_id); + if (ContainsCooperativeMatrix(_, member_type)) return true; + } + break; + default: + break; + } + return false; +} + +std::pair GetStorageClass( + ValidationState_t& _, const Instruction* inst) { + spv::StorageClass dst_sc = spv::StorageClass::Max; + spv::StorageClass src_sc = spv::StorageClass::Max; + switch (inst->opcode()) { + case spv::Op::OpCooperativeMatrixLoadNV: + case spv::Op::OpCooperativeMatrixLoadKHR: + case spv::Op::OpLoad: { + auto load_pointer = _.FindDef(inst->GetOperandAs(2)); + auto load_pointer_type = _.FindDef(load_pointer->type_id()); + dst_sc = load_pointer_type->GetOperandAs(1); + break; + } + case spv::Op::OpCooperativeMatrixStoreNV: + case spv::Op::OpCooperativeMatrixStoreKHR: + case spv::Op::OpStore: { + auto store_pointer = _.FindDef(inst->GetOperandAs(0)); + auto store_pointer_type = _.FindDef(store_pointer->type_id()); + dst_sc = store_pointer_type->GetOperandAs(1); + break; + } + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: { + auto dst = _.FindDef(inst->GetOperandAs(0)); + auto dst_type = _.FindDef(dst->type_id()); + dst_sc = dst_type->GetOperandAs(1); + auto src = _.FindDef(inst->GetOperandAs(1)); + auto src_type = _.FindDef(src->type_id()); + src_sc = src_type->GetOperandAs(1); + break; + } + default: + break; + } + + return std::make_pair(dst_sc, src_sc); +} + +// Returns the number of instruction words taken up by a memory access +// argument and its implied operands. +int MemoryAccessNumWords(uint32_t mask) { + int result = 1; // Count the mask + if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) ++result; + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) ++result; + return result; +} + +// Returns the scope ID operand for MakeAvailable memory access with mask +// at the given operand index. +// This function is only called for OpLoad, OpStore, OpCopyMemory and +// OpCopyMemorySized, OpCooperativeMatrixLoadNV, and +// OpCooperativeMatrixStoreNV. +uint32_t GetMakeAvailableScope(const Instruction* inst, uint32_t mask, + uint32_t mask_index) { + assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)); + uint32_t this_bit = uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR); + uint32_t index = + mask_index - 1 + MemoryAccessNumWords(mask & (this_bit | (this_bit - 1))); + return inst->GetOperandAs(index); +} + +// This function is only called for OpLoad, OpStore, OpCopyMemory, +// OpCopyMemorySized, OpCooperativeMatrixLoadNV, and +// OpCooperativeMatrixStoreNV. +uint32_t GetMakeVisibleScope(const Instruction* inst, uint32_t mask, + uint32_t mask_index) { + assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)); + uint32_t this_bit = uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR); + uint32_t index = + mask_index - 1 + MemoryAccessNumWords(mask & (this_bit | (this_bit - 1))); + return inst->GetOperandAs(index); +} + +bool DoesStructContainRTA(const ValidationState_t& _, const Instruction* inst) { + for (size_t member_index = 1; member_index < inst->operands().size(); + ++member_index) { + const auto member_id = inst->GetOperandAs(member_index); + const auto member_type = _.FindDef(member_id); + if (member_type->opcode() == spv::Op::OpTypeRuntimeArray) return true; + } + return false; +} + +spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, + uint32_t index) { + spv::StorageClass dst_sc, src_sc; + std::tie(dst_sc, src_sc) = GetStorageClass(_, inst); + if (inst->operands().size() <= index) { + // Cases where lack of some operand is invalid + if (src_sc == spv::StorageClass::PhysicalStorageBuffer || + dst_sc == spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4708) + << "Memory accesses with PhysicalStorageBuffer must use Aligned."; + } + return SPV_SUCCESS; + } + + const uint32_t mask = inst->GetOperandAs(index); + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) { + if (inst->opcode() == spv::Op::OpLoad || + inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV || + inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "MakePointerAvailableKHR cannot be used with OpLoad."; + } + + if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "NonPrivatePointerKHR must be specified if " + "MakePointerAvailableKHR is specified."; + } + + // Check the associated scope for MakeAvailableKHR. + const auto available_scope = GetMakeAvailableScope(inst, mask, index); + if (auto error = ValidateMemoryScope(_, inst, available_scope)) + return error; + } + + if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) { + if (inst->opcode() == spv::Op::OpStore || + inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "MakePointerVisibleKHR cannot be used with OpStore."; + } + + if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "NonPrivatePointerKHR must be specified if " + << "MakePointerVisibleKHR is specified."; + } + + // Check the associated scope for MakeVisibleKHR. + const auto visible_scope = GetMakeVisibleScope(inst, mask, index); + if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error; + } + + if (mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR)) { + if (dst_sc != spv::StorageClass::Uniform && + dst_sc != spv::StorageClass::Workgroup && + dst_sc != spv::StorageClass::CrossWorkgroup && + dst_sc != spv::StorageClass::Generic && + dst_sc != spv::StorageClass::Image && + dst_sc != spv::StorageClass::StorageBuffer && + dst_sc != spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "NonPrivatePointerKHR requires a pointer in Uniform, " + << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer " + << "storage classes."; + } + if (src_sc != spv::StorageClass::Max && + src_sc != spv::StorageClass::Uniform && + src_sc != spv::StorageClass::Workgroup && + src_sc != spv::StorageClass::CrossWorkgroup && + src_sc != spv::StorageClass::Generic && + src_sc != spv::StorageClass::Image && + src_sc != spv::StorageClass::StorageBuffer && + src_sc != spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "NonPrivatePointerKHR requires a pointer in Uniform, " + << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer " + << "storage classes."; + } + } + + if (!(mask & uint32_t(spv::MemoryAccessMask::Aligned))) { + if (src_sc == spv::StorageClass::PhysicalStorageBuffer || + dst_sc == spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4708) + << "Memory accesses with PhysicalStorageBuffer must use Aligned."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { + auto result_type = _.FindDef(inst->type_id()); + if (!result_type || result_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVariable Result Type " << _.getIdName(inst->type_id()) + << " is not a pointer type."; + } + + const auto type_index = 2; + const auto value_id = result_type->GetOperandAs(type_index); + auto value_type = _.FindDef(value_id); + + const auto initializer_index = 3; + const auto storage_class_index = 2; + if (initializer_index < inst->operands().size()) { + const auto initializer_id = inst->GetOperandAs(initializer_index); + const auto initializer = _.FindDef(initializer_id); + const auto is_module_scope_var = + initializer && (initializer->opcode() == spv::Op::OpVariable) && + (initializer->GetOperandAs(storage_class_index) != + spv::StorageClass::Function); + const auto is_constant = + initializer && spvOpcodeIsConstant(initializer->opcode()); + if (!initializer || !(is_constant || is_module_scope_var)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVariable Initializer " << _.getIdName(initializer_id) + << " is not a constant or module-scope variable."; + } + if (initializer->type_id() != value_id) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Initializer type must match the type pointed to by the Result " + "Type"; + } + } + + auto storage_class = + inst->GetOperandAs(storage_class_index); + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::CrossWorkgroup && + storage_class != spv::StorageClass::Private && + storage_class != spv::StorageClass::Function && + storage_class != spv::StorageClass::UniformConstant && + storage_class != spv::StorageClass::RayPayloadKHR && + storage_class != spv::StorageClass::IncomingRayPayloadKHR && + storage_class != spv::StorageClass::HitAttributeKHR && + storage_class != spv::StorageClass::CallableDataKHR && + storage_class != spv::StorageClass::IncomingCallableDataKHR && + storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT && + storage_class != spv::StorageClass::HitObjectAttributeNV) { + bool storage_input_or_output = storage_class == spv::StorageClass::Input || + storage_class == spv::StorageClass::Output; + bool builtin = false; + if (storage_input_or_output) { + for (const Decoration& decoration : _.id_decorations(inst->id())) { + if (decoration.dec_type() == spv::Decoration::BuiltIn) { + builtin = true; + break; + } + } + } + if (!builtin && + ContainsInvalidBool(_, value_type, storage_input_or_output)) { + if (storage_input_or_output) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(7290) + << "If OpTypeBool is stored in conjunction with OpVariable " + "using Input or Output Storage Classes it requires a BuiltIn " + "decoration"; + + } else { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "If OpTypeBool is stored in conjunction with OpVariable, it " + "can only be used with non-externally visible shader Storage " + "Classes: Workgroup, CrossWorkgroup, Private, Function, " + "Input, Output, RayPayloadKHR, IncomingRayPayloadKHR, " + "HitAttributeKHR, CallableDataKHR, " + "IncomingCallableDataKHR, or UniformConstant"; + } + } + } + + if (!_.IsValidStorageClass(storage_class)) { + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << _.VkErrorID(4643) + << "Invalid storage class for target environment"; + } + + if (storage_class == spv::StorageClass::Generic) { + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << "OpVariable storage class cannot be Generic"; + } + + if (inst->function() && storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Variables must have a function[7] storage class inside" + " of a function"; + } + + if (!inst->function() && storage_class == spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) + << "Variables can not have a function[7] storage class " + "outside of a function"; + } + + // SPIR-V 3.32.8: Check that pointer type and variable type have the same + // storage class. + const auto result_storage_class_index = 1; + const auto result_storage_class = + result_type->GetOperandAs(result_storage_class_index); + if (storage_class != result_storage_class) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "From SPIR-V spec, section 3.32.8 on OpVariable:\n" + << "Its Storage Class operand must be the same as the Storage Class " + << "operand of the result type."; + } + + // Variable pointer related restrictions. + const auto pointee = _.FindDef(result_type->word(3)); + if (_.addressing_model() == spv::AddressingModel::Logical && + !_.options()->relax_logical_pointer) { + // VariablePointersStorageBuffer is implied by VariablePointers. + if (pointee->opcode() == spv::Op::OpTypePointer) { + if (!_.HasCapability(spv::Capability::VariablePointersStorageBuffer)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "In Logical addressing, variables may not allocate a pointer " + << "type"; + } else if (storage_class != spv::StorageClass::Function && + storage_class != spv::StorageClass::Private) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "In Logical addressing with variable pointers, variables " + << "that allocate pointers must be in Function or Private " + << "storage classes"; + } + } + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + // Vulkan Push Constant Interface section: Check type of PushConstant + // variables. + if (storage_class == spv::StorageClass::PushConstant) { + if (pointee->opcode() != spv::Op::OpTypeStruct) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(6808) << "PushConstant OpVariable " + << _.getIdName(inst->id()) << " has illegal type.\n" + << "From Vulkan spec, Push Constant Interface section:\n" + << "Such variables must be typed as OpTypeStruct"; + } + } + + // Vulkan Descriptor Set Interface: Check type of UniformConstant and + // Uniform variables. + if (storage_class == spv::StorageClass::UniformConstant) { + if (!IsAllowedTypeOrArrayOfSame( + _, pointee, + {spv::Op::OpTypeImage, spv::Op::OpTypeSampler, + spv::Op::OpTypeSampledImage, + spv::Op::OpTypeAccelerationStructureKHR})) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4655) << "UniformConstant OpVariable " + << _.getIdName(inst->id()) << " has illegal type.\n" + << "Variables identified with the UniformConstant storage class " + << "are used only as handles to refer to opaque resources. Such " + << "variables must be typed as OpTypeImage, OpTypeSampler, " + << "OpTypeSampledImage, OpTypeAccelerationStructureKHR, " + << "or an array of one of these types."; + } + } + + if (storage_class == spv::StorageClass::Uniform) { + if (!IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(6807) << "Uniform OpVariable " + << _.getIdName(inst->id()) << " has illegal type.\n" + << "From Vulkan spec:\n" + << "Variables identified with the Uniform storage class are " + << "used to access transparent buffer backed resources. Such " + << "variables must be typed as OpTypeStruct, or an array of " + << "this type"; + } + } + + if (storage_class == spv::StorageClass::StorageBuffer) { + if (!IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(6807) << "StorageBuffer OpVariable " + << _.getIdName(inst->id()) << " has illegal type.\n" + << "From Vulkan spec:\n" + << "Variables identified with the StorageBuffer storage class " + "are used to access transparent buffer backed resources. " + "Such variables must be typed as OpTypeStruct, or an array " + "of this type"; + } + } + + // Check for invalid use of Invariant + if (storage_class != spv::StorageClass::Input && + storage_class != spv::StorageClass::Output) { + if (_.HasDecoration(inst->id(), spv::Decoration::Invariant)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4677) + << "Variable decorated with Invariant must only be identified " + "with the Input or Output storage class in Vulkan " + "environment."; + } + // Need to check if only the members in a struct are decorated + if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) { + if (_.HasDecoration(value_id, spv::Decoration::Invariant)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4677) + << "Variable struct member decorated with Invariant must only " + "be identified with the Input or Output storage class in " + "Vulkan environment."; + } + } + } + + // Initializers in Vulkan are only allowed in some storage clases + if (inst->operands().size() > 3) { + if (storage_class == spv::StorageClass::Workgroup) { + auto init_id = inst->GetOperandAs(3); + auto init = _.FindDef(init_id); + if (init->opcode() != spv::Op::OpConstantNull) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4734) << "OpVariable, " + << _.getIdName(inst->id()) + << ", initializers are limited to OpConstantNull in " + "Workgroup " + "storage class"; + } + } else if (storage_class != spv::StorageClass::Output && + storage_class != spv::StorageClass::Private && + storage_class != spv::StorageClass::Function) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4651) << "OpVariable, " + << _.getIdName(inst->id()) + << ", has a disallowed initializer & storage class " + << "combination.\n" + << "From " << spvLogStringForEnv(_.context()->target_env) + << " spec:\n" + << "Variable declarations that include initializers must have " + << "one of the following storage classes: Output, Private, " + << "Function or Workgroup"; + } + } + } + + if (inst->operands().size() > 3) { + if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVariable, " << _.getIdName(inst->id()) + << ", initializer are not allowed for TaskPayloadWorkgroupEXT"; + } + if (storage_class == spv::StorageClass::Input) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVariable, " << _.getIdName(inst->id()) + << ", initializer are not allowed for Input"; + } + if (storage_class == spv::StorageClass::HitObjectAttributeNV) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVariable, " << _.getIdName(inst->id()) + << ", initializer are not allowed for HitObjectAttributeNV"; + } + } + + if (storage_class == spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "PhysicalStorageBuffer must not be used with OpVariable."; + } + + auto pointee_base = pointee; + while (pointee_base->opcode() == spv::Op::OpTypeArray) { + pointee_base = _.FindDef(pointee_base->GetOperandAs(1u)); + } + if (pointee_base->opcode() == spv::Op::OpTypePointer) { + if (pointee_base->GetOperandAs(1u) == + spv::StorageClass::PhysicalStorageBuffer) { + // check for AliasedPointer/RestrictPointer + bool foundAliased = + _.HasDecoration(inst->id(), spv::Decoration::AliasedPointer); + bool foundRestrict = + _.HasDecoration(inst->id(), spv::Decoration::RestrictPointer); + if (!foundAliased && !foundRestrict) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVariable " << inst->id() + << ": expected AliasedPointer or RestrictPointer for " + << "PhysicalStorageBuffer pointer."; + } + if (foundAliased && foundRestrict) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpVariable " << inst->id() + << ": can't specify both AliasedPointer and " + << "RestrictPointer for PhysicalStorageBuffer pointer."; + } + } + } + + // Vulkan specific validation rules for OpTypeRuntimeArray + if (spvIsVulkanEnv(_.context()->target_env)) { + // OpTypeRuntimeArray should only ever be in a container like OpTypeStruct, + // so should never appear as a bare variable. + // Unless the module has the RuntimeDescriptorArrayEXT capability. + if (value_type && value_type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (!_.HasCapability(spv::Capability::RuntimeDescriptorArrayEXT)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) << "OpVariable, " + << _.getIdName(inst->id()) + << ", is attempting to create memory for an illegal type, " + << "OpTypeRuntimeArray.\nFor Vulkan OpTypeRuntimeArray can only " + << "appear as the final member of an OpTypeStruct, thus cannot " + << "be instantiated via OpVariable"; + } else { + // A bare variable OpTypeRuntimeArray is allowed in this context, but + // still need to check the storage class. + if (storage_class != spv::StorageClass::StorageBuffer && + storage_class != spv::StorageClass::Uniform && + storage_class != spv::StorageClass::UniformConstant) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) + << "For Vulkan with RuntimeDescriptorArrayEXT, a variable " + << "containing OpTypeRuntimeArray must have storage class of " + << "StorageBuffer, Uniform, or UniformConstant."; + } + } + } + + // If an OpStruct has an OpTypeRuntimeArray somewhere within it, then it + // must either have the storage class StorageBuffer and be decorated + // with Block, or it must be in the Uniform storage class and be decorated + // as BufferBlock. + if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) { + if (DoesStructContainRTA(_, value_type)) { + if (storage_class == spv::StorageClass::StorageBuffer || + storage_class == spv::StorageClass::PhysicalStorageBuffer) { + if (!_.HasDecoration(value_id, spv::Decoration::Block)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) + << "For Vulkan, an OpTypeStruct variable containing an " + << "OpTypeRuntimeArray must be decorated with Block if it " + << "has storage class StorageBuffer or " + "PhysicalStorageBuffer."; + } + } else if (storage_class == spv::StorageClass::Uniform) { + if (!_.HasDecoration(value_id, spv::Decoration::BufferBlock)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) + << "For Vulkan, an OpTypeStruct variable containing an " + << "OpTypeRuntimeArray must be decorated with BufferBlock " + << "if it has storage class Uniform."; + } + } else { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) + << "For Vulkan, OpTypeStruct variables containing " + << "OpTypeRuntimeArray must have storage class of " + << "StorageBuffer, PhysicalStorageBuffer, or Uniform."; + } + } + } + } + + // Cooperative matrix types can only be allocated in Function or Private + if ((storage_class != spv::StorageClass::Function && + storage_class != spv::StorageClass::Private) && + ContainsCooperativeMatrix(_, pointee)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cooperative matrix types (or types containing them) can only be " + "allocated " + << "in Function or Private storage classes or as function " + "parameters"; + } + + if (_.HasCapability(spv::Capability::Shader)) { + // Don't allow variables containing 16-bit elements without the appropriate + // capabilities. + if ((!_.HasCapability(spv::Capability::Int16) && + _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 16)) || + (!_.HasCapability(spv::Capability::Float16) && + _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeFloat, 16))) { + auto underlying_type = value_type; + while (underlying_type->opcode() == spv::Op::OpTypePointer) { + storage_class = underlying_type->GetOperandAs(1u); + underlying_type = + _.FindDef(underlying_type->GetOperandAs(2u)); + } + bool storage_class_ok = true; + std::string sc_name = _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class)); + switch (storage_class) { + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::PhysicalStorageBuffer: + if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess)) { + storage_class_ok = false; + } + break; + case spv::StorageClass::Uniform: + if (!_.HasCapability( + spv::Capability::UniformAndStorageBuffer16BitAccess)) { + if (underlying_type->opcode() == spv::Op::OpTypeArray || + underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) { + underlying_type = + _.FindDef(underlying_type->GetOperandAs(1u)); + } + if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess) || + !_.HasDecoration(underlying_type->id(), + spv::Decoration::BufferBlock)) { + storage_class_ok = false; + } + } + break; + case spv::StorageClass::PushConstant: + if (!_.HasCapability(spv::Capability::StoragePushConstant16)) { + storage_class_ok = false; + } + break; + case spv::StorageClass::Input: + case spv::StorageClass::Output: + if (!_.HasCapability(spv::Capability::StorageInputOutput16)) { + storage_class_ok = false; + } + break; + case spv::StorageClass::Workgroup: + if (!_.HasCapability( + spv::Capability:: + WorkgroupMemoryExplicitLayout16BitAccessKHR)) { + storage_class_ok = false; + } + break; + default: + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cannot allocate a variable containing a 16-bit type in " + << sc_name << " storage class"; + } + if (!storage_class_ok) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Allocating a variable containing a 16-bit element in " + << sc_name << " storage class requires an additional capability"; + } + } + // Don't allow variables containing 8-bit elements without the appropriate + // capabilities. + if (!_.HasCapability(spv::Capability::Int8) && + _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 8)) { + auto underlying_type = value_type; + while (underlying_type->opcode() == spv::Op::OpTypePointer) { + storage_class = underlying_type->GetOperandAs(1u); + underlying_type = + _.FindDef(underlying_type->GetOperandAs(2u)); + } + bool storage_class_ok = true; + std::string sc_name = _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class)); + switch (storage_class) { + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::PhysicalStorageBuffer: + if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess)) { + storage_class_ok = false; + } + break; + case spv::StorageClass::Uniform: + if (!_.HasCapability( + spv::Capability::UniformAndStorageBuffer8BitAccess)) { + if (underlying_type->opcode() == spv::Op::OpTypeArray || + underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) { + underlying_type = + _.FindDef(underlying_type->GetOperandAs(1u)); + } + if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess) || + !_.HasDecoration(underlying_type->id(), + spv::Decoration::BufferBlock)) { + storage_class_ok = false; + } + } + break; + case spv::StorageClass::PushConstant: + if (!_.HasCapability(spv::Capability::StoragePushConstant8)) { + storage_class_ok = false; + } + break; + case spv::StorageClass::Workgroup: + if (!_.HasCapability( + spv::Capability:: + WorkgroupMemoryExplicitLayout8BitAccessKHR)) { + storage_class_ok = false; + } + break; + default: + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cannot allocate a variable containing a 8-bit type in " + << sc_name << " storage class"; + } + if (!storage_class_ok) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Allocating a variable containing a 8-bit element in " + << sc_name << " storage class requires an additional capability"; + } + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) { + const auto result_type = _.FindDef(inst->type_id()); + if (!result_type) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpLoad Result Type " << _.getIdName(inst->type_id()) + << " is not defined."; + } + + const auto pointer_index = 2; + const auto pointer_id = inst->GetOperandAs(pointer_index); + const auto pointer = _.FindDef(pointer_id); + if (!pointer || + ((_.addressing_model() == spv::AddressingModel::Logical) && + ((!_.features().variable_pointers && + !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || + (_.features().variable_pointers && + !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpLoad Pointer " << _.getIdName(pointer_id) + << " is not a logical pointer."; + } + + const auto pointer_type = _.FindDef(pointer->type_id()); + if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpLoad type for pointer " << _.getIdName(pointer_id) + << " is not a pointer type."; + } + + uint32_t pointee_data_type; + spv::StorageClass storage_class; + if (!_.GetPointerTypeInfo(pointer_type->id(), &pointee_data_type, + &storage_class) || + result_type->id() != pointee_data_type) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpLoad Result Type " << _.getIdName(inst->type_id()) + << " does not match Pointer " << _.getIdName(pointer->id()) + << "s type."; + } + + if (!_.options()->before_hlsl_legalization && + _.ContainsRuntimeArray(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cannot load a runtime-sized array"; + } + + if (auto error = CheckMemoryAccess(_, inst, 3)) return error; + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && + result_type->opcode() != spv::Op::OpTypePointer) { + if (result_type->opcode() != spv::Op::OpTypeInt && + result_type->opcode() != spv::Op::OpTypeFloat && + result_type->opcode() != spv::Op::OpTypeVector && + result_type->opcode() != spv::Op::OpTypeMatrix) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "8- or 16-bit loads must be a scalar, vector or matrix type"; + } + } + + _.RegisterQCOMImageProcessingTextureConsumer(pointer_id, inst, nullptr); + + return SPV_SUCCESS; +} + +spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { + const auto pointer_index = 0; + const auto pointer_id = inst->GetOperandAs(pointer_index); + const auto pointer = _.FindDef(pointer_id); + if (!pointer || + (_.addressing_model() == spv::AddressingModel::Logical && + ((!_.features().variable_pointers && + !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || + (_.features().variable_pointers && + !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore Pointer " << _.getIdName(pointer_id) + << " is not a logical pointer."; + } + const auto pointer_type = _.FindDef(pointer->type_id()); + if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore type for pointer " << _.getIdName(pointer_id) + << " is not a pointer type."; + } + const auto type_id = pointer_type->GetOperandAs(2); + const auto type = _.FindDef(type_id); + if (!type || spv::Op::OpTypeVoid == type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore Pointer " << _.getIdName(pointer_id) + << "s type is void."; + } + + // validate storage class + { + uint32_t data_type; + spv::StorageClass storage_class; + if (!_.GetPointerTypeInfo(pointer_type->id(), &data_type, &storage_class)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore Pointer " << _.getIdName(pointer_id) + << " is not pointer type"; + } + + if (storage_class == spv::StorageClass::UniformConstant || + storage_class == spv::StorageClass::Input || + storage_class == spv::StorageClass::PushConstant) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore Pointer " << _.getIdName(pointer_id) + << " storage class is read-only"; + } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "ShaderRecordBufferKHR Storage Class variables are read only"; + } else if (storage_class == spv::StorageClass::HitAttributeKHR) { + std::string errorVUID = _.VkErrorID(4703); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model == spv::ExecutionModel::AnyHitKHR || + model == spv::ExecutionModel::ClosestHitKHR) { + if (message) { + *message = + errorVUID + + "HitAttributeKHR Storage Class variables are read only " + "with AnyHitKHR and ClosestHitKHR"; + } + return false; + } + return true; + }); + } + + if (spvIsVulkanEnv(_.context()->target_env) && + storage_class == spv::StorageClass::Uniform) { + auto base_ptr = _.TracePointer(pointer); + if (base_ptr->opcode() == spv::Op::OpVariable) { + // If it's not a variable a different check should catch the problem. + auto base_type = _.FindDef(base_ptr->GetOperandAs(0)); + // Get the pointed-to type. + base_type = _.FindDef(base_type->GetOperandAs(2u)); + if (base_type->opcode() == spv::Op::OpTypeArray || + base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + base_type = _.FindDef(base_type->GetOperandAs(1u)); + } + if (_.HasDecoration(base_type->id(), spv::Decoration::Block)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(6925) + << "In the Vulkan environment, cannot store to Uniform Blocks"; + } + } + } + } + + const auto object_index = 1; + const auto object_id = inst->GetOperandAs(object_index); + const auto object = _.FindDef(object_id); + if (!object || !object->type_id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore Object " << _.getIdName(object_id) + << " is not an object."; + } + const auto object_type = _.FindDef(object->type_id()); + if (!object_type || spv::Op::OpTypeVoid == object_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore Object " << _.getIdName(object_id) + << "s type is void."; + } + + if (type->id() != object_type->id()) { + if (!_.options()->relax_struct_store || + type->opcode() != spv::Op::OpTypeStruct || + object_type->opcode() != spv::Op::OpTypeStruct) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore Pointer " << _.getIdName(pointer_id) + << "s type does not match Object " + << _.getIdName(object->id()) << "s type."; + } + + // TODO: Check for layout compatible matricies and arrays as well. + if (!AreLayoutCompatibleStructs(_, type, object_type)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpStore Pointer " << _.getIdName(pointer_id) + << "s layout does not match Object " + << _.getIdName(object->id()) << "s layout."; + } + } + + if (auto error = CheckMemoryAccess(_, inst, 2)) return error; + + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && + object_type->opcode() != spv::Op::OpTypePointer) { + if (object_type->opcode() != spv::Op::OpTypeInt && + object_type->opcode() != spv::Op::OpTypeFloat && + object_type->opcode() != spv::Op::OpTypeVector && + object_type->opcode() != spv::Op::OpTypeMatrix) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "8- or 16-bit stores must be a scalar, vector or matrix type"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateCopyMemoryMemoryAccess(ValidationState_t& _, + const Instruction* inst) { + assert(inst->opcode() == spv::Op::OpCopyMemory || + inst->opcode() == spv::Op::OpCopyMemorySized); + const uint32_t first_access_index = + inst->opcode() == spv::Op::OpCopyMemory ? 2 : 3; + if (inst->operands().size() > first_access_index) { + if (auto error = CheckMemoryAccess(_, inst, first_access_index)) + return error; + + const auto first_access = inst->GetOperandAs(first_access_index); + const uint32_t second_access_index = + first_access_index + MemoryAccessNumWords(first_access); + if (inst->operands().size() > second_access_index) { + if (_.features().copy_memory_permits_two_memory_accesses) { + if (auto error = CheckMemoryAccess(_, inst, second_access_index)) + return error; + + // In the two-access form in SPIR-V 1.4 and later: + // - the first is the target (write) access and it can't have + // make-visible. + // - the second is the source (read) access and it can't have + // make-available. + if (first_access & + uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Target memory access must not include " + "MakePointerVisibleKHR"; + } + const auto second_access = + inst->GetOperandAs(second_access_index); + if (second_access & + uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Source memory access must not include " + "MakePointerAvailableKHR"; + } + } else { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(static_cast(inst->opcode())) + << " with two memory access operands requires SPIR-V 1.4 or " + "later"; + } + } + } + return SPV_SUCCESS; +} + +spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { + const auto target_index = 0; + const auto target_id = inst->GetOperandAs(target_index); + const auto target = _.FindDef(target_id); + if (!target) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Target operand " << _.getIdName(target_id) + << " is not defined."; + } + + const auto source_index = 1; + const auto source_id = inst->GetOperandAs(source_index); + const auto source = _.FindDef(source_id); + if (!source) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Source operand " << _.getIdName(source_id) + << " is not defined."; + } + + const auto target_pointer_type = _.FindDef(target->type_id()); + if (!target_pointer_type || + target_pointer_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Target operand " << _.getIdName(target_id) + << " is not a pointer."; + } + + const auto source_pointer_type = _.FindDef(source->type_id()); + if (!source_pointer_type || + source_pointer_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Source operand " << _.getIdName(source_id) + << " is not a pointer."; + } + + if (inst->opcode() == spv::Op::OpCopyMemory) { + const auto target_type = + _.FindDef(target_pointer_type->GetOperandAs(2)); + if (!target_type || target_type->opcode() == spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Target operand " << _.getIdName(target_id) + << " cannot be a void pointer."; + } + + const auto source_type = + _.FindDef(source_pointer_type->GetOperandAs(2)); + if (!source_type || source_type->opcode() == spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Source operand " << _.getIdName(source_id) + << " cannot be a void pointer."; + } + + if (target_type->id() != source_type->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Target " << _.getIdName(source_id) + << "s type does not match Source " + << _.getIdName(source_type->id()) << "s type."; + } + } else { + const auto size_id = inst->GetOperandAs(2); + const auto size = _.FindDef(size_id); + if (!size) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size operand " << _.getIdName(size_id) + << " is not defined."; + } + + const auto size_type = _.FindDef(size->type_id()); + if (!_.IsIntScalarType(size_type->id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size operand " << _.getIdName(size_id) + << " must be a scalar integer type."; + } + + bool is_zero = true; + switch (size->opcode()) { + case spv::Op::OpConstantNull: + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size operand " << _.getIdName(size_id) + << " cannot be a constant zero."; + case spv::Op::OpConstant: + if (size_type->word(3) == 1 && + size->word(size->words().size() - 1) & 0x80000000) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size operand " << _.getIdName(size_id) + << " cannot have the sign bit set to 1."; + } + for (size_t i = 3; is_zero && i < size->words().size(); ++i) { + is_zero &= (size->word(i) == 0); + } + if (is_zero) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Size operand " << _.getIdName(size_id) + << " cannot be a constant zero."; + } + break; + default: + // Cannot infer any other opcodes. + break; + } + } + if (auto error = ValidateCopyMemoryMemoryAccess(_, inst)) return error; + + // Get past the pointers to avoid checking a pointer copy. + auto sub_type = _.FindDef(target_pointer_type->GetOperandAs(2)); + while (sub_type->opcode() == spv::Op::OpTypePointer) { + sub_type = _.FindDef(sub_type->GetOperandAs(2)); + } + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(sub_type->id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cannot copy memory of objects containing 8- or 16-bit types"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateAccessChain(ValidationState_t& _, + const Instruction* inst) { + std::string instr_name = + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + + // The result type must be OpTypePointer. + auto result_type = _.FindDef(inst->type_id()); + if (spv::Op::OpTypePointer != result_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Result Type of " << instr_name << " " + << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op" + << spvOpcodeString(static_cast(result_type->opcode())) + << "."; + } + + // Result type is a pointer. Find out what it's pointing to. + // This will be used to make sure the indexing results in the same type. + // OpTypePointer word 3 is the type being pointed to. + const auto result_type_pointee = _.FindDef(result_type->word(3)); + + // Base must be a pointer, pointing to the base of a composite object. + const auto base_index = 2; + const auto base_id = inst->GetOperandAs(base_index); + const auto base = _.FindDef(base_id); + const auto base_type = _.FindDef(base->type_id()); + if (!base_type || spv::Op::OpTypePointer != base_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Base " << _.getIdName(base_id) << " in " << instr_name + << " instruction must be a pointer."; + } + + // The result pointer storage class and base pointer storage class must match. + // Word 2 of OpTypePointer is the Storage Class. + auto result_type_storage_class = result_type->word(2); + auto base_type_storage_class = base_type->word(2); + if (result_type_storage_class != base_type_storage_class) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The result pointer storage class and base " + "pointer storage class in " + << instr_name << " do not match."; + } + + // The type pointed to by OpTypePointer (word 3) must be a composite type. + auto type_pointee = _.FindDef(base_type->word(3)); + + // Check Universal Limit (SPIR-V Spec. Section 2.17). + // The number of indexes passed to OpAccessChain may not exceed 255 + // The instruction includes 4 words + N words (for N indexes) + size_t num_indexes = inst->words().size() - 4; + if (inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { + // In pointer access chains, the element operand is required, but not + // counted as an index. + --num_indexes; + } + const size_t num_indexes_limit = + _.options()->universal_limits_.max_access_chain_indexes; + if (num_indexes > num_indexes_limit) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The number of indexes in " << instr_name << " may not exceed " + << num_indexes_limit << ". Found " << num_indexes << " indexes."; + } + // Indexes walk the type hierarchy to the desired depth, potentially down to + // scalar granularity. The first index in Indexes will select the top-level + // member/element/component/element of the base composite. All composite + // constituents use zero-based numbering, as described by their OpType... + // instruction. The second index will apply similarly to that result, and so + // on. Once any non-composite type is reached, there must be no remaining + // (unused) indexes. + auto starting_index = 4; + if (inst->opcode() == spv::Op::OpPtrAccessChain || + inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { + ++starting_index; + } + for (size_t i = starting_index; i < inst->words().size(); ++i) { + const uint32_t cur_word = inst->words()[i]; + // Earlier ID checks ensure that cur_word definition exists. + auto cur_word_instr = _.FindDef(cur_word); + // The index must be a scalar integer type (See OpAccessChain in the Spec.) + auto index_type = _.FindDef(cur_word_instr->type_id()); + if (!index_type || spv::Op::OpTypeInt != index_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Indexes passed to " << instr_name + << " must be of type integer."; + } + switch (type_pointee->opcode()) { + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: { + // In OpTypeMatrix, OpTypeVector, spv::Op::OpTypeCooperativeMatrixNV, + // OpTypeArray, and OpTypeRuntimeArray, word 2 is the Element Type. + type_pointee = _.FindDef(type_pointee->word(2)); + break; + } + case spv::Op::OpTypeStruct: { + // In case of structures, there is an additional constraint on the + // index: the index must be an OpConstant. + int64_t cur_index; + if (!_.EvalConstantValInt64(cur_word, &cur_index)) { + return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr) + << "The passed to " << instr_name + << " to index into a " + "structure must be an OpConstant."; + } + + // The index points to the struct member we want, therefore, the index + // should be less than the number of struct members. + const int64_t num_struct_members = + static_cast(type_pointee->words().size() - 2); + if (cur_index >= num_struct_members || cur_index < 0) { + return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr) + << "Index is out of bounds: " << instr_name + << " cannot find index " << cur_index + << " into the structure " + << _.getIdName(type_pointee->id()) << ". This structure has " + << num_struct_members << " members. Largest valid index is " + << num_struct_members - 1 << "."; + } + // Struct members IDs start at word 2 of OpTypeStruct. + const size_t word_index = static_cast(cur_index) + 2; + auto structMemberId = type_pointee->word(word_index); + type_pointee = _.FindDef(structMemberId); + break; + } + default: { + // Give an error. reached non-composite type while indexes still remain. + return _.diag(SPV_ERROR_INVALID_ID, inst) + << instr_name + << " reached non-composite type while indexes " + "still remain to be traversed."; + } + } + } + // At this point, we have fully walked down from the base using the indices. + // The type being pointed to should be the same as the result type. + if (type_pointee->id() != result_type_pointee->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << instr_name << " result type (Op" + << spvOpcodeString( + static_cast(result_type_pointee->opcode())) + << ") does not match the type that results from indexing into the " + "base " + " (Op" + << spvOpcodeString(static_cast(type_pointee->opcode())) + << ")."; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidatePtrAccessChain(ValidationState_t& _, + const Instruction* inst) { + if (_.addressing_model() == spv::AddressingModel::Logical) { + if (!_.features().variable_pointers) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Generating variable pointers requires capability " + << "VariablePointers or VariablePointersStorageBuffer"; + } + } + + // Need to call first, will make sure Base is a valid ID + if (auto error = ValidateAccessChain(_, inst)) return error; + + const auto base_id = inst->GetOperandAs(2); + const auto base = _.FindDef(base_id); + const auto base_type = _.FindDef(base->type_id()); + const auto base_type_storage_class = + base_type->GetOperandAs(1); + + if (_.HasCapability(spv::Capability::Shader) && + (base_type_storage_class == spv::StorageClass::Uniform || + base_type_storage_class == spv::StorageClass::StorageBuffer || + base_type_storage_class == spv::StorageClass::PhysicalStorageBuffer || + base_type_storage_class == spv::StorageClass::PushConstant || + (_.HasCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR) && + base_type_storage_class == spv::StorageClass::Workgroup)) && + !_.HasDecoration(base_type->id(), spv::Decoration::ArrayStride)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "OpPtrAccessChain must have a Base whose type is decorated " + "with ArrayStride"; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (base_type_storage_class == spv::StorageClass::Workgroup) { + if (!_.HasCapability(spv::Capability::VariablePointers)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(7651) + << "OpPtrAccessChain Base operand pointing to Workgroup " + "storage class must use VariablePointers capability"; + } + } else if (base_type_storage_class == spv::StorageClass::StorageBuffer) { + if (!_.features().variable_pointers) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(7652) + << "OpPtrAccessChain Base operand pointing to StorageBuffer " + "storage class must use VariablePointers or " + "VariablePointersStorageBuffer capability"; + } + } else if (base_type_storage_class != + spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(7650) + << "OpPtrAccessChain Base operand must point to Workgroup, " + "StorageBuffer, or PhysicalStorageBuffer storage class"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateArrayLength(ValidationState_t& state, + const Instruction* inst) { + std::string instr_name = + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + + // Result type must be a 32-bit unsigned int. + auto result_type = state.FindDef(inst->type_id()); + if (result_type->opcode() != spv::Op::OpTypeInt || + result_type->GetOperandAs(1) != 32 || + result_type->GetOperandAs(2) != 0) { + return state.diag(SPV_ERROR_INVALID_ID, inst) + << "The Result Type of " << instr_name << " " + << state.getIdName(inst->id()) + << " must be OpTypeInt with width 32 and signedness 0."; + } + + // The structure that is passed in must be an pointer to a structure, whose + // last element is a runtime array. + auto pointer = state.FindDef(inst->GetOperandAs(2)); + auto pointer_type = state.FindDef(pointer->type_id()); + if (pointer_type->opcode() != spv::Op::OpTypePointer) { + return state.diag(SPV_ERROR_INVALID_ID, inst) + << "The Structure's type in " << instr_name << " " + << state.getIdName(inst->id()) + << " must be a pointer to an OpTypeStruct."; + } + + auto structure_type = state.FindDef(pointer_type->GetOperandAs(2)); + if (structure_type->opcode() != spv::Op::OpTypeStruct) { + return state.diag(SPV_ERROR_INVALID_ID, inst) + << "The Structure's type in " << instr_name << " " + << state.getIdName(inst->id()) + << " must be a pointer to an OpTypeStruct."; + } + + auto num_of_members = structure_type->operands().size() - 1; + auto last_member = + state.FindDef(structure_type->GetOperandAs(num_of_members)); + if (last_member->opcode() != spv::Op::OpTypeRuntimeArray) { + return state.diag(SPV_ERROR_INVALID_ID, inst) + << "The Structure's last member in " << instr_name << " " + << state.getIdName(inst->id()) << " must be an OpTypeRuntimeArray."; + } + + // The array member must the index of the last element (the run time + // array). + if (inst->GetOperandAs(3) != num_of_members - 1) { + return state.diag(SPV_ERROR_INVALID_ID, inst) + << "The array member in " << instr_name << " " + << state.getIdName(inst->id()) + << " must be an the last member of the struct."; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateCooperativeMatrixLengthNV(ValidationState_t& state, + const Instruction* inst) { + std::string instr_name = + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + + // Result type must be a 32-bit unsigned int. + auto result_type = state.FindDef(inst->type_id()); + if (result_type->opcode() != spv::Op::OpTypeInt || + result_type->GetOperandAs(1) != 32 || + result_type->GetOperandAs(2) != 0) { + return state.diag(SPV_ERROR_INVALID_ID, inst) + << "The Result Type of " << instr_name << " " + << state.getIdName(inst->id()) + << " must be OpTypeInt with width 32 and signedness 0."; + } + + bool isKhr = inst->opcode() == spv::Op::OpCooperativeMatrixLengthKHR; + auto type_id = inst->GetOperandAs(2); + auto type = state.FindDef(type_id); + if (isKhr && type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) { + return state.diag(SPV_ERROR_INVALID_ID, inst) + << "The type in " << instr_name << " " + << state.getIdName(type_id) + << " must be OpTypeCooperativeMatrixKHR."; + } else if (!isKhr && type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) { + return state.diag(SPV_ERROR_INVALID_ID, inst) + << "The type in " << instr_name << " " + << state.getIdName(type_id) << " must be OpTypeCooperativeMatrixNV."; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, + const Instruction* inst) { + uint32_t type_id; + const char* opname; + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) { + type_id = inst->type_id(); + opname = "spv::Op::OpCooperativeMatrixLoadNV"; + } else { + // get Object operand's type + type_id = _.FindDef(inst->GetOperandAs(1))->type_id(); + opname = "spv::Op::OpCooperativeMatrixStoreNV"; + } + + auto matrix_type = _.FindDef(type_id); + + if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) { + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "spv::Op::OpCooperativeMatrixLoadNV Result Type " + << _.getIdName(type_id) << " is not a cooperative matrix type."; + } else { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "spv::Op::OpCooperativeMatrixStoreNV Object type " + << _.getIdName(type_id) << " is not a cooperative matrix type."; + } + } + + const auto pointer_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 2u : 0u; + const auto pointer_id = inst->GetOperandAs(pointer_index); + const auto pointer = _.FindDef(pointer_id); + if (!pointer || + ((_.addressing_model() == spv::AddressingModel::Logical) && + ((!_.features().variable_pointers && + !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || + (_.features().variable_pointers && + !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " Pointer " << _.getIdName(pointer_id) + << " is not a logical pointer."; + } + + const auto pointer_type_id = pointer->type_id(); + const auto pointer_type = _.FindDef(pointer_type_id); + if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " type for pointer " << _.getIdName(pointer_id) + << " is not a pointer type."; + } + + const auto storage_class_index = 1u; + const auto storage_class = + pointer_type->GetOperandAs(storage_class_index); + + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::StorageBuffer && + storage_class != spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " storage class for pointer type " + << _.getIdName(pointer_type_id) + << " is not Workgroup or StorageBuffer."; + } + + const auto pointee_id = pointer_type->GetOperandAs(2); + const auto pointee_type = _.FindDef(pointee_id); + if (!pointee_type || !(_.IsIntScalarOrVectorType(pointee_id) || + _.IsFloatScalarOrVectorType(pointee_id))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " Pointer " << _.getIdName(pointer->id()) + << "s Type must be a scalar or vector type."; + } + + const auto stride_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 3u : 2u; + const auto stride_id = inst->GetOperandAs(stride_index); + const auto stride = _.FindDef(stride_id); + if (!stride || !_.IsIntScalarType(stride->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Stride operand " << _.getIdName(stride_id) + << " must be a scalar integer type."; + } + + const auto colmajor_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 4u : 3u; + const auto colmajor_id = inst->GetOperandAs(colmajor_index); + const auto colmajor = _.FindDef(colmajor_id); + if (!colmajor || !_.IsBoolScalarType(colmajor->type_id()) || + !(spvOpcodeIsConstant(colmajor->opcode()) || + spvOpcodeIsSpecConstant(colmajor->opcode()))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Column Major operand " << _.getIdName(colmajor_id) + << " must be a boolean constant instruction."; + } + + const auto memory_access_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 5u : 4u; + if (inst->operands().size() > memory_access_index) { + if (auto error = CheckMemoryAccess(_, inst, memory_access_index)) + return error; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateCooperativeMatrixLoadStoreKHR(ValidationState_t& _, + const Instruction* inst) { + uint32_t type_id; + const char* opname; + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) { + type_id = inst->type_id(); + opname = "spv::Op::OpCooperativeMatrixLoadKHR"; + } else { + // get Object operand's type + type_id = _.FindDef(inst->GetOperandAs(1))->type_id(); + opname = "spv::Op::OpCooperativeMatrixStoreKHR"; + } + + auto matrix_type = _.FindDef(type_id); + + if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) { + if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "spv::Op::OpCooperativeMatrixLoadKHR Result Type " + << _.getIdName(type_id) << " is not a cooperative matrix type."; + } else { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "spv::Op::OpCooperativeMatrixStoreKHR Object type " + << _.getIdName(type_id) << " is not a cooperative matrix type."; + } + } + + const auto pointer_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 2u : 0u; + const auto pointer_id = inst->GetOperandAs(pointer_index); + const auto pointer = _.FindDef(pointer_id); + if (!pointer || + ((_.addressing_model() == spv::AddressingModel::Logical) && + ((!_.features().variable_pointers && + !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || + (_.features().variable_pointers && + !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " Pointer " << _.getIdName(pointer_id) + << " is not a logical pointer."; + } + + const auto pointer_type_id = pointer->type_id(); + const auto pointer_type = _.FindDef(pointer_type_id); + if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " type for pointer " << _.getIdName(pointer_id) + << " is not a pointer type."; + } + + const auto storage_class_index = 1u; + const auto storage_class = + pointer_type->GetOperandAs(storage_class_index); + + if (storage_class != spv::StorageClass::Workgroup && + storage_class != spv::StorageClass::StorageBuffer && + storage_class != spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(8973) << opname + << " storage class for pointer type " + << _.getIdName(pointer_type_id) + << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer."; + } + + const auto pointee_id = pointer_type->GetOperandAs(2); + const auto pointee_type = _.FindDef(pointee_id); + if (!pointee_type || !(_.IsIntScalarOrVectorType(pointee_id) || + _.IsFloatScalarOrVectorType(pointee_id))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << opname << " Pointer " << _.getIdName(pointer->id()) + << "s Type must be a scalar or vector type."; + } + + const auto layout_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 3u : 2u; + const auto colmajor_id = inst->GetOperandAs(layout_index); + const auto colmajor = _.FindDef(colmajor_id); + if (!colmajor || !_.IsIntScalarType(colmajor->type_id()) || + !(spvOpcodeIsConstant(colmajor->opcode()) || + spvOpcodeIsSpecConstant(colmajor->opcode()))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "MemoryLayout operand " << _.getIdName(colmajor_id) + << " must be a 32-bit integer constant instruction."; + } + + const auto stride_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 4u : 3u; + if (inst->operands().size() > stride_index) { + const auto stride_id = inst->GetOperandAs(stride_index); + const auto stride = _.FindDef(stride_id); + if (!stride || !_.IsIntScalarType(stride->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Stride operand " << _.getIdName(stride_id) + << " must be a scalar integer type."; + } + } + + const auto memory_access_index = + (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 5u : 4u; + if (inst->operands().size() > memory_access_index) { + if (auto error = CheckMemoryAccess(_, inst, memory_access_index)) + return error; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidatePtrComparison(ValidationState_t& _, + const Instruction* inst) { + if (_.addressing_model() == spv::AddressingModel::Logical && + !_.features().variable_pointers) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Instruction cannot for logical addressing model be used without " + "a variable pointers capability"; + } + + const auto result_type = _.FindDef(inst->type_id()); + if (inst->opcode() == spv::Op::OpPtrDiff) { + if (!result_type || result_type->opcode() != spv::Op::OpTypeInt) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result Type must be an integer scalar"; + } + } else { + if (!result_type || result_type->opcode() != spv::Op::OpTypeBool) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result Type must be OpTypeBool"; + } + } + + const auto op1 = _.FindDef(inst->GetOperandAs(2u)); + const auto op2 = _.FindDef(inst->GetOperandAs(3u)); + if (!op1 || !op2 || op1->type_id() != op2->type_id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The types of Operand 1 and Operand 2 must match"; + } + const auto op1_type = _.FindDef(op1->type_id()); + if (!op1_type || op1_type->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Operand type must be a pointer"; + } + + spv::StorageClass sc = op1_type->GetOperandAs(1u); + if (_.addressing_model() == spv::AddressingModel::Logical) { + if (sc != spv::StorageClass::Workgroup && + sc != spv::StorageClass::StorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Invalid pointer storage class"; + } + + if (sc == spv::StorageClass::Workgroup && + !_.HasCapability(spv::Capability::VariablePointers)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Workgroup storage class pointer requires VariablePointers " + "capability to be specified"; + } + } else if (sc == spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cannot use a pointer in the PhysicalStorageBuffer storage class"; + } + + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpVariable: + if (auto error = ValidateVariable(_, inst)) return error; + break; + case spv::Op::OpLoad: + if (auto error = ValidateLoad(_, inst)) return error; + break; + case spv::Op::OpStore: + if (auto error = ValidateStore(_, inst)) return error; + break; + case spv::Op::OpCopyMemory: + case spv::Op::OpCopyMemorySized: + if (auto error = ValidateCopyMemory(_, inst)) return error; + break; + case spv::Op::OpPtrAccessChain: + if (auto error = ValidatePtrAccessChain(_, inst)) return error; + break; + case spv::Op::OpAccessChain: + case spv::Op::OpInBoundsAccessChain: + case spv::Op::OpInBoundsPtrAccessChain: + if (auto error = ValidateAccessChain(_, inst)) return error; + break; + case spv::Op::OpArrayLength: + if (auto error = ValidateArrayLength(_, inst)) return error; + break; + case spv::Op::OpCooperativeMatrixLoadNV: + case spv::Op::OpCooperativeMatrixStoreNV: + if (auto error = ValidateCooperativeMatrixLoadStoreNV(_, inst)) + return error; + break; + case spv::Op::OpCooperativeMatrixLengthKHR: + case spv::Op::OpCooperativeMatrixLengthNV: + if (auto error = ValidateCooperativeMatrixLengthNV(_, inst)) return error; + break; + case spv::Op::OpCooperativeMatrixLoadKHR: + case spv::Op::OpCooperativeMatrixStoreKHR: + if (auto error = ValidateCooperativeMatrixLoadStoreKHR(_, inst)) + return error; + break; + case spv::Op::OpPtrEqual: + case spv::Op::OpPtrNotEqual: + case spv::Op::OpPtrDiff: + if (auto error = ValidatePtrComparison(_, inst)) return error; + break; + case spv::Op::OpImageTexelPointer: + case spv::Op::OpGenericPtrMemSemantics: + default: + break; + } + + return SPV_SUCCESS; +} +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_memory_semantics.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_memory_semantics.cpp new file mode 100644 index 000000000000..dab7b5a19413 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_memory_semantics.cpp @@ -0,0 +1,261 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/validate_memory_semantics.h" + +#include "source/spirv_target_env.h" +#include "source/util/bitutils.h" +#include "source/val/instruction.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +spv_result_t ValidateMemorySemantics(ValidationState_t& _, + const Instruction* inst, + uint32_t operand_index, + uint32_t memory_scope) { + const spv::Op opcode = inst->opcode(); + const auto id = inst->GetOperandAs(operand_index); + bool is_int32 = false, is_const_int32 = false; + uint32_t value = 0; + std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(id); + + if (!is_int32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Memory Semantics to be a 32-bit int"; + } + + if (!is_const_int32) { + if (_.HasCapability(spv::Capability::Shader) && + !_.HasCapability(spv::Capability::CooperativeMatrixNV)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Memory Semantics ids must be OpConstant when Shader " + "capability is present"; + } + + if (_.HasCapability(spv::Capability::Shader) && + _.HasCapability(spv::Capability::CooperativeMatrixNV) && + !spvOpcodeIsConstant(_.GetIdOpcode(id))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Memory Semantics must be a constant instruction when " + "CooperativeMatrixNV capability is present"; + } + return SPV_SUCCESS; + } + + const size_t num_memory_order_set_bits = spvtools::utils::CountSetBits( + value & uint32_t(spv::MemorySemanticsMask::Acquire | + spv::MemorySemanticsMask::Release | + spv::MemorySemanticsMask::AcquireRelease | + spv::MemorySemanticsMask::SequentiallyConsistent)); + + if (num_memory_order_set_bits > 1) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Memory Semantics can have at most one of the following " + "bits " + "set: Acquire, Release, AcquireRelease or " + "SequentiallyConsistent"; + } + + if (_.memory_model() == spv::MemoryModel::VulkanKHR && + value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SequentiallyConsistent memory " + "semantics cannot be used with " + "the VulkanKHR memory model."; + } + + if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR) && + !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Memory Semantics MakeAvailableKHR requires capability " + << "VulkanMemoryModelKHR"; + } + + if (value & uint32_t(spv::MemorySemanticsMask::MakeVisibleKHR) && + !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Memory Semantics MakeVisibleKHR requires capability " + << "VulkanMemoryModelKHR"; + } + + if (value & uint32_t(spv::MemorySemanticsMask::OutputMemoryKHR) && + !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Memory Semantics OutputMemoryKHR requires capability " + << "VulkanMemoryModelKHR"; + } + + if (value & uint32_t(spv::MemorySemanticsMask::Volatile)) { + if (!_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Memory Semantics Volatile requires capability " + "VulkanMemoryModelKHR"; + } + + if (!spvOpcodeIsAtomicOp(inst->opcode())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Memory Semantics Volatile can only be used with atomic " + "instructions"; + } + } + + if (value & uint32_t(spv::MemorySemanticsMask::UniformMemory) && + !_.HasCapability(spv::Capability::Shader)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Memory Semantics UniformMemory requires capability Shader"; + } + + // Checking for spv::Capability::AtomicStorage is intentionally not done here. + // See https://github.com/KhronosGroup/glslang/issues/1618 for the reasoning + // why. + + if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR | + spv::MemorySemanticsMask::MakeVisibleKHR)) { + const bool includes_storage_class = + value & uint32_t(spv::MemorySemanticsMask::UniformMemory | + spv::MemorySemanticsMask::SubgroupMemory | + spv::MemorySemanticsMask::WorkgroupMemory | + spv::MemorySemanticsMask::CrossWorkgroupMemory | + spv::MemorySemanticsMask::AtomicCounterMemory | + spv::MemorySemanticsMask::ImageMemory | + spv::MemorySemanticsMask::OutputMemoryKHR); + + if (!includes_storage_class) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Memory Semantics to include a storage class"; + } + } + + if (value & uint32_t(spv::MemorySemanticsMask::MakeVisibleKHR) && + !(value & uint32_t(spv::MemorySemanticsMask::Acquire | + spv::MemorySemanticsMask::AcquireRelease))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": MakeVisibleKHR Memory Semantics also requires either Acquire " + "or AcquireRelease Memory Semantics"; + } + + if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR) && + !(value & uint32_t(spv::MemorySemanticsMask::Release | + spv::MemorySemanticsMask::AcquireRelease))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": MakeAvailableKHR Memory Semantics also requires either " + "Release or AcquireRelease Memory Semantics"; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + const bool includes_storage_class = + value & uint32_t(spv::MemorySemanticsMask::UniformMemory | + spv::MemorySemanticsMask::WorkgroupMemory | + spv::MemorySemanticsMask::ImageMemory | + spv::MemorySemanticsMask::OutputMemoryKHR); + + if (opcode == spv::Op::OpMemoryBarrier && !num_memory_order_set_bits) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4732) << spvOpcodeString(opcode) + << ": Vulkan specification requires Memory Semantics to have " + "one " + "of the following bits set: Acquire, Release, " + "AcquireRelease " + "or SequentiallyConsistent"; + } else if (opcode != spv::Op::OpMemoryBarrier && + num_memory_order_set_bits) { + // should leave only atomics and control barriers for Vulkan env + bool memory_is_int32 = false, memory_is_const_int32 = false; + uint32_t memory_value = 0; + std::tie(memory_is_int32, memory_is_const_int32, memory_value) = + _.EvalInt32IfConst(memory_scope); + if (memory_is_int32 && + spv::Scope(memory_value) == spv::Scope::Invocation) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4641) << spvOpcodeString(opcode) + << ": Vulkan specification requires Memory Semantics to be None " + "if used with Invocation Memory Scope"; + } + } + + if (opcode == spv::Op::OpMemoryBarrier && !includes_storage_class) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4733) << spvOpcodeString(opcode) + << ": expected Memory Semantics to include a Vulkan-supported " + "storage class"; + } + + if (opcode == spv::Op::OpControlBarrier && value && !includes_storage_class) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4650) << spvOpcodeString(opcode) + << ": expected Memory Semantics to include a Vulkan-supported " + "storage class if Memory Semantics is not None"; + } + } + + if (opcode == spv::Op::OpAtomicFlagClear && + (value & uint32_t(spv::MemorySemanticsMask::Acquire) || + value & uint32_t(spv::MemorySemanticsMask::AcquireRelease))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Memory Semantics Acquire and AcquireRelease cannot be used " + "with " + << spvOpcodeString(opcode); + } + + if (opcode == spv::Op::OpAtomicCompareExchange && operand_index == 5 && + (value & uint32_t(spv::MemorySemanticsMask::Release) || + value & uint32_t(spv::MemorySemanticsMask::AcquireRelease))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Memory Semantics Release and AcquireRelease cannot be " + "used " + "for operand Unequal"; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (opcode == spv::Op::OpAtomicLoad && + (value & uint32_t(spv::MemorySemanticsMask::Release) || + value & uint32_t(spv::MemorySemanticsMask::AcquireRelease) || + value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4731) + << "Vulkan spec disallows OpAtomicLoad with Memory Semantics " + "Release, AcquireRelease and SequentiallyConsistent"; + } + + if (opcode == spv::Op::OpAtomicStore && + (value & uint32_t(spv::MemorySemanticsMask::Acquire) || + value & uint32_t(spv::MemorySemanticsMask::AcquireRelease) || + value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4730) + << "Vulkan spec disallows OpAtomicStore with Memory Semantics " + "Acquire, AcquireRelease and SequentiallyConsistent"; + } + } + + // TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments. + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_memory_semantics.h b/thirdparty/glslang/External/spirv-tools/source/val/validate_memory_semantics.h new file mode 100644 index 000000000000..9e6f93a36758 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_memory_semantics.h @@ -0,0 +1,29 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of memory semantics for SPIR-V instructions. + +#include "source/opcode.h" +#include "source/val/validate.h" + +namespace spvtools { +namespace val { + +spv_result_t ValidateMemorySemantics(ValidationState_t& _, + const Instruction* inst, + uint32_t operand_index, + uint32_t memory_scope); + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_mesh_shading.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_mesh_shading.cpp new file mode 100644 index 000000000000..e569e251c08e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_mesh_shading.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates ray query instructions from SPV_KHR_ray_query + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + switch (opcode) { + case spv::Op::OpEmitMeshTasksEXT: { + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::TaskEXT) { + if (message) { + *message = + "OpEmitMeshTasksEXT requires TaskEXT execution model"; + } + return false; + } + return true; + }); + + const uint32_t group_count_x = _.GetOperandTypeId(inst, 0); + if (!_.IsUnsignedIntScalarType(group_count_x) || + _.GetBitWidth(group_count_x) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Group Count X must be a 32-bit unsigned int scalar"; + } + + const uint32_t group_count_y = _.GetOperandTypeId(inst, 1); + if (!_.IsUnsignedIntScalarType(group_count_y) || + _.GetBitWidth(group_count_y) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Group Count Y must be a 32-bit unsigned int scalar"; + } + + const uint32_t group_count_z = _.GetOperandTypeId(inst, 2); + if (!_.IsUnsignedIntScalarType(group_count_z) || + _.GetBitWidth(group_count_z) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Group Count Z must be a 32-bit unsigned int scalar"; + } + + if (inst->operands().size() == 4) { + const auto payload = _.FindDef(inst->GetOperandAs(3)); + if (payload->opcode() != spv::Op::OpVariable) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Payload must be the result of a OpVariable"; + } + if (payload->GetOperandAs(2) != + spv::StorageClass::TaskPayloadWorkgroupEXT) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Payload OpVariable must have a storage class of " + "TaskPayloadWorkgroupEXT"; + } + } + break; + } + + case spv::Op::OpSetMeshOutputsEXT: { + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::MeshEXT) { + if (message) { + *message = + "OpSetMeshOutputsEXT requires MeshEXT execution model"; + } + return false; + } + return true; + }); + + const uint32_t vertex_count = _.GetOperandTypeId(inst, 0); + if (!_.IsUnsignedIntScalarType(vertex_count) || + _.GetBitWidth(vertex_count) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Vertex Count must be a 32-bit unsigned int scalar"; + } + + const uint32_t primitive_count = _.GetOperandTypeId(inst, 1); + if (!_.IsUnsignedIntScalarType(primitive_count) || + _.GetBitWidth(primitive_count) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Primitive Count must be a 32-bit unsigned int scalar"; + } + + break; + } + + case spv::Op::OpWritePackedPrimitiveIndices4x8NV: { + // No validation rules (for the moment). + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_misc.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_misc.cpp new file mode 100644 index 000000000000..d71fd2d26133 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_misc.cpp @@ -0,0 +1,202 @@ +// Copyright (c) 2018 Google LLC. +// Copyright (c) 2019 NVIDIA Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/validate.h" + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate_scopes.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidateUndef(ValidationState_t& _, const Instruction* inst) { + if (_.IsVoidType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cannot create undefined values with void type"; + } + if (_.HasCapability(spv::Capability::Shader) && + _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && + !_.IsPointerType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Cannot create undefined values with 8- or 16-bit types"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateShaderClock(ValidationState_t& _, + const Instruction* inst) { + const uint32_t scope = inst->GetOperandAs(2); + if (auto error = ValidateScope(_, inst, scope)) { + return error; + } + + bool is_int32 = false, is_const_int32 = false; + uint32_t value = 0; + std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); + if (is_const_int32 && spv::Scope(value) != spv::Scope::Subgroup && + spv::Scope(value) != spv::Scope::Device) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4652) << "Scope must be Subgroup or Device"; + } + + // Result Type must be a 64 - bit unsigned integer type or + // a vector of two - components of 32 - + // bit unsigned integer type + const uint32_t result_type = inst->type_id(); + if (!_.IsUnsigned64BitHandle(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Value to be a " + "vector of two components" + " of unsigned integer" + " or 64bit unsigned integer"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateAssumeTrue(ValidationState_t& _, const Instruction* inst) { + const auto operand_type_id = _.GetOperandTypeId(inst, 0); + if (!operand_type_id || !_.IsBoolScalarType(operand_type_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Value operand of OpAssumeTrueKHR must be a boolean scalar"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateExpect(ValidationState_t& _, const Instruction* inst) { + const auto result_type = inst->type_id(); + if (!_.IsBoolScalarOrVectorType(result_type) && + !_.IsIntScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Result of OpExpectKHR must be a scalar or vector of integer " + "type or boolean type"; + } + + if (_.GetOperandTypeId(inst, 2) != result_type) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Type of Value operand of OpExpectKHR does not match the result " + "type "; + } + if (_.GetOperandTypeId(inst, 3) != result_type) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Type of ExpectedValue operand of OpExpectKHR does not match the " + "result type "; + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpUndef: + if (auto error = ValidateUndef(_, inst)) return error; + break; + default: + break; + } + switch (inst->opcode()) { + case spv::Op::OpBeginInvocationInterlockEXT: + case spv::Op::OpEndInvocationInterlockEXT: + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + spv::ExecutionModel::Fragment, + "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT " + "require Fragment execution model"); + + _.function(inst->function()->id()) + ->RegisterLimitation([](const ValidationState_t& state, + const Function* entry_point, + std::string* message) { + const auto* execution_modes = + state.GetExecutionModes(entry_point->id()); + + auto find_interlock = [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::PixelInterlockOrderedEXT: + case spv::ExecutionMode::PixelInterlockUnorderedEXT: + case spv::ExecutionMode::SampleInterlockOrderedEXT: + case spv::ExecutionMode::SampleInterlockUnorderedEXT: + case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: + case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT: + return true; + default: + return false; + } + }; + + bool found = false; + if (execution_modes) { + auto i = std::find_if(execution_modes->begin(), + execution_modes->end(), find_interlock); + found = (i != execution_modes->end()); + } + + if (!found) { + *message = + "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT " + "require a fragment shader interlock execution mode."; + return false; + } + return true; + }); + break; + case spv::Op::OpDemoteToHelperInvocationEXT: + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + spv::ExecutionModel::Fragment, + "OpDemoteToHelperInvocationEXT requires Fragment execution " + "model"); + break; + case spv::Op::OpIsHelperInvocationEXT: { + const uint32_t result_type = inst->type_id(); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + spv::ExecutionModel::Fragment, + "OpIsHelperInvocationEXT requires Fragment execution model"); + if (!_.IsBoolScalarType(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected bool scalar type as Result Type: " + << spvOpcodeString(inst->opcode()); + break; + } + case spv::Op::OpReadClockKHR: + if (auto error = ValidateShaderClock(_, inst)) { + return error; + } + break; + case spv::Op::OpAssumeTrueKHR: + if (auto error = ValidateAssumeTrue(_, inst)) { + return error; + } + break; + case spv::Op::OpExpectKHR: + if (auto error = ValidateExpect(_, inst)) { + return error; + } + break; + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_mode_setting.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_mode_setting.cpp new file mode 100644 index 000000000000..82c6c3f0e80e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_mode_setting.cpp @@ -0,0 +1,811 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { + const auto entry_point_id = inst->GetOperandAs(1); + auto entry_point = _.FindDef(entry_point_id); + if (!entry_point || spv::Op::OpFunction != entry_point->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpEntryPoint Entry Point " << _.getIdName(entry_point_id) + << " is not a function."; + } + + // Only check the shader execution models + const spv::ExecutionModel execution_model = + inst->GetOperandAs(0); + if (execution_model != spv::ExecutionModel::Kernel) { + const auto entry_point_type_id = entry_point->GetOperandAs(3); + const auto entry_point_type = _.FindDef(entry_point_type_id); + if (!entry_point_type || 3 != entry_point_type->words().size()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4633) << "OpEntryPoint Entry Point " + << _.getIdName(entry_point_id) + << "s function parameter count is not zero."; + } + } + + auto return_type = _.FindDef(entry_point->type_id()); + if (!return_type || spv::Op::OpTypeVoid != return_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4633) << "OpEntryPoint Entry Point " + << _.getIdName(entry_point_id) + << "s function return type is not void."; + } + + const auto* execution_modes = _.GetExecutionModes(entry_point_id); + if (_.HasCapability(spv::Capability::Shader)) { + switch (execution_model) { + case spv::ExecutionModel::Fragment: + if (execution_modes && + execution_modes->count(spv::ExecutionMode::OriginUpperLeft) && + execution_modes->count(spv::ExecutionMode::OriginLowerLeft)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Fragment execution model entry points can only specify " + "one of OriginUpperLeft or OriginLowerLeft execution " + "modes."; + } + if (!execution_modes || + (!execution_modes->count(spv::ExecutionMode::OriginUpperLeft) && + !execution_modes->count(spv::ExecutionMode::OriginLowerLeft))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Fragment execution model entry points require either an " + "OriginUpperLeft or OriginLowerLeft execution mode."; + } + if (execution_modes && + 1 < std::count_if(execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::DepthGreater: + case spv::ExecutionMode::DepthLess: + case spv::ExecutionMode::DepthUnchanged: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Fragment execution model entry points can specify at most " + "one of DepthGreater, DepthLess or DepthUnchanged " + "execution modes."; + } + if (execution_modes && + 1 < std::count_if( + execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::PixelInterlockOrderedEXT: + case spv::ExecutionMode::PixelInterlockUnorderedEXT: + case spv::ExecutionMode::SampleInterlockOrderedEXT: + case spv::ExecutionMode::SampleInterlockUnorderedEXT: + case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: + case spv::ExecutionMode:: + ShadingRateInterlockUnorderedEXT: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Fragment execution model entry points can specify at most " + "one fragment shader interlock execution mode."; + } + if (execution_modes && + 1 < std::count_if( + execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::StencilRefUnchangedFrontAMD: + case spv::ExecutionMode::StencilRefLessFrontAMD: + case spv::ExecutionMode::StencilRefGreaterFrontAMD: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Fragment execution model entry points can specify at most " + "one of StencilRefUnchangedFrontAMD, " + "StencilRefLessFrontAMD or StencilRefGreaterFrontAMD " + "execution modes."; + } + if (execution_modes && + 1 < std::count_if( + execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::StencilRefUnchangedBackAMD: + case spv::ExecutionMode::StencilRefLessBackAMD: + case spv::ExecutionMode::StencilRefGreaterBackAMD: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Fragment execution model entry points can specify at most " + "one of StencilRefUnchangedBackAMD, " + "StencilRefLessBackAMD or StencilRefGreaterBackAMD " + "execution modes."; + } + break; + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + if (execution_modes && + 1 < std::count_if( + execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::SpacingEqual: + case spv::ExecutionMode::SpacingFractionalEven: + case spv::ExecutionMode::SpacingFractionalOdd: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Tessellation execution model entry points can specify at " + "most one of SpacingEqual, SpacingFractionalOdd or " + "SpacingFractionalEven execution modes."; + } + if (execution_modes && + 1 < std::count_if(execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::Triangles: + case spv::ExecutionMode::Quads: + case spv::ExecutionMode::Isolines: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Tessellation execution model entry points can specify at " + "most one of Triangles, Quads or Isolines execution modes."; + } + if (execution_modes && + 1 < std::count_if(execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::VertexOrderCw: + case spv::ExecutionMode::VertexOrderCcw: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Tessellation execution model entry points can specify at " + "most one of VertexOrderCw or VertexOrderCcw execution " + "modes."; + } + break; + case spv::ExecutionModel::Geometry: + if (!execution_modes || + 1 != std::count_if( + execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::InputPoints: + case spv::ExecutionMode::InputLines: + case spv::ExecutionMode::InputLinesAdjacency: + case spv::ExecutionMode::Triangles: + case spv::ExecutionMode::InputTrianglesAdjacency: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Geometry execution model entry points must specify " + "exactly one of InputPoints, InputLines, " + "InputLinesAdjacency, Triangles or InputTrianglesAdjacency " + "execution modes."; + } + if (!execution_modes || + 1 != std::count_if(execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::OutputPoints: + case spv::ExecutionMode::OutputLineStrip: + case spv::ExecutionMode::OutputTriangleStrip: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Geometry execution model entry points must specify " + "exactly one of OutputPoints, OutputLineStrip or " + "OutputTriangleStrip execution modes."; + } + break; + case spv::ExecutionModel::MeshEXT: + if (!execution_modes || + 1 != std::count_if(execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::OutputPoints: + case spv::ExecutionMode::OutputLinesEXT: + case spv::ExecutionMode::OutputTrianglesEXT: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "MeshEXT execution model entry points must specify exactly " + "one of OutputPoints, OutputLinesEXT, or " + "OutputTrianglesEXT Execution Modes."; + } else if (2 != std::count_if( + execution_modes->begin(), execution_modes->end(), + [](const spv::ExecutionMode& mode) { + switch (mode) { + case spv::ExecutionMode::OutputPrimitivesEXT: + case spv::ExecutionMode::OutputVertices: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "MeshEXT execution model entry points must specify both " + "OutputPrimitivesEXT and OutputVertices Execution Modes."; + } + break; + default: + break; + } + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + switch (execution_model) { + case spv::ExecutionModel::GLCompute: + if (!execution_modes || + !execution_modes->count(spv::ExecutionMode::LocalSize)) { + bool ok = false; + for (auto& i : _.ordered_instructions()) { + if (i.opcode() == spv::Op::OpDecorate) { + if (i.operands().size() > 2) { + if (i.GetOperandAs(1) == + spv::Decoration::BuiltIn && + i.GetOperandAs(2) == + spv::BuiltIn::WorkgroupSize) { + ok = true; + break; + } + } + } + if (i.opcode() == spv::Op::OpExecutionModeId) { + const auto mode = i.GetOperandAs(1); + if (mode == spv::ExecutionMode::LocalSizeId) { + ok = true; + break; + } + } + } + if (!ok) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(6426) + << "In the Vulkan environment, GLCompute execution model " + "entry points require either the LocalSize or " + "LocalSizeId execution mode or an object decorated with " + "WorkgroupSize must be specified."; + } + } + break; + default: + break; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateExecutionMode(ValidationState_t& _, + const Instruction* inst) { + const auto entry_point_id = inst->GetOperandAs(0); + const auto found = std::find(_.entry_points().cbegin(), + _.entry_points().cend(), entry_point_id); + if (found == _.entry_points().cend()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpExecutionMode Entry Point " << _.getIdName(entry_point_id) + << " is not the Entry Point " + "operand of an OpEntryPoint."; + } + + const auto mode = inst->GetOperandAs(1); + if (inst->opcode() == spv::Op::OpExecutionModeId) { + bool valid_mode = false; + switch (mode) { + case spv::ExecutionMode::SubgroupsPerWorkgroupId: + case spv::ExecutionMode::LocalSizeHintId: + case spv::ExecutionMode::LocalSizeId: + case spv::ExecutionMode::FPFastMathDefault: + valid_mode = true; + break; + default: + valid_mode = false; + break; + } + if (!valid_mode) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpExecutionModeId is only valid when the Mode operand is an " + "execution mode that takes Extra Operands that are id " + "operands."; + } + + size_t operand_count = inst->operands().size(); + for (size_t i = 2; i < operand_count; ++i) { + const auto operand_id = inst->GetOperandAs(i); + const auto* operand_inst = _.FindDef(operand_id); + switch (mode) { + case spv::ExecutionMode::SubgroupsPerWorkgroupId: + case spv::ExecutionMode::LocalSizeHintId: + case spv::ExecutionMode::LocalSizeId: + if (!spvOpcodeIsConstant(operand_inst->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "For OpExecutionModeId all Extra Operand ids must be " + "constant instructions."; + } + break; + case spv::ExecutionMode::FPFastMathDefault: + if (i == 2) { + if (!_.IsFloatScalarType(operand_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Target Type operand must be a floating-point " + "scalar type"; + } + } else { + bool is_int32 = false; + bool is_const = false; + uint32_t value = 0; + std::tie(is_int32, is_const, value) = + _.EvalInt32IfConst(operand_id); + if (is_int32 && is_const) { + // Valid values include up to 0x00040000 (AllowTransform). + uint32_t invalid_mask = 0xfff80000; + if ((invalid_mask & value) != 0) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Fast Math Default operand is an invalid bitmask " + "value"; + } + if (value & + static_cast(spv::FPFastMathModeMask::Fast)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Fast Math Default operand must not include Fast"; + } + const auto reassoc_contract = + spv::FPFastMathModeMask::AllowContract | + spv::FPFastMathModeMask::AllowReassoc; + if ((value & static_cast( + spv::FPFastMathModeMask::AllowTransform)) != 0 && + ((value & static_cast(reassoc_contract)) != + static_cast(reassoc_contract))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Fast Math Default operand must include " + "AllowContract and AllowReassoc when AllowTransform " + "is specified"; + } + } else { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "The Fast Math Default operand must be a " + "non-specialization constant"; + } + } + break; + default: + break; + } + } + } else if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId || + mode == spv::ExecutionMode::LocalSizeHintId || + mode == spv::ExecutionMode::LocalSizeId || + mode == spv::ExecutionMode::FPFastMathDefault) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "OpExecutionMode is only valid when the Mode operand is an " + "execution mode that takes no Extra Operands, or takes Extra " + "Operands that are not id operands."; + } + + const auto* models = _.GetExecutionModels(entry_point_id); + switch (mode) { + case spv::ExecutionMode::Invocations: + case spv::ExecutionMode::InputPoints: + case spv::ExecutionMode::InputLines: + case spv::ExecutionMode::InputLinesAdjacency: + case spv::ExecutionMode::InputTrianglesAdjacency: + case spv::ExecutionMode::OutputLineStrip: + case spv::ExecutionMode::OutputTriangleStrip: + if (!std::all_of(models->begin(), models->end(), + [](const spv::ExecutionModel& model) { + return model == spv::ExecutionModel::Geometry; + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with the Geometry execution " + "model."; + } + break; + case spv::ExecutionMode::OutputPoints: + if (!std::all_of( + models->begin(), models->end(), + [&_](const spv::ExecutionModel& model) { + switch (model) { + case spv::ExecutionModel::Geometry: + return true; + case spv::ExecutionModel::MeshNV: + return _.HasCapability(spv::Capability::MeshShadingNV); + case spv::ExecutionModel::MeshEXT: + return _.HasCapability(spv::Capability::MeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(spv::Capability::MeshShadingNV) || + _.HasCapability(spv::Capability::MeshShadingEXT)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with the Geometry " + "MeshNV or MeshEXT execution model."; + } else { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with the Geometry " + "execution " + "model."; + } + } + break; + case spv::ExecutionMode::SpacingEqual: + case spv::ExecutionMode::SpacingFractionalEven: + case spv::ExecutionMode::SpacingFractionalOdd: + case spv::ExecutionMode::VertexOrderCw: + case spv::ExecutionMode::VertexOrderCcw: + case spv::ExecutionMode::PointMode: + case spv::ExecutionMode::Quads: + case spv::ExecutionMode::Isolines: + if (!std::all_of( + models->begin(), models->end(), + [](const spv::ExecutionModel& model) { + return (model == spv::ExecutionModel::TessellationControl) || + (model == spv::ExecutionModel::TessellationEvaluation); + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with a tessellation " + "execution model."; + } + break; + case spv::ExecutionMode::Triangles: + if (!std::all_of(models->begin(), models->end(), + [](const spv::ExecutionModel& model) { + switch (model) { + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + return true; + default: + return false; + } + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with a Geometry or " + "tessellation execution model."; + } + break; + case spv::ExecutionMode::OutputVertices: + if (!std::all_of( + models->begin(), models->end(), + [&_](const spv::ExecutionModel& model) { + switch (model) { + case spv::ExecutionModel::Geometry: + case spv::ExecutionModel::TessellationControl: + case spv::ExecutionModel::TessellationEvaluation: + return true; + case spv::ExecutionModel::MeshNV: + return _.HasCapability(spv::Capability::MeshShadingNV); + case spv::ExecutionModel::MeshEXT: + return _.HasCapability(spv::Capability::MeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(spv::Capability::MeshShadingNV) || + _.HasCapability(spv::Capability::MeshShadingEXT)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with a Geometry, " + "tessellation, MeshNV or MeshEXT execution model."; + } else { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with a Geometry or " + "tessellation execution model."; + } + } + break; + case spv::ExecutionMode::OutputLinesEXT: + case spv::ExecutionMode::OutputTrianglesEXT: + case spv::ExecutionMode::OutputPrimitivesEXT: + if (!std::all_of(models->begin(), models->end(), + [](const spv::ExecutionModel& model) { + return (model == spv::ExecutionModel::MeshEXT || + model == spv::ExecutionModel::MeshNV); + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with the MeshEXT or MeshNV " + "execution " + "model."; + } + break; + case spv::ExecutionMode::QuadDerivativesKHR: + if (!std::all_of(models->begin(), models->end(), + [](const spv::ExecutionModel& model) { + return (model == spv::ExecutionModel::Fragment || + model == spv::ExecutionModel::GLCompute); + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with the Fragment or " + "GLCompute execution model."; + } + break; + case spv::ExecutionMode::PixelCenterInteger: + case spv::ExecutionMode::OriginUpperLeft: + case spv::ExecutionMode::OriginLowerLeft: + case spv::ExecutionMode::EarlyFragmentTests: + case spv::ExecutionMode::DepthReplacing: + case spv::ExecutionMode::DepthGreater: + case spv::ExecutionMode::DepthLess: + case spv::ExecutionMode::DepthUnchanged: + case spv::ExecutionMode::NonCoherentColorAttachmentReadEXT: + case spv::ExecutionMode::NonCoherentDepthAttachmentReadEXT: + case spv::ExecutionMode::NonCoherentStencilAttachmentReadEXT: + case spv::ExecutionMode::PixelInterlockOrderedEXT: + case spv::ExecutionMode::PixelInterlockUnorderedEXT: + case spv::ExecutionMode::SampleInterlockOrderedEXT: + case spv::ExecutionMode::SampleInterlockUnorderedEXT: + case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: + case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT: + case spv::ExecutionMode::EarlyAndLateFragmentTestsAMD: + case spv::ExecutionMode::StencilRefUnchangedFrontAMD: + case spv::ExecutionMode::StencilRefGreaterFrontAMD: + case spv::ExecutionMode::StencilRefLessFrontAMD: + case spv::ExecutionMode::StencilRefUnchangedBackAMD: + case spv::ExecutionMode::StencilRefGreaterBackAMD: + case spv::ExecutionMode::StencilRefLessBackAMD: + case spv::ExecutionMode::RequireFullQuadsKHR: + if (!std::all_of(models->begin(), models->end(), + [](const spv::ExecutionModel& model) { + return model == spv::ExecutionModel::Fragment; + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with the Fragment execution " + "model."; + } + break; + case spv::ExecutionMode::LocalSizeHint: + case spv::ExecutionMode::VecTypeHint: + case spv::ExecutionMode::ContractionOff: + case spv::ExecutionMode::LocalSizeHintId: + if (!std::all_of(models->begin(), models->end(), + [](const spv::ExecutionModel& model) { + return model == spv::ExecutionModel::Kernel; + })) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with the Kernel execution " + "model."; + } + break; + case spv::ExecutionMode::LocalSize: + case spv::ExecutionMode::LocalSizeId: + if (mode == spv::ExecutionMode::LocalSizeId && !_.IsLocalSizeIdAllowed()) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "LocalSizeId mode is not allowed by the current environment."; + + if (!std::all_of( + models->begin(), models->end(), + [&_](const spv::ExecutionModel& model) { + switch (model) { + case spv::ExecutionModel::Kernel: + case spv::ExecutionModel::GLCompute: + return true; + case spv::ExecutionModel::TaskNV: + case spv::ExecutionModel::MeshNV: + return _.HasCapability(spv::Capability::MeshShadingNV); + case spv::ExecutionModel::TaskEXT: + case spv::ExecutionModel::MeshEXT: + return _.HasCapability(spv::Capability::MeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(spv::Capability::MeshShadingNV) || + _.HasCapability(spv::Capability::MeshShadingEXT)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with a Kernel, GLCompute, " + "MeshNV, MeshEXT, TaskNV or TaskEXT execution model."; + } else { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Execution mode can only be used with a Kernel or " + "GLCompute " + "execution model."; + } + } + default: + break; + } + + if (mode == spv::ExecutionMode::FPFastMathDefault) { + const auto* modes = _.GetExecutionModes(entry_point_id); + if (modes && modes->count(spv::ExecutionMode::ContractionOff)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "FPFastMathDefault and ContractionOff execution modes cannot " + "be applied to the same entry point"; + } + if (modes && modes->count(spv::ExecutionMode::SignedZeroInfNanPreserve)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "FPFastMathDefault and SignedZeroInfNanPreserve execution " + "modes cannot be applied to the same entry point"; + } + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (mode == spv::ExecutionMode::OriginLowerLeft) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4653) + << "In the Vulkan environment, the OriginLowerLeft execution mode " + "must not be used."; + } + if (mode == spv::ExecutionMode::PixelCenterInteger) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4654) + << "In the Vulkan environment, the PixelCenterInteger execution " + "mode must not be used."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateMemoryModel(ValidationState_t& _, + const Instruction* inst) { + // Already produced an error if multiple memory model instructions are + // present. + if (_.memory_model() != spv::MemoryModel::VulkanKHR && + _.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "VulkanMemoryModelKHR capability must only be specified if " + "the VulkanKHR memory model is used."; + } + + if (spvIsOpenCLEnv(_.context()->target_env)) { + if ((_.addressing_model() != spv::AddressingModel::Physical32) && + (_.addressing_model() != spv::AddressingModel::Physical64)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Addressing model must be Physical32 or Physical64 " + << "in the OpenCL environment."; + } + if (_.memory_model() != spv::MemoryModel::OpenCL) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Memory model must be OpenCL in the OpenCL environment."; + } + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if ((_.addressing_model() != spv::AddressingModel::Logical) && + (_.addressing_model() != + spv::AddressingModel::PhysicalStorageBuffer64)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4635) + << "Addressing model must be Logical or PhysicalStorageBuffer64 " + << "in the Vulkan environment."; + } + } + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t ValidateFloatControls2(ValidationState_t& _) { + std::unordered_set fp_fast_math_default_entry_points; + for (auto entry_point : _.entry_points()) { + const auto* exec_modes = _.GetExecutionModes(entry_point); + if (exec_modes && + exec_modes->count(spv::ExecutionMode::FPFastMathDefault)) { + fp_fast_math_default_entry_points.insert(entry_point); + } + } + + std::vector> worklist; + for (const auto& inst : _.ordered_instructions()) { + if (inst.opcode() != spv::Op::OpDecorate) { + continue; + } + + const auto decoration = inst.GetOperandAs(1); + const auto target_id = inst.GetOperandAs(0); + const auto target = _.FindDef(target_id); + if (decoration == spv::Decoration::NoContraction) { + worklist.push_back(std::make_pair(target, decoration)); + } else if (decoration == spv::Decoration::FPFastMathMode) { + auto mask = inst.GetOperandAs(2); + if ((mask & spv::FPFastMathModeMask::Fast) != + spv::FPFastMathModeMask::MaskNone) { + worklist.push_back(std::make_pair(target, decoration)); + } + } + } + + std::unordered_set visited; + while (!worklist.empty()) { + const auto inst = worklist.back().first; + const auto decoration = worklist.back().second; + worklist.pop_back(); + + if (!visited.insert(inst).second) { + continue; + } + + const auto function = inst->function(); + if (function) { + const auto& entry_points = _.FunctionEntryPoints(function->id()); + for (auto entry_point : entry_points) { + if (fp_fast_math_default_entry_points.count(entry_point)) { + const std::string dec = decoration == spv::Decoration::NoContraction + ? "NoContraction" + : "FPFastMathMode Fast"; + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << dec + << " cannot be used by an entry point with the " + "FPFastMathDefault execution mode"; + } + } + } else { + for (const auto& pair : inst->uses()) { + worklist.push_back(std::make_pair(pair.first, decoration)); + } + } + } + + return SPV_SUCCESS; +} + +spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpEntryPoint: + if (auto error = ValidateEntryPoint(_, inst)) return error; + break; + case spv::Op::OpExecutionMode: + case spv::Op::OpExecutionModeId: + if (auto error = ValidateExecutionMode(_, inst)) return error; + break; + case spv::Op::OpMemoryModel: + if (auto error = ValidateMemoryModel(_, inst)) return error; + break; + default: + break; + } + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_non_uniform.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_non_uniform.cpp new file mode 100644 index 000000000000..75967d2ff988 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_non_uniform.cpp @@ -0,0 +1,497 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of barrier SPIR-V instructions. + +#include "source/opcode.h" +#include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validate_scopes.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidateGroupNonUniformElect(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsBoolScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a boolean scalar type"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformAnyAll(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsBoolScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a boolean scalar type"; + } + + if (!_.IsBoolScalarType(_.GetOperandTypeId(inst, 3))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Predicate must be a boolean scalar type"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformAllEqual(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsBoolScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a boolean scalar type"; + } + + const auto value_type = _.GetOperandTypeId(inst, 3); + if (!_.IsFloatScalarOrVectorType(value_type) && + !_.IsIntScalarOrVectorType(value_type) && + !_.IsBoolScalarOrVectorType(value_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Value must be a scalar or vector of integer, floating-point, or " + "boolean type"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformBroadcastShuffle(ValidationState_t& _, + const Instruction* inst) { + const auto type_id = inst->type_id(); + if (!_.IsFloatScalarOrVectorType(type_id) && + !_.IsIntScalarOrVectorType(type_id) && + !_.IsBoolScalarOrVectorType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a scalar or vector of integer, floating-point, " + "or boolean type"; + } + + const auto value_type_id = _.GetOperandTypeId(inst, 3); + if (value_type_id != type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The type of Value must match the Result type"; + } + + const auto GetOperandName = [](const spv::Op opcode) { + std::string operand; + switch (opcode) { + case spv::Op::OpGroupNonUniformBroadcast: + case spv::Op::OpGroupNonUniformShuffle: + operand = "Id"; + break; + case spv::Op::OpGroupNonUniformShuffleXor: + operand = "Mask"; + break; + case spv::Op::OpGroupNonUniformQuadBroadcast: + operand = "Index"; + break; + case spv::Op::OpGroupNonUniformQuadSwap: + operand = "Direction"; + break; + case spv::Op::OpGroupNonUniformShuffleUp: + case spv::Op::OpGroupNonUniformShuffleDown: + default: + operand = "Delta"; + break; + } + return operand; + }; + + const auto id_type_id = _.GetOperandTypeId(inst, 4); + if (!_.IsUnsignedIntScalarType(id_type_id)) { + std::string operand = GetOperandName(inst->opcode()); + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << operand << " must be an unsigned integer scalar"; + } + + const bool should_be_constant = + inst->opcode() == spv::Op::OpGroupNonUniformQuadSwap || + ((inst->opcode() == spv::Op::OpGroupNonUniformBroadcast || + inst->opcode() == spv::Op::OpGroupNonUniformQuadBroadcast) && + _.version() < SPV_SPIRV_VERSION_WORD(1, 5)); + if (should_be_constant) { + const auto id_id = inst->GetOperandAs(4); + const auto id_op = _.GetIdOpcode(id_id); + if (!spvOpcodeIsConstant(id_op)) { + std::string operand = GetOperandName(inst->opcode()); + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Before SPIR-V 1.5, " << operand + << " must be a constant instruction"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformBroadcastFirst(ValidationState_t& _, + const Instruction* inst) { + const auto type_id = inst->type_id(); + if (!_.IsFloatScalarOrVectorType(type_id) && + !_.IsIntScalarOrVectorType(type_id) && + !_.IsBoolScalarOrVectorType(type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a scalar or vector of integer, floating-point, " + "or boolean type"; + } + + const auto value_type_id = _.GetOperandTypeId(inst, 3); + if (value_type_id != type_id) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The type of Value must match the Result type"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformBallot(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsUnsignedIntVectorType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a 4-component unsigned integer vector"; + } + + if (_.GetDimension(inst->type_id()) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a 4-component unsigned integer vector"; + } + + const auto pred_type_id = _.GetOperandTypeId(inst, 3); + if (!_.IsBoolScalarType(pred_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Predicate must be a boolean scalar"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformInverseBallot(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsBoolScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a boolean scalar"; + } + + const auto value_type_id = _.GetOperandTypeId(inst, 3); + if (!_.IsUnsignedIntVectorType(value_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Value must be a 4-component unsigned integer vector"; + } + + if (_.GetDimension(value_type_id) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Value must be a 4-component unsigned integer vector"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformBallotBitExtract(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsBoolScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a boolean scalar"; + } + + const auto value_type_id = _.GetOperandTypeId(inst, 3); + if (!_.IsUnsignedIntVectorType(value_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Value must be a 4-component unsigned integer vector"; + } + + if (_.GetDimension(value_type_id) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Value must be a 4-component unsigned integer vector"; + } + + const auto id_type_id = _.GetOperandTypeId(inst, 4); + if (!_.IsUnsignedIntScalarType(id_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Id must be an unsigned integer scalar"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformBallotBitCount(ValidationState_t& _, + const Instruction* inst) { + // Scope is already checked by ValidateExecutionScope() above. + + const uint32_t result_type = inst->type_id(); + if (!_.IsUnsignedIntScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be an unsigned integer type scalar."; + } + + const auto value = inst->GetOperandAs(4); + const auto value_type = _.FindDef(value)->type_id(); + if (!_.IsUnsignedIntVectorType(value_type) || + _.GetDimension(value_type) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Value to be a " + "vector of four components " + "of integer type scalar"; + } + + const auto group = inst->GetOperandAs(3); + if (spvIsVulkanEnv(_.context()->target_env)) { + if ((group != spv::GroupOperation::Reduce) && + (group != spv::GroupOperation::InclusiveScan) && + (group != spv::GroupOperation::ExclusiveScan)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4685) + << "In Vulkan: The OpGroupNonUniformBallotBitCount group " + "operation must be only: Reduce, InclusiveScan, or " + "ExclusiveScan."; + } + } + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformBallotFind(ValidationState_t& _, + const Instruction* inst) { + if (!_.IsUnsignedIntScalarType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be an unsigned integer scalar"; + } + + const auto value_type_id = _.GetOperandTypeId(inst, 3); + if (!_.IsUnsignedIntVectorType(value_type_id)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Value must be a 4-component unsigned integer vector"; + } + + if (_.GetDimension(value_type_id) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Value must be a 4-component unsigned integer vector"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformArithmetic(ValidationState_t& _, + const Instruction* inst) { + const bool is_unsigned = inst->opcode() == spv::Op::OpGroupNonUniformUMin || + inst->opcode() == spv::Op::OpGroupNonUniformUMax; + const bool is_float = inst->opcode() == spv::Op::OpGroupNonUniformFAdd || + inst->opcode() == spv::Op::OpGroupNonUniformFMul || + inst->opcode() == spv::Op::OpGroupNonUniformFMin || + inst->opcode() == spv::Op::OpGroupNonUniformFMax; + const bool is_bool = inst->opcode() == spv::Op::OpGroupNonUniformLogicalAnd || + inst->opcode() == spv::Op::OpGroupNonUniformLogicalOr || + inst->opcode() == spv::Op::OpGroupNonUniformLogicalXor; + if (is_float) { + if (!_.IsFloatScalarOrVectorType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a floating-point scalar or vector"; + } + } else if (is_bool) { + if (!_.IsBoolScalarOrVectorType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be a boolean scalar or vector"; + } + } else if (is_unsigned) { + if (!_.IsUnsignedIntScalarOrVectorType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be an unsigned integer scalar or vector"; + } + } else if (!_.IsIntScalarOrVectorType(inst->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result must be an integer scalar or vector"; + } + + const auto value_type_id = _.GetOperandTypeId(inst, 4); + if (value_type_id != inst->type_id()) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The type of Value must match the Result type"; + } + + const auto group_op = inst->GetOperandAs(3); + bool is_clustered_reduce = group_op == spv::GroupOperation::ClusteredReduce; + bool is_partitioned_nv = + group_op == spv::GroupOperation::PartitionedReduceNV || + group_op == spv::GroupOperation::PartitionedInclusiveScanNV || + group_op == spv::GroupOperation::PartitionedExclusiveScanNV; + if (inst->operands().size() <= 5) { + if (is_clustered_reduce) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ClusterSize must be present when Operation is ClusteredReduce"; + } else if (is_partitioned_nv) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ballot must be present when Operation is PartitionedReduceNV, " + "PartitionedInclusiveScanNV, or PartitionedExclusiveScanNV"; + } + } else { + const auto operand_id = inst->GetOperandAs(5); + const auto* operand = _.FindDef(operand_id); + if (is_partitioned_nv) { + if (!operand || !_.IsIntScalarOrVectorType(operand->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ballot must be a 4-component integer vector"; + } + + if (_.GetDimension(operand->type_id()) != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ballot must be a 4-component integer vector"; + } + } else { + if (!operand || !_.IsUnsignedIntScalarType(operand->type_id())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ClusterSize must be an unsigned integer scalar"; + } + + if (!spvOpcodeIsConstant(operand->opcode())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ClusterSize must be a constant instruction"; + } + } + } + return SPV_SUCCESS; +} + +spv_result_t ValidateGroupNonUniformRotateKHR(ValidationState_t& _, + const Instruction* inst) { + // Scope is already checked by ValidateExecutionScope() above. + const uint32_t result_type = inst->type_id(); + if (!_.IsIntScalarOrVectorType(result_type) && + !_.IsFloatScalarOrVectorType(result_type) && + !_.IsBoolScalarOrVectorType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Result Type to be a scalar or vector of " + "floating-point, integer or boolean type."; + } + + const uint32_t value_type = _.GetTypeId(inst->GetOperandAs(3)); + if (value_type != result_type) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Result Type must be the same as the type of Value."; + } + + const uint32_t delta_type = _.GetTypeId(inst->GetOperandAs(4)); + if (!_.IsUnsignedIntScalarType(delta_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Delta must be a scalar of integer type, whose Signedness " + "operand is 0."; + } + + if (inst->words().size() > 6) { + const uint32_t cluster_size_op_id = inst->GetOperandAs(5); + const Instruction* cluster_size_inst = _.FindDef(cluster_size_op_id); + const uint32_t cluster_size_type = + cluster_size_inst ? cluster_size_inst->type_id() : 0; + if (!_.IsUnsignedIntScalarType(cluster_size_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ClusterSize must be a scalar of integer type, whose " + "Signedness operand is 0."; + } + + if (!spvOpcodeIsConstant(cluster_size_inst->opcode())) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "ClusterSize must come from a constant instruction."; + } + + uint64_t cluster_size; + const bool valid_const = + _.EvalConstantValUint64(cluster_size_op_id, &cluster_size); + if (valid_const && + ((cluster_size == 0) || ((cluster_size & (cluster_size - 1)) != 0))) { + return _.diag(SPV_WARNING, inst) + << "Behavior is undefined unless ClusterSize is at least 1 and a " + "power of 2."; + } + + // TODO(kpet) Warn about undefined behavior when ClusterSize is greater than + // the declared SubGroupSize + } + + return SPV_SUCCESS; +} + +} // namespace + +// Validates correctness of non-uniform group instructions. +spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + + if (spvOpcodeIsNonUniformGroupOperation(opcode)) { + // OpGroupNonUniformQuadAllKHR and OpGroupNonUniformQuadAnyKHR don't have + // scope paramter + if ((opcode != spv::Op::OpGroupNonUniformQuadAllKHR) && + (opcode != spv::Op::OpGroupNonUniformQuadAnyKHR)) { + const uint32_t execution_scope = inst->GetOperandAs(2); + if (auto error = ValidateExecutionScope(_, inst, execution_scope)) { + return error; + } + } + } + + switch (opcode) { + case spv::Op::OpGroupNonUniformElect: + return ValidateGroupNonUniformElect(_, inst); + case spv::Op::OpGroupNonUniformAny: + case spv::Op::OpGroupNonUniformAll: + return ValidateGroupNonUniformAnyAll(_, inst); + case spv::Op::OpGroupNonUniformAllEqual: + return ValidateGroupNonUniformAllEqual(_, inst); + case spv::Op::OpGroupNonUniformBroadcast: + case spv::Op::OpGroupNonUniformShuffle: + case spv::Op::OpGroupNonUniformShuffleXor: + case spv::Op::OpGroupNonUniformShuffleUp: + case spv::Op::OpGroupNonUniformShuffleDown: + case spv::Op::OpGroupNonUniformQuadBroadcast: + case spv::Op::OpGroupNonUniformQuadSwap: + return ValidateGroupNonUniformBroadcastShuffle(_, inst); + case spv::Op::OpGroupNonUniformBroadcastFirst: + return ValidateGroupNonUniformBroadcastFirst(_, inst); + case spv::Op::OpGroupNonUniformBallot: + return ValidateGroupNonUniformBallot(_, inst); + case spv::Op::OpGroupNonUniformInverseBallot: + return ValidateGroupNonUniformInverseBallot(_, inst); + case spv::Op::OpGroupNonUniformBallotBitExtract: + return ValidateGroupNonUniformBallotBitExtract(_, inst); + case spv::Op::OpGroupNonUniformBallotBitCount: + return ValidateGroupNonUniformBallotBitCount(_, inst); + case spv::Op::OpGroupNonUniformBallotFindLSB: + case spv::Op::OpGroupNonUniformBallotFindMSB: + return ValidateGroupNonUniformBallotFind(_, inst); + case spv::Op::OpGroupNonUniformIAdd: + case spv::Op::OpGroupNonUniformFAdd: + case spv::Op::OpGroupNonUniformIMul: + case spv::Op::OpGroupNonUniformFMul: + case spv::Op::OpGroupNonUniformSMin: + case spv::Op::OpGroupNonUniformUMin: + case spv::Op::OpGroupNonUniformFMin: + case spv::Op::OpGroupNonUniformSMax: + case spv::Op::OpGroupNonUniformUMax: + case spv::Op::OpGroupNonUniformFMax: + case spv::Op::OpGroupNonUniformBitwiseAnd: + case spv::Op::OpGroupNonUniformBitwiseOr: + case spv::Op::OpGroupNonUniformBitwiseXor: + case spv::Op::OpGroupNonUniformLogicalAnd: + case spv::Op::OpGroupNonUniformLogicalOr: + case spv::Op::OpGroupNonUniformLogicalXor: + return ValidateGroupNonUniformArithmetic(_, inst); + case spv::Op::OpGroupNonUniformRotateKHR: + return ValidateGroupNonUniformRotateKHR(_, inst); + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_primitives.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_primitives.cpp new file mode 100644 index 000000000000..6769090db8e5 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_primitives.cpp @@ -0,0 +1,73 @@ +// Copyright (c) 2017 LunarG Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of primitive SPIR-V instructions. + +#include + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +// Validates correctness of primitive instructions. +spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + + switch (opcode) { + case spv::Op::OpEmitVertex: + case spv::Op::OpEndPrimitive: + case spv::Op::OpEmitStreamVertex: + case spv::Op::OpEndStreamPrimitive: + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + spv::ExecutionModel::Geometry, + std::string(spvOpcodeString(opcode)) + + " instructions require Geometry execution model"); + break; + default: + break; + } + + switch (opcode) { + case spv::Op::OpEmitStreamVertex: + case spv::Op::OpEndStreamPrimitive: { + const uint32_t stream_id = inst->word(1); + const uint32_t stream_type = _.GetTypeId(stream_id); + if (!_.IsIntScalarType(stream_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Stream to be int scalar"; + } + + const spv::Op stream_opcode = _.GetIdOpcode(stream_id); + if (!spvOpcodeIsConstant(stream_opcode)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": expected Stream to be constant instruction"; + } + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_query.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_query.cpp new file mode 100644 index 000000000000..9b67fc922bf4 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_query.cpp @@ -0,0 +1,274 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates ray query instructions from SPV_KHR_ray_query + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +spv_result_t ValidateRayQueryPointer(ValidationState_t& _, + const Instruction* inst, + uint32_t ray_query_index) { + const uint32_t ray_query_id = inst->GetOperandAs(ray_query_index); + auto variable = _.FindDef(ray_query_id); + const auto var_opcode = variable->opcode(); + if (!variable || (var_opcode != spv::Op::OpVariable && + var_opcode != spv::Op::OpFunctionParameter && + var_opcode != spv::Op::OpAccessChain)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Query must be a memory object declaration"; + } + auto pointer = _.FindDef(variable->GetOperandAs(0)); + if (!pointer || pointer->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Query must be a pointer"; + } + auto type = _.FindDef(pointer->GetOperandAs(2)); + if (!type || type->opcode() != spv::Op::OpTypeRayQueryKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Query must be a pointer to OpTypeRayQueryKHR"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateIntersectionId(ValidationState_t& _, + const Instruction* inst, + uint32_t intersection_index) { + const uint32_t intersection_id = + inst->GetOperandAs(intersection_index); + const uint32_t intersection_type = _.GetTypeId(intersection_id); + const spv::Op intersection_opcode = _.GetIdOpcode(intersection_id); + if (!_.IsIntScalarType(intersection_type) || + _.GetBitWidth(intersection_type) != 32 || + !spvOpcodeIsConstant(intersection_opcode)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Intersection ID to be a constant 32-bit int scalar"; + } + + return SPV_SUCCESS; +} + +} // namespace + +spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + switch (opcode) { + case spv::Op::OpRayQueryInitializeKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; + + if (_.GetIdOpcode(_.GetOperandTypeId(inst, 1)) != + spv::Op::OpTypeAccelerationStructureKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Acceleration Structure to be of type " + "OpTypeAccelerationStructureKHR"; + } + + const uint32_t ray_flags = _.GetOperandTypeId(inst, 2); + if (!_.IsIntScalarType(ray_flags) || _.GetBitWidth(ray_flags) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Flags must be a 32-bit int scalar"; + } + + const uint32_t cull_mask = _.GetOperandTypeId(inst, 3); + if (!_.IsIntScalarType(cull_mask) || _.GetBitWidth(cull_mask) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cull Mask must be a 32-bit int scalar"; + } + + const uint32_t ray_origin = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 || + _.GetBitWidth(ray_origin) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Origin must be a 32-bit float 3-component vector"; + } + + const uint32_t ray_tmin = _.GetOperandTypeId(inst, 5); + if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMin must be a 32-bit float scalar"; + } + + const uint32_t ray_direction = _.GetOperandTypeId(inst, 6); + if (!_.IsFloatVectorType(ray_direction) || + _.GetDimension(ray_direction) != 3 || + _.GetBitWidth(ray_direction) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Direction must be a 32-bit float 3-component vector"; + } + + const uint32_t ray_tmax = _.GetOperandTypeId(inst, 7); + if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMax must be a 32-bit float scalar"; + } + break; + } + + case spv::Op::OpRayQueryTerminateKHR: + case spv::Op::OpRayQueryConfirmIntersectionKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; + break; + } + + case spv::Op::OpRayQueryGenerateIntersectionKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; + + const uint32_t hit_t_id = _.GetOperandTypeId(inst, 1); + if (!_.IsFloatScalarType(hit_t_id) || _.GetBitWidth(hit_t_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit T must be a 32-bit float scalar"; + } + + break; + } + + case spv::Op::OpRayQueryGetIntersectionFrontFaceKHR: + case spv::Op::OpRayQueryProceedKHR: + case spv::Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; + + if (!_.IsBoolScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type to be bool scalar type"; + } + + if (opcode == spv::Op::OpRayQueryGetIntersectionFrontFaceKHR) { + if (auto error = ValidateIntersectionId(_, inst, 3)) return error; + } + + break; + } + + case spv::Op::OpRayQueryGetIntersectionTKHR: + case spv::Op::OpRayQueryGetRayTMinKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; + + if (!_.IsFloatScalarType(result_type) || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type to be 32-bit float scalar type"; + } + + if (opcode == spv::Op::OpRayQueryGetIntersectionTKHR) { + if (auto error = ValidateIntersectionId(_, inst, 3)) return error; + } + + break; + } + + case spv::Op::OpRayQueryGetIntersectionTypeKHR: + case spv::Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR: + case spv::Op::OpRayQueryGetIntersectionInstanceIdKHR: + case spv::Op:: + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: + case spv::Op::OpRayQueryGetIntersectionGeometryIndexKHR: + case spv::Op::OpRayQueryGetIntersectionPrimitiveIndexKHR: + case spv::Op::OpRayQueryGetRayFlagsKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; + + if (!_.IsIntScalarType(result_type) || _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type to be 32-bit int scalar type"; + } + + if (opcode != spv::Op::OpRayQueryGetRayFlagsKHR) { + if (auto error = ValidateIntersectionId(_, inst, 3)) return error; + } + + break; + } + + case spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR: + case spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR: + case spv::Op::OpRayQueryGetWorldRayDirectionKHR: + case spv::Op::OpRayQueryGetWorldRayOriginKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; + + if (!_.IsFloatVectorType(result_type) || + _.GetDimension(result_type) != 3 || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type to be 32-bit float 3-component " + "vector type"; + } + + if (opcode == spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR || + opcode == spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR) { + if (auto error = ValidateIntersectionId(_, inst, 3)) return error; + } + + break; + } + + case spv::Op::OpRayQueryGetIntersectionBarycentricsKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; + if (auto error = ValidateIntersectionId(_, inst, 3)) return error; + + if (!_.IsFloatVectorType(result_type) || + _.GetDimension(result_type) != 2 || + _.GetBitWidth(result_type) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type to be 32-bit float 2-component " + "vector type"; + } + + break; + } + + case spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR: + case spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR: { + if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; + if (auto error = ValidateIntersectionId(_, inst, 3)) return error; + + uint32_t num_rows = 0; + uint32_t num_cols = 0; + uint32_t col_type = 0; + uint32_t component_type = 0; + if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type, + &component_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected matrix type as Result Type"; + } + + if (num_cols != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type matrix to have a Column Count of 4"; + } + + if (!_.IsFloatScalarType(component_type) || + _.GetBitWidth(result_type) != 32 || num_rows != 3) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type matrix to have a Column Type of " + "3-component 32-bit float vectors"; + } + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_tracing.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_tracing.cpp new file mode 100644 index 000000000000..f74e9d4b9d73 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_tracing.cpp @@ -0,0 +1,209 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates ray tracing instructions from SPV_KHR_ray_tracing + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + switch (opcode) { + case spv::Op::OpTraceRayKHR: { + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = + "OpTraceRayKHR requires RayGenerationKHR, " + "ClosestHitKHR and MissKHR execution models"; + } + return false; + } + return true; + }); + + if (_.GetIdOpcode(_.GetOperandTypeId(inst, 0)) != + spv::Op::OpTypeAccelerationStructureKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Acceleration Structure to be of type " + "OpTypeAccelerationStructureKHR"; + } + + const uint32_t ray_flags = _.GetOperandTypeId(inst, 1); + if (!_.IsIntScalarType(ray_flags) || _.GetBitWidth(ray_flags) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Flags must be a 32-bit int scalar"; + } + + const uint32_t cull_mask = _.GetOperandTypeId(inst, 2); + if (!_.IsIntScalarType(cull_mask) || _.GetBitWidth(cull_mask) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cull Mask must be a 32-bit int scalar"; + } + + const uint32_t sbt_offset = _.GetOperandTypeId(inst, 3); + if (!_.IsIntScalarType(sbt_offset) || _.GetBitWidth(sbt_offset) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Offset must be a 32-bit int scalar"; + } + + const uint32_t sbt_stride = _.GetOperandTypeId(inst, 4); + if (!_.IsIntScalarType(sbt_stride) || _.GetBitWidth(sbt_stride) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Stride must be a 32-bit int scalar"; + } + + const uint32_t miss_index = _.GetOperandTypeId(inst, 5); + if (!_.IsIntScalarType(miss_index) || _.GetBitWidth(miss_index) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Miss Index must be a 32-bit int scalar"; + } + + const uint32_t ray_origin = _.GetOperandTypeId(inst, 6); + if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 || + _.GetBitWidth(ray_origin) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Origin must be a 32-bit float 3-component vector"; + } + + const uint32_t ray_tmin = _.GetOperandTypeId(inst, 7); + if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMin must be a 32-bit float scalar"; + } + + const uint32_t ray_direction = _.GetOperandTypeId(inst, 8); + if (!_.IsFloatVectorType(ray_direction) || + _.GetDimension(ray_direction) != 3 || + _.GetBitWidth(ray_direction) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Direction must be a 32-bit float 3-component vector"; + } + + const uint32_t ray_tmax = _.GetOperandTypeId(inst, 9); + if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMax must be a 32-bit float scalar"; + } + + const Instruction* payload = _.FindDef(inst->GetOperandAs(10)); + if (payload->opcode() != spv::Op::OpVariable) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Payload must be the result of a OpVariable"; + } else if (payload->GetOperandAs(2) != + spv::StorageClass::RayPayloadKHR && + payload->GetOperandAs(2) != + spv::StorageClass::IncomingRayPayloadKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Payload must have storage class RayPayloadKHR or " + "IncomingRayPayloadKHR"; + } + break; + } + + case spv::Op::OpReportIntersectionKHR: { + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::IntersectionKHR) { + if (message) { + *message = + "OpReportIntersectionKHR requires IntersectionKHR " + "execution model"; + } + return false; + } + return true; + }); + + if (!_.IsBoolScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type to be bool scalar type"; + } + + const uint32_t hit = _.GetOperandTypeId(inst, 2); + if (!_.IsFloatScalarType(hit) || _.GetBitWidth(hit) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit must be a 32-bit int scalar"; + } + + const uint32_t hit_kind = _.GetOperandTypeId(inst, 3); + if (!_.IsUnsignedIntScalarType(hit_kind) || + _.GetBitWidth(hit_kind) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Kind must be a 32-bit unsigned int scalar"; + } + break; + } + + case spv::Op::OpExecuteCallableKHR: { + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation([](spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR && + model != spv::ExecutionModel::CallableKHR) { + if (message) { + *message = + "OpExecuteCallableKHR requires RayGenerationKHR, " + "ClosestHitKHR, MissKHR and CallableKHR execution models"; + } + return false; + } + return true; + }); + + const uint32_t sbt_index = _.GetOperandTypeId(inst, 0); + if (!_.IsUnsignedIntScalarType(sbt_index) || + _.GetBitWidth(sbt_index) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Index must be a 32-bit unsigned int scalar"; + } + + const auto callable_data = _.FindDef(inst->GetOperandAs(1)); + if (callable_data->opcode() != spv::Op::OpVariable) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Callable Data must be the result of a OpVariable"; + } else if (callable_data->GetOperandAs(2) != + spv::StorageClass::CallableDataKHR && + callable_data->GetOperandAs(2) != + spv::StorageClass::IncomingCallableDataKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Callable Data must have storage class CallableDataKHR or " + "IncomingCallableDataKHR"; + } + + break; + } + + default: + break; + } + + return SPV_SUCCESS; +} +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_tracing_reorder.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_tracing_reorder.cpp new file mode 100644 index 000000000000..cb190f91e4f7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_ray_tracing_reorder.cpp @@ -0,0 +1,625 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates ray tracing instructions from SPV_NV_shader_execution_reorder + +#include "source/opcode.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +#include + +namespace spvtools { +namespace val { + +static const uint32_t KRayParamInvalidId = std::numeric_limits::max(); + +spv_result_t ValidateHitObjectPointer(ValidationState_t& _, + const Instruction* inst, + uint32_t hit_object_index) { + const uint32_t hit_object_id = inst->GetOperandAs(hit_object_index); + auto variable = _.FindDef(hit_object_id); + const auto var_opcode = variable->opcode(); + if (!variable || (var_opcode != spv::Op::OpVariable && + var_opcode != spv::Op::OpFunctionParameter && + var_opcode != spv::Op::OpAccessChain)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object must be a memory object declaration"; + } + auto pointer = _.FindDef(variable->GetOperandAs(0)); + if (!pointer || pointer->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object must be a pointer"; + } + auto type = _.FindDef(pointer->GetOperandAs(2)); + if (!type || type->opcode() != spv::Op::OpTypeHitObjectNV) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Type must be OpTypeHitObjectNV"; + } + return SPV_SUCCESS; +} + +spv_result_t ValidateHitObjectInstructionCommonParameters( + ValidationState_t& _, const Instruction* inst, + uint32_t acceleration_struct_index, uint32_t instance_id_index, + uint32_t primtive_id_index, uint32_t geometry_index, + uint32_t ray_flags_index, uint32_t cull_mask_index, uint32_t hit_kind_index, + uint32_t sbt_index, uint32_t sbt_offset_index, uint32_t sbt_stride_index, + uint32_t sbt_record_offset_index, uint32_t sbt_record_stride_index, + uint32_t miss_index, uint32_t ray_origin_index, uint32_t ray_tmin_index, + uint32_t ray_direction_index, uint32_t ray_tmax_index, + uint32_t payload_index, uint32_t hit_object_attr_index) { + auto isValidId = [](uint32_t spvid) { return spvid < KRayParamInvalidId; }; + if (isValidId(acceleration_struct_index) && + _.GetIdOpcode(_.GetOperandTypeId(inst, acceleration_struct_index)) != + spv::Op::OpTypeAccelerationStructureKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Acceleration Structure to be of type " + "OpTypeAccelerationStructureKHR"; + } + + if (isValidId(instance_id_index)) { + const uint32_t instance_id = _.GetOperandTypeId(inst, instance_id_index); + if (!_.IsIntScalarType(instance_id) || _.GetBitWidth(instance_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Instance Id must be a 32-bit int scalar"; + } + } + + if (isValidId(primtive_id_index)) { + const uint32_t primitive_id = _.GetOperandTypeId(inst, primtive_id_index); + if (!_.IsIntScalarType(primitive_id) || _.GetBitWidth(primitive_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Primitive Id must be a 32-bit int scalar"; + } + } + + if (isValidId(geometry_index)) { + const uint32_t geometry_index_id = _.GetOperandTypeId(inst, geometry_index); + if (!_.IsIntScalarType(geometry_index_id) || + _.GetBitWidth(geometry_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Geometry Index must be a 32-bit int scalar"; + } + } + + if (isValidId(miss_index)) { + const uint32_t miss_index_id = _.GetOperandTypeId(inst, miss_index); + if (!_.IsUnsignedIntScalarType(miss_index_id) || + _.GetBitWidth(miss_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Miss Index must be a 32-bit int scalar"; + } + } + + if (isValidId(cull_mask_index)) { + const uint32_t cull_mask_id = _.GetOperandTypeId(inst, cull_mask_index); + if (!_.IsUnsignedIntScalarType(cull_mask_id) || + _.GetBitWidth(cull_mask_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Cull mask must be a 32-bit int scalar"; + } + } + + if (isValidId(sbt_index)) { + const uint32_t sbt_index_id = _.GetOperandTypeId(inst, sbt_index); + if (!_.IsUnsignedIntScalarType(sbt_index_id) || + _.GetBitWidth(sbt_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Index must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(sbt_offset_index)) { + const uint32_t sbt_offset_id = _.GetOperandTypeId(inst, sbt_offset_index); + if (!_.IsUnsignedIntScalarType(sbt_offset_id) || + _.GetBitWidth(sbt_offset_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Offset must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(sbt_stride_index)) { + const uint32_t sbt_stride_index_id = + _.GetOperandTypeId(inst, sbt_stride_index); + if (!_.IsUnsignedIntScalarType(sbt_stride_index_id) || + _.GetBitWidth(sbt_stride_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT Stride must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(sbt_record_offset_index)) { + const uint32_t sbt_record_offset_index_id = + _.GetOperandTypeId(inst, sbt_record_offset_index); + if (!_.IsUnsignedIntScalarType(sbt_record_offset_index_id) || + _.GetBitWidth(sbt_record_offset_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT record offset must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(sbt_record_stride_index)) { + const uint32_t sbt_record_stride_index_id = + _.GetOperandTypeId(inst, sbt_record_stride_index); + if (!_.IsUnsignedIntScalarType(sbt_record_stride_index_id) || + _.GetBitWidth(sbt_record_stride_index_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "SBT record stride must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(ray_origin_index)) { + const uint32_t ray_origin_id = _.GetOperandTypeId(inst, ray_origin_index); + if (!_.IsFloatVectorType(ray_origin_id) || + _.GetDimension(ray_origin_id) != 3 || + _.GetBitWidth(ray_origin_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Origin must be a 32-bit float 3-component vector"; + } + } + + if (isValidId(ray_tmin_index)) { + const uint32_t ray_tmin_id = _.GetOperandTypeId(inst, ray_tmin_index); + if (!_.IsFloatScalarType(ray_tmin_id) || _.GetBitWidth(ray_tmin_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMin must be a 32-bit float scalar"; + } + } + + if (isValidId(ray_direction_index)) { + const uint32_t ray_direction_id = + _.GetOperandTypeId(inst, ray_direction_index); + if (!_.IsFloatVectorType(ray_direction_id) || + _.GetDimension(ray_direction_id) != 3 || + _.GetBitWidth(ray_direction_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Direction must be a 32-bit float 3-component vector"; + } + } + + if (isValidId(ray_tmax_index)) { + const uint32_t ray_tmax_id = _.GetOperandTypeId(inst, ray_tmax_index); + if (!_.IsFloatScalarType(ray_tmax_id) || _.GetBitWidth(ray_tmax_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMax must be a 32-bit float scalar"; + } + } + + if (isValidId(ray_flags_index)) { + const uint32_t ray_flags_id = _.GetOperandTypeId(inst, ray_flags_index); + if (!_.IsIntScalarType(ray_flags_id) || _.GetBitWidth(ray_flags_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Flags must be a 32-bit int scalar"; + } + } + + if (isValidId(payload_index)) { + const uint32_t payload_id = inst->GetOperandAs(payload_index); + auto variable = _.FindDef(payload_id); + const auto var_opcode = variable->opcode(); + if (!variable || var_opcode != spv::Op::OpVariable || + (variable->GetOperandAs(2) != + spv::StorageClass::RayPayloadKHR && + variable->GetOperandAs(2) != + spv::StorageClass::IncomingRayPayloadKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "payload must be a OpVariable of storage " + "class RayPayloadKHR or IncomingRayPayloadKHR"; + } + } + + if (isValidId(hit_kind_index)) { + const uint32_t hit_kind_id = _.GetOperandTypeId(inst, hit_kind_index); + if (!_.IsUnsignedIntScalarType(hit_kind_id) || + _.GetBitWidth(hit_kind_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Kind must be a 32-bit unsigned int scalar"; + } + } + + if (isValidId(hit_object_attr_index)) { + const uint32_t hit_object_attr_id = + inst->GetOperandAs(hit_object_attr_index); + auto variable = _.FindDef(hit_object_attr_id); + const auto var_opcode = variable->opcode(); + if (!variable || var_opcode != spv::Op::OpVariable || + (variable->GetOperandAs(2)) != + spv::StorageClass::HitObjectAttributeNV) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object Attributes id must be a OpVariable of storage " + "class HitObjectAttributeNV"; + } + } + + return SPV_SUCCESS; +} + +spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst) { + const spv::Op opcode = inst->opcode(); + const uint32_t result_type = inst->type_id(); + + auto RegisterOpcodeForValidModel = [](ValidationState_t& vs, + const Instruction* rtinst) { + std::string opcode_name = spvOpcodeString(rtinst->opcode()); + vs.function(rtinst->function()->id()) + ->RegisterExecutionModelLimitation( + [opcode_name](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = opcode_name + + " requires RayGenerationKHR, ClosestHitKHR and " + "MissKHR execution models"; + } + return false; + } + return true; + }); + return; + }; + + switch (opcode) { + case spv::Op::OpHitObjectIsMissNV: + case spv::Op::OpHitObjectIsHitNV: + case spv::Op::OpHitObjectIsEmptyNV: { + RegisterOpcodeForValidModel(_, inst); + if (!_.IsBoolScalarType(result_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type to be bool scalar type"; + } + + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + break; + } + + case spv::Op::OpHitObjectGetShaderRecordBufferHandleNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + if (!_.IsIntVectorType(result_type) || + (_.GetDimension(result_type) != 2) || + (_.GetBitWidth(result_type) != 32)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit integer type 2-component vector as Result " + "Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpHitObjectGetHitKindNV: + case spv::Op::OpHitObjectGetPrimitiveIndexNV: + case spv::Op::OpHitObjectGetGeometryIndexNV: + case spv::Op::OpHitObjectGetInstanceIdNV: + case spv::Op::OpHitObjectGetInstanceCustomIndexNV: + case spv::Op::OpHitObjectGetShaderBindingTableRecordIndexNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + if (!_.IsIntScalarType(result_type) || !_.GetBitWidth(result_type)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit integer type scalar as Result Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpHitObjectGetCurrentTimeNV: + case spv::Op::OpHitObjectGetRayTMaxNV: + case spv::Op::OpHitObjectGetRayTMinNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + if (!_.IsFloatScalarType(result_type) || _.GetBitWidth(result_type) != 32) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit floating-point type scalar as Result Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpHitObjectGetObjectToWorldNV: + case spv::Op::OpHitObjectGetWorldToObjectNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + uint32_t num_rows = 0; + uint32_t num_cols = 0; + uint32_t col_type = 0; + uint32_t component_type = 0; + + if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type, + &component_type)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected matrix type as Result Type: " + << spvOpcodeString(opcode); + } + + if (num_cols != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type matrix to have a Column Count of 4" + << spvOpcodeString(opcode); + } + + if (!_.IsFloatScalarType(component_type) || + _.GetBitWidth(result_type) != 32 || num_rows != 3) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "expected Result Type matrix to have a Column Type of " + "3-component 32-bit float vectors: " + << spvOpcodeString(opcode); + } + break; + } + + case spv::Op::OpHitObjectGetObjectRayOriginNV: + case spv::Op::OpHitObjectGetObjectRayDirectionNV: + case spv::Op::OpHitObjectGetWorldRayDirectionNV: + case spv::Op::OpHitObjectGetWorldRayOriginNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; + + if (!_.IsFloatVectorType(result_type) || + (_.GetDimension(result_type) != 3) || + (_.GetBitWidth(result_type) != 32)) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected 32-bit floating-point type 3-component vector as " + "Result Type: " + << spvOpcodeString(opcode); + break; + } + + case spv::Op::OpHitObjectGetAttributesNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + const uint32_t hit_object_attr_id = inst->GetOperandAs(1); + auto variable = _.FindDef(hit_object_attr_id); + const auto var_opcode = variable->opcode(); + if (!variable || var_opcode != spv::Op::OpVariable || + variable->GetOperandAs(2) != + spv::StorageClass::HitObjectAttributeNV) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object Attributes id must be a OpVariable of storage " + "class HitObjectAttributeNV"; + } + break; + } + + case spv::Op::OpHitObjectExecuteShaderNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + const uint32_t hit_object_attr_id = inst->GetOperandAs(1); + auto variable = _.FindDef(hit_object_attr_id); + const auto var_opcode = variable->opcode(); + if (!variable || var_opcode != spv::Op::OpVariable || + (variable->GetOperandAs(2)) != + spv::StorageClass::RayPayloadKHR) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hit Object Attributes id must be a OpVariable of storage " + "class RayPayloadKHR"; + } + break; + } + + case spv::Op::OpHitObjectRecordEmptyNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + break; + } + + case spv::Op::OpHitObjectRecordMissNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + const uint32_t miss_index = _.GetOperandTypeId(inst, 1); + if (!_.IsUnsignedIntScalarType(miss_index) || + _.GetBitWidth(miss_index) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Miss Index must be a 32-bit int scalar"; + } + + const uint32_t ray_origin = _.GetOperandTypeId(inst, 2); + if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 || + _.GetBitWidth(ray_origin) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Origin must be a 32-bit float 3-component vector"; + } + + const uint32_t ray_tmin = _.GetOperandTypeId(inst, 3); + if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMin must be a 32-bit float scalar"; + } + + const uint32_t ray_direction = _.GetOperandTypeId(inst, 4); + if (!_.IsFloatVectorType(ray_direction) || + _.GetDimension(ray_direction) != 3 || + _.GetBitWidth(ray_direction) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray Direction must be a 32-bit float 3-component vector"; + } + + const uint32_t ray_tmax = _.GetOperandTypeId(inst, 5); + if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Ray TMax must be a 32-bit float scalar"; + } + break; + } + + case spv::Op::OpHitObjectRecordHitWithIndexNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (auto error = ValidateHitObjectInstructionCommonParameters( + _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */, + 3 /* Primtive Id */, 4 /* Geometry Index */, + KRayParamInvalidId /* Ray Flags */, + KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/, + 6 /* SBT index */, KRayParamInvalidId /* SBT Offset */, + KRayParamInvalidId /* SBT Stride */, + KRayParamInvalidId /* SBT Record Offset */, + KRayParamInvalidId /* SBT Record Stride */, + KRayParamInvalidId /* Miss Index */, 7 /* Ray Origin */, + 8 /* Ray TMin */, 9 /* Ray Direction */, 10 /* Ray TMax */, + KRayParamInvalidId /* Payload */, 11 /* Hit Object Attribute */)) + return error; + + break; + } + + case spv::Op::OpHitObjectRecordHitNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (auto error = ValidateHitObjectInstructionCommonParameters( + _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */, + 3 /* Primtive Id */, 4 /* Geometry Index */, + KRayParamInvalidId /* Ray Flags */, + KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/, + KRayParamInvalidId /* SBT index */, + KRayParamInvalidId /* SBT Offset */, + KRayParamInvalidId /* SBT Stride */, 6 /* SBT Record Offset */, + 7 /* SBT Record Stride */, KRayParamInvalidId /* Miss Index */, + 8 /* Ray Origin */, 9 /* Ray TMin */, 10 /* Ray Direction */, + 11 /* Ray TMax */, KRayParamInvalidId /* Payload */, + 12 /* Hit Object Attribute */)) + return error; + + break; + } + + case spv::Op::OpHitObjectTraceRayMotionNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (auto error = ValidateHitObjectInstructionCommonParameters( + _, inst, 1 /* Acceleration Struct */, + KRayParamInvalidId /* Instance Id */, + KRayParamInvalidId /* Primtive Id */, + KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */, + 3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/, + KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */, + 5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */, + KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */, + 7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */, + 10 /* Ray TMax */, 12 /* Payload */, + KRayParamInvalidId /* Hit Object Attribute */)) + return error; + // Current Time + const uint32_t current_time_id = _.GetOperandTypeId(inst, 11); + if (!_.IsFloatScalarType(current_time_id) || + _.GetBitWidth(current_time_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Current Times must be a 32-bit float scalar type"; + } + + break; + } + + case spv::Op::OpHitObjectTraceRayNV: { + RegisterOpcodeForValidModel(_, inst); + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (auto error = ValidateHitObjectInstructionCommonParameters( + _, inst, 1 /* Acceleration Struct */, + KRayParamInvalidId /* Instance Id */, + KRayParamInvalidId /* Primtive Id */, + KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */, + 3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/, + KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */, + 5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */, + KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */, + 7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */, + 10 /* Ray TMax */, 11 /* Payload */, + KRayParamInvalidId /* Hit Object Attribute */)) + return error; + break; + } + + case spv::Op::OpReorderThreadWithHitObjectNV: { + std::string opcode_name = spvOpcodeString(inst->opcode()); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [opcode_name](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR) { + if (message) { + *message = opcode_name + + " requires RayGenerationKHR execution model"; + } + return false; + } + return true; + }); + + if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; + + if (inst->operands().size() > 1) { + if (inst->operands().size() != 3) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hint and Bits are optional together i.e " + << " Either both Hint and Bits should be provided or neither."; + } + + // Validate the optional opreands Hint and Bits + const uint32_t hint_id = _.GetOperandTypeId(inst, 1); + if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hint must be a 32-bit int scalar"; + } + const uint32_t bits_id = _.GetOperandTypeId(inst, 2); + if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "bits must be a 32-bit int scalar"; + } + } + break; + } + + case spv::Op::OpReorderThreadWithHintNV: { + std::string opcode_name = spvOpcodeString(inst->opcode()); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [opcode_name](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR) { + if (message) { + *message = opcode_name + + " requires RayGenerationKHR execution model"; + } + return false; + } + return true; + }); + + const uint32_t hint_id = _.GetOperandTypeId(inst, 0); + if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Hint must be a 32-bit int scalar"; + } + + const uint32_t bits_id = _.GetOperandTypeId(inst, 1); + if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "bits must be a 32-bit int scalar"; + } + } + + default: + break; + } + return SPV_SUCCESS; +} +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_scopes.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_scopes.cpp new file mode 100644 index 000000000000..6b493538a525 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_scopes.cpp @@ -0,0 +1,323 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/validate_scopes.h" + +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +bool IsValidScope(uint32_t scope) { + // Deliberately avoid a default case so we have to update the list when the + // scopes list changes. + switch (static_cast(scope)) { + case spv::Scope::CrossDevice: + case spv::Scope::Device: + case spv::Scope::Workgroup: + case spv::Scope::Subgroup: + case spv::Scope::Invocation: + case spv::Scope::QueueFamilyKHR: + case spv::Scope::ShaderCallKHR: + return true; + case spv::Scope::Max: + break; + } + return false; +} + +spv_result_t ValidateScope(ValidationState_t& _, const Instruction* inst, + uint32_t scope) { + spv::Op opcode = inst->opcode(); + bool is_int32 = false, is_const_int32 = false; + uint32_t value = 0; + std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); + + if (!is_int32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) << ": expected scope to be a 32-bit int"; + } + + if (!is_const_int32) { + if (_.HasCapability(spv::Capability::Shader) && + !_.HasCapability(spv::Capability::CooperativeMatrixNV)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Scope ids must be OpConstant when Shader capability is " + << "present"; + } + if (_.HasCapability(spv::Capability::Shader) && + _.HasCapability(spv::Capability::CooperativeMatrixNV) && + !spvOpcodeIsConstant(_.GetIdOpcode(scope))) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Scope ids must be constant or specialization constant when " + << "CooperativeMatrixNV capability is present"; + } + } + + if (is_const_int32 && !IsValidScope(value)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Invalid scope value:\n " << _.Disassemble(*_.FindDef(scope)); + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateExecutionScope(ValidationState_t& _, + const Instruction* inst, uint32_t scope) { + spv::Op opcode = inst->opcode(); + bool is_int32 = false, is_const_int32 = false; + uint32_t tmp_value = 0; + std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope); + + if (auto error = ValidateScope(_, inst, scope)) { + return error; + } + + if (!is_const_int32) { + return SPV_SUCCESS; + } + + spv::Scope value = spv::Scope(tmp_value); + + // Vulkan specific rules + if (spvIsVulkanEnv(_.context()->target_env)) { + // Vulkan 1.1 specific rules + if (_.context()->target_env != SPV_ENV_VULKAN_1_0) { + // Scope for Non Uniform Group Operations must be limited to Subgroup + if ((spvOpcodeIsNonUniformGroupOperation(opcode) && + (opcode != spv::Op::OpGroupNonUniformQuadAllKHR) && + (opcode != spv::Op::OpGroupNonUniformQuadAnyKHR)) && + (value != spv::Scope::Subgroup)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4642) << spvOpcodeString(opcode) + << ": in Vulkan environment Execution scope is limited to " + << "Subgroup"; + } + } + + // OpControlBarrier must only use Subgroup execution scope for a subset of + // execution models. + if (opcode == spv::Op::OpControlBarrier && value != spv::Scope::Subgroup) { + std::string errorVUID = _.VkErrorID(4682); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation([errorVUID]( + spv::ExecutionModel model, + std::string* message) { + if (model == spv::ExecutionModel::Fragment || + model == spv::ExecutionModel::Vertex || + model == spv::ExecutionModel::Geometry || + model == spv::ExecutionModel::TessellationEvaluation || + model == spv::ExecutionModel::RayGenerationKHR || + model == spv::ExecutionModel::IntersectionKHR || + model == spv::ExecutionModel::AnyHitKHR || + model == spv::ExecutionModel::ClosestHitKHR || + model == spv::ExecutionModel::MissKHR) { + if (message) { + *message = + errorVUID + + "in Vulkan environment, OpControlBarrier execution scope " + "must be Subgroup for Fragment, Vertex, Geometry, " + "TessellationEvaluation, RayGeneration, Intersection, " + "AnyHit, ClosestHit, and Miss execution models"; + } + return false; + } + return true; + }); + } + + // Only subset of execution models support Workgroup. + if (value == spv::Scope::Workgroup) { + std::string errorVUID = _.VkErrorID(4637); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::TaskNV && + model != spv::ExecutionModel::MeshNV && + model != spv::ExecutionModel::TaskEXT && + model != spv::ExecutionModel::MeshEXT && + model != spv::ExecutionModel::TessellationControl && + model != spv::ExecutionModel::GLCompute) { + if (message) { + *message = + errorVUID + + "in Vulkan environment, Workgroup execution scope is " + "only for TaskNV, MeshNV, TaskEXT, MeshEXT, " + "TessellationControl, and GLCompute execution models"; + } + return false; + } + return true; + }); + } + + // Vulkan generic rules + // Scope for execution must be limited to Workgroup or Subgroup + if (value != spv::Scope::Workgroup && value != spv::Scope::Subgroup) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4636) << spvOpcodeString(opcode) + << ": in Vulkan environment Execution Scope is limited to " + << "Workgroup and Subgroup"; + } + } + + // TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments. + + // General SPIRV rules + // Scope for execution must be limited to Workgroup or Subgroup for + // non-uniform operations + if (spvOpcodeIsNonUniformGroupOperation(opcode) && + opcode != spv::Op::OpGroupNonUniformQuadAllKHR && + opcode != spv::Op::OpGroupNonUniformQuadAnyKHR && + value != spv::Scope::Subgroup && value != spv::Scope::Workgroup) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Execution scope is limited to Subgroup or Workgroup"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, + uint32_t scope) { + const spv::Op opcode = inst->opcode(); + bool is_int32 = false, is_const_int32 = false; + uint32_t tmp_value = 0; + std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope); + + if (auto error = ValidateScope(_, inst, scope)) { + return error; + } + + if (!is_const_int32) { + return SPV_SUCCESS; + } + + spv::Scope value = spv::Scope(tmp_value); + + if (value == spv::Scope::QueueFamilyKHR) { + if (_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + return SPV_SUCCESS; + } else { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << spvOpcodeString(opcode) + << ": Memory Scope QueueFamilyKHR requires capability " + << "VulkanMemoryModelKHR"; + } + } + + if (value == spv::Scope::Device && + _.HasCapability(spv::Capability::VulkanMemoryModelKHR) && + !_.HasCapability(spv::Capability::VulkanMemoryModelDeviceScopeKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Use of device scope with VulkanKHR memory model requires the " + << "VulkanMemoryModelDeviceScopeKHR capability"; + } + + // Vulkan Specific rules + if (spvIsVulkanEnv(_.context()->target_env)) { + if (value != spv::Scope::Device && value != spv::Scope::Workgroup && + value != spv::Scope::Subgroup && value != spv::Scope::Invocation && + value != spv::Scope::ShaderCallKHR && + value != spv::Scope::QueueFamily) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4638) << spvOpcodeString(opcode) + << ": in Vulkan environment Memory Scope is limited to Device, " + "QueueFamily, Workgroup, ShaderCallKHR, Subgroup, or " + "Invocation"; + } else if (_.context()->target_env == SPV_ENV_VULKAN_1_0 && + value == spv::Scope::Subgroup && + !_.HasCapability(spv::Capability::SubgroupBallotKHR) && + !_.HasCapability(spv::Capability::SubgroupVoteKHR)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(7951) << spvOpcodeString(opcode) + << ": in Vulkan 1.0 environment Memory Scope is can not be " + "Subgroup without SubgroupBallotKHR or SubgroupVoteKHR " + "declared"; + } + + if (value == spv::Scope::ShaderCallKHR) { + std::string errorVUID = _.VkErrorID(4640); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::IntersectionKHR && + model != spv::ExecutionModel::AnyHitKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR && + model != spv::ExecutionModel::CallableKHR) { + if (message) { + *message = + errorVUID + + "ShaderCallKHR Memory Scope requires a ray tracing " + "execution model"; + } + return false; + } + return true; + }); + } + + if (value == spv::Scope::Workgroup) { + std::string errorVUID = _.VkErrorID(7321); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::GLCompute && + model != spv::ExecutionModel::TessellationControl && + model != spv::ExecutionModel::TaskNV && + model != spv::ExecutionModel::MeshNV && + model != spv::ExecutionModel::TaskEXT && + model != spv::ExecutionModel::MeshEXT) { + if (message) { + *message = errorVUID + + "Workgroup Memory Scope is limited to MeshNV, " + "TaskNV, MeshEXT, TaskEXT, TessellationControl, " + "and GLCompute execution model"; + } + return false; + } + return true; + }); + + if (_.memory_model() == spv::MemoryModel::GLSL450) { + errorVUID = _.VkErrorID(7320); + _.function(inst->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model == spv::ExecutionModel::TessellationControl) { + if (message) { + *message = + errorVUID + + "Workgroup Memory Scope can't be used with " + "TessellationControl using GLSL450 Memory Model"; + } + return false; + } + return true; + }); + } + } + } + + // TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments. + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_scopes.h b/thirdparty/glslang/External/spirv-tools/source/val/validate_scopes.h new file mode 100644 index 000000000000..ba8b301a8bb6 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_scopes.h @@ -0,0 +1,33 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Validates correctness of scopes for SPIR-V instructions. + +#include "source/opcode.h" +#include "source/val/validate.h" + +namespace spvtools { +namespace val { + +spv_result_t ValidateScope(ValidationState_t& _, const Instruction* inst, + uint32_t scope); + +spv_result_t ValidateExecutionScope(ValidationState_t& _, + const Instruction* inst, uint32_t scope); + +spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, + uint32_t scope); + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_small_type_uses.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_small_type_uses.cpp new file mode 100644 index 000000000000..69f61ee4f30d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_small_type_uses.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/validate.h" + +#include "source/val/instruction.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { + +spv_result_t ValidateSmallTypeUses(ValidationState_t& _, + const Instruction* inst) { + if (!_.HasCapability(spv::Capability::Shader) || inst->type_id() == 0 || + !_.ContainsLimitedUseIntOrFloatType(inst->type_id())) { + return SPV_SUCCESS; + } + + if (_.IsPointerType(inst->type_id())) return SPV_SUCCESS; + + // The validator should previously have checked ways to generate 8- or 16-bit + // types. So we only need to considervalid paths from source to sink. + // When restricted, uses of 8- or 16-bit types can only be stores, + // width-only conversions, decorations and copy object. + for (auto use : inst->uses()) { + const auto* user = use.first; + switch (user->opcode()) { + case spv::Op::OpDecorate: + case spv::Op::OpDecorateId: + case spv::Op::OpCopyObject: + case spv::Op::OpStore: + case spv::Op::OpFConvert: + case spv::Op::OpUConvert: + case spv::Op::OpSConvert: + break; + default: + return _.diag(SPV_ERROR_INVALID_ID, user) + << "Invalid use of 8- or 16-bit result"; + } + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validate_type.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validate_type.cpp new file mode 100644 index 000000000000..cb26a527cc3a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validate_type.cpp @@ -0,0 +1,639 @@ +// Copyright (c) 2018 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Ensures type declarations are unique unless allowed by the specification. + +#include "source/opcode.h" +#include "source/spirv_target_env.h" +#include "source/val/instruction.h" +#include "source/val/validate.h" +#include "source/val/validation_state.h" + +namespace spvtools { +namespace val { +namespace { + +// Validates that type declarations are unique, unless multiple declarations +// of the same data type are allowed by the specification. +// (see section 2.8 Types and Variables) +// Doesn't do anything if SPV_VAL_ignore_type_decl_unique was declared in the +// module. +spv_result_t ValidateUniqueness(ValidationState_t& _, const Instruction* inst) { + if (_.HasExtension(Extension::kSPV_VALIDATOR_ignore_type_decl_unique)) + return SPV_SUCCESS; + + const auto opcode = inst->opcode(); + if (opcode != spv::Op::OpTypeArray && opcode != spv::Op::OpTypeRuntimeArray && + opcode != spv::Op::OpTypeStruct && opcode != spv::Op::OpTypePointer && + !_.RegisterUniqueTypeDeclaration(inst)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Duplicate non-aggregate type declarations are not allowed. " + "Opcode: " + << spvOpcodeString(opcode) << " id: " << inst->id(); + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeInt(ValidationState_t& _, const Instruction* inst) { + // Validates that the number of bits specified for an Int type is valid. + // Scalar integer types can be parameterized only with 32-bits. + // Int8, Int16, and Int64 capabilities allow using 8-bit, 16-bit, and 64-bit + // integers, respectively. + auto num_bits = inst->GetOperandAs(1); + if (num_bits != 32) { + if (num_bits == 8) { + if (_.features().declare_int8_type) { + return SPV_SUCCESS; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Using an 8-bit integer type requires the Int8 capability," + " or an extension that explicitly enables 8-bit integers."; + } else if (num_bits == 16) { + if (_.features().declare_int16_type) { + return SPV_SUCCESS; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Using a 16-bit integer type requires the Int16 capability," + " or an extension that explicitly enables 16-bit integers."; + } else if (num_bits == 64) { + if (_.HasCapability(spv::Capability::Int64)) { + return SPV_SUCCESS; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Using a 64-bit integer type requires the Int64 capability."; + } else { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Invalid number of bits (" << num_bits + << ") used for OpTypeInt."; + } + } + + const auto signedness_index = 2; + const auto signedness = inst->GetOperandAs(signedness_index); + if (signedness != 0 && signedness != 1) { + return _.diag(SPV_ERROR_INVALID_VALUE, inst) + << "OpTypeInt has invalid signedness:"; + } + + // SPIR-V Spec 2.16.3: Validation Rules for Kernel Capabilities: The + // Signedness in OpTypeInt must always be 0. + if (spv::Op::OpTypeInt == inst->opcode() && + _.HasCapability(spv::Capability::Kernel) && + inst->GetOperandAs(2) != 0u) { + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << "The Signedness in OpTypeInt " + "must always be 0 when Kernel " + "capability is used."; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeFloat(ValidationState_t& _, const Instruction* inst) { + // Validates that the number of bits specified for an Int type is valid. + // Scalar integer types can be parameterized only with 32-bits. + // Int8, Int16, and Int64 capabilities allow using 8-bit, 16-bit, and 64-bit + // integers, respectively. + auto num_bits = inst->GetOperandAs(1); + if (num_bits == 32) { + return SPV_SUCCESS; + } + if (num_bits == 16) { + if (_.features().declare_float16_type) { + return SPV_SUCCESS; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Using a 16-bit floating point " + << "type requires the Float16 or Float16Buffer capability," + " or an extension that explicitly enables 16-bit floating point."; + } + if (num_bits == 64) { + if (_.HasCapability(spv::Capability::Float64)) { + return SPV_SUCCESS; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Using a 64-bit floating point " + << "type requires the Float64 capability."; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Invalid number of bits (" << num_bits << ") used for OpTypeFloat."; +} + +spv_result_t ValidateTypeVector(ValidationState_t& _, const Instruction* inst) { + const auto component_index = 1; + const auto component_id = inst->GetOperandAs(component_index); + const auto component_type = _.FindDef(component_id); + if (!component_type || !spvOpcodeIsScalarType(component_type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeVector Component Type " << _.getIdName(component_id) + << " is not a scalar type."; + } + + // Validates that the number of components in the vector is valid. + // Vector types can only be parameterized as having 2, 3, or 4 components. + // If the Vector16 capability is added, 8 and 16 components are also allowed. + auto num_components = inst->GetOperandAs(2); + if (num_components == 2 || num_components == 3 || num_components == 4) { + return SPV_SUCCESS; + } else if (num_components == 8 || num_components == 16) { + if (_.HasCapability(spv::Capability::Vector16)) { + return SPV_SUCCESS; + } + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Having " << num_components << " components for " + << spvOpcodeString(inst->opcode()) + << " requires the Vector16 capability"; + } else { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Illegal number of components (" << num_components << ") for " + << spvOpcodeString(inst->opcode()); + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeMatrix(ValidationState_t& _, const Instruction* inst) { + const auto column_type_index = 1; + const auto column_type_id = inst->GetOperandAs(column_type_index); + const auto column_type = _.FindDef(column_type_id); + if (!column_type || spv::Op::OpTypeVector != column_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Columns in a matrix must be of type vector."; + } + + // Trace back once more to find out the type of components in the vector. + // Operand 1 is the of the type of data in the vector. + const auto comp_type_id = column_type->GetOperandAs(1); + auto comp_type_instruction = _.FindDef(comp_type_id); + if (comp_type_instruction->opcode() != spv::Op::OpTypeFloat) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Matrix types can only be " + "parameterized with " + "floating-point types."; + } + + // Validates that the matrix has 2,3, or 4 columns. + auto num_cols = inst->GetOperandAs(2); + if (num_cols != 2 && num_cols != 3 && num_cols != 4) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Matrix types can only be " + "parameterized as having " + "only 2, 3, or 4 columns."; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { + const auto element_type_index = 1; + const auto element_type_id = inst->GetOperandAs(element_type_index); + const auto element_type = _.FindDef(element_type_id); + if (!element_type || !spvOpcodeGeneratesType(element_type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeArray Element Type " << _.getIdName(element_type_id) + << " is not a type."; + } + + if (element_type->opcode() == spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeArray Element Type " << _.getIdName(element_type_id) + << " is a void type."; + } + + if (spvIsVulkanEnv(_.context()->target_env) && + element_type->opcode() == spv::Op::OpTypeRuntimeArray) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) << "OpTypeArray Element Type " + << _.getIdName(element_type_id) << " is not valid in " + << spvLogStringForEnv(_.context()->target_env) << " environments."; + } + + const auto length_index = 2; + const auto length_id = inst->GetOperandAs(length_index); + const auto length = _.FindDef(length_id); + if (!length || !spvOpcodeIsConstant(length->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeArray Length " << _.getIdName(length_id) + << " is not a scalar constant type."; + } + + // NOTE: Check the initialiser value of the constant + const auto const_inst = length->words(); + const auto const_result_type_index = 1; + const auto const_result_type = _.FindDef(const_inst[const_result_type_index]); + if (!const_result_type || spv::Op::OpTypeInt != const_result_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeArray Length " << _.getIdName(length_id) + << " is not a constant integer type."; + } + + int64_t length_value; + if (_.EvalConstantValInt64(length_id, &length_value)) { + auto& type_words = const_result_type->words(); + const bool is_signed = type_words[3] > 0; + if (length_value == 0 || (length_value < 0 && is_signed)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeArray Length " << _.getIdName(length_id) + << " default value must be at least 1: found " << length_value; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeRuntimeArray(ValidationState_t& _, + const Instruction* inst) { + const auto element_type_index = 1; + const auto element_id = inst->GetOperandAs(element_type_index); + const auto element_type = _.FindDef(element_id); + if (!element_type || !spvOpcodeGeneratesType(element_type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeRuntimeArray Element Type " << _.getIdName(element_id) + << " is not a type."; + } + + if (element_type->opcode() == spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeRuntimeArray Element Type " << _.getIdName(element_id) + << " is a void type."; + } + + if (spvIsVulkanEnv(_.context()->target_env) && + element_type->opcode() == spv::Op::OpTypeRuntimeArray) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) << "OpTypeRuntimeArray Element Type " + << _.getIdName(element_id) << " is not valid in " + << spvLogStringForEnv(_.context()->target_env) << " environments."; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { + const uint32_t struct_id = inst->GetOperandAs(0); + for (size_t member_type_index = 1; + member_type_index < inst->operands().size(); ++member_type_index) { + auto member_type_id = inst->GetOperandAs(member_type_index); + if (member_type_id == inst->id()) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Structure members may not be self references"; + } + + auto member_type = _.FindDef(member_type_id); + if (!member_type || !spvOpcodeGeneratesType(member_type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeStruct Member Type " << _.getIdName(member_type_id) + << " is not a type."; + } + if (member_type->opcode() == spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Structures cannot contain a void type."; + } + if (spv::Op::OpTypeStruct == member_type->opcode() && + _.IsStructTypeWithBuiltInMember(member_type_id)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Structure " << _.getIdName(member_type_id) + << " contains members with BuiltIn decoration. Therefore this " + << "structure may not be contained as a member of another " + << "structure " + << "type. Structure " << _.getIdName(struct_id) + << " contains structure " << _.getIdName(member_type_id) + << "."; + } + + if (spvIsVulkanEnv(_.context()->target_env) && + member_type->opcode() == spv::Op::OpTypeRuntimeArray) { + const bool is_last_member = + member_type_index == inst->operands().size() - 1; + if (!is_last_member) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) << "In " + << spvLogStringForEnv(_.context()->target_env) + << ", OpTypeRuntimeArray must only be used for the last member " + "of an OpTypeStruct"; + } + + if (!_.HasDecoration(inst->id(), spv::Decoration::Block) && + !_.HasDecoration(inst->id(), spv::Decoration::BufferBlock)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4680) + << spvLogStringForEnv(_.context()->target_env) + << ", OpTypeStruct containing an OpTypeRuntimeArray " + << "must be decorated with Block or BufferBlock."; + } + } + } + + bool has_nested_blockOrBufferBlock_struct = false; + // Struct members start at word 2 of OpTypeStruct instruction. + for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) { + auto member = inst->word(word_i); + auto memberTypeInstr = _.FindDef(member); + if (memberTypeInstr && spv::Op::OpTypeStruct == memberTypeInstr->opcode()) { + if (_.HasDecoration(memberTypeInstr->id(), spv::Decoration::Block) || + _.HasDecoration(memberTypeInstr->id(), + spv::Decoration::BufferBlock) || + _.GetHasNestedBlockOrBufferBlockStruct(memberTypeInstr->id())) + has_nested_blockOrBufferBlock_struct = true; + } + } + + _.SetHasNestedBlockOrBufferBlockStruct(inst->id(), + has_nested_blockOrBufferBlock_struct); + if (_.GetHasNestedBlockOrBufferBlockStruct(inst->id()) && + (_.HasDecoration(inst->id(), spv::Decoration::BufferBlock) || + _.HasDecoration(inst->id(), spv::Decoration::Block))) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "rules: A Block or BufferBlock cannot be nested within another " + "Block or BufferBlock. "; + } + + std::unordered_set built_in_members; + for (auto decoration : _.id_decorations(struct_id)) { + if (decoration.dec_type() == spv::Decoration::BuiltIn && + decoration.struct_member_index() != Decoration::kInvalidMember) { + built_in_members.insert(decoration.struct_member_index()); + } + } + int num_struct_members = static_cast(inst->operands().size() - 1); + int num_builtin_members = static_cast(built_in_members.size()); + if (num_builtin_members > 0 && num_builtin_members != num_struct_members) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "When BuiltIn decoration is applied to a structure-type member, " + << "all members of that structure type must also be decorated with " + << "BuiltIn (No allowed mixing of built-in variables and " + << "non-built-in variables within a single structure). Structure id " + << struct_id << " does not meet this requirement."; + } + if (num_builtin_members > 0) { + _.RegisterStructTypeWithBuiltInMember(struct_id); + } + + const auto isOpaqueType = [&_](const Instruction* opaque_inst) { + auto opcode = opaque_inst->opcode(); + if (_.HasCapability(spv::Capability::BindlessTextureNV) && + (opcode == spv::Op::OpTypeImage || opcode == spv::Op::OpTypeSampler || + opcode == spv::Op::OpTypeSampledImage)) { + return false; + } else if (spvOpcodeIsBaseOpaqueType(opcode)) { + return true; + } + return false; + }; + + if (spvIsVulkanEnv(_.context()->target_env) && + !_.options()->before_hlsl_legalization && + _.ContainsType(inst->id(), isOpaqueType)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4667) << "In " + << spvLogStringForEnv(_.context()->target_env) + << ", OpTypeStruct must not contain an opaque type."; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypePointer(ValidationState_t& _, + const Instruction* inst) { + auto type_id = inst->GetOperandAs(2); + auto type = _.FindDef(type_id); + if (!type || !spvOpcodeGeneratesType(type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypePointer Type " << _.getIdName(type_id) + << " is not a type."; + } + // See if this points to a storage image. + const auto storage_class = inst->GetOperandAs(1); + if (storage_class == spv::StorageClass::UniformConstant) { + // Unpack an optional level of arraying. + if (type->opcode() == spv::Op::OpTypeArray || + type->opcode() == spv::Op::OpTypeRuntimeArray) { + type_id = type->GetOperandAs(1); + type = _.FindDef(type_id); + } + if (type->opcode() == spv::Op::OpTypeImage) { + const auto sampled = type->GetOperandAs(6); + // 2 indicates this image is known to be be used without a sampler, i.e. + // a storage image. + if (sampled == 2) _.RegisterPointerToStorageImage(inst->id()); + } + } + + if (!_.IsValidStorageClass(storage_class)) { + return _.diag(SPV_ERROR_INVALID_BINARY, inst) + << _.VkErrorID(4643) + << "Invalid storage class for target environment"; + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeFunction(ValidationState_t& _, + const Instruction* inst) { + const auto return_type_id = inst->GetOperandAs(1); + const auto return_type = _.FindDef(return_type_id); + if (!return_type || !spvOpcodeGeneratesType(return_type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeFunction Return Type " << _.getIdName(return_type_id) + << " is not a type."; + } + size_t num_args = 0; + for (size_t param_type_index = 2; param_type_index < inst->operands().size(); + ++param_type_index, ++num_args) { + const auto param_id = inst->GetOperandAs(param_type_index); + const auto param_type = _.FindDef(param_id); + if (!param_type || !spvOpcodeGeneratesType(param_type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeFunction Parameter Type " << _.getIdName(param_id) + << " is not a type."; + } + + if (param_type->opcode() == spv::Op::OpTypeVoid) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeFunction Parameter Type " << _.getIdName(param_id) + << " cannot be OpTypeVoid."; + } + } + const uint32_t num_function_args_limit = + _.options()->universal_limits_.max_function_args; + if (num_args > num_function_args_limit) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeFunction may not take more than " + << num_function_args_limit << " arguments. OpTypeFunction " + << _.getIdName(inst->GetOperandAs(0)) << " has " + << num_args << " arguments."; + } + + // The only valid uses of OpTypeFunction are in an OpFunction, debugging, or + // decoration instruction. + for (auto& pair : inst->uses()) { + const auto* use = pair.first; + if (use->opcode() != spv::Op::OpFunction && + !spvOpcodeIsDebug(use->opcode()) && !use->IsNonSemantic() && + !spvOpcodeIsDecoration(use->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, use) + << "Invalid use of function type result id " + << _.getIdName(inst->id()) << "."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeForwardPointer(ValidationState_t& _, + const Instruction* inst) { + const auto pointer_type_id = inst->GetOperandAs(0); + const auto pointer_type_inst = _.FindDef(pointer_type_id); + if (pointer_type_inst->opcode() != spv::Op::OpTypePointer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Pointer type in OpTypeForwardPointer is not a pointer type."; + } + + const auto storage_class = inst->GetOperandAs(1); + if (storage_class != pointer_type_inst->GetOperandAs(1)) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Storage class in OpTypeForwardPointer does not match the " + << "pointer definition."; + } + + const auto pointee_type_id = pointer_type_inst->GetOperandAs(2); + const auto pointee_type = _.FindDef(pointee_type_id); + if (!pointee_type || pointee_type->opcode() != spv::Op::OpTypeStruct) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Forward pointers must point to a structure"; + } + + if (spvIsVulkanEnv(_.context()->target_env)) { + if (storage_class != spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << _.VkErrorID(4711) + << "In Vulkan, OpTypeForwardPointer must have " + << "a storage class of PhysicalStorageBuffer."; + } + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateTypeCooperativeMatrix(ValidationState_t& _, + const Instruction* inst) { + const auto component_type_index = 1; + const auto component_type_id = + inst->GetOperandAs(component_type_index); + const auto component_type = _.FindDef(component_type_id); + if (!component_type || (spv::Op::OpTypeFloat != component_type->opcode() && + spv::Op::OpTypeInt != component_type->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeCooperativeMatrix Component Type " + << _.getIdName(component_type_id) + << " is not a scalar numerical type."; + } + + const auto scope_index = 2; + const auto scope_id = inst->GetOperandAs(scope_index); + const auto scope = _.FindDef(scope_id); + if (!scope || !_.IsIntScalarType(scope->type_id()) || + !spvOpcodeIsConstant(scope->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeCooperativeMatrix Scope " << _.getIdName(scope_id) + << " is not a constant instruction with scalar integer type."; + } + + const auto rows_index = 3; + const auto rows_id = inst->GetOperandAs(rows_index); + const auto rows = _.FindDef(rows_id); + if (!rows || !_.IsIntScalarType(rows->type_id()) || + !spvOpcodeIsConstant(rows->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeCooperativeMatrix Rows " << _.getIdName(rows_id) + << " is not a constant instruction with scalar integer type."; + } + + const auto cols_index = 4; + const auto cols_id = inst->GetOperandAs(cols_index); + const auto cols = _.FindDef(cols_id); + if (!cols || !_.IsIntScalarType(cols->type_id()) || + !spvOpcodeIsConstant(cols->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeCooperativeMatrix Cols " << _.getIdName(cols_id) + << " is not a constant instruction with scalar integer type."; + } + + if (inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR) { + const auto use_index = 5; + const auto use_id = inst->GetOperandAs(use_index); + const auto use = _.FindDef(use_id); + if (!use || !_.IsIntScalarType(use->type_id()) || + !spvOpcodeIsConstant(use->opcode())) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "OpTypeCooperativeMatrixKHR Use " << _.getIdName(use_id) + << " is not a constant instruction with scalar integer type."; + } + } + + return SPV_SUCCESS; +} +} // namespace + +spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) { + if (!spvOpcodeGeneratesType(inst->opcode()) && + inst->opcode() != spv::Op::OpTypeForwardPointer) { + return SPV_SUCCESS; + } + + if (auto error = ValidateUniqueness(_, inst)) return error; + + switch (inst->opcode()) { + case spv::Op::OpTypeInt: + if (auto error = ValidateTypeInt(_, inst)) return error; + break; + case spv::Op::OpTypeFloat: + if (auto error = ValidateTypeFloat(_, inst)) return error; + break; + case spv::Op::OpTypeVector: + if (auto error = ValidateTypeVector(_, inst)) return error; + break; + case spv::Op::OpTypeMatrix: + if (auto error = ValidateTypeMatrix(_, inst)) return error; + break; + case spv::Op::OpTypeArray: + if (auto error = ValidateTypeArray(_, inst)) return error; + break; + case spv::Op::OpTypeRuntimeArray: + if (auto error = ValidateTypeRuntimeArray(_, inst)) return error; + break; + case spv::Op::OpTypeStruct: + if (auto error = ValidateTypeStruct(_, inst)) return error; + break; + case spv::Op::OpTypePointer: + if (auto error = ValidateTypePointer(_, inst)) return error; + break; + case spv::Op::OpTypeFunction: + if (auto error = ValidateTypeFunction(_, inst)) return error; + break; + case spv::Op::OpTypeForwardPointer: + if (auto error = ValidateTypeForwardPointer(_, inst)) return error; + break; + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + if (auto error = ValidateTypeCooperativeMatrix(_, inst)) return error; + break; + default: + break; + } + + return SPV_SUCCESS; +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validation_state.cpp b/thirdparty/glslang/External/spirv-tools/source/val/validation_state.cpp new file mode 100644 index 000000000000..fa5ae3e00fc7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validation_state.cpp @@ -0,0 +1,2360 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/val/validation_state.h" + +#include +#include +#include + +#include "source/opcode.h" +#include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/util/make_unique.h" +#include "source/val/basic_block.h" +#include "source/val/construct.h" +#include "source/val/function.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace val { +namespace { + +ModuleLayoutSection InstructionLayoutSection( + ModuleLayoutSection current_section, spv::Op op) { + // See Section 2.4 + if (spvOpcodeGeneratesType(op) || spvOpcodeIsConstant(op)) + return kLayoutTypes; + + switch (op) { + case spv::Op::OpCapability: + return kLayoutCapabilities; + case spv::Op::OpExtension: + return kLayoutExtensions; + case spv::Op::OpExtInstImport: + return kLayoutExtInstImport; + case spv::Op::OpMemoryModel: + return kLayoutMemoryModel; + case spv::Op::OpEntryPoint: + return kLayoutEntryPoint; + case spv::Op::OpExecutionMode: + case spv::Op::OpExecutionModeId: + return kLayoutExecutionMode; + case spv::Op::OpSourceContinued: + case spv::Op::OpSource: + case spv::Op::OpSourceExtension: + case spv::Op::OpString: + return kLayoutDebug1; + case spv::Op::OpName: + case spv::Op::OpMemberName: + return kLayoutDebug2; + case spv::Op::OpModuleProcessed: + return kLayoutDebug3; + case spv::Op::OpDecorate: + case spv::Op::OpMemberDecorate: + case spv::Op::OpGroupDecorate: + case spv::Op::OpGroupMemberDecorate: + case spv::Op::OpDecorationGroup: + case spv::Op::OpDecorateId: + case spv::Op::OpDecorateStringGOOGLE: + case spv::Op::OpMemberDecorateStringGOOGLE: + return kLayoutAnnotations; + case spv::Op::OpTypeForwardPointer: + return kLayoutTypes; + case spv::Op::OpVariable: + if (current_section == kLayoutTypes) return kLayoutTypes; + return kLayoutFunctionDefinitions; + case spv::Op::OpExtInst: + // spv::Op::OpExtInst is only allowed in types section for certain + // extended instruction sets. This will be checked separately. + if (current_section == kLayoutTypes) return kLayoutTypes; + return kLayoutFunctionDefinitions; + case spv::Op::OpLine: + case spv::Op::OpNoLine: + case spv::Op::OpUndef: + if (current_section == kLayoutTypes) return kLayoutTypes; + return kLayoutFunctionDefinitions; + case spv::Op::OpFunction: + case spv::Op::OpFunctionParameter: + case spv::Op::OpFunctionEnd: + if (current_section == kLayoutFunctionDeclarations) + return kLayoutFunctionDeclarations; + return kLayoutFunctionDefinitions; + case spv::Op::OpSamplerImageAddressingModeNV: + return kLayoutSamplerImageAddressMode; + default: + break; + } + return kLayoutFunctionDefinitions; +} + +bool IsInstructionInLayoutSection(ModuleLayoutSection layout, spv::Op op) { + return layout == InstructionLayoutSection(layout, op); +} + +// Counts the number of instructions and functions in the file. +spv_result_t CountInstructions(void* user_data, + const spv_parsed_instruction_t* inst) { + ValidationState_t& _ = *(reinterpret_cast(user_data)); + if (spv::Op(inst->opcode) == spv::Op::OpFunction) { + _.increment_total_functions(); + } + _.increment_total_instructions(); + + return SPV_SUCCESS; +} + +spv_result_t setHeader(void* user_data, spv_endianness_t, uint32_t, + uint32_t version, uint32_t generator, uint32_t id_bound, + uint32_t) { + ValidationState_t& vstate = + *(reinterpret_cast(user_data)); + vstate.setIdBound(id_bound); + vstate.setGenerator(generator); + vstate.setVersion(version); + + return SPV_SUCCESS; +} + +// Add features based on SPIR-V core version number. +void UpdateFeaturesBasedOnSpirvVersion(ValidationState_t::Feature* features, + uint32_t version) { + assert(features); + if (version >= SPV_SPIRV_VERSION_WORD(1, 4)) { + features->select_between_composites = true; + features->copy_memory_permits_two_memory_accesses = true; + features->uconvert_spec_constant_op = true; + features->nonwritable_var_in_function_or_private = true; + } +} + +} // namespace + +ValidationState_t::ValidationState_t(const spv_const_context ctx, + const spv_const_validator_options opt, + const uint32_t* words, + const size_t num_words, + const uint32_t max_warnings) + : context_(ctx), + options_(opt), + words_(words), + num_words_(num_words), + unresolved_forward_ids_{}, + operand_names_{}, + current_layout_section_(kLayoutCapabilities), + module_functions_(), + module_capabilities_(), + module_extensions_(), + ordered_instructions_(), + all_definitions_(), + global_vars_(), + local_vars_(), + struct_nesting_depth_(), + struct_has_nested_blockorbufferblock_struct_(), + grammar_(ctx), + addressing_model_(spv::AddressingModel::Max), + memory_model_(spv::MemoryModel::Max), + pointer_size_and_alignment_(0), + sampler_image_addressing_mode_(0), + in_function_(false), + num_of_warnings_(0), + max_num_of_warnings_(max_warnings) { + assert(opt && "Validator options may not be Null."); + + const auto env = context_->target_env; + + if (spvIsVulkanEnv(env)) { + // Vulkan 1.1 includes VK_KHR_relaxed_block_layout in core. + if (env != SPV_ENV_VULKAN_1_0) { + features_.env_relaxed_block_layout = true; + } + } + + // LocalSizeId is only disallowed prior to Vulkan 1.3 without maintenance4. + switch (env) { + case SPV_ENV_VULKAN_1_0: + case SPV_ENV_VULKAN_1_1: + case SPV_ENV_VULKAN_1_1_SPIRV_1_4: + case SPV_ENV_VULKAN_1_2: + features_.env_allow_localsizeid = false; + break; + default: + features_.env_allow_localsizeid = true; + break; + } + + // Only attempt to count if we have words, otherwise let the other validation + // fail and generate an error. + if (num_words > 0) { + // Count the number of instructions in the binary. + // This parse should not produce any error messages. Hijack the context and + // replace the message consumer so that we do not pollute any state in input + // consumer. + spv_context_t hijacked_context = *ctx; + hijacked_context.consumer = [](spv_message_level_t, const char*, + const spv_position_t&, const char*) {}; + spvBinaryParse(&hijacked_context, this, words, num_words, setHeader, + CountInstructions, + /* diagnostic = */ nullptr); + preallocateStorage(); + } + UpdateFeaturesBasedOnSpirvVersion(&features_, version_); + + name_mapper_ = spvtools::GetTrivialNameMapper(); + if (options_->use_friendly_names) { + friendly_mapper_ = spvtools::MakeUnique( + context_, words_, num_words_); + name_mapper_ = friendly_mapper_->GetNameMapper(); + } +} + +void ValidationState_t::preallocateStorage() { + ordered_instructions_.reserve(total_instructions_); + module_functions_.reserve(total_functions_); +} + +spv_result_t ValidationState_t::ForwardDeclareId(uint32_t id) { + unresolved_forward_ids_.insert(id); + return SPV_SUCCESS; +} + +spv_result_t ValidationState_t::RemoveIfForwardDeclared(uint32_t id) { + unresolved_forward_ids_.erase(id); + return SPV_SUCCESS; +} + +spv_result_t ValidationState_t::RegisterForwardPointer(uint32_t id) { + forward_pointer_ids_.insert(id); + return SPV_SUCCESS; +} + +bool ValidationState_t::IsForwardPointer(uint32_t id) const { + return (forward_pointer_ids_.find(id) != forward_pointer_ids_.end()); +} + +void ValidationState_t::AssignNameToId(uint32_t id, std::string name) { + operand_names_[id] = name; +} + +std::string ValidationState_t::getIdName(uint32_t id) const { + const std::string id_name = name_mapper_(id); + + std::stringstream out; + out << "'" << id << "[%" << id_name << "]'"; + return out.str(); +} + +size_t ValidationState_t::unresolved_forward_id_count() const { + return unresolved_forward_ids_.size(); +} + +std::vector ValidationState_t::UnresolvedForwardIds() const { + std::vector out(std::begin(unresolved_forward_ids_), + std::end(unresolved_forward_ids_)); + return out; +} + +bool ValidationState_t::IsDefinedId(uint32_t id) const { + return all_definitions_.find(id) != std::end(all_definitions_); +} + +const Instruction* ValidationState_t::FindDef(uint32_t id) const { + auto it = all_definitions_.find(id); + if (it == all_definitions_.end()) return nullptr; + return it->second; +} + +Instruction* ValidationState_t::FindDef(uint32_t id) { + auto it = all_definitions_.find(id); + if (it == all_definitions_.end()) return nullptr; + return it->second; +} + +ModuleLayoutSection ValidationState_t::current_layout_section() const { + return current_layout_section_; +} + +void ValidationState_t::ProgressToNextLayoutSectionOrder() { + // Guard against going past the last element(kLayoutFunctionDefinitions) + if (current_layout_section_ <= kLayoutFunctionDefinitions) { + current_layout_section_ = + static_cast(current_layout_section_ + 1); + } +} + +bool ValidationState_t::IsOpcodeInPreviousLayoutSection(spv::Op op) { + ModuleLayoutSection section = + InstructionLayoutSection(current_layout_section_, op); + return section < current_layout_section_; +} + +bool ValidationState_t::IsOpcodeInCurrentLayoutSection(spv::Op op) { + return IsInstructionInLayoutSection(current_layout_section_, op); +} + +DiagnosticStream ValidationState_t::diag(spv_result_t error_code, + const Instruction* inst) { + if (error_code == SPV_WARNING) { + if (num_of_warnings_ == max_num_of_warnings_) { + DiagnosticStream({0, 0, 0}, context_->consumer, "", error_code) + << "Other warnings have been suppressed.\n"; + } + if (num_of_warnings_ >= max_num_of_warnings_) { + return DiagnosticStream({0, 0, 0}, nullptr, "", error_code); + } + ++num_of_warnings_; + } + + std::string disassembly; + if (inst) disassembly = Disassemble(*inst); + + return DiagnosticStream({0, 0, inst ? inst->LineNum() : 0}, + context_->consumer, disassembly, error_code); +} + +std::vector& ValidationState_t::functions() { + return module_functions_; +} + +Function& ValidationState_t::current_function() { + assert(in_function_body()); + return module_functions_.back(); +} + +const Function& ValidationState_t::current_function() const { + assert(in_function_body()); + return module_functions_.back(); +} + +const Function* ValidationState_t::function(uint32_t id) const { + const auto it = id_to_function_.find(id); + if (it == id_to_function_.end()) return nullptr; + return it->second; +} + +Function* ValidationState_t::function(uint32_t id) { + auto it = id_to_function_.find(id); + if (it == id_to_function_.end()) return nullptr; + return it->second; +} + +bool ValidationState_t::in_function_body() const { return in_function_; } + +bool ValidationState_t::in_block() const { + return module_functions_.empty() == false && + module_functions_.back().current_block() != nullptr; +} + +void ValidationState_t::RegisterCapability(spv::Capability cap) { + // Avoid redundant work. Otherwise the recursion could induce work + // quadrdatic in the capability dependency depth. (Ok, not much, but + // it's something.) + if (module_capabilities_.contains(cap)) return; + + module_capabilities_.insert(cap); + spv_operand_desc desc; + if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, + uint32_t(cap), &desc)) { + for (auto capability : + CapabilitySet(desc->numCapabilities, desc->capabilities)) { + RegisterCapability(capability); + } + } + + switch (cap) { + case spv::Capability::Kernel: + features_.group_ops_reduce_and_scans = true; + break; + case spv::Capability::Int8: + features_.use_int8_type = true; + features_.declare_int8_type = true; + break; + case spv::Capability::StorageBuffer8BitAccess: + case spv::Capability::UniformAndStorageBuffer8BitAccess: + case spv::Capability::StoragePushConstant8: + case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR: + features_.declare_int8_type = true; + break; + case spv::Capability::Int16: + features_.declare_int16_type = true; + break; + case spv::Capability::Float16: + case spv::Capability::Float16Buffer: + features_.declare_float16_type = true; + break; + case spv::Capability::StorageUniformBufferBlock16: + case spv::Capability::StorageUniform16: + case spv::Capability::StoragePushConstant16: + case spv::Capability::StorageInputOutput16: + case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR: + features_.declare_int16_type = true; + features_.declare_float16_type = true; + features_.free_fp_rounding_mode = true; + break; + case spv::Capability::VariablePointers: + case spv::Capability::VariablePointersStorageBuffer: + features_.variable_pointers = true; + break; + default: + // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses + // capability spv::Capability::RayTracingNV. + // spv::Capability::RayTracingProvisionalKHR would need the same + // treatment. One of the differences going from SPV_KHR_ray_tracing from + // provisional to final spec was the provisional spec uses Locations + // for variables in certain storage classes, just like the + // SPV_NV_ray_tracing extension. So it mimics the NVIDIA extension. + // The final SPV_KHR_ray_tracing uses a different capability token + // number, so it doesn't fall into this case. + break; + } +} + +void ValidationState_t::RegisterExtension(Extension ext) { + if (module_extensions_.contains(ext)) return; + + module_extensions_.insert(ext); + + switch (ext) { + case kSPV_AMD_gpu_shader_half_float: + case kSPV_AMD_gpu_shader_half_float_fetch: + // SPV_AMD_gpu_shader_half_float enables float16 type. + // https://github.com/KhronosGroup/SPIRV-Tools/issues/1375 + features_.declare_float16_type = true; + break; + case kSPV_AMD_gpu_shader_int16: + // This is not yet in the extension, but it's recommended for it. + // See https://github.com/KhronosGroup/glslang/issues/848 + features_.uconvert_spec_constant_op = true; + break; + case kSPV_AMD_shader_ballot: + // The grammar doesn't encode the fact that SPV_AMD_shader_ballot + // enables the use of group operations Reduce, InclusiveScan, + // and ExclusiveScan. Enable it manually. + // https://github.com/KhronosGroup/SPIRV-Tools/issues/991 + features_.group_ops_reduce_and_scans = true; + break; + default: + break; + } +} + +bool ValidationState_t::HasAnyOfCapabilities( + const CapabilitySet& capabilities) const { + return module_capabilities_.HasAnyOf(capabilities); +} + +bool ValidationState_t::HasAnyOfExtensions( + const ExtensionSet& extensions) const { + return module_extensions_.HasAnyOf(extensions); +} + +void ValidationState_t::set_addressing_model(spv::AddressingModel am) { + addressing_model_ = am; + switch (am) { + case spv::AddressingModel::Physical32: + pointer_size_and_alignment_ = 4; + break; + default: + // fall through + case spv::AddressingModel::Physical64: + case spv::AddressingModel::PhysicalStorageBuffer64: + pointer_size_and_alignment_ = 8; + break; + } +} + +spv::AddressingModel ValidationState_t::addressing_model() const { + return addressing_model_; +} + +void ValidationState_t::set_memory_model(spv::MemoryModel mm) { + memory_model_ = mm; +} + +spv::MemoryModel ValidationState_t::memory_model() const { + return memory_model_; +} + +void ValidationState_t::set_samplerimage_variable_address_mode( + uint32_t bit_width) { + sampler_image_addressing_mode_ = bit_width; +} + +uint32_t ValidationState_t::samplerimage_variable_address_mode() const { + return sampler_image_addressing_mode_; +} + +spv_result_t ValidationState_t::RegisterFunction( + uint32_t id, uint32_t ret_type_id, + spv::FunctionControlMask function_control, uint32_t function_type_id) { + assert(in_function_body() == false && + "RegisterFunction can only be called when parsing the binary outside " + "of another function"); + in_function_ = true; + module_functions_.emplace_back(id, ret_type_id, function_control, + function_type_id); + id_to_function_.emplace(id, ¤t_function()); + + // TODO(umar): validate function type and type_id + + return SPV_SUCCESS; +} + +spv_result_t ValidationState_t::RegisterFunctionEnd() { + assert(in_function_body() == true && + "RegisterFunctionEnd can only be called when parsing the binary " + "inside of another function"); + assert(in_block() == false && + "RegisterFunctionParameter can only be called when parsing the binary " + "outside of a block"); + current_function().RegisterFunctionEnd(); + in_function_ = false; + return SPV_SUCCESS; +} + +Instruction* ValidationState_t::AddOrderedInstruction( + const spv_parsed_instruction_t* inst) { + ordered_instructions_.emplace_back(inst); + ordered_instructions_.back().SetLineNum(ordered_instructions_.size()); + return &ordered_instructions_.back(); +} + +// Improves diagnostic messages by collecting names of IDs +void ValidationState_t::RegisterDebugInstruction(const Instruction* inst) { + switch (inst->opcode()) { + case spv::Op::OpName: { + const auto target = inst->GetOperandAs(0); + const std::string str = inst->GetOperandAs(1); + AssignNameToId(target, str); + break; + } + case spv::Op::OpMemberName: { + const auto target = inst->GetOperandAs(0); + const std::string str = inst->GetOperandAs(2); + AssignNameToId(target, str); + break; + } + case spv::Op::OpSourceContinued: + case spv::Op::OpSource: + case spv::Op::OpSourceExtension: + case spv::Op::OpString: + case spv::Op::OpLine: + case spv::Op::OpNoLine: + default: + break; + } +} + +void ValidationState_t::RegisterInstruction(Instruction* inst) { + if (inst->id()) all_definitions_.insert(std::make_pair(inst->id(), inst)); + + // Some validation checks are easier by getting all the consumers + for (size_t i = 0; i < inst->operands().size(); ++i) { + const spv_parsed_operand_t& operand = inst->operand(i); + if ((SPV_OPERAND_TYPE_ID == operand.type) || + (SPV_OPERAND_TYPE_TYPE_ID == operand.type)) { + const uint32_t operand_word = inst->word(operand.offset); + Instruction* operand_inst = FindDef(operand_word); + if (!operand_inst) { + continue; + } + + // If the instruction is using an OpTypeSampledImage as an operand, it + // should be recorded. The validator will ensure that all usages of an + // OpTypeSampledImage and its definition are in the same basic block. + if ((SPV_OPERAND_TYPE_ID == operand.type) && + (spv::Op::OpSampledImage == operand_inst->opcode())) { + RegisterSampledImageConsumer(operand_word, inst); + } + + // In order to track storage classes (not Function) used per execution + // model we can't use RegisterExecutionModelLimitation on instructions + // like OpTypePointer which are going to be in the pre-function section. + // Instead just need to register storage class usage for consumers in a + // function block. + if (inst->function()) { + if (operand_inst->opcode() == spv::Op::OpTypePointer) { + RegisterStorageClassConsumer( + operand_inst->GetOperandAs(1), inst); + } else if (operand_inst->opcode() == spv::Op::OpVariable) { + RegisterStorageClassConsumer( + operand_inst->GetOperandAs(2), inst); + } + } + } + } +} + +std::vector ValidationState_t::getSampledImageConsumers( + uint32_t sampled_image_id) const { + std::vector result; + auto iter = sampled_image_consumers_.find(sampled_image_id); + if (iter != sampled_image_consumers_.end()) { + result = iter->second; + } + return result; +} + +void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id, + Instruction* consumer) { + sampled_image_consumers_[sampled_image_id].push_back(consumer); +} + +void ValidationState_t::RegisterQCOMImageProcessingTextureConsumer( + uint32_t texture_id, const Instruction* consumer0, + const Instruction* consumer1) { + if (HasDecoration(texture_id, spv::Decoration::WeightTextureQCOM) || + HasDecoration(texture_id, spv::Decoration::BlockMatchTextureQCOM)) { + qcom_image_processing_consumers_.insert(consumer0->id()); + if (consumer1) { + qcom_image_processing_consumers_.insert(consumer1->id()); + } + } +} + +void ValidationState_t::RegisterStorageClassConsumer( + spv::StorageClass storage_class, Instruction* consumer) { + if (spvIsVulkanEnv(context()->target_env)) { + if (storage_class == spv::StorageClass::Output) { + std::string errorVUID = VkErrorID(4644); + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation([errorVUID]( + spv::ExecutionModel model, + std::string* message) { + if (model == spv::ExecutionModel::GLCompute || + model == spv::ExecutionModel::RayGenerationKHR || + model == spv::ExecutionModel::IntersectionKHR || + model == spv::ExecutionModel::AnyHitKHR || + model == spv::ExecutionModel::ClosestHitKHR || + model == spv::ExecutionModel::MissKHR || + model == spv::ExecutionModel::CallableKHR) { + if (message) { + *message = + errorVUID + + "in Vulkan environment, Output Storage Class must not be " + "used in GLCompute, RayGenerationKHR, IntersectionKHR, " + "AnyHitKHR, ClosestHitKHR, MissKHR, or CallableKHR " + "execution models"; + } + return false; + } + return true; + }); + } + + if (storage_class == spv::StorageClass::Workgroup) { + std::string errorVUID = VkErrorID(4645); + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation([errorVUID]( + spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::GLCompute && + model != spv::ExecutionModel::TaskNV && + model != spv::ExecutionModel::MeshNV && + model != spv::ExecutionModel::TaskEXT && + model != spv::ExecutionModel::MeshEXT) { + if (message) { + *message = + errorVUID + + "in Vulkan environment, Workgroup Storage Class is limited " + "to MeshNV, TaskNV, and GLCompute execution model"; + } + return false; + } + return true; + }); + } + } + + if (storage_class == spv::StorageClass::CallableDataKHR) { + std::string errorVUID = VkErrorID(4704); + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::CallableKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = + errorVUID + + "CallableDataKHR Storage Class is limited to " + "RayGenerationKHR, ClosestHitKHR, CallableKHR, and " + "MissKHR execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == spv::StorageClass::IncomingCallableDataKHR) { + std::string errorVUID = VkErrorID(4705); + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::CallableKHR) { + if (message) { + *message = + errorVUID + + "IncomingCallableDataKHR Storage Class is limited to " + "CallableKHR execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == spv::StorageClass::RayPayloadKHR) { + std::string errorVUID = VkErrorID(4698); + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation([errorVUID]( + spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = + errorVUID + + "RayPayloadKHR Storage Class is limited to RayGenerationKHR, " + "ClosestHitKHR, and MissKHR execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == spv::StorageClass::HitAttributeKHR) { + std::string errorVUID = VkErrorID(4701); + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::IntersectionKHR && + model != spv::ExecutionModel::AnyHitKHR && + model != spv::ExecutionModel::ClosestHitKHR) { + if (message) { + *message = errorVUID + + "HitAttributeKHR Storage Class is limited to " + "IntersectionKHR, AnyHitKHR, sand ClosestHitKHR " + "execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == spv::StorageClass::IncomingRayPayloadKHR) { + std::string errorVUID = VkErrorID(4699); + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::AnyHitKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = + errorVUID + + "IncomingRayPayloadKHR Storage Class is limited to " + "AnyHitKHR, ClosestHitKHR, and MissKHR execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) { + std::string errorVUID = VkErrorID(7119); + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation( + [errorVUID](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::IntersectionKHR && + model != spv::ExecutionModel::AnyHitKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::CallableKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = + errorVUID + + "ShaderRecordBufferKHR Storage Class is limited to " + "RayGenerationKHR, IntersectionKHR, AnyHitKHR, " + "ClosestHitKHR, CallableKHR, and MissKHR execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) { + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation( + [](spv::ExecutionModel model, std::string* message) { + if (model != spv::ExecutionModel::TaskEXT && + model != spv::ExecutionModel::MeshEXT) { + if (message) { + *message = + "TaskPayloadWorkgroupEXT Storage Class is limited to " + "TaskEXT and MeshKHR execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == spv::StorageClass::HitObjectAttributeNV) { + function(consumer->function()->id()) + ->RegisterExecutionModelLimitation([](spv::ExecutionModel model, + std::string* message) { + if (model != spv::ExecutionModel::RayGenerationKHR && + model != spv::ExecutionModel::ClosestHitKHR && + model != spv::ExecutionModel::MissKHR) { + if (message) { + *message = + "HitObjectAttributeNV Storage Class is limited to " + "RayGenerationKHR, ClosestHitKHR or MissKHR execution model"; + } + return false; + } + return true; + }); + } +} + +uint32_t ValidationState_t::getIdBound() const { return id_bound_; } + +void ValidationState_t::setIdBound(const uint32_t bound) { id_bound_ = bound; } + +bool ValidationState_t::RegisterUniqueTypeDeclaration(const Instruction* inst) { + std::vector key; + key.push_back(static_cast(inst->opcode())); + for (size_t index = 0; index < inst->operands().size(); ++index) { + const spv_parsed_operand_t& operand = inst->operand(index); + + if (operand.type == SPV_OPERAND_TYPE_RESULT_ID) continue; + + const int words_begin = operand.offset; + const int words_end = words_begin + operand.num_words; + assert(words_end <= static_cast(inst->words().size())); + + key.insert(key.end(), inst->words().begin() + words_begin, + inst->words().begin() + words_end); + } + + return unique_type_declarations_.insert(std::move(key)).second; +} + +uint32_t ValidationState_t::GetTypeId(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst ? inst->type_id() : 0; +} + +spv::Op ValidationState_t::GetIdOpcode(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst ? inst->opcode() : spv::Op::OpNop; +} + +uint32_t ValidationState_t::GetComponentType(uint32_t id) const { + const Instruction* inst = FindDef(id); + assert(inst); + + switch (inst->opcode()) { + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeBool: + return id; + + case spv::Op::OpTypeVector: + return inst->word(2); + + case spv::Op::OpTypeMatrix: + return GetComponentType(inst->word(2)); + + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + return inst->word(2); + + default: + break; + } + + if (inst->type_id()) return GetComponentType(inst->type_id()); + + assert(0); + return 0; +} + +uint32_t ValidationState_t::GetDimension(uint32_t id) const { + const Instruction* inst = FindDef(id); + assert(inst); + + switch (inst->opcode()) { + case spv::Op::OpTypeFloat: + case spv::Op::OpTypeInt: + case spv::Op::OpTypeBool: + return 1; + + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + return inst->word(3); + + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + // Actual dimension isn't known, return 0 + return 0; + + default: + break; + } + + if (inst->type_id()) return GetDimension(inst->type_id()); + + assert(0); + return 0; +} + +uint32_t ValidationState_t::GetBitWidth(uint32_t id) const { + const uint32_t component_type_id = GetComponentType(id); + const Instruction* inst = FindDef(component_type_id); + assert(inst); + + if (inst->opcode() == spv::Op::OpTypeFloat || + inst->opcode() == spv::Op::OpTypeInt) + return inst->word(2); + + if (inst->opcode() == spv::Op::OpTypeBool) return 1; + + assert(0); + return 0; +} + +bool ValidationState_t::IsVoidType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeVoid; +} + +bool ValidationState_t::IsFloatScalarType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeFloat; +} + +bool ValidationState_t::IsFloatVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsFloatScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsFloat16Vector2Or4Type(uint32_t id) const { + const Instruction* inst = FindDef(id); + assert(inst); + + if (inst->opcode() == spv::Op::OpTypeVector) { + uint32_t vectorDim = GetDimension(id); + return IsFloatScalarType(GetComponentType(id)) && + (vectorDim == 2 || vectorDim == 4) && + (GetBitWidth(GetComponentType(id)) == 16); + } + + return false; +} + +bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeFloat) { + return true; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsFloatScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsIntScalarType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeInt; +} + +bool ValidationState_t::IsIntVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsIntScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeInt) { + return true; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsIntScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 0; +} + +bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsUnsignedIntScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsUnsignedIntScalarOrVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeInt) { + return inst->GetOperandAs(2) == 0; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsUnsignedIntScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsSignedIntScalarType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 1; +} + +bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsSignedIntScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsBoolScalarType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeBool; +} + +bool ValidationState_t::IsBoolVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsBoolScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeBool) { + return true; + } + + if (inst->opcode() == spv::Op::OpTypeVector) { + return IsBoolScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::IsFloatMatrixType(uint32_t id) const { + const Instruction* inst = FindDef(id); + if (!inst) { + return false; + } + + if (inst->opcode() == spv::Op::OpTypeMatrix) { + return IsFloatScalarType(GetComponentType(id)); + } + + return false; +} + +bool ValidationState_t::GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows, + uint32_t* num_cols, + uint32_t* column_type, + uint32_t* component_type) const { + if (!id) return false; + + const Instruction* mat_inst = FindDef(id); + assert(mat_inst); + if (mat_inst->opcode() != spv::Op::OpTypeMatrix) return false; + + const uint32_t vec_type = mat_inst->word(2); + const Instruction* vec_inst = FindDef(vec_type); + assert(vec_inst); + + if (vec_inst->opcode() != spv::Op::OpTypeVector) { + assert(0); + return false; + } + + *num_cols = mat_inst->word(3); + *num_rows = vec_inst->word(3); + *column_type = mat_inst->word(2); + *component_type = vec_inst->word(2); + + return true; +} + +bool ValidationState_t::GetStructMemberTypes( + uint32_t struct_type_id, std::vector* member_types) const { + member_types->clear(); + if (!struct_type_id) return false; + + const Instruction* inst = FindDef(struct_type_id); + assert(inst); + if (inst->opcode() != spv::Op::OpTypeStruct) return false; + + *member_types = + std::vector(inst->words().cbegin() + 2, inst->words().cend()); + + if (member_types->empty()) return false; + + return true; +} + +bool ValidationState_t::IsPointerType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypePointer; +} + +bool ValidationState_t::GetPointerTypeInfo( + uint32_t id, uint32_t* data_type, spv::StorageClass* storage_class) const { + *storage_class = spv::StorageClass::Max; + if (!id) return false; + + const Instruction* inst = FindDef(id); + assert(inst); + if (inst->opcode() != spv::Op::OpTypePointer) return false; + + *storage_class = spv::StorageClass(inst->word(2)); + *data_type = inst->word(3); + return true; +} + +bool ValidationState_t::IsAccelerationStructureType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeAccelerationStructureKHR; +} + +bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && (inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV || + inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR); +} + +bool ValidationState_t::IsCooperativeMatrixNVType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV; +} + +bool ValidationState_t::IsCooperativeMatrixKHRType(uint32_t id) const { + const Instruction* inst = FindDef(id); + return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR; +} + +bool ValidationState_t::IsCooperativeMatrixAType(uint32_t id) const { + if (!IsCooperativeMatrixKHRType(id)) return false; + const Instruction* inst = FindDef(id); + uint64_t matrixUse = 0; + if (EvalConstantValUint64(inst->word(6), &matrixUse)) { + return matrixUse == + static_cast(spv::CooperativeMatrixUse::MatrixAKHR); + } + return false; +} + +bool ValidationState_t::IsCooperativeMatrixBType(uint32_t id) const { + if (!IsCooperativeMatrixKHRType(id)) return false; + const Instruction* inst = FindDef(id); + uint64_t matrixUse = 0; + if (EvalConstantValUint64(inst->word(6), &matrixUse)) { + return matrixUse == + static_cast(spv::CooperativeMatrixUse::MatrixBKHR); + } + return false; +} +bool ValidationState_t::IsCooperativeMatrixAccType(uint32_t id) const { + if (!IsCooperativeMatrixKHRType(id)) return false; + const Instruction* inst = FindDef(id); + uint64_t matrixUse = 0; + if (EvalConstantValUint64(inst->word(6), &matrixUse)) { + return matrixUse == static_cast( + spv::CooperativeMatrixUse::MatrixAccumulatorKHR); + } + return false; +} + +bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const { + if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id)) + return false; + return IsFloatScalarType(FindDef(id)->word(2)); +} + +bool ValidationState_t::IsIntCooperativeMatrixType(uint32_t id) const { + if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id)) + return false; + return IsIntScalarType(FindDef(id)->word(2)); +} + +bool ValidationState_t::IsUnsignedIntCooperativeMatrixType(uint32_t id) const { + if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id)) + return false; + return IsUnsignedIntScalarType(FindDef(id)->word(2)); +} + +// Either a 32 bit 2-component uint vector or a 64 bit uint scalar +bool ValidationState_t::IsUnsigned64BitHandle(uint32_t id) const { + return ((IsUnsignedIntScalarType(id) && GetBitWidth(id) == 64) || + (IsUnsignedIntVectorType(id) && GetDimension(id) == 2 && + GetBitWidth(id) == 32)); +} + +spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( + const Instruction* inst, uint32_t m1, uint32_t m2) { + const auto m1_type = FindDef(m1); + const auto m2_type = FindDef(m2); + + if (m1_type->opcode() != m2_type->opcode()) { + return diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected cooperative matrix types"; + } + + uint32_t m1_scope_id = m1_type->GetOperandAs(2); + uint32_t m1_rows_id = m1_type->GetOperandAs(3); + uint32_t m1_cols_id = m1_type->GetOperandAs(4); + + uint32_t m2_scope_id = m2_type->GetOperandAs(2); + uint32_t m2_rows_id = m2_type->GetOperandAs(3); + uint32_t m2_cols_id = m2_type->GetOperandAs(4); + + bool m1_is_int32 = false, m1_is_const_int32 = false, m2_is_int32 = false, + m2_is_const_int32 = false; + uint32_t m1_value = 0, m2_value = 0; + + std::tie(m1_is_int32, m1_is_const_int32, m1_value) = + EvalInt32IfConst(m1_scope_id); + std::tie(m2_is_int32, m2_is_const_int32, m2_value) = + EvalInt32IfConst(m2_scope_id); + + if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { + return diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected scopes of Matrix and Result Type to be " + << "identical"; + } + + std::tie(m1_is_int32, m1_is_const_int32, m1_value) = + EvalInt32IfConst(m1_rows_id); + std::tie(m2_is_int32, m2_is_const_int32, m2_value) = + EvalInt32IfConst(m2_rows_id); + + if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { + return diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected rows of Matrix type and Result Type to be " + << "identical"; + } + + std::tie(m1_is_int32, m1_is_const_int32, m1_value) = + EvalInt32IfConst(m1_cols_id); + std::tie(m2_is_int32, m2_is_const_int32, m2_value) = + EvalInt32IfConst(m2_cols_id); + + if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { + return diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected columns of Matrix type and Result Type to be " + << "identical"; + } + + if (m1_type->opcode() == spv::Op::OpTypeCooperativeMatrixKHR) { + uint32_t m1_use_id = m1_type->GetOperandAs(5); + uint32_t m2_use_id = m2_type->GetOperandAs(5); + std::tie(m1_is_int32, m1_is_const_int32, m1_value) = + EvalInt32IfConst(m1_use_id); + std::tie(m2_is_int32, m2_is_const_int32, m2_value) = + EvalInt32IfConst(m2_use_id); + + if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { + return diag(SPV_ERROR_INVALID_DATA, inst) + << "Expected Use of Matrix type and Result Type to be " + << "identical"; + } + } + + return SPV_SUCCESS; +} + +uint32_t ValidationState_t::GetOperandTypeId(const Instruction* inst, + size_t operand_index) const { + return GetTypeId(inst->GetOperandAs(operand_index)); +} + +bool ValidationState_t::EvalConstantValUint64(uint32_t id, + uint64_t* val) const { + const Instruction* inst = FindDef(id); + if (!inst) { + assert(0 && "Instruction not found"); + return false; + } + + if (!IsIntScalarType(inst->type_id())) return false; + + if (inst->opcode() == spv::Op::OpConstantNull) { + *val = 0; + } else if (inst->opcode() != spv::Op::OpConstant) { + // Spec constant values cannot be evaluated so don't consider constant for + // static validation + return false; + } else if (inst->words().size() == 4) { + *val = inst->word(3); + } else { + assert(inst->words().size() == 5); + *val = inst->word(3); + *val |= uint64_t(inst->word(4)) << 32; + } + return true; +} + +bool ValidationState_t::EvalConstantValInt64(uint32_t id, int64_t* val) const { + const Instruction* inst = FindDef(id); + if (!inst) { + assert(0 && "Instruction not found"); + return false; + } + + if (!IsIntScalarType(inst->type_id())) return false; + + if (inst->opcode() == spv::Op::OpConstantNull) { + *val = 0; + } else if (inst->opcode() != spv::Op::OpConstant) { + // Spec constant values cannot be evaluated so don't consider constant for + // static validation + return false; + } else if (inst->words().size() == 4) { + *val = int32_t(inst->word(3)); + } else { + assert(inst->words().size() == 5); + const uint32_t lo_word = inst->word(3); + const uint32_t hi_word = inst->word(4); + *val = static_cast(uint64_t(lo_word) | uint64_t(hi_word) << 32); + } + return true; +} + +std::tuple ValidationState_t::EvalInt32IfConst( + uint32_t id) const { + const Instruction* const inst = FindDef(id); + assert(inst); + const uint32_t type = inst->type_id(); + + if (type == 0 || !IsIntScalarType(type) || GetBitWidth(type) != 32) { + return std::make_tuple(false, false, 0); + } + + // Spec constant values cannot be evaluated so don't consider constant for + // the purpose of this method. + if (!spvOpcodeIsConstant(inst->opcode()) || + spvOpcodeIsSpecConstant(inst->opcode())) { + return std::make_tuple(true, false, 0); + } + + if (inst->opcode() == spv::Op::OpConstantNull) { + return std::make_tuple(true, true, 0); + } + + assert(inst->words().size() == 4); + return std::make_tuple(true, true, inst->word(3)); +} + +void ValidationState_t::ComputeFunctionToEntryPointMapping() { + for (const uint32_t entry_point : entry_points()) { + std::stack call_stack; + std::set visited; + call_stack.push(entry_point); + while (!call_stack.empty()) { + const uint32_t called_func_id = call_stack.top(); + call_stack.pop(); + if (!visited.insert(called_func_id).second) continue; + + function_to_entry_points_[called_func_id].push_back(entry_point); + + const Function* called_func = function(called_func_id); + if (called_func) { + // Other checks should error out on this invalid SPIR-V. + for (const uint32_t new_call : called_func->function_call_targets()) { + call_stack.push(new_call); + } + } + } + } +} + +void ValidationState_t::ComputeRecursiveEntryPoints() { + for (const Function& func : functions()) { + std::stack call_stack; + std::set visited; + + for (const uint32_t new_call : func.function_call_targets()) { + call_stack.push(new_call); + } + + while (!call_stack.empty()) { + const uint32_t called_func_id = call_stack.top(); + call_stack.pop(); + + if (!visited.insert(called_func_id).second) continue; + + if (called_func_id == func.id()) { + for (const uint32_t entry_point : + function_to_entry_points_[called_func_id]) + recursive_entry_points_.insert(entry_point); + break; + } + + const Function* called_func = function(called_func_id); + if (called_func) { + // Other checks should error out on this invalid SPIR-V. + for (const uint32_t new_call : called_func->function_call_targets()) { + call_stack.push(new_call); + } + } + } + } +} + +const std::vector& ValidationState_t::FunctionEntryPoints( + uint32_t func) const { + auto iter = function_to_entry_points_.find(func); + if (iter == function_to_entry_points_.end()) { + return empty_ids_; + } else { + return iter->second; + } +} + +std::set ValidationState_t::EntryPointReferences(uint32_t id) const { + std::set referenced_entry_points; + const auto inst = FindDef(id); + if (!inst) return referenced_entry_points; + + std::vector stack; + stack.push_back(inst); + while (!stack.empty()) { + const auto current_inst = stack.back(); + stack.pop_back(); + + if (const auto func = current_inst->function()) { + // Instruction lives in a function, we can stop searching. + const auto function_entry_points = FunctionEntryPoints(func->id()); + referenced_entry_points.insert(function_entry_points.begin(), + function_entry_points.end()); + } else { + // Instruction is in the global scope, keep searching its uses. + for (auto pair : current_inst->uses()) { + const auto next_inst = pair.first; + stack.push_back(next_inst); + } + } + } + + return referenced_entry_points; +} + +std::string ValidationState_t::Disassemble(const Instruction& inst) const { + const spv_parsed_instruction_t& c_inst(inst.c_inst()); + return Disassemble(c_inst.words, c_inst.num_words); +} + +std::string ValidationState_t::Disassemble(const uint32_t* words, + uint16_t num_words) const { + uint32_t disassembly_options = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER | + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES; + + return spvInstructionBinaryToText(context()->target_env, words, num_words, + words_, num_words_, disassembly_options); +} + +bool ValidationState_t::LogicallyMatch(const Instruction* lhs, + const Instruction* rhs, + bool check_decorations) { + if (lhs->opcode() != rhs->opcode()) { + return false; + } + + if (check_decorations) { + const auto& dec_a = id_decorations(lhs->id()); + const auto& dec_b = id_decorations(rhs->id()); + + for (const auto& dec : dec_b) { + if (std::find(dec_a.begin(), dec_a.end(), dec) == dec_a.end()) { + return false; + } + } + } + + if (lhs->opcode() == spv::Op::OpTypeArray) { + // Size operands must match. + if (lhs->GetOperandAs(2u) != rhs->GetOperandAs(2u)) { + return false; + } + + // Elements must match or logically match. + const auto lhs_ele_id = lhs->GetOperandAs(1u); + const auto rhs_ele_id = rhs->GetOperandAs(1u); + if (lhs_ele_id == rhs_ele_id) { + return true; + } + + const auto lhs_ele = FindDef(lhs_ele_id); + const auto rhs_ele = FindDef(rhs_ele_id); + if (!lhs_ele || !rhs_ele) { + return false; + } + return LogicallyMatch(lhs_ele, rhs_ele, check_decorations); + } else if (lhs->opcode() == spv::Op::OpTypeStruct) { + // Number of elements must match. + if (lhs->operands().size() != rhs->operands().size()) { + return false; + } + + for (size_t i = 1u; i < lhs->operands().size(); ++i) { + const auto lhs_ele_id = lhs->GetOperandAs(i); + const auto rhs_ele_id = rhs->GetOperandAs(i); + // Elements must match or logically match. + if (lhs_ele_id == rhs_ele_id) { + continue; + } + + const auto lhs_ele = FindDef(lhs_ele_id); + const auto rhs_ele = FindDef(rhs_ele_id); + if (!lhs_ele || !rhs_ele) { + return false; + } + + if (!LogicallyMatch(lhs_ele, rhs_ele, check_decorations)) { + return false; + } + } + + // All checks passed. + return true; + } + + // No other opcodes are acceptable at this point. Arrays and structs are + // caught above and if they're elements are not arrays or structs they are + // required to match exactly. + return false; +} + +const Instruction* ValidationState_t::TracePointer( + const Instruction* inst) const { + auto base_ptr = inst; + while (base_ptr->opcode() == spv::Op::OpAccessChain || + base_ptr->opcode() == spv::Op::OpInBoundsAccessChain || + base_ptr->opcode() == spv::Op::OpPtrAccessChain || + base_ptr->opcode() == spv::Op::OpInBoundsPtrAccessChain || + base_ptr->opcode() == spv::Op::OpCopyObject) { + base_ptr = FindDef(base_ptr->GetOperandAs(2u)); + } + return base_ptr; +} + +bool ValidationState_t::ContainsType( + uint32_t id, const std::function& f, + bool traverse_all_types) const { + const auto inst = FindDef(id); + if (!inst) return false; + + if (f(inst)) return true; + + switch (inst->opcode()) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeRuntimeArray: + case spv::Op::OpTypeVector: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeImage: + case spv::Op::OpTypeSampledImage: + case spv::Op::OpTypeCooperativeMatrixNV: + case spv::Op::OpTypeCooperativeMatrixKHR: + return ContainsType(inst->GetOperandAs(1u), f, + traverse_all_types); + case spv::Op::OpTypePointer: + if (IsForwardPointer(id)) return false; + if (traverse_all_types) { + return ContainsType(inst->GetOperandAs(2u), f, + traverse_all_types); + } + break; + case spv::Op::OpTypeFunction: + case spv::Op::OpTypeStruct: + if (inst->opcode() == spv::Op::OpTypeFunction && !traverse_all_types) { + return false; + } + for (uint32_t i = 1; i < inst->operands().size(); ++i) { + if (ContainsType(inst->GetOperandAs(i), f, + traverse_all_types)) { + return true; + } + } + break; + default: + break; + } + + return false; +} + +bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, + uint32_t width) const { + if (type != spv::Op::OpTypeInt && type != spv::Op::OpTypeFloat) return false; + + const auto f = [type, width](const Instruction* inst) { + if (inst->opcode() == type) { + return inst->GetOperandAs(1u) == width; + } + return false; + }; + return ContainsType(id, f); +} + +bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const { + if ((!HasCapability(spv::Capability::Int16) && + ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 16)) || + (!HasCapability(spv::Capability::Int8) && + ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 8)) || + (!HasCapability(spv::Capability::Float16) && + ContainsSizedIntOrFloatType(id, spv::Op::OpTypeFloat, 16))) { + return true; + } + return false; +} + +bool ValidationState_t::ContainsRuntimeArray(uint32_t id) const { + const auto f = [](const Instruction* inst) { + return inst->opcode() == spv::Op::OpTypeRuntimeArray; + }; + return ContainsType(id, f, /* traverse_all_types = */ false); +} + +bool ValidationState_t::IsValidStorageClass( + spv::StorageClass storage_class) const { + if (spvIsVulkanEnv(context()->target_env)) { + switch (storage_class) { + case spv::StorageClass::UniformConstant: + case spv::StorageClass::Uniform: + case spv::StorageClass::StorageBuffer: + case spv::StorageClass::Input: + case spv::StorageClass::Output: + case spv::StorageClass::Image: + case spv::StorageClass::Workgroup: + case spv::StorageClass::Private: + case spv::StorageClass::Function: + case spv::StorageClass::PushConstant: + case spv::StorageClass::PhysicalStorageBuffer: + case spv::StorageClass::RayPayloadKHR: + case spv::StorageClass::IncomingRayPayloadKHR: + case spv::StorageClass::HitAttributeKHR: + case spv::StorageClass::CallableDataKHR: + case spv::StorageClass::IncomingCallableDataKHR: + case spv::StorageClass::ShaderRecordBufferKHR: + case spv::StorageClass::TaskPayloadWorkgroupEXT: + case spv::StorageClass::HitObjectAttributeNV: + case spv::StorageClass::TileImageEXT: + return true; + default: + return false; + } + } + + return true; +} + +#define VUID_WRAP(vuid) "[" #vuid "] " + +// Currently no 2 VUID share the same id, so no need for |reference| +std::string ValidationState_t::VkErrorID(uint32_t id, + const char* /*reference*/) const { + if (!spvIsVulkanEnv(context_->target_env)) { + return ""; + } + + // This large switch case is only searched when an error has occurred. + // If an id is changed, the old case must be modified or removed. Each string + // here is interpreted as being "implemented" + + // Clang format adds spaces between hyphens + // clang-format off + switch (id) { + case 4154: + return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04154); + case 4155: + return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04155); + case 4156: + return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04156); + case 4160: + return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04160); + case 4161: + return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04161); + case 4162: + return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04162); + case 4181: + return VUID_WRAP(VUID-BaseInstance-BaseInstance-04181); + case 4182: + return VUID_WRAP(VUID-BaseInstance-BaseInstance-04182); + case 4183: + return VUID_WRAP(VUID-BaseInstance-BaseInstance-04183); + case 4184: + return VUID_WRAP(VUID-BaseVertex-BaseVertex-04184); + case 4185: + return VUID_WRAP(VUID-BaseVertex-BaseVertex-04185); + case 4186: + return VUID_WRAP(VUID-BaseVertex-BaseVertex-04186); + case 4187: + return VUID_WRAP(VUID-ClipDistance-ClipDistance-04187); + case 4188: + return VUID_WRAP(VUID-ClipDistance-ClipDistance-04188); + case 4189: + return VUID_WRAP(VUID-ClipDistance-ClipDistance-04189); + case 4190: + return VUID_WRAP(VUID-ClipDistance-ClipDistance-04190); + case 4191: + return VUID_WRAP(VUID-ClipDistance-ClipDistance-04191); + case 4196: + return VUID_WRAP(VUID-CullDistance-CullDistance-04196); + case 4197: + return VUID_WRAP(VUID-CullDistance-CullDistance-04197); + case 4198: + return VUID_WRAP(VUID-CullDistance-CullDistance-04198); + case 4199: + return VUID_WRAP(VUID-CullDistance-CullDistance-04199); + case 4200: + return VUID_WRAP(VUID-CullDistance-CullDistance-04200); + case 6735: + return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06735); // Execution Model + case 6736: + return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06736); // input storage + case 6737: + return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06737); // 32 int scalar + case 4205: + return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04205); + case 4206: + return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04206); + case 4207: + return VUID_WRAP(VUID-DrawIndex-DrawIndex-04207); + case 4208: + return VUID_WRAP(VUID-DrawIndex-DrawIndex-04208); + case 4209: + return VUID_WRAP(VUID-DrawIndex-DrawIndex-04209); + case 4210: + return VUID_WRAP(VUID-FragCoord-FragCoord-04210); + case 4211: + return VUID_WRAP(VUID-FragCoord-FragCoord-04211); + case 4212: + return VUID_WRAP(VUID-FragCoord-FragCoord-04212); + case 4213: + return VUID_WRAP(VUID-FragDepth-FragDepth-04213); + case 4214: + return VUID_WRAP(VUID-FragDepth-FragDepth-04214); + case 4215: + return VUID_WRAP(VUID-FragDepth-FragDepth-04215); + case 4216: + return VUID_WRAP(VUID-FragDepth-FragDepth-04216); + case 4217: + return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217); + case 4218: + return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218); + case 4219: + return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219); + case 4220: + return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04220); + case 4221: + return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04221); + case 4222: + return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04222); + case 4223: + return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04223); + case 4224: + return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04224); + case 4225: + return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04225); + case 4229: + return VUID_WRAP(VUID-FrontFacing-FrontFacing-04229); + case 4230: + return VUID_WRAP(VUID-FrontFacing-FrontFacing-04230); + case 4231: + return VUID_WRAP(VUID-FrontFacing-FrontFacing-04231); + case 4232: + return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04232); + case 4233: + return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04233); + case 4234: + return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04234); + case 4236: + return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04236); + case 4237: + return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04237); + case 4238: + return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04238); + case 4239: + return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04239); + case 4240: + return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04240); + case 4241: + return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04241); + case 4242: + return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04242); + case 4243: + return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04243); + case 4244: + return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04244); + case 4245: + return VUID_WRAP(VUID-HitTNV-HitTNV-04245); + case 4246: + return VUID_WRAP(VUID-HitTNV-HitTNV-04246); + case 4247: + return VUID_WRAP(VUID-HitTNV-HitTNV-04247); + case 4248: + return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248); + case 4249: + return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249); + case 4250: + return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250); + case 4251: + return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251); + case 4252: + return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252); + case 4253: + return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253); + case 4254: + return VUID_WRAP(VUID-InstanceId-InstanceId-04254); + case 4255: + return VUID_WRAP(VUID-InstanceId-InstanceId-04255); + case 4256: + return VUID_WRAP(VUID-InstanceId-InstanceId-04256); + case 4257: + return VUID_WRAP(VUID-InvocationId-InvocationId-04257); + case 4258: + return VUID_WRAP(VUID-InvocationId-InvocationId-04258); + case 4259: + return VUID_WRAP(VUID-InvocationId-InvocationId-04259); + case 4263: + return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04263); + case 4264: + return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04264); + case 4265: + return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04265); + case 4266: + return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04266); + case 4267: + return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04267); + case 4268: + return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04268); + case 4269: + return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04269); + case 4270: + return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04270); + case 4271: + return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271); + case 4272: + return VUID_WRAP(VUID-Layer-Layer-04272); + case 4273: + return VUID_WRAP(VUID-Layer-Layer-04273); + case 4274: + return VUID_WRAP(VUID-Layer-Layer-04274); + case 4275: + return VUID_WRAP(VUID-Layer-Layer-04275); + case 4276: + return VUID_WRAP(VUID-Layer-Layer-04276); + case 4281: + return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04281); + case 4282: + return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04282); + case 4283: + return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04283); + case 4293: + return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04293); + case 4294: + return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04294); + case 4295: + return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04295); + case 4296: + return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04296); + case 4297: + return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04297); + case 4298: + return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04298); + case 4299: + return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299); + case 4300: + return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300); + case 4301: + return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301); + case 4302: + return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302); + case 4303: + return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303); + case 4304: + return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304); + case 4305: + return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305); + case 4306: + return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306); + case 4307: + return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307); + case 4308: + return VUID_WRAP(VUID-PatchVertices-PatchVertices-04308); + case 4309: + return VUID_WRAP(VUID-PatchVertices-PatchVertices-04309); + case 4310: + return VUID_WRAP(VUID-PatchVertices-PatchVertices-04310); + case 4311: + return VUID_WRAP(VUID-PointCoord-PointCoord-04311); + case 4312: + return VUID_WRAP(VUID-PointCoord-PointCoord-04312); + case 4313: + return VUID_WRAP(VUID-PointCoord-PointCoord-04313); + case 4314: + return VUID_WRAP(VUID-PointSize-PointSize-04314); + case 4315: + return VUID_WRAP(VUID-PointSize-PointSize-04315); + case 4316: + return VUID_WRAP(VUID-PointSize-PointSize-04316); + case 4317: + return VUID_WRAP(VUID-PointSize-PointSize-04317); + case 4318: + return VUID_WRAP(VUID-Position-Position-04318); + case 4319: + return VUID_WRAP(VUID-Position-Position-04319); + case 4320: + return VUID_WRAP(VUID-Position-Position-04320); + case 4321: + return VUID_WRAP(VUID-Position-Position-04321); + case 4330: + return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04330); + case 4334: + return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04334); + case 4337: + return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04337); + case 4345: + return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345); + case 4346: + return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346); + case 4347: + return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347); + case 4348: + return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04348); + case 4349: + return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04349); + case 4350: + return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04350); + case 4351: + return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04351); + case 4352: + return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04352); + case 4353: + return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04353); + case 4354: + return VUID_WRAP(VUID-SampleId-SampleId-04354); + case 4355: + return VUID_WRAP(VUID-SampleId-SampleId-04355); + case 4356: + return VUID_WRAP(VUID-SampleId-SampleId-04356); + case 4357: + return VUID_WRAP(VUID-SampleMask-SampleMask-04357); + case 4358: + return VUID_WRAP(VUID-SampleMask-SampleMask-04358); + case 4359: + return VUID_WRAP(VUID-SampleMask-SampleMask-04359); + case 4360: + return VUID_WRAP(VUID-SamplePosition-SamplePosition-04360); + case 4361: + return VUID_WRAP(VUID-SamplePosition-SamplePosition-04361); + case 4362: + return VUID_WRAP(VUID-SamplePosition-SamplePosition-04362); + case 4367: + return VUID_WRAP(VUID-SubgroupId-SubgroupId-04367); + case 4368: + return VUID_WRAP(VUID-SubgroupId-SubgroupId-04368); + case 4369: + return VUID_WRAP(VUID-SubgroupId-SubgroupId-04369); + case 4370: + return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04370); + case 4371: + return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04371); + case 4372: + return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04372); + case 4373: + return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04373); + case 4374: + return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04374); + case 4375: + return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04375); + case 4376: + return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04376); + case 4377: + return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04377); + case 4378: + return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04378); + case 4379: + return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04379); + case 4380: + return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04380); + case 4381: + return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04381); + case 4382: + return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04382); + case 4383: + return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04383); + case 4387: + return VUID_WRAP(VUID-TessCoord-TessCoord-04387); + case 4388: + return VUID_WRAP(VUID-TessCoord-TessCoord-04388); + case 4389: + return VUID_WRAP(VUID-TessCoord-TessCoord-04389); + case 4390: + return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04390); + case 4391: + return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04391); + case 4392: + return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04392); + case 4393: + return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04393); + case 4394: + return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04394); + case 4395: + return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04395); + case 4396: + return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04396); + case 4397: + return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04397); + case 4398: + return VUID_WRAP(VUID-VertexIndex-VertexIndex-04398); + case 4399: + return VUID_WRAP(VUID-VertexIndex-VertexIndex-04399); + case 4400: + return VUID_WRAP(VUID-VertexIndex-VertexIndex-04400); + case 4401: + return VUID_WRAP(VUID-ViewIndex-ViewIndex-04401); + case 4402: + return VUID_WRAP(VUID-ViewIndex-ViewIndex-04402); + case 4403: + return VUID_WRAP(VUID-ViewIndex-ViewIndex-04403); + case 4404: + return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04404); + case 4405: + return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04405); + case 4406: + return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04406); + case 4407: + return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04407); + case 4408: + return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04408); + case 4422: + return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04422); + case 4423: + return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04423); + case 4424: + return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04424); + case 4425: + return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04425); + case 4426: + return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04426); + case 4427: + return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04427); + case 4428: + return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428); + case 4429: + return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429); + case 4430: + return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430); + case 4431: + return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431); + case 4432: + return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432); + case 4433: + return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433); + case 4434: + return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04434); + case 4435: + return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04435); + case 4436: + return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04436); + case 4484: + return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484); + case 4485: + return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04485); + case 4486: + return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04486); + case 4490: + return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04490); + case 4491: + return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04491); + case 4492: + return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04492); + case 4633: + return VUID_WRAP(VUID-StandaloneSpirv-None-04633); + case 4634: + return VUID_WRAP(VUID-StandaloneSpirv-None-04634); + case 4635: + return VUID_WRAP(VUID-StandaloneSpirv-None-04635); + case 4636: + return VUID_WRAP(VUID-StandaloneSpirv-None-04636); + case 4637: + return VUID_WRAP(VUID-StandaloneSpirv-None-04637); + case 4638: + return VUID_WRAP(VUID-StandaloneSpirv-None-04638); + case 7321: + return VUID_WRAP(VUID-StandaloneSpirv-None-07321); + case 4640: + return VUID_WRAP(VUID-StandaloneSpirv-None-04640); + case 4641: + return VUID_WRAP(VUID-StandaloneSpirv-None-04641); + case 4642: + return VUID_WRAP(VUID-StandaloneSpirv-None-04642); + case 4643: + return VUID_WRAP(VUID-StandaloneSpirv-None-04643); + case 4644: + return VUID_WRAP(VUID-StandaloneSpirv-None-04644); + case 4645: + return VUID_WRAP(VUID-StandaloneSpirv-None-04645); + case 4650: + return VUID_WRAP(VUID-StandaloneSpirv-OpControlBarrier-04650); + case 4651: + return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04651); + case 4652: + return VUID_WRAP(VUID-StandaloneSpirv-OpReadClockKHR-04652); + case 4653: + return VUID_WRAP(VUID-StandaloneSpirv-OriginLowerLeft-04653); + case 4654: + return VUID_WRAP(VUID-StandaloneSpirv-PixelCenterInteger-04654); + case 4655: + return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-04655); + case 4656: + return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04656); + case 4657: + return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04657); + case 4658: + return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658); + case 4659: + return VUID_WRAP(VUID-StandaloneSpirv-OpImageQuerySizeLod-04659); + case 4663: + return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663); + case 4664: + return VUID_WRAP(VUID-StandaloneSpirv-OpImageGather-04664); + case 4667: + return VUID_WRAP(VUID-StandaloneSpirv-None-04667); + case 4669: + return VUID_WRAP(VUID-StandaloneSpirv-GLSLShared-04669); + case 4670: + return VUID_WRAP(VUID-StandaloneSpirv-Flat-04670); + case 4675: + return VUID_WRAP(VUID-StandaloneSpirv-FPRoundingMode-04675); + case 4677: + return VUID_WRAP(VUID-StandaloneSpirv-Invariant-04677); + case 4680: + return VUID_WRAP(VUID-StandaloneSpirv-OpTypeRuntimeArray-04680); + case 4682: + return VUID_WRAP(VUID-StandaloneSpirv-OpControlBarrier-04682); + case 6426: + return VUID_WRAP(VUID-StandaloneSpirv-LocalSize-06426); // formally 04683 + case 4685: + return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685); + case 4686: + return VUID_WRAP(VUID-StandaloneSpirv-None-04686); + case 4698: + return VUID_WRAP(VUID-StandaloneSpirv-RayPayloadKHR-04698); + case 4699: + return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699); + case 4700: + return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04700); + case 4701: + return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04701); + case 4702: + return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04702); + case 4703: + return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04703); + case 4704: + return VUID_WRAP(VUID-StandaloneSpirv-CallableDataKHR-04704); + case 4705: + return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04705); + case 4706: + return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04706); + case 7119: + return VUID_WRAP(VUID-StandaloneSpirv-ShaderRecordBufferKHR-07119); + case 4708: + return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708); + case 4710: + return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710); + case 4711: + return VUID_WRAP(VUID-StandaloneSpirv-OpTypeForwardPointer-04711); + case 4730: + return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicStore-04730); + case 4731: + return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicLoad-04731); + case 4732: + return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04732); + case 4733: + return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733); + case 4734: + return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04734); + case 4744: + return VUID_WRAP(VUID-StandaloneSpirv-Flat-04744); + case 4777: + return VUID_WRAP(VUID-StandaloneSpirv-OpImage-04777); + case 4780: + return VUID_WRAP(VUID-StandaloneSpirv-Result-04780); + case 4781: + return VUID_WRAP(VUID-StandaloneSpirv-Base-04781); + case 4915: + return VUID_WRAP(VUID-StandaloneSpirv-Location-04915); + case 4916: + return VUID_WRAP(VUID-StandaloneSpirv-Location-04916); + case 4917: + return VUID_WRAP(VUID-StandaloneSpirv-Location-04917); + case 4918: + return VUID_WRAP(VUID-StandaloneSpirv-Location-04918); + case 4919: + return VUID_WRAP(VUID-StandaloneSpirv-Location-04919); + case 4920: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04920); + case 4921: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04921); + case 4922: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04922); + case 4923: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04923); + case 4924: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04924); + case 6201: + return VUID_WRAP(VUID-StandaloneSpirv-Flat-06201); + case 6202: + return VUID_WRAP(VUID-StandaloneSpirv-Flat-06202); + case 6214: + return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06214); + case 6491: + return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491); + case 6671: + return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671); + case 6672: + return VUID_WRAP(VUID-StandaloneSpirv-Location-06672); + case 6673: + return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-06673); + case 6674: + return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674); + case 6675: + return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06675); + case 6676: + return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06676); + case 6677: + return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-06677); + case 6678: + return VUID_WRAP(VUID-StandaloneSpirv-InputAttachmentIndex-06678); + case 6777: + return VUID_WRAP(VUID-StandaloneSpirv-PerVertexKHR-06777); + case 6778: + return VUID_WRAP(VUID-StandaloneSpirv-Input-06778); + case 6807: + return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06807); + case 6808: + return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06808); + case 6925: + return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06925); + case 7041: + return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07041); + case 7043: + return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07043); + case 7044: + return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07044); + case 7047: + return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07047); + case 7049: + return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07049); + case 7050: + return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07050); + case 7053: + return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07053); + case 7055: + return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07055); + case 7056: + return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07056); + case 7102: + return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07102); + case 7320: + return VUID_WRAP(VUID-StandaloneSpirv-ExecutionModel-07320); + case 7290: + return VUID_WRAP(VUID-StandaloneSpirv-Input-07290); + case 7650: + return VUID_WRAP(VUID-StandaloneSpirv-Base-07650); + case 7651: + return VUID_WRAP(VUID-StandaloneSpirv-Base-07651); + case 7652: + return VUID_WRAP(VUID-StandaloneSpirv-Base-07652); + case 7703: + return VUID_WRAP(VUID-StandaloneSpirv-Component-07703); + case 7951: + return VUID_WRAP(VUID-StandaloneSpirv-SubgroupVoteKHR-07951); + case 8721: + return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-08721); + case 8722: + return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-08722); + case 8973: + return VUID_WRAP(VUID-StandaloneSpirv-Pointer-08973); + default: + return ""; // unknown id + } + // clang-format on +} + +} // namespace val +} // namespace spvtools diff --git a/thirdparty/glslang/External/spirv-tools/source/val/validation_state.h b/thirdparty/glslang/External/spirv-tools/source/val/validation_state.h new file mode 100644 index 000000000000..27acdcc2f2e7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/source/val/validation_state.h @@ -0,0 +1,982 @@ +// Copyright (c) 2015-2016 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_VAL_VALIDATION_STATE_H_ +#define SOURCE_VAL_VALIDATION_STATE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "source/assembly_grammar.h" +#include "source/diagnostic.h" +#include "source/disassemble.h" +#include "source/enum_set.h" +#include "source/latest_version_spirv_header.h" +#include "source/name_mapper.h" +#include "source/spirv_definition.h" +#include "source/spirv_validator_options.h" +#include "source/val/decoration.h" +#include "source/val/function.h" +#include "source/val/instruction.h" +#include "spirv-tools/libspirv.h" + +namespace spvtools { +namespace val { + +/// This enum represents the sections of a SPIRV module. See section 2.4 +/// of the SPIRV spec for additional details of the order. The enumerant values +/// are in the same order as the vector returned by GetModuleOrder +enum ModuleLayoutSection { + kLayoutCapabilities, /// < Section 2.4 #1 + kLayoutExtensions, /// < Section 2.4 #2 + kLayoutExtInstImport, /// < Section 2.4 #3 + kLayoutMemoryModel, /// < Section 2.4 #4 + kLayoutSamplerImageAddressMode, /// < Section 2.4 #5 + kLayoutEntryPoint, /// < Section 2.4 #6 + kLayoutExecutionMode, /// < Section 2.4 #7 + kLayoutDebug1, /// < Section 2.4 #8 > 1 + kLayoutDebug2, /// < Section 2.4 #8 > 2 + kLayoutDebug3, /// < Section 2.4 #8 > 3 + kLayoutAnnotations, /// < Section 2.4 #9 + kLayoutTypes, /// < Section 2.4 #10 + kLayoutFunctionDeclarations, /// < Section 2.4 #11 + kLayoutFunctionDefinitions /// < Section 2.4 #12 +}; + +/// This class manages the state of the SPIR-V validation as it is being parsed. +class ValidationState_t { + public: + // Features that can optionally be turned on by a capability or environment. + struct Feature { + bool declare_int16_type = false; // Allow OpTypeInt with 16 bit width? + bool declare_float16_type = false; // Allow OpTypeFloat with 16 bit width? + bool free_fp_rounding_mode = false; // Allow the FPRoundingMode decoration + // and its values to be used without + // requiring any capability + + // Allow functionalities enabled by VariablePointers or + // VariablePointersStorageBuffer capability. + bool variable_pointers = false; + + // Permit group oerations Reduce, InclusiveScan, ExclusiveScan + bool group_ops_reduce_and_scans = false; + + // Allow OpTypeInt with 8 bit width? + bool declare_int8_type = false; + + // Target environment uses relaxed block layout. + // This is true for Vulkan 1.1 or later. + bool env_relaxed_block_layout = false; + + // Allow an OpTypeInt with 8 bit width to be used in more than just int + // conversion opcodes + bool use_int8_type = false; + + // SPIR-V 1.4 allows us to select between any two composite values + // of the same type. + bool select_between_composites = false; + + // SPIR-V 1.4 allows two memory access operands for OpCopyMemory and + // OpCopyMemorySized. + bool copy_memory_permits_two_memory_accesses = false; + + // SPIR-V 1.4 allows UConvert as a spec constant op in any environment. + // The Kernel capability already enables it, separately from this flag. + bool uconvert_spec_constant_op = false; + + // SPIR-V 1.4 allows Function and Private variables to be NonWritable + bool nonwritable_var_in_function_or_private = false; + + // Whether LocalSizeId execution mode is allowed by the environment. + bool env_allow_localsizeid = false; + }; + + ValidationState_t(const spv_const_context context, + const spv_const_validator_options opt, + const uint32_t* words, const size_t num_words, + const uint32_t max_warnings); + + /// Returns the context + spv_const_context context() const { return context_; } + + /// Returns the command line options + spv_const_validator_options options() const { return options_; } + + /// Sets the ID of the generator for this module. + void setGenerator(uint32_t gen) { generator_ = gen; } + + /// Returns the ID of the generator for this module. + uint32_t generator() const { return generator_; } + + /// Sets the SPIR-V version of this module. + void setVersion(uint32_t ver) { version_ = ver; } + + /// Gets the SPIR-V version of this module. + uint32_t version() const { return version_; } + + /// Forward declares the id in the module + spv_result_t ForwardDeclareId(uint32_t id); + + /// Removes a forward declared ID if it has been defined + spv_result_t RemoveIfForwardDeclared(uint32_t id); + + /// Registers an ID as a forward pointer + spv_result_t RegisterForwardPointer(uint32_t id); + + /// Returns whether or not an ID is a forward pointer + bool IsForwardPointer(uint32_t id) const; + + /// Assigns a name to an ID + void AssignNameToId(uint32_t id, std::string name); + + /// Returns a string representation of the ID in the format [Name] where + /// the is the numeric valid of the id and the Name is a name assigned by + /// the OpName instruction + std::string getIdName(uint32_t id) const; + + /// Accessor function for ID bound. + uint32_t getIdBound() const; + + /// Mutator function for ID bound. + void setIdBound(uint32_t bound); + + /// Returns the number of ID which have been forward referenced but not + /// defined + size_t unresolved_forward_id_count() const; + + /// Returns a vector of unresolved forward ids. + std::vector UnresolvedForwardIds() const; + + /// Returns true if the id has been defined + bool IsDefinedId(uint32_t id) const; + + /// Increments the total number of instructions in the file. + void increment_total_instructions() { total_instructions_++; } + + /// Increments the total number of functions in the file. + void increment_total_functions() { total_functions_++; } + + /// Allocates internal storage. Note, calling this will invalidate any + /// pointers to |ordered_instructions_| or |module_functions_| and, hence, + /// should only be called at the beginning of validation. + void preallocateStorage(); + + /// Returns the current layout section which is being processed + ModuleLayoutSection current_layout_section() const; + + /// Increments the module_layout_order_section_ + void ProgressToNextLayoutSectionOrder(); + + /// Determines if the op instruction is in a previous layout section + bool IsOpcodeInPreviousLayoutSection(spv::Op op); + + /// Determines if the op instruction is part of the current section + bool IsOpcodeInCurrentLayoutSection(spv::Op op); + + DiagnosticStream diag(spv_result_t error_code, const Instruction* inst); + + /// Returns the function states + std::vector& functions(); + + /// Returns the function states + Function& current_function(); + const Function& current_function() const; + + /// Returns function state with the given id, or nullptr if no such function. + const Function* function(uint32_t id) const; + Function* function(uint32_t id); + + /// Returns true if the called after a function instruction but before the + /// function end instruction + bool in_function_body() const; + + /// Returns true if called after a label instruction but before a branch + /// instruction + bool in_block() const; + + struct EntryPointDescription { + std::string name; + std::vector interfaces; + }; + + /// Registers |id| as an entry point with |execution_model| and |interfaces|. + void RegisterEntryPoint(const uint32_t id, + spv::ExecutionModel execution_model, + EntryPointDescription&& desc) { + entry_points_.push_back(id); + entry_point_to_execution_models_[id].insert(execution_model); + entry_point_descriptions_[id].emplace_back(desc); + } + + /// Returns a list of entry point function ids + const std::vector& entry_points() const { return entry_points_; } + + /// Returns the set of entry points that root call graphs that contain + /// recursion. + const std::set& recursive_entry_points() const { + return recursive_entry_points_; + } + + /// Registers execution mode for the given entry point. + void RegisterExecutionModeForEntryPoint(uint32_t entry_point, + spv::ExecutionMode execution_mode) { + entry_point_to_execution_modes_[entry_point].insert(execution_mode); + } + + /// Returns the interface descriptions of a given entry point. + const std::vector& entry_point_descriptions( + uint32_t entry_point) { + return entry_point_descriptions_.at(entry_point); + } + + /// Returns Execution Models for the given Entry Point. + /// Returns nullptr if none found (would trigger assertion). + const std::set* GetExecutionModels( + uint32_t entry_point) const { + const auto it = entry_point_to_execution_models_.find(entry_point); + if (it == entry_point_to_execution_models_.end()) { + assert(0); + return nullptr; + } + return &it->second; + } + + /// Returns Execution Modes for the given Entry Point. + /// Returns nullptr if none found. + const std::set* GetExecutionModes( + uint32_t entry_point) const { + const auto it = entry_point_to_execution_modes_.find(entry_point); + if (it == entry_point_to_execution_modes_.end()) { + return nullptr; + } + return &it->second; + } + + /// Traverses call tree and computes function_to_entry_points_. + /// Note: called after fully parsing the binary. + void ComputeFunctionToEntryPointMapping(); + + /// Traverse call tree and computes recursive_entry_points_. + /// Note: called after fully parsing the binary and calling + /// ComputeFunctionToEntryPointMapping. + void ComputeRecursiveEntryPoints(); + + /// Returns all the entry points that can call |func|. + const std::vector& FunctionEntryPoints(uint32_t func) const; + + /// Returns all the entry points that statically use |id|. + /// + /// Note: requires ComputeFunctionToEntryPointMapping to have been called. + std::set EntryPointReferences(uint32_t id) const; + + /// Inserts an to the set of functions that are target of OpFunctionCall. + void AddFunctionCallTarget(const uint32_t id) { + function_call_targets_.insert(id); + current_function().AddFunctionCallTarget(id); + } + + /// Returns whether or not a function is the target of OpFunctionCall. + bool IsFunctionCallTarget(const uint32_t id) { + return (function_call_targets_.find(id) != function_call_targets_.end()); + } + + bool IsFunctionCallDefined(const uint32_t id) { + return (id_to_function_.find(id) != id_to_function_.end()); + } + /// Registers the capability and its dependent capabilities + void RegisterCapability(spv::Capability cap); + + /// Registers the extension. + void RegisterExtension(Extension ext); + + /// Registers the function in the module. Subsequent instructions will be + /// called against this function + spv_result_t RegisterFunction(uint32_t id, uint32_t ret_type_id, + spv::FunctionControlMask function_control, + uint32_t function_type_id); + + /// Register a function end instruction + spv_result_t RegisterFunctionEnd(); + + /// Returns true if the capability is enabled in the module. + bool HasCapability(spv::Capability cap) const { + return module_capabilities_.contains(cap); + } + + /// Returns a reference to the set of capabilities in the module. + /// This is provided for debuggability. + const CapabilitySet& module_capabilities() const { + return module_capabilities_; + } + + /// Returns true if the extension is enabled in the module. + bool HasExtension(Extension ext) const { + return module_extensions_.contains(ext); + } + + /// Returns true if any of the capabilities is enabled, or if |capabilities| + /// is an empty set. + bool HasAnyOfCapabilities(const CapabilitySet& capabilities) const; + + /// Returns true if any of the extensions is enabled, or if |extensions| + /// is an empty set. + bool HasAnyOfExtensions(const ExtensionSet& extensions) const; + + /// Sets the addressing model of this module (logical/physical). + void set_addressing_model(spv::AddressingModel am); + + /// Returns true if the OpMemoryModel was found. + bool has_memory_model_specified() const { + return addressing_model_ != spv::AddressingModel::Max && + memory_model_ != spv::MemoryModel::Max; + } + + /// Returns the addressing model of this module, or Logical if uninitialized. + spv::AddressingModel addressing_model() const; + + /// Returns the addressing model of this module, or Logical if uninitialized. + uint32_t pointer_size_and_alignment() const { + return pointer_size_and_alignment_; + } + + /// Sets the memory model of this module. + void set_memory_model(spv::MemoryModel mm); + + /// Returns the memory model of this module, or Simple if uninitialized. + spv::MemoryModel memory_model() const; + + /// Sets the bit width for sampler/image type variables. If not set, they are + /// considered opaque + void set_samplerimage_variable_address_mode(uint32_t bit_width); + + /// Get the addressing mode currently set. If 0, it means addressing mode is + /// invalid Sampler/Image type variables must be considered opaque This mode + /// is only valid after the instruction has been read + uint32_t samplerimage_variable_address_mode() const; + + /// Returns true if the OpSamplerImageAddressingModeNV was found. + bool has_samplerimage_variable_address_mode_specified() const { + return sampler_image_addressing_mode_ != 0; + } + + const AssemblyGrammar& grammar() const { return grammar_; } + + /// Inserts the instruction into the list of ordered instructions in the file. + Instruction* AddOrderedInstruction(const spv_parsed_instruction_t* inst); + + /// Registers the instruction. This will add the instruction to the list of + /// definitions and register sampled image consumers. + void RegisterInstruction(Instruction* inst); + + /// Registers the debug instruction information. + void RegisterDebugInstruction(const Instruction* inst); + + /// Registers the decoration for the given + void RegisterDecorationForId(uint32_t id, const Decoration& dec) { + auto& dec_list = id_decorations_[id]; + dec_list.insert(dec); + } + + /// Registers the list of decorations for the given + template + void RegisterDecorationsForId(uint32_t id, InputIt begin, InputIt end) { + std::set& cur_decs = id_decorations_[id]; + cur_decs.insert(begin, end); + } + + /// Registers the list of decorations for the given member of the given + /// structure. + template + void RegisterDecorationsForStructMember(uint32_t struct_id, + uint32_t member_index, InputIt begin, + InputIt end) { + std::set& cur_decs = id_decorations_[struct_id]; + for (InputIt iter = begin; iter != end; ++iter) { + Decoration dec = *iter; + dec.set_struct_member_index(member_index); + cur_decs.insert(dec); + } + } + + /// Returns all the decorations for the given . If no decorations exist + /// for the , it registers an empty set for it in the map and + /// returns the empty set. + std::set& id_decorations(uint32_t id) { + return id_decorations_[id]; + } + + /// Returns the range of decorations for the given field of the given . + struct FieldDecorationsIter { + std::set::const_iterator begin; + std::set::const_iterator end; + }; + FieldDecorationsIter id_member_decorations(uint32_t id, + uint32_t member_index) { + const auto& decorations = id_decorations_[id]; + + // The decorations are sorted by member_index, so this look up will give the + // exact range of decorations for this member index. + Decoration min_decoration((spv::Decoration)0, {}, member_index); + Decoration max_decoration(spv::Decoration::Max, {}, member_index); + + FieldDecorationsIter result; + result.begin = decorations.lower_bound(min_decoration); + result.end = decorations.upper_bound(max_decoration); + + return result; + } + + // Returns const pointer to the internal decoration container. + const std::map>& id_decorations() const { + return id_decorations_; + } + + /// Returns true if the given id has the given decoration , + /// otherwise returns false. + bool HasDecoration(uint32_t id, spv::Decoration dec) { + const auto& decorations = id_decorations_.find(id); + if (decorations == id_decorations_.end()) return false; + + return std::any_of( + decorations->second.begin(), decorations->second.end(), + [dec](const Decoration& d) { return dec == d.dec_type(); }); + } + + /// Finds id's def, if it exists. If found, returns the definition otherwise + /// nullptr + const Instruction* FindDef(uint32_t id) const; + + /// Finds id's def, if it exists. If found, returns the definition otherwise + /// nullptr + Instruction* FindDef(uint32_t id); + + /// Returns the instructions in the order they appear in the binary + const std::vector& ordered_instructions() const { + return ordered_instructions_; + } + + /// Returns a map of instructions mapped by their result id + const std::unordered_map& all_definitions() const { + return all_definitions_; + } + + /// Returns a vector containing the instructions that consume the given + /// SampledImage id. + std::vector getSampledImageConsumers(uint32_t id) const; + + /// Records cons_id as a consumer of sampled_image_id. + void RegisterSampledImageConsumer(uint32_t sampled_image_id, + Instruction* consumer); + + // Record a cons_id as a consumer of texture_id + // if texture 'texture_id' has a QCOM image processing decoration + // and consumer is a load or a sampled image instruction + void RegisterQCOMImageProcessingTextureConsumer(uint32_t texture_id, + const Instruction* consumer0, + const Instruction* consumer1); + + // Record a function's storage class consumer instruction + void RegisterStorageClassConsumer(spv::StorageClass storage_class, + Instruction* consumer); + + /// Returns the set of Global Variables. + std::unordered_set& global_vars() { return global_vars_; } + + /// Returns the set of Local Variables. + std::unordered_set& local_vars() { return local_vars_; } + + /// Returns the number of Global Variables. + size_t num_global_vars() { return global_vars_.size(); } + + /// Returns the number of Local Variables. + size_t num_local_vars() { return local_vars_.size(); } + + /// Inserts a new to the set of Global Variables. + void registerGlobalVariable(const uint32_t id) { global_vars_.insert(id); } + + /// Inserts a new to the set of Local Variables. + void registerLocalVariable(const uint32_t id) { local_vars_.insert(id); } + + // Returns true if using relaxed block layout, equivalent to + // VK_KHR_relaxed_block_layout. + bool IsRelaxedBlockLayout() const { + return features_.env_relaxed_block_layout || options()->relax_block_layout; + } + + // Returns true if allowing localsizeid, either because the environment always + // allows it, or because it is enabled from the command-line. + bool IsLocalSizeIdAllowed() const { + return features_.env_allow_localsizeid || options()->allow_localsizeid; + } + + /// Sets the struct nesting depth for a given struct ID + void set_struct_nesting_depth(uint32_t id, uint32_t depth) { + struct_nesting_depth_[id] = depth; + } + + /// Returns the nesting depth of a given structure ID + uint32_t struct_nesting_depth(uint32_t id) { + return struct_nesting_depth_[id]; + } + + /// Records the has a nested block/bufferblock decorated struct for a given + /// struct ID + void SetHasNestedBlockOrBufferBlockStruct(uint32_t id, bool has) { + struct_has_nested_blockorbufferblock_struct_[id] = has; + } + + /// For a given struct ID returns true if it has a nested block/bufferblock + /// decorated struct + bool GetHasNestedBlockOrBufferBlockStruct(uint32_t id) { + return struct_has_nested_blockorbufferblock_struct_[id]; + } + + /// Records that the structure type has a member decorated with a built-in. + void RegisterStructTypeWithBuiltInMember(uint32_t id) { + builtin_structs_.insert(id); + } + + /// Returns true if the struct type with the given Id has a BuiltIn member. + bool IsStructTypeWithBuiltInMember(uint32_t id) const { + return (builtin_structs_.find(id) != builtin_structs_.end()); + } + + // Returns the state of optional features. + const Feature& features() const { return features_; } + + /// Adds the instruction data to unique_type_declarations_. + /// Returns false if an identical type declaration already exists. + bool RegisterUniqueTypeDeclaration(const Instruction* inst); + + // Returns type_id of the scalar component of |id|. + // |id| can be either + // - scalar, vector or matrix type + // - object of either scalar, vector or matrix type + uint32_t GetComponentType(uint32_t id) const; + + // Returns + // - 1 for scalar types or objects + // - vector size for vector types or objects + // - num columns for matrix types or objects + // Should not be called with any other arguments (will return zero and invoke + // assertion). + uint32_t GetDimension(uint32_t id) const; + + // Returns bit width of scalar or component. + // |id| can be + // - scalar, vector or matrix type + // - object of either scalar, vector or matrix type + // Will invoke assertion and return 0 if |id| is none of the above. + uint32_t GetBitWidth(uint32_t id) const; + + // Provides detailed information on matrix type. + // Returns false iff |id| is not matrix type. + bool GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows, uint32_t* num_cols, + uint32_t* column_type, uint32_t* component_type) const; + + // Collects struct member types into |member_types|. + // Returns false iff not struct type or has no members. + // Deletes prior contents of |member_types|. + bool GetStructMemberTypes(uint32_t struct_type_id, + std::vector* member_types) const; + + // Returns true iff |id| is a type corresponding to the name of the function. + // Only works for types not for objects. + bool IsVoidType(uint32_t id) const; + bool IsFloatScalarType(uint32_t id) const; + bool IsFloatVectorType(uint32_t id) const; + bool IsFloat16Vector2Or4Type(uint32_t id) const; + bool IsFloatScalarOrVectorType(uint32_t id) const; + bool IsFloatMatrixType(uint32_t id) const; + bool IsIntScalarType(uint32_t id) const; + bool IsIntVectorType(uint32_t id) const; + bool IsIntScalarOrVectorType(uint32_t id) const; + bool IsUnsignedIntScalarType(uint32_t id) const; + bool IsUnsignedIntVectorType(uint32_t id) const; + bool IsUnsignedIntScalarOrVectorType(uint32_t id) const; + bool IsSignedIntScalarType(uint32_t id) const; + bool IsSignedIntVectorType(uint32_t id) const; + bool IsBoolScalarType(uint32_t id) const; + bool IsBoolVectorType(uint32_t id) const; + bool IsBoolScalarOrVectorType(uint32_t id) const; + bool IsPointerType(uint32_t id) const; + bool IsAccelerationStructureType(uint32_t id) const; + bool IsCooperativeMatrixType(uint32_t id) const; + bool IsCooperativeMatrixNVType(uint32_t id) const; + bool IsCooperativeMatrixKHRType(uint32_t id) const; + bool IsCooperativeMatrixAType(uint32_t id) const; + bool IsCooperativeMatrixBType(uint32_t id) const; + bool IsCooperativeMatrixAccType(uint32_t id) const; + bool IsFloatCooperativeMatrixType(uint32_t id) const; + bool IsIntCooperativeMatrixType(uint32_t id) const; + bool IsUnsignedIntCooperativeMatrixType(uint32_t id) const; + bool IsUnsigned64BitHandle(uint32_t id) const; + + // Returns true if |id| is a type id that contains |type| (or integer or + // floating point type) of |width| bits. + bool ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, + uint32_t width) const; + // Returns true if |id| is a type id that contains a 8- or 16-bit int or + // 16-bit float that is not generally enabled for use. + bool ContainsLimitedUseIntOrFloatType(uint32_t id) const; + + // Returns true if |id| is a type that contains a runtime-sized array. + // Does not consider a pointers as contains the array. + bool ContainsRuntimeArray(uint32_t id) const; + + // Generic type traversal. + // Only traverse pointers and functions if |traverse_all_types| is true. + // Recursively tests |f| against the type hierarchy headed by |id|. + bool ContainsType(uint32_t id, + const std::function& f, + bool traverse_all_types = true) const; + + // Returns type_id if id has type or zero otherwise. + uint32_t GetTypeId(uint32_t id) const; + + // Returns opcode of the instruction which issued the id or OpNop if the + // instruction is not registered. + spv::Op GetIdOpcode(uint32_t id) const; + + // Returns type_id for given id operand if it has a type or zero otherwise. + // |operand_index| is expected to be pointing towards an operand which is an + // id. + uint32_t GetOperandTypeId(const Instruction* inst, + size_t operand_index) const; + + // Provides information on pointer type. Returns false iff not pointer type. + bool GetPointerTypeInfo(uint32_t id, uint32_t* data_type, + spv::StorageClass* storage_class) const; + + // Is the ID the type of a pointer to a uniform block: Block-decorated struct + // in uniform storage class? The result is only valid after internal method + // CheckDecorationsOfBuffers has been called. + bool IsPointerToUniformBlock(uint32_t type_id) const { + return pointer_to_uniform_block_.find(type_id) != + pointer_to_uniform_block_.cend(); + } + // Save the ID of a pointer to uniform block. + void RegisterPointerToUniformBlock(uint32_t type_id) { + pointer_to_uniform_block_.insert(type_id); + } + // Is the ID the type of a struct used as a uniform block? + // The result is only valid after internal method CheckDecorationsOfBuffers + // has been called. + bool IsStructForUniformBlock(uint32_t type_id) const { + return struct_for_uniform_block_.find(type_id) != + struct_for_uniform_block_.cend(); + } + // Save the ID of a struct of a uniform block. + void RegisterStructForUniformBlock(uint32_t type_id) { + struct_for_uniform_block_.insert(type_id); + } + // Is the ID the type of a pointer to a storage buffer: BufferBlock-decorated + // struct in uniform storage class, or Block-decorated struct in StorageBuffer + // storage class? The result is only valid after internal method + // CheckDecorationsOfBuffers has been called. + bool IsPointerToStorageBuffer(uint32_t type_id) const { + return pointer_to_storage_buffer_.find(type_id) != + pointer_to_storage_buffer_.cend(); + } + // Save the ID of a pointer to a storage buffer. + void RegisterPointerToStorageBuffer(uint32_t type_id) { + pointer_to_storage_buffer_.insert(type_id); + } + // Is the ID the type of a struct for storage buffer? + // The result is only valid after internal method CheckDecorationsOfBuffers + // has been called. + bool IsStructForStorageBuffer(uint32_t type_id) const { + return struct_for_storage_buffer_.find(type_id) != + struct_for_storage_buffer_.cend(); + } + // Save the ID of a struct of a storage buffer. + void RegisterStructForStorageBuffer(uint32_t type_id) { + struct_for_storage_buffer_.insert(type_id); + } + + // Is the ID the type of a pointer to a storage image? That is, the pointee + // type is an image type which is known to not use a sampler. + bool IsPointerToStorageImage(uint32_t type_id) const { + return pointer_to_storage_image_.find(type_id) != + pointer_to_storage_image_.cend(); + } + // Save the ID of a pointer to a storage image. + void RegisterPointerToStorageImage(uint32_t type_id) { + pointer_to_storage_image_.insert(type_id); + } + + // Tries to evaluate a any scalar integer OpConstant as uint64. + // OpConstantNull is defined as zero for scalar int (will return true) + // OpSpecConstant* return false since their values cannot be relied upon + // during validation. + bool EvalConstantValUint64(uint32_t id, uint64_t* val) const; + // Same as EvalConstantValUint64 but returns a signed int + bool EvalConstantValInt64(uint32_t id, int64_t* val) const; + + // Tries to evaluate a 32-bit signed or unsigned scalar integer constant. + // Returns tuple . + // OpSpecConstant* return |is_const_int32| as false since their values cannot + // be relied upon during validation. + std::tuple EvalInt32IfConst(uint32_t id) const; + + // Returns the disassembly string for the given instruction. + std::string Disassemble(const Instruction& inst) const; + + // Returns the disassembly string for the given instruction. + std::string Disassemble(const uint32_t* words, uint16_t num_words) const; + + // Returns the string name for |decoration|. + std::string SpvDecorationString(uint32_t decoration) { + spv_operand_desc desc = nullptr; + if (grammar_.lookupOperand(SPV_OPERAND_TYPE_DECORATION, decoration, + &desc) != SPV_SUCCESS) { + return std::string("Unknown"); + } + return std::string(desc->name); + } + std::string SpvDecorationString(spv::Decoration decoration) { + return SpvDecorationString(uint32_t(decoration)); + } + + // Returns whether type m1 and type m2 are cooperative matrices with + // the same "shape" (matching scope, rows, cols). If any are specialization + // constants, we assume they can match because we can't prove they don't. + spv_result_t CooperativeMatrixShapesMatch(const Instruction* inst, + uint32_t m1, uint32_t m2); + + // Returns true if |lhs| and |rhs| logically match and, if the decorations of + // |rhs| are a subset of |lhs|. + // + // 1. Must both be either OpTypeArray or OpTypeStruct + // 2. If OpTypeArray, then + // * Length must be the same + // * Element type must match or logically match + // 3. If OpTypeStruct, then + // * Both have same number of elements + // * Element N for both structs must match or logically match + // + // If |check_decorations| is false, then the decorations are not checked. + bool LogicallyMatch(const Instruction* lhs, const Instruction* rhs, + bool check_decorations); + + // Traces |inst| to find a single base pointer. Returns the base pointer. + // Will trace through the following instructions: + // * OpAccessChain + // * OpInBoundsAccessChain + // * OpPtrAccessChain + // * OpInBoundsPtrAccessChain + // * OpCopyObject + const Instruction* TracePointer(const Instruction* inst) const; + + // Validates the storage class for the target environment. + bool IsValidStorageClass(spv::StorageClass storage_class) const; + + // Takes a Vulkan Valid Usage ID (VUID) as |id| and optional |reference| and + // will return a non-empty string only if ID is known and targeting Vulkan. + // VUIDs are found in the Vulkan-Docs repo in the form "[[VUID-ref-ref-id]]" + // where "id" is always an 5 char long number (with zeros padding) and matches + // to |id|. |reference| is used if there is a "common validity" and the VUID + // shares the same |id| value. + // + // More details about Vulkan validation can be found in Vulkan Guide: + // https://github.com/KhronosGroup/Vulkan-Guide/blob/master/chapters/validation_overview.md + std::string VkErrorID(uint32_t id, const char* reference = nullptr) const; + + // Testing method to allow setting the current layout section. + void SetCurrentLayoutSectionForTesting(ModuleLayoutSection section) { + current_layout_section_ = section; + } + + // Check if instruction 'id' is a consumer of a texture decorated + // with a QCOM image processing decoration + bool IsQCOMImageProcessingTextureConsumer(uint32_t id) { + return qcom_image_processing_consumers_.find(id) != + qcom_image_processing_consumers_.end(); + } + + private: + ValidationState_t(const ValidationState_t&); + + const spv_const_context context_; + + /// Stores the Validator command line options. Must be a valid options object. + const spv_const_validator_options options_; + + /// The SPIR-V binary module we're validating. + const uint32_t* words_; + const size_t num_words_; + + /// The generator of the SPIR-V. + uint32_t generator_ = 0; + + /// The version of the SPIR-V. + uint32_t version_ = 0; + + /// The total number of instructions in the binary. + size_t total_instructions_ = 0; + /// The total number of functions in the binary. + size_t total_functions_ = 0; + + /// IDs which have been forward declared but have not been defined + std::unordered_set unresolved_forward_ids_; + + /// IDs that have been declared as forward pointers. + std::unordered_set forward_pointer_ids_; + + /// Stores a vector of instructions that use the result of a given + /// OpSampledImage instruction. + std::unordered_map> + sampled_image_consumers_; + + /// Stores load instructions that load textures used + // in QCOM image processing functions + std::unordered_set qcom_image_processing_consumers_; + + /// A map of operand IDs and their names defined by the OpName instruction + std::unordered_map operand_names_; + + /// The section of the code being processed + ModuleLayoutSection current_layout_section_; + + /// A list of functions in the module. + /// Pointers to objects in this container are guaranteed to be stable and + /// valid until the end of lifetime of the validation state. + std::vector module_functions_; + + /// Capabilities declared in the module + CapabilitySet module_capabilities_; + + /// Extensions declared in the module + ExtensionSet module_extensions_; + + /// List of all instructions in the order they appear in the binary + std::vector ordered_instructions_; + + /// Instructions that can be referenced by Ids + std::unordered_map all_definitions_; + + /// IDs that are entry points, ie, arguments to OpEntryPoint. + std::vector entry_points_; + + /// Maps an entry point id to its descriptions. + std::unordered_map> + entry_point_descriptions_; + + /// IDs that are entry points, ie, arguments to OpEntryPoint, and root a call + /// graph that recurses. + std::set recursive_entry_points_; + + /// Functions IDs that are target of OpFunctionCall. + std::unordered_set function_call_targets_; + + /// ID Bound from the Header + uint32_t id_bound_; + + /// Set of Global Variable IDs (Storage Class other than 'Function') + std::unordered_set global_vars_; + + /// Set of Local Variable IDs ('Function' Storage Class) + std::unordered_set local_vars_; + + /// Set of struct types that have members with a BuiltIn decoration. + std::unordered_set builtin_structs_; + + /// Structure Nesting Depth + std::unordered_map struct_nesting_depth_; + + /// Structure has nested blockorbufferblock struct + std::unordered_map + struct_has_nested_blockorbufferblock_struct_; + + /// Stores the list of decorations for a given + std::map> id_decorations_; + + /// Stores type declarations which need to be unique (i.e. non-aggregates), + /// in the form [opcode, operand words], result_id is not stored. + /// Using ordered set to avoid the need for a vector hash function. + /// The size of this container is expected not to exceed double-digits. + std::set> unique_type_declarations_; + + AssemblyGrammar grammar_; + + spv::AddressingModel addressing_model_; + spv::MemoryModel memory_model_; + // pointer size derived from addressing model. Assumes all storage classes + // have the same pointer size (for physical pointer types). + uint32_t pointer_size_and_alignment_; + + /// bit width of sampler/image type variables. Valid values are 32 and 64 + uint32_t sampler_image_addressing_mode_; + + /// NOTE: See correspoding getter functions + bool in_function_; + + /// The state of optional features. These are determined by capabilities + /// declared by the module and the environment. + Feature features_; + + /// Maps function ids to function stat objects. + std::unordered_map id_to_function_; + + /// Mapping entry point -> execution models. It is presumed that the same + /// function could theoretically be used as 'main' by multiple OpEntryPoint + /// instructions. + std::unordered_map> + entry_point_to_execution_models_; + + /// Mapping entry point -> execution modes. + std::unordered_map> + entry_point_to_execution_modes_; + + /// Mapping function -> array of entry points inside this + /// module which can (indirectly) call the function. + std::unordered_map> function_to_entry_points_; + const std::vector empty_ids_; + + // The IDs of types of pointers to Block-decorated structs in Uniform storage + // class. This is populated at the start of ValidateDecorations. + std::unordered_set pointer_to_uniform_block_; + // The IDs of struct types for uniform blocks. + // This is populated at the start of ValidateDecorations. + std::unordered_set struct_for_uniform_block_; + // The IDs of types of pointers to BufferBlock-decorated structs in Uniform + // storage class, or Block-decorated structs in StorageBuffer storage class. + // This is populated at the start of ValidateDecorations. + std::unordered_set pointer_to_storage_buffer_; + // The IDs of struct types for storage buffers. + // This is populated at the start of ValidateDecorations. + std::unordered_set struct_for_storage_buffer_; + // The IDs of types of pointers to storage images. This is populated in the + // TypePass. + std::unordered_set pointer_to_storage_image_; + + /// Maps ids to friendly names. + std::unique_ptr friendly_mapper_; + spvtools::NameMapper name_mapper_; + + /// Variables used to reduce the number of diagnostic messages. + uint32_t num_of_warnings_; + uint32_t max_num_of_warnings_; +}; + +} // namespace val +} // namespace spvtools + +#endif // SOURCE_VAL_VALIDATION_STATE_H_ diff --git a/thirdparty/glslang/External/spirv-tools/utils/check_code_format.sh b/thirdparty/glslang/External/spirv-tools/utils/check_code_format.sh new file mode 100644 index 000000000000..da5e019859d7 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/check_code_format.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (c) 2017 Google Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Script to determine if source code in Pull Request is properly formatted. +# Exits with non 0 exit code if formatting is needed. +# +# This script assumes to be invoked at the project root directory. + +BASE_BRANCH=${1:-main} + +FILES_TO_CHECK=$(git diff --name-only ${BASE_BRANCH} | grep -E ".*\.(cpp|cc|c\+\+|cxx|c|h|hpp)$") + +if [ -z "${FILES_TO_CHECK}" ]; then + echo "No source code to check for formatting." + exit 0 +fi + +FORMAT_DIFF=$(git diff -U0 ${BASE_BRANCH} -- ${FILES_TO_CHECK} | python ./utils/clang-format-diff.py -p1 -style=file) + +if [ -z "${FORMAT_DIFF}" ]; then + echo "All source code in PR properly formatted." + exit 0 +else + echo "Found formatting errors!" + echo "${FORMAT_DIFF}" + exit 1 +fi diff --git a/thirdparty/glslang/External/spirv-tools/utils/check_copyright.py b/thirdparty/glslang/External/spirv-tools/utils/check_copyright.py new file mode 100644 index 000000000000..a849d04672fa --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/check_copyright.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python3 +# coding=utf-8 +# Copyright (c) 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Checks for copyright notices in all the files that need them under the + +current directory. Optionally insert them. When inserting, replaces +an MIT or Khronos free use license with Apache 2. +""" + +import argparse +import fileinput +import fnmatch +import inspect +import os +import re +import sys + +# List of designated copyright owners. +AUTHORS = ['The Khronos Group Inc.', + 'LunarG Inc.', + 'Google Inc.', + 'Google LLC', + 'Pierre Moreau', + 'Samsung Inc', + 'André Perez Maselco', + 'Vasyl Teliman', + 'Advanced Micro Devices, Inc.', + 'Stefano Milizia', + 'Alastair F. Donaldson', + 'Mostafa Ashraf', + 'Shiyu Liu', + 'ZHOU He', + 'Nintendo'] +CURRENT_YEAR = 2023 + +FIRST_YEAR = 2014 +FINAL_YEAR = CURRENT_YEAR + 5 +# A regular expression to match the valid years in the copyright information. +YEAR_REGEX = '(' + '|'.join( + str(year) for year in range(FIRST_YEAR, FINAL_YEAR + 1)) + ')' + +# A regular expression to make a range of years in the form -. +YEAR_RANGE_REGEX = '(' +for year1 in range(FIRST_YEAR, FINAL_YEAR + 1): + for year2 in range(year1 + 1, FINAL_YEAR + 1): + YEAR_RANGE_REGEX += str(year1) + '-' + str(year2) + '|' +YEAR_RANGE_REGEX = YEAR_RANGE_REGEX[:-1] + ')' + +# In the copyright info, the year can be a single year or a range. This is a +# regex to make sure it matches one of them. +YEAR_OR_RANGE_REGEX = '(' + YEAR_REGEX + '|' + YEAR_RANGE_REGEX + ')' + +# The final regular expression to match a valid copyright line. +COPYRIGHT_RE = re.compile('Copyright \(c\) {} ({})'.format( + YEAR_OR_RANGE_REGEX, '|'.join(AUTHORS))) + +MIT_BEGIN_RE = re.compile('Permission is hereby granted, ' + 'free of charge, to any person obtaining a') +MIT_END_RE = re.compile('MATERIALS OR THE USE OR OTHER DEALINGS IN ' + 'THE MATERIALS.') +APACHE2_BEGIN_RE = re.compile('Licensed under the Apache License, ' + 'Version 2.0 \(the "License"\);') +APACHE2_END_RE = re.compile('limitations under the License.') + +LICENSED = """Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.""" +LICENSED_LEN = 10 # Number of lines in LICENSED + + +def find(top, filename_glob, skip_glob_dir_list, skip_glob_files_list): + """Returns files in the tree rooted at top matching filename_glob but not + in directories matching skip_glob_dir_list nor files matching + skip_glob_dir_list.""" + + file_list = [] + for path, dirs, files in os.walk(top): + for glob in skip_glob_dir_list: + for match in fnmatch.filter(dirs, glob): + dirs.remove(match) + for filename in fnmatch.filter(files, filename_glob): + full_file = os.path.join(path, filename) + if full_file not in skip_glob_files_list: + file_list.append(full_file) + return file_list + + +def filtered_descendants(glob): + """Returns glob-matching filenames under the current directory, but skips + some irrelevant paths.""" + return find('.', glob, ['third_party', 'external', 'CompilerIdCXX', + 'build*', 'out*'], ['./utils/clang-format-diff.py']) + + +def skip(line): + """Returns true if line is all whitespace or shebang.""" + stripped = line.lstrip() + return stripped == '' or stripped.startswith('#!') + + +def comment(text, prefix): + """Returns commented-out text. + + Each line of text will be prefixed by prefix and a space character. Any + trailing whitespace will be trimmed. + """ + accum = ['{} {}'.format(prefix, line).rstrip() for line in text.split('\n')] + return '\n'.join(accum) + + +def insert_copyright(author, glob, comment_prefix): + """Finds all glob-matching files under the current directory and inserts the + copyright message, and license notice. An MIT license or Khronos free + use license (modified MIT) is replaced with an Apache 2 license. + + The copyright message goes into the first non-whitespace, non-shebang line + in a file. The license notice follows it. Both are prefixed on each line + by comment_prefix and a space. + """ + + copyright = comment('Copyright (c) {} {}'.format(CURRENT_YEAR, author), + comment_prefix) + '\n\n' + licensed = comment(LICENSED, comment_prefix) + '\n\n' + for file in filtered_descendants(glob): + # Parsing states are: + # 0 Initial: Have not seen a copyright declaration. + # 1 Seen a copyright line and no other interesting lines + # 2 In the middle of an MIT or Khronos free use license + # 9 Exited any of the above + state = 0 + update_file = False + for line in fileinput.input(file, inplace=1): + emit = True + if state == 0: + if COPYRIGHT_RE.search(line): + state = 1 + elif skip(line): + pass + else: + # Didn't see a copyright. Inject copyright and license. + sys.stdout.write(copyright) + sys.stdout.write(licensed) + # Assume there isn't a previous license notice. + state = 1 + elif state == 1: + if MIT_BEGIN_RE.search(line): + state = 2 + emit = False + elif APACHE2_BEGIN_RE.search(line): + # Assume an Apache license is preceded by a copyright + # notice. So just emit it like the rest of the file. + state = 9 + elif state == 2: + # Replace the MIT license with Apache 2 + emit = False + if MIT_END_RE.search(line): + state = 9 + sys.stdout.write(licensed) + if emit: + sys.stdout.write(line) + + +def alert_if_no_copyright(glob, comment_prefix): + """Prints names of all files missing either a copyright or Apache 2 license. + + Finds all glob-matching files under the current directory and checks if they + contain the copyright message and license notice. Prints the names of all the + files that don't meet both criteria. + + Returns the total number of file names printed. + """ + printed_count = 0 + for file in filtered_descendants(glob): + has_copyright = False + has_apache2 = False + line_num = 0 + apache_expected_end = 0 + with open(file, encoding='utf-8') as contents: + for line in contents: + line_num += 1 + if COPYRIGHT_RE.search(line): + has_copyright = True + if APACHE2_BEGIN_RE.search(line): + apache_expected_end = line_num + LICENSED_LEN + if (line_num is apache_expected_end) and APACHE2_END_RE.search(line): + has_apache2 = True + if not (has_copyright and has_apache2): + message = file + if not has_copyright: + message += ' has no copyright' + if not has_apache2: + message += ' has no Apache 2 license notice' + print(message) + printed_count += 1 + return printed_count + + +class ArgParser(argparse.ArgumentParser): + def __init__(self): + super(ArgParser, self).__init__( + description=inspect.getdoc(sys.modules[__name__])) + self.add_argument('--update', dest='author', action='store', + help='For files missing a copyright notice, insert ' + 'one for the given author, and add a license ' + 'notice. The author must be in the AUTHORS ' + 'list in the script.') + + +def main(): + glob_comment_pairs = [('*.h', '//'), ('*.hpp', '//'), ('*.sh', '#'), + ('*.py', '#'), ('*.cpp', '//'), + ('CMakeLists.txt', '#')] + argparser = ArgParser() + args = argparser.parse_args() + + if args.author: + if args.author not in AUTHORS: + print('error: --update argument must be in the AUTHORS list in ' + 'check_copyright.py: {}'.format(AUTHORS)) + sys.exit(1) + for pair in glob_comment_pairs: + insert_copyright(args.author, *pair) + sys.exit(0) + else: + count = sum([alert_if_no_copyright(*p) for p in glob_comment_pairs]) + sys.exit(count > 0) + + +if __name__ == '__main__': + main() diff --git a/thirdparty/glslang/External/spirv-tools/utils/check_symbol_exports.py b/thirdparty/glslang/External/spirv-tools/utils/check_symbol_exports.py new file mode 100644 index 000000000000..e44294fe8bc1 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/check_symbol_exports.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 Google Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Ensures that all externally visible functions in the library have an appropriate name + +Appropriate function names are: + - names starting with spv, + - anything in a namespace, + - functions added by the protobuf compiler, + - and weak definitions of new and delete.""" + +import os.path +import re +import subprocess +import sys + + +PROG = 'check_symbol_exports' + + +def command_output(cmd, directory): + """Runs a command in a directory and returns its standard output stream. + + Captures the standard error stream. + + Raises a RuntimeError if the command fails to launch or otherwise fails. + """ + p = subprocess.Popen(cmd, + cwd=directory, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + (stdout, _) = p.communicate() + if p.returncode != 0: + raise RuntimeError('Failed to run %s in %s' % (cmd, directory)) + return stdout + + +def check_library(library): + """Scans the given library file for global exports. If all such + exports are namespaced or begin with spv (in either C or C++ styles) + then return 0. Otherwise emit a message and return 1.""" + + # The pattern for an externally visible symbol record + symbol_pattern = re.compile(r'^[0-aA-Fa-f]+ +([wg]) *F \.text.*[0-9A-Fa-f]+ +(.*)') + + # Ok patterns are as follows, assuming Itanium name mangling: + # spv[A-Z] : extern "C" symbol starting with spv + # _ZN : something in a namespace + # _ZSt : something in the standard namespace + # _ZZN : something in a local scope and namespace + # _Z[0-9]+spv[A-Z_] : C++ symbol starting with spv[A-Z_] + symbol_ok_pattern = re.compile(r'^(spv[A-Z]|_ZN|_ZSt|_ZZN|_Z[0-9]+spv[A-Z_])') + + # In addition, the following pattern allowlists global functions that are added + # by the protobuf compiler: + # - AddDescriptors_spvtoolsfuzz_2eproto() + # - InitDefaults_spvtoolsfuzz_2eproto() + symbol_allowlist_pattern = re.compile(r'_Z[0-9]+.*spvtoolsfuzz_2eproto.*') + + symbol_is_new_or_delete = re.compile(r'^(_Zna|_Znw|_Zdl|_Zda)') + # Compilaion for Arm has various thunks for constructors, destructors, vtables. + # They are weak. + symbol_is_thunk = re.compile(r'^_ZT') + + # This occurs in NDK builds. + symbol_is_hidden = re.compile(r'^\.hidden ') + + seen = set() + result = 0 + for line in command_output(['objdump', '-t', library], '.').split('\n'): + match = symbol_pattern.search(line) + if match: + linkage = match.group(1) + symbol = match.group(2) + if symbol not in seen: + seen.add(symbol) + #print("look at '{}'".format(symbol)) + if not (symbol_is_new_or_delete.match(symbol) and linkage == 'w'): + if not (symbol_is_thunk.match(symbol) and linkage == 'w'): + if not (symbol_allowlist_pattern.match(symbol) or + symbol_ok_pattern.match(symbol) or + symbol_is_hidden.match(symbol)): + print('{}: error: Unescaped exported symbol: {}'.format(PROG, symbol)) + result = 1 + return result + + +def main(): + import argparse + parser = argparse.ArgumentParser(description='Check global names exported from a library') + parser.add_argument('library', help='The static library to examine') + args = parser.parse_args() + + if not os.path.isfile(args.library): + print('{}: error: {} does not exist'.format(PROG, args.library)) + sys.exit(1) + + if os.name == 'posix': + status = check_library(args.library) + sys.exit(status) + else: + print('Passing test since not on Posix') + sys.exit(0) + + +if __name__ == '__main__': + main() diff --git a/thirdparty/glslang/External/spirv-tools/utils/fixup_fuzz_result.py b/thirdparty/glslang/External/spirv-tools/utils/fixup_fuzz_result.py new file mode 100644 index 000000000000..5b14a7db9b18 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/fixup_fuzz_result.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys + +if len(sys.argv) < 1: + print("Need file to chop"); + +with open(sys.argv[1], mode='rb') as file: + file_content = file.read() + content = file_content[:len(file_content) - (len(file_content) % 4)] + sys.stdout.write(content) + diff --git a/thirdparty/glslang/External/spirv-tools/utils/generate_changelog.py b/thirdparty/glslang/External/spirv-tools/utils/generate_changelog.py new file mode 100644 index 000000000000..348bc50a6ae2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/generate_changelog.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Args: +# Updates an output file with changelog from the given CHANGES file and tag. +# - search for first line matching in file +# - search for the next line with a tag +# - writes all the lines in between those 2 tags into + +import errno +import os +import os.path +import re +import subprocess +import logging +import sys + +# Regex to match the SPIR-V version tag. +# Example of matching tags: +# - v2020.1 +# - v2020.1-dev +# - v2020.1.rc1 +VERSION_REGEX = re.compile(r'^(v\d+\.\d+) +[0-9]+-[0-9]+-[0-9]+$') + +def mkdir_p(directory): + """Make the directory, and all its ancestors as required. Any of the + directories are allowed to already exist.""" + + if directory == "": + # We're being asked to make the current directory. + return + + try: + os.makedirs(directory) + except OSError as e: + if e.errno == errno.EEXIST and os.path.isdir(directory): + pass + else: + raise + +def main(): + FORMAT = '%(asctime)s %(message)s' + logging.basicConfig(format="[%(asctime)s][%(levelname)-8s] %(message)s", datefmt="%H:%M:%S") + if len(sys.argv) != 4: + logging.error("usage: {} ".format(sys.argv[0])) + sys.exit(1) + + changes_path = sys.argv[1] + start_tag = sys.argv[2] + output_file_path = sys.argv[3] + + changelog = [] + has_found_start = False + with open(changes_path, "r") as file: + for line in file.readlines(): + m = VERSION_REGEX.match(line) + if m: + print(m.groups()[0]) + print(start_tag) + if has_found_start: + break; + if start_tag == m.groups()[0]: + has_found_start = True + continue + + if has_found_start: + changelog.append(line) + + if not has_found_start: + logging.error("No tag matching {} found.".format(start_tag)) + sys.exit(1) + + content = "".join(changelog) + if os.path.isfile(output_file_path): + with open(output_file_path, 'r') as f: + if content == f.read(): + sys.exit(0) + + mkdir_p(os.path.dirname(output_file_path)) + with open(output_file_path, 'w') as f: + f.write(content) + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/thirdparty/glslang/External/spirv-tools/utils/generate_grammar_tables.py b/thirdparty/glslang/External/spirv-tools/utils/generate_grammar_tables.py new file mode 100644 index 000000000000..48f83c33abaf --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/generate_grammar_tables.py @@ -0,0 +1,903 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 Google Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Generates various info tables from SPIR-V JSON grammar.""" + +import errno +import json +import os.path +import re + +# Prefix for all C variables generated by this script. +PYGEN_VARIABLE_PREFIX = 'pygen_variable' + +# Extensions to recognize, but which don't necessarily come from the SPIR-V +# core or KHR grammar files. Get this list from the SPIR-V registry web page. +# NOTE: Only put things on this list if it is not in those grammar files. +EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS = """ +SPV_AMD_gcn_shader +SPV_AMD_gpu_shader_half_float +SPV_AMD_gpu_shader_int16 +SPV_AMD_shader_trinary_minmax +SPV_KHR_non_semantic_info +""" + +OUTPUT_LANGUAGE = 'c' + +def make_path_to_file(f): + """Makes all ancestor directories to the given file, if they don't yet + exist. + + Arguments: + f: The file whose ancestor directories are to be created. + """ + dir = os.path.dirname(os.path.abspath(f)) + try: + os.makedirs(dir) + except OSError as e: + if e.errno == errno.EEXIST and os.path.isdir(dir): + pass + else: + raise + + +def convert_min_required_version(version): + """Converts the minimal required SPIR-V version encoded in the grammar to + the symbol in SPIRV-Tools.""" + if version is None: + return 'SPV_SPIRV_VERSION_WORD(1, 0)' + if version == 'None': + return '0xffffffffu' + return 'SPV_SPIRV_VERSION_WORD({})'.format(version.replace('.', ',')) + + +def convert_max_required_version(version): + """Converts the maximum required SPIR-V version encoded in the grammar to + the symbol in SPIRV-Tools.""" + if version is None: + return '0xffffffffu' + return 'SPV_SPIRV_VERSION_WORD({})'.format(version.replace('.', ',')) + + +def compose_capability_list(caps): + """Returns a string containing a braced list of capabilities as enums. + + Arguments: + - caps: a sequence of capability names + + Returns: + a string containing the braced list of SpvCapability* or spv::Capability:: enums named by caps. + """ + base_string = 'SpvCapability' + global OUTPUT_LANGUAGE + if OUTPUT_LANGUAGE == 'c++': + base_string = 'spv::Capability::' + + return '{' + ', '.join([(base_string + '{}').format(c) for c in caps]) + '}' + + +def get_capability_array_name(caps): + """Returns the name of the array containing all the given capabilities. + + Args: + - caps: a sequence of capability names + """ + if not caps: + return 'nullptr' + return '{}_caps_{}'.format(PYGEN_VARIABLE_PREFIX, ''.join(caps)) + + +def generate_capability_arrays(caps): + """Returns the arrays of capabilities. + + Arguments: + - caps: a sequence of sequence of capability names + """ + caps = sorted(set([tuple(c) for c in caps if c])) + cap_str = 'SpvCapability' + global OUTPUT_LANGUAGE + if OUTPUT_LANGUAGE == 'c++': + cap_str = 'spv::Capability' + arrays = [ + 'static const ' + cap_str + ' {}[] = {};'.format( + get_capability_array_name(c), compose_capability_list(c)) + for c in caps] + return '\n'.join(arrays) + + +def compose_extension_list(exts): + """Returns a string containing a braced list of extensions as enums. + + Arguments: + - exts: a sequence of extension names + + Returns: + a string containing the braced list of extensions named by exts. + """ + return '{' + ', '.join( + ['spvtools::Extension::k{}'.format(e) for e in exts]) + '}' + + +def get_extension_array_name(extensions): + """Returns the name of the array containing all the given extensions. + + Args: + - extensions: a sequence of extension names + """ + if not extensions: + return 'nullptr' + else: + return '{}_exts_{}'.format( + PYGEN_VARIABLE_PREFIX, ''.join(extensions)) + + +def generate_extension_arrays(extensions): + """Returns the arrays of extensions. + + Arguments: + - caps: a sequence of sequence of extension names + """ + extensions = sorted(set([tuple(e) for e in extensions if e])) + arrays = [ + 'static const spvtools::Extension {}[] = {};'.format( + get_extension_array_name(e), compose_extension_list(e)) + for e in extensions] + return '\n'.join(arrays) + + +def convert_operand_kind(operand_tuple): + """Returns the corresponding operand type used in spirv-tools for the given + operand kind and quantifier used in the JSON grammar. + + Arguments: + - operand_tuple: a tuple of two elements: + - operand kind: used in the JSON grammar + - quantifier: '', '?', or '*' + + Returns: + a string of the enumerant name in spv_operand_type_t + """ + kind, quantifier = operand_tuple + # The following cases are where we differ between the JSON grammar and + # spirv-tools. + if kind == 'IdResultType': + kind = 'TypeId' + elif kind == 'IdResult': + kind = 'ResultId' + elif kind == 'IdMemorySemantics' or kind == 'MemorySemantics': + kind = 'MemorySemanticsId' + elif kind == 'IdScope' or kind == 'Scope': + kind = 'ScopeId' + elif kind == 'IdRef': + kind = 'Id' + + elif kind == 'ImageOperands': + kind = 'Image' + elif kind == 'Dim': + kind = 'Dimensionality' + elif kind == 'ImageFormat': + kind = 'SamplerImageFormat' + elif kind == 'KernelEnqueueFlags': + kind = 'KernelEnqFlags' + + elif kind == 'LiteralExtInstInteger': + kind = 'ExtensionInstructionNumber' + elif kind == 'LiteralSpecConstantOpInteger': + kind = 'SpecConstantOpNumber' + elif kind == 'LiteralContextDependentNumber': + kind = 'TypedLiteralNumber' + + elif kind == 'PairLiteralIntegerIdRef': + kind = 'LiteralIntegerId' + elif kind == 'PairIdRefLiteralInteger': + kind = 'IdLiteralInteger' + elif kind == 'PairIdRefIdRef': # Used by OpPhi in the grammar + kind = 'Id' + + if kind == 'FPRoundingMode': + kind = 'FpRoundingMode' + elif kind == 'FPFastMathMode': + kind = 'FpFastMathMode' + + if quantifier == '?': + kind = 'Optional{}'.format(kind) + elif quantifier == '*': + kind = 'Variable{}'.format(kind) + + return 'SPV_OPERAND_TYPE_{}'.format( + re.sub(r'([a-z])([A-Z])', r'\1_\2', kind).upper()) + + +class InstInitializer(object): + """Instances holds a SPIR-V instruction suitable for printing as the + initializer for spv_opcode_desc_t.""" + + def __init__(self, opname, caps, exts, operands, version, lastVersion): + """Initialization. + + Arguments: + - opname: opcode name (with the 'Op' prefix) + - caps: a sequence of capability names required by this opcode + - exts: a sequence of names of extensions enabling this enumerant + - operands: a sequence of (operand-kind, operand-quantifier) tuples + - version: minimal SPIR-V version required for this opcode + - lastVersion: last version of SPIR-V that includes this opcode + """ + + assert opname.startswith('Op') + self.opname = opname[2:] # Remove the "Op" prefix. + self.num_caps = len(caps) + self.caps_mask = get_capability_array_name(caps) + self.num_exts = len(exts) + self.exts = get_extension_array_name(exts) + self.operands = [convert_operand_kind(o) for o in operands] + + self.fix_syntax() + + operands = [o[0] for o in operands] + self.ref_type_id = 'IdResultType' in operands + self.def_result_id = 'IdResult' in operands + + self.version = convert_min_required_version(version) + self.lastVersion = convert_max_required_version(lastVersion) + + def fix_syntax(self): + """Fix an instruction's syntax, adjusting for differences between the + officially released grammar and how SPIRV-Tools uses the grammar. + + Fixes: + - ExtInst should not end with SPV_OPERAND_VARIABLE_ID. + https://github.com/KhronosGroup/SPIRV-Tools/issues/233 + """ + if (self.opname == 'ExtInst' + and self.operands[-1] == 'SPV_OPERAND_TYPE_VARIABLE_ID'): + self.operands.pop() + + def __str__(self): + global OUTPUT_LANGUAGE + base_str = 'SpvOp' + if OUTPUT_LANGUAGE == 'c++': + base_str = 'spv::Op::Op' + + template = ['{{"{opname}"', base_str + '{opname}', + '{num_caps}', '{caps_mask}', + '{num_operands}', '{{{operands}}}', + '{def_result_id}', '{ref_type_id}', + '{num_exts}', '{exts}', + '{min_version}', '{max_version}}}'] + return ', '.join(template).format( + opname=self.opname, + num_caps=self.num_caps, + caps_mask=self.caps_mask, + num_operands=len(self.operands), + operands=', '.join(self.operands), + def_result_id=(1 if self.def_result_id else 0), + ref_type_id=(1 if self.ref_type_id else 0), + num_exts=self.num_exts, + exts=self.exts, + min_version=self.version, + max_version=self.lastVersion) + + +class ExtInstInitializer(object): + """Instances holds a SPIR-V extended instruction suitable for printing as + the initializer for spv_ext_inst_desc_t.""" + + def __init__(self, opname, opcode, caps, operands): + """Initialization. + + Arguments: + - opname: opcode name + - opcode: enumerant value for this opcode + - caps: a sequence of capability names required by this opcode + - operands: a sequence of (operand-kind, operand-quantifier) tuples + """ + self.opname = opname + self.opcode = opcode + self.num_caps = len(caps) + self.caps_mask = get_capability_array_name(caps) + self.operands = [convert_operand_kind(o) for o in operands] + self.operands.append('SPV_OPERAND_TYPE_NONE') + + def __str__(self): + template = ['{{"{opname}"', '{opcode}', '{num_caps}', '{caps_mask}', + '{{{operands}}}}}'] + return ', '.join(template).format( + opname=self.opname, + opcode=self.opcode, + num_caps=self.num_caps, + caps_mask=self.caps_mask, + operands=', '.join(self.operands)) + + +def generate_instruction(inst, is_ext_inst): + """Returns the C initializer for the given SPIR-V instruction. + + Arguments: + - inst: a dict containing information about a SPIR-V instruction + - is_ext_inst: a bool indicating whether |inst| is an extended + instruction. + + Returns: + a string containing the C initializer for spv_opcode_desc_t or + spv_ext_inst_desc_t + """ + opname = inst.get('opname') + opcode = inst.get('opcode') + caps = inst.get('capabilities', []) + exts = inst.get('extensions', []) + operands = inst.get('operands', {}) + operands = [(o['kind'], o.get('quantifier', '')) for o in operands] + min_version = inst.get('version', None) + max_version = inst.get('lastVersion', None) + + assert opname is not None + + if is_ext_inst: + return str(ExtInstInitializer(opname, opcode, caps, operands)) + else: + return str(InstInitializer(opname, caps, exts, operands, min_version, max_version)) + + +def generate_instruction_table(inst_table): + """Returns the info table containing all SPIR-V instructions, sorted by + opcode, and prefixed by capability arrays. + + Note: + - the built-in sorted() function is guaranteed to be stable. + https://docs.python.org/3/library/functions.html#sorted + + Arguments: + - inst_table: a list containing all SPIR-V instructions. + """ + inst_table = sorted(inst_table, key=lambda k: (k['opcode'], k['opname'])) + + caps_arrays = generate_capability_arrays( + [inst.get('capabilities', []) for inst in inst_table]) + exts_arrays = generate_extension_arrays( + [inst.get('extensions', []) for inst in inst_table]) + + insts = [generate_instruction(inst, False) for inst in inst_table] + insts = ['static const spv_opcode_desc_t kOpcodeTableEntries[] = {{\n' + ' {}\n}};'.format(',\n '.join(insts))] + + return '{}\n\n{}\n\n{}'.format(caps_arrays, exts_arrays, '\n'.join(insts)) + + +def generate_extended_instruction_table(json_grammar, set_name, operand_kind_prefix=""): + """Returns the info table containing all SPIR-V extended instructions, + sorted by opcode, and prefixed by capability arrays. + + Arguments: + - inst_table: a list containing all SPIR-V instructions. + - set_name: the name of the extended instruction set. + - operand_kind_prefix: the prefix, if any, to add to the front + of operand kind names. + """ + if operand_kind_prefix: + prefix_operand_kind_names(operand_kind_prefix, json_grammar) + + inst_table = json_grammar["instructions"] + set_name = set_name.replace(".", "_") + + inst_table = sorted(inst_table, key=lambda k: k['opcode']) + caps = [inst.get('capabilities', []) for inst in inst_table] + caps_arrays = generate_capability_arrays(caps) + insts = [generate_instruction(inst, True) for inst in inst_table] + insts = ['static const spv_ext_inst_desc_t {}_entries[] = {{\n' + ' {}\n}};'.format(set_name, ',\n '.join(insts))] + + return '{}\n\n{}'.format(caps_arrays, '\n'.join(insts)) + + +class EnumerantInitializer(object): + """Prints an enumerant as the initializer for spv_operand_desc_t.""" + + def __init__(self, enumerant, value, caps, exts, parameters, version, lastVersion): + """Initialization. + + Arguments: + - enumerant: enumerant name + - value: enumerant value + - caps: a sequence of capability names required by this enumerant + - exts: a sequence of names of extensions enabling this enumerant + - parameters: a sequence of (operand-kind, operand-quantifier) tuples + - version: minimal SPIR-V version required for this opcode + - lastVersion: last SPIR-V version this opode appears + """ + self.enumerant = enumerant + self.value = value + self.num_caps = len(caps) + self.caps = get_capability_array_name(caps) + self.num_exts = len(exts) + self.exts = get_extension_array_name(exts) + self.parameters = [convert_operand_kind(p) for p in parameters] + self.version = convert_min_required_version(version) + self.lastVersion = convert_max_required_version(lastVersion) + + def __str__(self): + template = ['{{"{enumerant}"', '{value}', '{num_caps}', + '{caps}', '{num_exts}', '{exts}', + '{{{parameters}}}', '{min_version}', + '{max_version}}}'] + return ', '.join(template).format( + enumerant=self.enumerant, + value=self.value, + num_caps=self.num_caps, + caps=self.caps, + num_exts=self.num_exts, + exts=self.exts, + parameters=', '.join(self.parameters), + min_version=self.version, + max_version=self.lastVersion) + + +def generate_enum_operand_kind_entry(entry, extension_map): + """Returns the C initializer for the given operand enum entry. + + Arguments: + - entry: a dict containing information about an enum entry + - extension_map: a dict mapping enum value to list of extensions + + Returns: + a string containing the C initializer for spv_operand_desc_t + """ + enumerant = entry.get('enumerant') + value = entry.get('value') + caps = entry.get('capabilities', []) + if value in extension_map: + exts = extension_map[value] + else: + exts = [] + params = entry.get('parameters', []) + params = [p.get('kind') for p in params] + params = zip(params, [''] * len(params)) + version = entry.get('version', None) + max_version = entry.get('lastVersion', None) + + assert enumerant is not None + assert value is not None + + return str(EnumerantInitializer( + enumerant, value, caps, exts, params, version, max_version)) + + +def generate_enum_operand_kind(enum, synthetic_exts_list): + """Returns the C definition for the given operand kind. + It's a static const named array of spv_operand_desc_t. + + Also appends to |synthetic_exts_list| a list of extension lists + used. + """ + kind = enum.get('kind') + assert kind is not None + + # Sort all enumerants according to their values, but otherwise + # preserve their order so the first name listed in the grammar + # as the preferred name for disassembly. + if enum.get('category') == 'ValueEnum': + def functor(k): return (k['value']) + else: + def functor(k): return (int(k['value'], 16)) + entries = sorted(enum.get('enumerants', []), key=functor) + + # SubgroupEqMask and SubgroupEqMaskKHR are the same number with + # same semantics, but one has no extension list while the other + # does. Both should have the extension list. + # So create a mapping from enum value to the union of the extensions + # across all those grammar entries. Preserve order. + extension_map = {} + for e in entries: + value = e.get('value') + extension_map[value] = [] + for e in entries: + value = e.get('value') + exts = e.get('extensions', []) + for ext in exts: + if ext not in extension_map[value]: + extension_map[value].append(ext) + synthetic_exts_list.extend(extension_map.values()) + + name = '{}_{}Entries'.format(PYGEN_VARIABLE_PREFIX, kind) + entries = [' {}'.format(generate_enum_operand_kind_entry(e, extension_map)) + for e in entries] + + template = ['static const spv_operand_desc_t {name}[] = {{', + '{entries}', '}};'] + entries = '\n'.join(template).format( + name=name, + entries=',\n'.join(entries)) + + return kind, name, entries + + +def generate_operand_kind_table(enums): + """Returns the info table containing all SPIR-V operand kinds.""" + # We only need to output info tables for those operand kinds that are enums. + enums = [e for e in enums if e.get('category') in ['ValueEnum', 'BitEnum']] + + caps = [entry.get('capabilities', []) + for enum in enums + for entry in enum.get('enumerants', [])] + caps_arrays = generate_capability_arrays(caps) + + exts = [entry.get('extensions', []) + for enum in enums + for entry in enum.get('enumerants', [])] + enums = [generate_enum_operand_kind(e, exts) for e in enums] + exts_arrays = generate_extension_arrays(exts) + + # We have a few operand kinds that require their optional counterpart to + # exist in the operand info table. + optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess', 'PackedVectorFormat', 'CooperativeMatrixOperands'] + optional_enums = [e for e in enums if e[0] in optional_enums] + enums.extend(optional_enums) + + enum_kinds, enum_names, enum_entries = zip(*enums) + # Mark the last few as optional ones. + enum_quantifiers = [''] * (len(enums) - len(optional_enums)) + ['?'] * len(optional_enums) + # And we don't want redefinition of them. + enum_entries = enum_entries[:-len(optional_enums)] + enum_kinds = [convert_operand_kind(e) + for e in zip(enum_kinds, enum_quantifiers)] + table_entries = zip(enum_kinds, enum_names, enum_names) + table_entries = [' {{{}, ARRAY_SIZE({}), {}}}'.format(*e) + for e in table_entries] + + template = [ + 'static const spv_operand_desc_group_t {p}_OperandInfoTable[] = {{', + '{enums}', '}};'] + table = '\n'.join(template).format( + p=PYGEN_VARIABLE_PREFIX, enums=',\n'.join(table_entries)) + + return '\n\n'.join((caps_arrays,) + (exts_arrays,) + enum_entries + (table,)) + + +def get_extension_list(instructions, operand_kinds): + """Returns extensions as an alphabetically sorted list of strings.""" + + things_with_an_extensions_field = [item for item in instructions] + + enumerants = sum([item.get('enumerants', []) + for item in operand_kinds], []) + + things_with_an_extensions_field.extend(enumerants) + + extensions = sum([item.get('extensions', []) + for item in things_with_an_extensions_field + if item.get('extensions')], []) + + for item in EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split(): + # If it's already listed in a grammar, then don't put it in the + # special exceptions list. + assert item not in extensions, 'Extension %s is already in a grammar file' % item + + extensions.extend( + EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split()) + + # Validator would ignore type declaration unique check. Should only be used + # for legacy autogenerated test files containing multiple instances of the + # same type declaration, if fixing the test by other methods is too + # difficult. Shouldn't be used for any other reasons. + extensions.append('SPV_VALIDATOR_ignore_type_decl_unique') + + return sorted(set(extensions)) + + +def get_capabilities(operand_kinds): + """Returns capabilities as a list of JSON objects, in order of + appearance.""" + enumerants = sum([item.get('enumerants', []) for item in operand_kinds + if item.get('kind') in ['Capability']], []) + return enumerants + + +def generate_extension_enum(extensions): + """Returns enumeration containing extensions declared in the grammar.""" + return ',\n'.join(['k' + extension for extension in extensions]) + + +def generate_extension_to_string_mapping(extensions): + """Returns mapping function from extensions to corresponding strings.""" + function = 'const char* ExtensionToString(Extension extension) {\n' + function += ' switch (extension) {\n' + template = ' case Extension::k{extension}:\n' \ + ' return "{extension}";\n' + function += ''.join([template.format(extension=extension) + for extension in extensions]) + function += ' }\n\n return "";\n}' + return function + + +def generate_string_to_extension_mapping(extensions): + """Returns mapping function from strings to corresponding extensions.""" + + function = ''' + bool GetExtensionFromString(const char* str, Extension* extension) {{ + static const char* known_ext_strs[] = {{ {strs} }}; + static const Extension known_ext_ids[] = {{ {ids} }}; + const auto b = std::begin(known_ext_strs); + const auto e = std::end(known_ext_strs); + const auto found = std::equal_range( + b, e, str, [](const char* str1, const char* str2) {{ + return std::strcmp(str1, str2) < 0; + }}); + if (found.first == e || found.first == found.second) return false; + + *extension = known_ext_ids[found.first - b]; + return true; + }} + '''.format(strs=', '.join(['"{}"'.format(e) for e in extensions]), + ids=', '.join(['Extension::k{}'.format(e) for e in extensions])) + + return function + + +def generate_capability_to_string_mapping(operand_kinds): + """Returns mapping function from capabilities to corresponding strings. + + We take care to avoid emitting duplicate values. + """ + cap_str = 'SpvCapability' + cap_join = '' + global OUTPUT_LANGUAGE + if OUTPUT_LANGUAGE == 'c++': + cap_str = 'spv::Capability' + cap_join = '::' + + function = 'const char* CapabilityToString(' + cap_str + ' capability) {\n' + function += ' switch (capability) {\n' + template = ' case ' + cap_str + cap_join + '{capability}:\n' \ + ' return "{capability}";\n' + emitted = set() # The values of capabilities we already have emitted + for capability in get_capabilities(operand_kinds): + value = capability.get('value') + if value not in emitted: + emitted.add(value) + function += template.format(capability=capability.get('enumerant')) + function += ' case ' + cap_str + cap_join + 'Max:\n' \ + ' assert(0 && "Attempting to convert ' + cap_str + cap_join + 'Max to string");\n' \ + ' return "";\n' + function += ' }\n\n return "";\n}' + return function + + +def generate_all_string_enum_mappings(extensions, operand_kinds): + """Returns all string-to-enum / enum-to-string mapping tables.""" + tables = [] + tables.append(generate_extension_to_string_mapping(extensions)) + tables.append(generate_string_to_extension_mapping(extensions)) + tables.append(generate_capability_to_string_mapping(operand_kinds)) + return '\n\n'.join(tables) + + +def precondition_operand_kinds(operand_kinds): + """For operand kinds that have the same number, make sure they all have the + same extension list.""" + + # Map operand kind and value to list of the union of extensions + # for same-valued enumerants. + exts = {} + for kind_entry in operand_kinds: + kind = kind_entry.get('kind') + for enum_entry in kind_entry.get('enumerants', []): + value = enum_entry.get('value') + key = kind + '.' + str(value) + if key in exts: + exts[key].extend(enum_entry.get('extensions', [])) + else: + exts[key] = enum_entry.get('extensions', []) + exts[key] = sorted(set(exts[key])) + + # Now make each entry the same list. + for kind_entry in operand_kinds: + kind = kind_entry.get('kind') + for enum_entry in kind_entry.get('enumerants', []): + value = enum_entry.get('value') + key = kind + '.' + str(value) + if len(exts[key]) > 0: + enum_entry['extensions'] = exts[key] + + return operand_kinds + + +def prefix_operand_kind_names(prefix, json_dict): + """Modifies json_dict, by prefixing all the operand kind names + with the given prefix. Also modifies their uses in the instructions + to match. + """ + + old_to_new = {} + for operand_kind in json_dict["operand_kinds"]: + old_name = operand_kind["kind"] + new_name = prefix + old_name + operand_kind["kind"] = new_name + old_to_new[old_name] = new_name + + for instruction in json_dict["instructions"]: + for operand in instruction.get("operands", []): + replacement = old_to_new.get(operand["kind"]) + if replacement is not None: + operand["kind"] = replacement + + +def main(): + import argparse + parser = argparse.ArgumentParser(description='Generate SPIR-V info tables') + + parser.add_argument('--spirv-core-grammar', metavar='', + type=str, required=False, + help='input JSON grammar file for core SPIR-V ' + 'instructions') + parser.add_argument('--extinst-debuginfo-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for DebugInfo extended ' + 'instruction set') + parser.add_argument('--extinst-cldebuginfo100-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for OpenCL.DebugInfo.100 ' + 'extended instruction set') + parser.add_argument('--extinst-glsl-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for GLSL extended ' + 'instruction set') + parser.add_argument('--extinst-opencl-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for OpenCL extended ' + 'instruction set') + parser.add_argument('--output-language', + type=str, required=False, default='c', + choices=['c','c++'], + help='specify output language type') + + parser.add_argument('--core-insts-output', metavar='', + type=str, required=False, default=None, + help='output file for core SPIR-V instructions') + parser.add_argument('--glsl-insts-output', metavar='', + type=str, required=False, default=None, + help='output file for GLSL extended instruction set') + parser.add_argument('--opencl-insts-output', metavar='', + type=str, required=False, default=None, + help='output file for OpenCL extended instruction set') + parser.add_argument('--operand-kinds-output', metavar='', + type=str, required=False, default=None, + help='output file for operand kinds') + parser.add_argument('--extension-enum-output', metavar='', + type=str, required=False, default=None, + help='output file for extension enumeration') + parser.add_argument('--enum-string-mapping-output', metavar='', + type=str, required=False, default=None, + help='output file for enum-string mappings') + parser.add_argument('--extinst-vendor-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for vendor extended ' + 'instruction set'), + parser.add_argument('--vendor-insts-output', metavar='', + type=str, required=False, default=None, + help='output file for vendor extended instruction set') + parser.add_argument('--vendor-operand-kind-prefix', metavar='', + type=str, required=False, default=None, + help='prefix for operand kinds (to disambiguate operand type enums)') + args = parser.parse_args() + + global OUTPUT_LANGUAGE + OUTPUT_LANGUAGE = args.output_language + + # The GN build system needs this because it doesn't handle quoting + # empty string arguments well. + if args.vendor_operand_kind_prefix == "...nil...": + args.vendor_operand_kind_prefix = "" + + if (args.core_insts_output is None) != \ + (args.operand_kinds_output is None): + print('error: --core-insts-output and --operand-kinds-output ' + 'should be specified together.') + exit(1) + if args.operand_kinds_output and not (args.spirv_core_grammar and + args.extinst_debuginfo_grammar and + args.extinst_cldebuginfo100_grammar): + print('error: --operand-kinds-output requires --spirv-core-grammar ' + 'and --extinst-debuginfo-grammar ' + 'and --extinst-cldebuginfo100-grammar') + exit(1) + if (args.glsl_insts_output is None) != \ + (args.extinst_glsl_grammar is None): + print('error: --glsl-insts-output and --extinst-glsl-grammar ' + 'should be specified together.') + exit(1) + if (args.opencl_insts_output is None) != \ + (args.extinst_opencl_grammar is None): + print('error: --opencl-insts-output and --extinst-opencl-grammar ' + 'should be specified together.') + exit(1) + if (args.vendor_insts_output is None) != \ + (args.extinst_vendor_grammar is None): + print('error: --vendor-insts-output and ' + '--extinst-vendor-grammar should be specified together.') + exit(1) + if all([args.core_insts_output is None, + args.glsl_insts_output is None, + args.opencl_insts_output is None, + args.vendor_insts_output is None, + args.extension_enum_output is None, + args.enum_string_mapping_output is None]): + print('error: at least one output should be specified.') + exit(1) + + if args.spirv_core_grammar is not None: + with open(args.spirv_core_grammar) as json_file: + core_grammar = json.loads(json_file.read()) + with open(args.extinst_debuginfo_grammar) as debuginfo_json_file: + debuginfo_grammar = json.loads(debuginfo_json_file.read()) + with open(args.extinst_cldebuginfo100_grammar) as cldebuginfo100_json_file: + cldebuginfo100_grammar = json.loads(cldebuginfo100_json_file.read()) + prefix_operand_kind_names("CLDEBUG100_", cldebuginfo100_grammar) + instructions = [] + instructions.extend(core_grammar['instructions']) + instructions.extend(debuginfo_grammar['instructions']) + instructions.extend(cldebuginfo100_grammar['instructions']) + operand_kinds = [] + operand_kinds.extend(core_grammar['operand_kinds']) + operand_kinds.extend(debuginfo_grammar['operand_kinds']) + operand_kinds.extend(cldebuginfo100_grammar['operand_kinds']) + extensions = get_extension_list(instructions, operand_kinds) + operand_kinds = precondition_operand_kinds(operand_kinds) + if args.core_insts_output is not None: + make_path_to_file(args.core_insts_output) + make_path_to_file(args.operand_kinds_output) + with open(args.core_insts_output, 'w') as f: + f.write(generate_instruction_table( + core_grammar['instructions'])) + with open(args.operand_kinds_output, 'w') as f: + f.write(generate_operand_kind_table(operand_kinds)) + if args.extension_enum_output is not None: + make_path_to_file(args.extension_enum_output) + with open(args.extension_enum_output, 'w') as f: + f.write(generate_extension_enum(extensions)) + if args.enum_string_mapping_output is not None: + make_path_to_file(args.enum_string_mapping_output) + with open(args.enum_string_mapping_output, 'w') as f: + f.write(generate_all_string_enum_mappings( + extensions, operand_kinds)) + + if args.extinst_glsl_grammar is not None: + with open(args.extinst_glsl_grammar) as json_file: + grammar = json.loads(json_file.read()) + make_path_to_file(args.glsl_insts_output) + with open(args.glsl_insts_output, 'w') as f: + f.write(generate_extended_instruction_table( + grammar, 'glsl')) + + if args.extinst_opencl_grammar is not None: + with open(args.extinst_opencl_grammar) as json_file: + grammar = json.loads(json_file.read()) + make_path_to_file(args.opencl_insts_output) + with open(args.opencl_insts_output, 'w') as f: + f.write(generate_extended_instruction_table( + grammar, 'opencl')) + + if args.extinst_vendor_grammar is not None: + with open(args.extinst_vendor_grammar) as json_file: + grammar = json.loads(json_file.read()) + make_path_to_file(args.vendor_insts_output) + name = args.extinst_vendor_grammar + start = name.find('extinst.') + len('extinst.') + name = name[start:-len('.grammar.json')].replace('-', '_') + with open(args.vendor_insts_output, 'w') as f: + f.write(generate_extended_instruction_table( + grammar, name, args.vendor_operand_kind_prefix)) + + +if __name__ == '__main__': + main() diff --git a/thirdparty/glslang/External/spirv-tools/utils/generate_language_headers.py b/thirdparty/glslang/External/spirv-tools/utils/generate_language_headers.py new file mode 100644 index 000000000000..18a8d5ea0163 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/generate_language_headers.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 Google Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Generates language headers from a JSON grammar file""" + +import errno +import json +import os.path +import re + + +def make_path_to_file(f): + """Makes all ancestor directories to the given file, if they + don't yet exist. + + Arguments: + f: The file whose ancestor directories are to be created. + """ + dir = os.path.dirname(os.path.abspath(f)) + try: + os.makedirs(dir) + except OSError as e: + if e.errno == errno.EEXIST and os.path.isdir(dir): + pass + else: + raise + +class ExtInstGrammar: + """The grammar for an extended instruction set""" + + def __init__(self, name, copyright, instructions, operand_kinds, version = None, revision = None): + self.name = name + self.copyright = copyright + self.instructions = instructions + self.operand_kinds = operand_kinds + self.version = version + self.revision = revision + + +class LangGenerator: + """A language-specific generator""" + + def __init__(self): + self.upper_case_initial = re.compile('^[A-Z]') + pass + + def comment_prefix(self): + return "" + + def namespace_prefix(self): + return "" + + def uses_guards(self): + return False + + def cpp_guard_preamble(self): + return "" + + def cpp_guard_postamble(self): + return "" + + def enum_value(self, prefix, name, value): + if self.upper_case_initial.match(name): + use_name = name + else: + use_name = '_' + name + + return " {}{} = {},".format(prefix, use_name, value) + + def generate(self, grammar): + """Returns a string that is the language-specific header for the given grammar""" + + parts = [] + if grammar.copyright: + parts.extend(["{}{}".format(self.comment_prefix(), f) for f in grammar.copyright]) + parts.append('') + + guard = 'SPIRV_EXTINST_{}_H_'.format(grammar.name) + if self.uses_guards: + parts.append('#ifndef {}'.format(guard)) + parts.append('#define {}'.format(guard)) + parts.append('') + + parts.append(self.cpp_guard_preamble()) + + if grammar.version: + parts.append(self.const_definition(grammar.name, 'Version', grammar.version)) + + if grammar.revision is not None: + parts.append(self.const_definition(grammar.name, 'Revision', grammar.revision)) + + parts.append('') + + if grammar.instructions: + parts.append(self.enum_prefix(grammar.name, 'Instructions')) + for inst in grammar.instructions: + parts.append(self.enum_value(grammar.name, inst['opname'], inst['opcode'])) + parts.append(self.enum_end(grammar.name, 'Instructions')) + parts.append('') + + if grammar.operand_kinds: + for kind in grammar.operand_kinds: + parts.append(self.enum_prefix(grammar.name, kind['kind'])) + for e in kind['enumerants']: + parts.append(self.enum_value(grammar.name, e['enumerant'], e['value'])) + parts.append(self.enum_end(grammar.name, kind['kind'])) + parts.append('') + + parts.append(self.cpp_guard_postamble()) + + if self.uses_guards: + parts.append('#endif // {}'.format(guard)) + + return '\n'.join(parts) + + +class CLikeGenerator(LangGenerator): + def uses_guards(self): + return True + + def comment_prefix(self): + return "// " + + def const_definition(self, prefix, var, value): + # Use an anonymous enum. Don't use a static const int variable because + # that can bloat binary size. + return 'enum {0} {1}{2} = {3}, {1}{2}_BitWidthPadding = 0x7fffffff {4};'.format( + '{', prefix, var, value, '}') + + def enum_prefix(self, prefix, name): + return 'enum {}{} {}'.format(prefix, name, '{') + + def enum_end(self, prefix, enum): + return ' {}{}Max = 0x7ffffff\n{};\n'.format(prefix, enum, '}') + + def cpp_guard_preamble(self): + return '#ifdef __cplusplus\nextern "C" {\n#endif\n' + + def cpp_guard_postamble(self): + return '#ifdef __cplusplus\n}\n#endif\n' + + +class CGenerator(CLikeGenerator): + pass + + +def main(): + import argparse + parser = argparse.ArgumentParser(description='Generate language headers from a JSON grammar') + + parser.add_argument('--extinst-grammar', metavar='', + type=str, required=True, + help='input JSON grammar file for extended instruction set') + parser.add_argument('--extinst-output-path', metavar='', + type=str, required=True, + help='Path of the language-specific output file.') + args = parser.parse_args() + + with open(args.extinst_grammar) as json_file: + grammar_json = json.loads(json_file.read()) + grammar_name = os.path.splitext(os.path.basename(args.extinst_output_path))[0] + grammar = ExtInstGrammar(name = grammar_name, + copyright = grammar_json['copyright'], + instructions = grammar_json['instructions'], + operand_kinds = grammar_json['operand_kinds'], + version = grammar_json['version'], + revision = grammar_json['revision']) + make_path_to_file(args.extinst_output_path) + with open(args.extinst_output_path, 'w') as f: + f.write(CGenerator().generate(grammar)) + + +if __name__ == '__main__': + main() diff --git a/thirdparty/glslang/External/spirv-tools/utils/generate_registry_tables.py b/thirdparty/glslang/External/spirv-tools/utils/generate_registry_tables.py new file mode 100644 index 000000000000..69628faadae2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/generate_registry_tables.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 Google Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Generates the vendor tool table from the SPIR-V XML registry.""" + +import errno +import io +import os.path +from xml.etree.ElementTree import XML, XMLParser, TreeBuilder + + +def mkdir_p(directory): + """Make the directory, and all its ancestors as required. Any of the + directories are allowed to already exist. + This is compatible with Python down to 3.0. + """ + + if directory == "": + # We're being asked to make the current directory. + return + + try: + os.makedirs(directory) + except OSError as e: + if e.errno == errno.EEXIST and os.path.isdir(directory): + pass + else: + raise + + +def generate_vendor_table(registry): + """Returns a list of C style initializers for the registered vendors + and their tools. + + Args: + registry: The SPIR-V XMLregistry as an xml.ElementTree + """ + + lines = [] + for ids in registry.iter('ids'): + if 'vendor' == ids.attrib['type']: + for an_id in ids.iter('id'): + value = an_id.attrib['value'] + vendor = an_id.attrib['vendor'] + if 'tool' in an_id.attrib: + tool = an_id.attrib['tool'] + vendor_tool = vendor + ' ' + tool + else: + tool = '' + vendor_tool = vendor + line = '{' + '{}, "{}", "{}", "{}"'.format(value, + vendor, + tool, + vendor_tool) + '},' + lines.append(line) + return '\n'.join(lines) + + +def main(): + import argparse + parser = argparse.ArgumentParser(description= + 'Generate tables from SPIR-V XML registry') + parser.add_argument('--xml', metavar='', + type=str, required=True, + help='SPIR-V XML Registry file') + parser.add_argument('--generator-output', metavar='', + type=str, required=True, + help='output file for SPIR-V generators table') + args = parser.parse_args() + + with io.open(args.xml, encoding='utf-8') as xml_in: + parser = XMLParser(target=TreeBuilder(), encoding='utf-8') + registry = XML(xml_in.read(), parser=parser) + + mkdir_p(os.path.dirname(args.generator_output)) + with open(args.generator_output, 'w') as f: + f.write(generate_vendor_table(registry)) + + +if __name__ == '__main__': + main() diff --git a/thirdparty/glslang/External/spirv-tools/utils/generate_vim_syntax.py b/thirdparty/glslang/External/spirv-tools/utils/generate_vim_syntax.py new file mode 100644 index 000000000000..5c9c6b21ae4f --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/generate_vim_syntax.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 Google Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Generates Vim syntax rules for SPIR-V assembly (.spvasm) files""" + +import json + +PREAMBLE="""" Vim syntax file +" Language: spvasm +" Generated by SPIRV-Tools + +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +syn case match +""" + +POSTAMBLE=""" + +syntax keyword spvasmTodo TODO FIXME contained + +syn match spvasmIdNumber /%\d\+\>/ + +" The assembler treats the leading minus sign as part of the number token. +" This applies to integers, and to floats below. +syn match spvasmNumber /-\?\<\d\+\>/ + +" Floating point literals. +" In general, C++ requires at least digit in the mantissa, and the +" floating point is optional. This applies to both the regular decimal float +" case and the hex float case. + +" First case: digits before the optional decimal, no trailing digits. +syn match spvasmFloat /-\?\d\+\.\?\(e[+-]\d\+\)\?/ +" Second case: optional digits before decimal, trailing digits +syn match spvasmFloat /-\?\d*\.\d\+\(e[+-]\d\+\)\?/ + +" First case: hex digits before the optional decimal, no trailing hex digits. +syn match spvasmFloat /-\?0[xX]\\x\+\.\?p[-+]\d\+/ +" Second case: optional hex digits before decimal, trailing hex digits +syn match spvasmFloat /-\?0[xX]\\x*\.\\x\+p[-+]\d\+/ + +syn match spvasmComment /;.*$/ contains=spvasmTodo +syn region spvasmString start=/"/ skip=/\\\\"/ end=/"/ +syn match spvasmId /%[a-zA-Z_][a-zA-Z_0-9]*/ + +" Highlight unknown constants and statements as errors +syn match spvasmError /[a-zA-Z][a-zA-Z_0-9]*/ + + +if version >= 508 || !exists("did_c_syn_inits") + if version < 508 + let did_c_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + HiLink spvasmStatement Statement + HiLink spvasmNumber Number + HiLink spvasmComment Comment + HiLink spvasmString String + HiLink spvasmFloat Float + HiLink spvasmConstant Constant + HiLink spvasmIdNumber Identifier + HiLink spvasmId Identifier + HiLink spvasmTodo Todo + + delcommand HiLink +endif + +let b:current_syntax = "spvasm" +""" + +# This list is taken from the description of OpSpecConstantOp in SPIR-V 1.1. +# TODO(dneto): Propose that this information be embedded in the grammar file. +SPEC_CONSTANT_OP_OPCODES = """ + OpSConvert, OpFConvert + OpSNegate, OpNot + OpIAdd, OpISub + OpIMul, OpUDiv, OpSDiv, OpUMod, OpSRem, OpSMod + OpShiftRightLogical, OpShiftRightArithmetic, OpShiftLeftLogical + OpBitwiseOr, OpBitwiseXor, OpBitwiseAnd + OpVectorShuffle, OpCompositeExtract, OpCompositeInsert + OpLogicalOr, OpLogicalAnd, OpLogicalNot, + OpLogicalEqual, OpLogicalNotEqual + OpSelect + OpIEqual, OpINotEqual + OpULessThan, OpSLessThan + OpUGreaterThan, OpSGreaterThan + OpULessThanEqual, OpSLessThanEqual + OpUGreaterThanEqual, OpSGreaterThanEqual + + OpQuantizeToF16 + + OpConvertFToS, OpConvertSToF + OpConvertFToU, OpConvertUToF + OpUConvert + OpConvertPtrToU, OpConvertUToPtr + OpGenericCastToPtr, OpPtrCastToGeneric + OpBitcast + OpFNegate + OpFAdd, OpFSub + OpFMul, OpFDiv + OpFRem, OpFMod + OpAccessChain, OpInBoundsAccessChain + OpPtrAccessChain, OpInBoundsPtrAccessChain""" + + +def EmitAsStatement(name): + """Emits the given name as a statement token""" + print('syn keyword spvasmStatement', name) + + +def EmitAsEnumerant(name): + """Emits the given name as an named operand token""" + print('syn keyword spvasmConstant', name) + + +def main(): + """Parses arguments, then generates the Vim syntax rules for SPIR-V assembly + on stdout.""" + import argparse + parser = argparse.ArgumentParser(description='Generate SPIR-V info tables') + parser.add_argument('--spirv-core-grammar', metavar='', + type=str, required=True, + help='input JSON grammar file for core SPIR-V ' + 'instructions') + parser.add_argument('--extinst-glsl-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for GLSL extended ' + 'instruction set') + parser.add_argument('--extinst-opencl-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for OpenGL extended ' + 'instruction set') + parser.add_argument('--extinst-debuginfo-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for DebugInfo extended ' + 'instruction set') + args = parser.parse_args() + + # Generate the syntax rules. + print(PREAMBLE) + + core = json.loads(open(args.spirv_core_grammar).read()) + print('\n" Core instructions') + for inst in core["instructions"]: + EmitAsStatement(inst['opname']) + print('\n" Core operand enums') + for operand_kind in core["operand_kinds"]: + if 'enumerants' in operand_kind: + for e in operand_kind['enumerants']: + EmitAsEnumerant(e['enumerant']) + + if args.extinst_glsl_grammar is not None: + print('\n" GLSL.std.450 extended instructions') + glsl = json.loads(open(args.extinst_glsl_grammar).read()) + # These opcodes are really enumerant operands for the OpExtInst + # instruction. + for inst in glsl["instructions"]: + EmitAsEnumerant(inst['opname']) + + if args.extinst_opencl_grammar is not None: + print('\n" OpenCL.std extended instructions') + opencl = json.loads(open(args.extinst_opencl_grammar).read()) + for inst in opencl["instructions"]: + EmitAsEnumerant(inst['opname']) + + if args.extinst_debuginfo_grammar is not None: + print('\n" DebugInfo extended instructions') + debuginfo = json.loads(open(args.extinst_debuginfo_grammar).read()) + for inst in debuginfo["instructions"]: + EmitAsEnumerant(inst['opname']) + print('\n" DebugInfo operand enums') + for operand_kind in debuginfo["operand_kinds"]: + if 'enumerants' in operand_kind: + for e in operand_kind['enumerants']: + EmitAsEnumerant(e['enumerant']) + + print('\n" OpSpecConstantOp opcodes') + for word in SPEC_CONSTANT_OP_OPCODES.split(' '): + stripped = word.strip('\n,') + if stripped != "": + # Treat as an enumerant, but without the leading "Op" + EmitAsEnumerant(stripped[2:]) + print(POSTAMBLE) + + +if __name__ == '__main__': + main() diff --git a/thirdparty/glslang/External/spirv-tools/utils/git-sync-deps b/thirdparty/glslang/External/spirv-tools/utils/git-sync-deps new file mode 100644 index 000000000000..6549afb1e6d8 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/git-sync-deps @@ -0,0 +1,338 @@ +#!/usr/bin/env python3 +# Copyright 2014 Google Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Parse a DEPS file and git checkout all of the dependencies. +""" + +EXTRA_HELP = """ +Environment Variables: + GIT_EXECUTABLE: path to "git" binary; if unset, will look for one of + ['git', 'git.exe', 'git.bat'] in your default path. + + GIT_SYNC_DEPS_PATH: file to get the dependency list from; if unset, + will use the file ../DEPS relative to this script's directory. + + GIT_SYNC_DEPS_QUIET: if set to non-empty string, suppress messages. + +Git Config: + To disable syncing of a single repository: + cd path/to/repository + git config sync-deps.disable true + + To re-enable sync: + cd path/to/repository + git config --unset sync-deps.disable +""" + + +import argparse +import os +import re +import subprocess +import sys +import threading +from builtins import bytes + +def git_executable(): + """Find the git executable. + + Returns: + A triple: + A string suitable for passing to subprocess functions, or None. + The major version number + The minor version number + """ + envgit = os.environ.get('GIT_EXECUTABLE') + searchlist = ['git', 'git.exe', 'git.bat'] + if envgit: + searchlist.insert(0, envgit) + with open(os.devnull, 'w') as devnull: + for git in searchlist: + major=None + minor=None + try: + version_info = subprocess.check_output([git, '--version']).decode('utf-8') + match = re.search("^git version (\d+)\.(\d+)",version_info) + print("Using {}".format(version_info)) + if match: + major = int(match.group(1)) + minor = int(match.group(2)) + else: + continue + except (OSError,): + continue + return (git,major,minor) + return (None,0,0) + + +DEFAULT_DEPS_PATH = os.path.normpath( + os.path.join(os.path.dirname(__file__), os.pardir, 'DEPS')) + +def get_deps_os_str(deps_file): + parsed_deps = parse_file_to_dict(deps_file) + parts = [] + if 'deps_os' in parsed_deps: + for deps_os in parsed_deps['deps_os']: + parts.append(' [{}]]'.format(deps_os)) + return "\n".join(parts) + +def looks_like_raw_commit(commit): + return re.match('^[a-f0-9]{40}$', commit) is not None + +def git_repository_sync_is_disabled(git, directory): + try: + disable = subprocess.check_output( + [git, 'config', 'sync-deps.disable'], cwd=directory) + return disable.lower().strip() in ['true', '1', 'yes', 'on'] + except subprocess.CalledProcessError: + return False + + +def is_git_toplevel(git, directory): + """Return true iff the directory is the top level of a Git repository. + + Args: + git (string) the git executable + + directory (string) the path into which the repository + is expected to be checked out. + """ + try: + toplevel = subprocess.check_output( + [git, 'rev-parse', '--show-toplevel'], cwd=directory).strip() + return os.path.realpath(bytes(directory, 'utf8')) == os.path.realpath(toplevel) + except subprocess.CalledProcessError: + return False + + +def status(directory, checkoutable): + def truncate(s, length): + return s if len(s) <= length else '...' + s[-(length - 3):] + dlen = 36 + directory = truncate(directory, dlen) + checkoutable = truncate(checkoutable, 40) + sys.stdout.write('%-*s @ %s\n' % (dlen, directory, checkoutable)) + + +def git_checkout_to_directory(git, repo, checkoutable, directory, verbose, treeless): + """Checkout (and clone if needed) a Git repository. + + Args: + git (string) the git executable + + repo (string) the location of the repository, suitable + for passing to `git clone`. + + checkoutable (string) a tag, branch, or commit, suitable for + passing to `git checkout` + + directory (string) the path into which the repository + should be checked out. + + verbose (boolean): emit status info to stdout + + treeless (boolean): when true, clone without any trees. + + Raises an exception if any calls to git fail. + """ + if not os.path.isdir(directory): + # Use blobless or treeless checkouts for faster downloads. + # This defers some work to checkout time. + # https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/ + filter = ['--filter=tree:0'] if treeless else ['--filter=blob:none'] + # If the thing to check out looks like a tag (and not like a commit), + # then limit the checkout to that branch. + branch = [] if looks_like_raw_commit(checkoutable) else ['--branch={}'.format(checkoutable)] + subprocess.check_call( + [git, 'clone', '--quiet', '--single-branch'] + filter + branch + [repo, directory]) + + if not is_git_toplevel(git, directory): + # if the directory exists, but isn't a git repo, you will modify + # the parent repostory, which isn't what you want. + sys.stdout.write('%s\n IS NOT TOP-LEVEL GIT DIRECTORY.\n' % directory) + return + + # Check to see if this repo is disabled. Quick return. + if git_repository_sync_is_disabled(git, directory): + sys.stdout.write('%s\n SYNC IS DISABLED.\n' % directory) + return + + with open(os.devnull, 'w') as devnull: + # If this fails, we will fetch before trying again. Don't spam user + # with error information. + if 0 == subprocess.call([git, 'checkout', '--quiet', checkoutable], + cwd=directory, stderr=devnull): + # if this succeeds, skip slow `git fetch`. + if verbose: + status(directory, checkoutable) # Success. + return + + # If the repo has changed, always force use of the correct repo. + # If origin already points to repo, this is a quick no-op. + subprocess.check_call( + [git, 'remote', 'set-url', 'origin', repo], cwd=directory) + + subprocess.check_call([git, 'fetch', '--quiet'], cwd=directory) + + subprocess.check_call([git, 'checkout', '--quiet', checkoutable], cwd=directory) + + if verbose: + status(directory, checkoutable) # Success. + + +def parse_file_to_dict(path): + dictionary = {} + contents = open(path).read() + # Need to convert Var() to vars[], so that the DEPS is actually Python. Var() + # comes from Autoroller using gclient which has a slightly different DEPS + # format. + contents = re.sub(r"Var\((.*?)\)", r"vars[\1]", contents) + exec(contents, dictionary) + return dictionary + + +def git_sync_deps(deps_file_path, command_line_os_requests, verbose, treeless): + """Grab dependencies, with optional platform support. + + Args: + deps_file_path (string) Path to the DEPS file. + + command_line_os_requests (list of strings) Can be empty list. + List of strings that should each be a key in the deps_os + dictionary in the DEPS file. + + verbose (boolean): emit status info to stdout + + treeless (boolean): when true, clone as treeless instead of blobless + + Raises git Exceptions. + """ + (git,git_major,git_minor) = git_executable() + assert git + + # --filter=tree:0 is available in git 2.20 and later + if (git_major,git_minor) < (2,20): + print("disabling --treeless: git is older than v2.20") + treeless = False + + deps_file_directory = os.path.dirname(deps_file_path) + deps_file = parse_file_to_dict(deps_file_path) + dependencies = deps_file['deps'].copy() + os_specific_dependencies = deps_file.get('deps_os', dict()) + if 'all' in command_line_os_requests: + for value in list(os_specific_dependencies.values()): + dependencies.update(value) + else: + for os_name in command_line_os_requests: + # Add OS-specific dependencies + if os_name in os_specific_dependencies: + dependencies.update(os_specific_dependencies[os_name]) + for directory in dependencies: + for other_dir in dependencies: + if directory.startswith(other_dir + '/'): + raise Exception('%r is parent of %r' % (other_dir, directory)) + list_of_arg_lists = [] + for directory in sorted(dependencies): + if '@' in dependencies[directory]: + repo, checkoutable = dependencies[directory].split('@', 1) + else: + raise Exception("please specify commit or tag") + + relative_directory = os.path.join(deps_file_directory, directory) + + list_of_arg_lists.append( + (git, repo, checkoutable, relative_directory, verbose, treeless)) + + multithread(git_checkout_to_directory, list_of_arg_lists) + + for directory in deps_file.get('recursedeps', []): + recursive_path = os.path.join(deps_file_directory, directory, 'DEPS') + git_sync_deps(recursive_path, command_line_os_requests, verbose) + + +def multithread(function, list_of_arg_lists): + # for args in list_of_arg_lists: + # function(*args) + # return + threads = [] + for args in list_of_arg_lists: + thread = threading.Thread(None, function, None, args) + thread.start() + threads.append(thread) + for thread in threads: + thread.join() + + +def main(argv): + argparser = argparse.ArgumentParser( + prog = "git-sync-deps", + description = "Checkout git-based dependencies as specified by the DEPS file", + add_help=False # Because we want to print deps_os with -h option + ) + argparser.add_argument("--help", "-h", + action='store_true', + help="show this help message and exit") + argparser.add_argument("--deps", + default = os.environ.get('GIT_SYNC_DEPS_PATH', DEFAULT_DEPS_PATH), + help="location of the the DEPS file") + argparser.add_argument("--verbose", + default=not bool(os.environ.get('GIT_SYNC_DEPS_QUIET', False)), + action='store_true', + help="be verbose: print status messages") + argparser.add_argument("--treeless", + default=False, + action='store_true', + help=""" + Clone repos without trees (--filter=tree:0). + This is the fastest option for a build machine, + when you only need a single commit. + Defers getting objects until checking out a commit. + + The default is to clone with trees but without blobs. + + Only takes effect if using git 2.20 or later. + + See https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/ + """) + argparser.add_argument("os_requests",nargs="*", + help="OS requests, as keys in the deps_os dictionariy in the DEPS file") + + args = argparser.parse_args() + if args.help: + print(argparser.format_help()) + print(EXTRA_HELP) + print(get_deps_os_str(args.deps)) + return 0 + + git_sync_deps(args.deps, args.os_requests, args.verbose, args.treeless) + return 0 + + +if __name__ == '__main__': + exit(main(sys.argv[1:])) diff --git a/thirdparty/glslang/External/spirv-tools/utils/roll_deps.sh b/thirdparty/glslang/External/spirv-tools/utils/roll_deps.sh new file mode 100644 index 000000000000..d19ee000e5d1 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/roll_deps.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# Copyright (c) 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Attempts to roll all entries in DEPS to tip-of-tree and create a commit. +# +# Depends on roll-dep from depot_tools +# (https://chromium.googlesource.com/chromium/tools/depot_tools) being in PATH. + +set -eo pipefail + +function ExitIfIsInterestingError() { + local return_code=$1 + if [[ ${return_code} -ne 0 && ${return_code} -ne 2 ]]; then + exit ${return_code} + fi + return 0 +} + + +dependencies=("external/effcee/" + "external/googletest/" + "external/re2/" + "external/spirv-headers/") + + +branch="origin/main" + +# This script assumes it's parent directory is the repo root. +repo_path=$(dirname "$0")/.. + +cd "$repo_path" + +if [[ $(git diff --stat) != '' ]]; then + echo "Working tree is dirty, commit changes before attempting to roll DEPS" + exit 1 +fi + +echo "*** Ignore messages about running 'git cl upload' ***" + +old_head=$(git rev-parse HEAD) + +set +e + +for dep in ${dependencies[@]}; do + echo "Rolling $dep" + roll-dep --ignore-dirty-tree --roll-to="${branch}" "${dep}" + ExitIfIsInterestingError $? +done diff --git a/thirdparty/glslang/External/spirv-tools/utils/update_build_version.py b/thirdparty/glslang/External/spirv-tools/utils/update_build_version.py new file mode 100644 index 000000000000..bb66e18a5aca --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/update_build_version.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Updates an output file with version info unless the new content is the same +# as the existing content. +# +# Args: +# +# The output file will contain a line of text consisting of two C source syntax +# string literals separated by a comma: +# - The software version deduced from the given CHANGES file. +# - A longer string with the project name, the software version number, and +# git commit information for the CHANGES file's directory. The commit +# information is the output of "git describe" if that succeeds, or "git +# rev-parse HEAD" if that succeeds, or otherwise a message containing the +# phrase "unknown hash". +# The string contents are escaped as necessary. + +import datetime +import errno +import os +import os.path +import re +import subprocess +import logging +import sys +import time + +# Format of the output generated by this script. Example: +# "v2023.1", "SPIRV-Tools v2023.1 0fc5526f2b01a0cc89192c10cf8bef77f1007a62, 2023-01-18T14:51:49" +OUTPUT_FORMAT = '"{version_tag}", "SPIRV-Tools {version_tag} {description}"\n' + +def mkdir_p(directory): + """Make the directory, and all its ancestors as required. Any of the + directories are allowed to already exist.""" + + if directory == "": + # We're being asked to make the current directory. + return + + try: + os.makedirs(directory) + except OSError as e: + if e.errno == errno.EEXIST and os.path.isdir(directory): + pass + else: + raise + +def command_output(cmd, directory): + """Runs a command in a directory and returns its standard output stream. + + Returns (False, None) if the command fails to launch or otherwise fails. + """ + try: + # Set shell=True on Windows so that Chromium's git.bat can be found when + # 'git' is invoked. + p = subprocess.Popen(cmd, + cwd=directory, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=os.name == 'nt') + (stdout, _) = p.communicate() + if p.returncode != 0: + return False, None + except Exception as e: + return False, None + return p.returncode == 0, stdout + +def deduce_software_version(changes_file): + """Returns a tuple (success, software version number) parsed from the + given CHANGES file. + + Success is set to True if the software version could be deduced. + Software version is undefined if success if False. + Function expects the CHANGES file to describes most recent versions first. + """ + + # Match the first well-formed version-and-date line + # Allow trailing whitespace in the checked-out source code has + # unexpected carriage returns on a linefeed-only system such as + # Linux. + pattern = re.compile(r'^(v\d+\.\d+(-dev)?) \d\d\d\d-\d\d-\d\d\s*$') + with open(changes_file, mode='r') as f: + for line in f.readlines(): + match = pattern.match(line) + if match: + return True, match.group(1) + return False, None + + +def describe(repo_path): + """Returns a string describing the current Git HEAD version as descriptively + as possible. + + Runs 'git describe', or alternately 'git rev-parse HEAD', in directory. If + successful, returns the output; otherwise returns 'unknown hash, '.""" + + # if we're in a git repository, attempt to extract version info + success, output = command_output(["git", "rev-parse", "--show-toplevel"], repo_path) + if success: + success, output = command_output(["git", "describe", "--tags", "--match=v*", "--long"], repo_path) + if not success: + success, output = command_output(["git", "rev-parse", "HEAD"], repo_path) + + if success: + # decode() is needed here for Python3 compatibility. In Python2, + # str and bytes are the same type, but not in Python3. + # Popen.communicate() returns a bytes instance, which needs to be + # decoded into text data first in Python3. And this decode() won't + # hurt Python2. + return output.rstrip().decode() + + # This is the fallback case where git gives us no information, + # e.g. because the source tree might not be in a git tree or + # git is not available on the system. + # In this case, usually use a timestamp. However, to ensure + # reproducible builds, allow the builder to override the wall + # clock time with environment variable SOURCE_DATE_EPOCH + # containing a (presumably) fixed timestamp. + timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time())) + iso_date = datetime.datetime.fromtimestamp(timestamp, datetime.timezone.utc).isoformat() + return "unknown hash, {}".format(iso_date) + +def main(): + FORMAT = '%(asctime)s %(message)s' + logging.basicConfig(format="[%(asctime)s][%(levelname)-8s] %(message)s", datefmt="%H:%M:%S") + if len(sys.argv) != 3: + logging.error("usage: {} ".format(sys.argv[0])) + sys.exit(1) + + changes_file_path = os.path.realpath(sys.argv[1]) + output_file_path = sys.argv[2] + + success, version = deduce_software_version(changes_file_path) + if not success: + logging.error("Could not deduce latest release version from {}.".format(changes_file_path)) + sys.exit(1) + + repo_path = os.path.dirname(changes_file_path) + description = describe(repo_path) + content = OUTPUT_FORMAT.format(version_tag=version, description=description) + + # Escape file content. + content.replace('"', '\\"') + + if os.path.isfile(output_file_path): + with open(output_file_path, 'r') as f: + if content == f.read(): + return + + mkdir_p(os.path.dirname(output_file_path)) + with open(output_file_path, 'w') as f: + f.write(content) + +if __name__ == '__main__': + main() diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/.gitignore b/thirdparty/glslang/External/spirv-tools/utils/vscode/.gitignore new file mode 100644 index 000000000000..e934adfd1b9e --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/.gitignore @@ -0,0 +1 @@ +cache/ diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/README.md b/thirdparty/glslang/External/spirv-tools/utils/vscode/README.md new file mode 100644 index 000000000000..d7aa2b413227 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/README.md @@ -0,0 +1,25 @@ +# Visual Studio Code extension for SPIR-V disassembly files + +This directory holds a Visual Studio Code language server extension for SPIR-V assembly files (`.spvasm`) + +The extension supports: +* Syntax highlighting +* Jump to definition +* Find all references +* Symbol renaming +* Operand hover information +* Formatting + +## Dependencies + +In order to build and install the Visual Studio Code language server extension, you will need to install and have on your `PATH` the following dependencies: +* [`npm`](https://www.npmjs.com/) +* [`golang 1.16+`](https://golang.org/) + +## Installing (macOS / Linux) + +Run `install.sh` + +## Installing (Windows) + +Run `install.bat` diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/extension.js b/thirdparty/glslang/External/spirv-tools/utils/vscode/extension.js new file mode 100644 index 000000000000..e7fec2854403 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/extension.js @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var path = require('path'); +var vscode = require('vscode'); +var langClient = require('vscode-languageclient'); + +var LanguageClient = langClient.LanguageClient; + +// this method is called when your extension is activated +// your extension is activated the very first time the command is executed +function activate(context) { + let serverModule = path.join(context.extensionPath, 'langsvr'); + let debugOptions = {}; + + // If the extension is launched in debug mode then the debug server options are used + // Otherwise the run options are used + let serverOptions = { + run: { command: serverModule, transport: langClient.stdio }, + debug: { command: serverModule, transport: langClient.stdio, options: debugOptions } + } + + // Options to control the language client + let clientOptions = { + documentSelector: ['spirv'], + synchronize: { + // Synchronize the setting section 'spirv' to the server + configurationSection: 'spirv', + // Notify the server about file changes to .spvasm files contained in the workspace + fileEvents: vscode.workspace.createFileSystemWatcher('**/*.spvasm') + } + } + + // Create the language client and start the client. + let disposable = new LanguageClient('spirv', serverOptions, clientOptions).start(); + + // Push the disposable to the context's subscriptions so that the + // client can be deactivated on extension deactivation + context.subscriptions.push(disposable); + + // Set the language configuration here instead of a language configuration + // file to work around https://github.com/microsoft/vscode/issues/42649. + vscode.languages.setLanguageConfiguration("spirv", { + comments: { "lineComment": ";" }, + wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, + }); +} +exports.activate = activate; + +// this method is called when your extension is deactivated +function deactivate() { +} +exports.deactivate = deactivate; diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/go.mod b/thirdparty/glslang/External/spirv-tools/utils/vscode/go.mod new file mode 100644 index 000000000000..ea4901a44859 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/go.mod @@ -0,0 +1,8 @@ +module github.com/KhronosGroup/SPIRV-Tools/utils/vscode + +go 1.16 + +require ( + github.com/pkg/errors v0.9.1 + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 +) diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/go.sum b/thirdparty/glslang/External/spirv-tools/utils/vscode/go.sum new file mode 100644 index 000000000000..328c85785e16 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/go.sum @@ -0,0 +1,4 @@ +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/install.bat b/thirdparty/glslang/External/spirv-tools/utils/vscode/install.bat new file mode 100644 index 000000000000..aa06fa91a0b0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/install.bat @@ -0,0 +1,30 @@ +@REM Copyright (c) 2019 Google Inc. +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. + +@set EXT_PATH=%userprofile%\.vscode\extensions\google.spirvls-0.0.1 +@set ROOT_PATH=%~dp0 + +go run %ROOT_PATH%\src\tools\gen-grammar.go --cache %ROOT_PATH%\cache --template %ROOT_PATH%\spirv.json.tmpl --out %ROOT_PATH%\spirv.json +go run %ROOT_PATH%\src\tools\gen-grammar.go --cache %ROOT_PATH%\cache --template %ROOT_PATH%\src\schema\schema.go.tmpl --out %ROOT_PATH%\src\schema\schema.go + +if not exist %EXT_PATH% mkdir -p %EXT_PATH% +copy %ROOT_PATH%\extension.js %EXT_PATH% +copy %ROOT_PATH%\package.json %EXT_PATH% +copy %ROOT_PATH%\spirv.json %EXT_PATH% + +go build -o %EXT_PATH%\langsvr.exe %ROOT_PATH%\src\langsvr.go + +@pushd %EXT_PATH% +call npm install +@popd diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/install.sh b/thirdparty/glslang/External/spirv-tools/utils/vscode/install.sh new file mode 100644 index 000000000000..de54c62396c2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/install.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Copyright (c) 2019 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e # Fail on any error. + +EXT_PATH=~/.vscode/extensions/google.spirvls-0.0.1 +ROOT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +pushd ${ROOT_PATH} + go run ./src/tools/gen-grammar.go --cache ./cache --template ./spirv.json.tmpl --out ./spirv.json + go run ./src/tools/gen-grammar.go --cache ./cache --template ./src/schema/schema.go.tmpl --out ./src/schema/schema.go + + mkdir -p ${EXT_PATH} + cp ./extension.js ${EXT_PATH} + cp ./package.json ${EXT_PATH} + cp ./spirv.json ${EXT_PATH} + + go build -o ${EXT_PATH}/langsvr ./src/langsvr.go +popd + +cd ${EXT_PATH} +npm install diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/package.json b/thirdparty/glslang/External/spirv-tools/utils/vscode/package.json new file mode 100644 index 000000000000..b058ed18b6a0 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/package.json @@ -0,0 +1,39 @@ +{ + "name": "spirvls", + "description": "Language support for SPIR-V disassembly files", + "author": "Google", + "license": "Apache-2.0", + "version": "0.0.1", + "private": true, + "publisher": "Google", + "engines": { + "vscode": "^0.10.10" + }, + "categories": [ + "Programming Languages" + ], + "contributes": { + "languages": [ + { + "id": "spirv", + "extensions": [ + "spvasm" + ] + } + ], + "grammars": [ + { + "language": "spirv", + "scopeName": "source.spirv", + "path": "spirv.json" + } + ] + }, + "dependencies": { + "vscode-languageclient": "~4.3.0" + }, + "activationEvents": [ + "*" + ], + "main": "./extension.js" +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/spirv.json b/thirdparty/glslang/External/spirv-tools/utils/vscode/spirv.json new file mode 100644 index 000000000000..2e88296e0b9d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/spirv.json @@ -0,0 +1,267 @@ +{ + "scopeName": "source.spirv", + "name": "SPIR-V", + "comment": "Generated by gen-grammar.go --template=./spirv.json.tmpl --out=./spirv.json. Do not modify this file directly.", + "patterns": [ + { "include": "#BitEnum_ImageOperands" }, + { "include": "#BitEnum_FPFastMathMode" }, + { "include": "#BitEnum_SelectionControl" }, + { "include": "#BitEnum_LoopControl" }, + { "include": "#BitEnum_FunctionControl" }, + { "include": "#BitEnum_MemorySemantics" }, + { "include": "#BitEnum_MemoryAccess" }, + { "include": "#BitEnum_KernelProfilingInfo" }, + { "include": "#BitEnum_RayFlags" }, + { "include": "#ValueEnum_SourceLanguage" }, + { "include": "#ValueEnum_ExecutionModel" }, + { "include": "#ValueEnum_AddressingModel" }, + { "include": "#ValueEnum_MemoryModel" }, + { "include": "#ValueEnum_ExecutionMode" }, + { "include": "#ValueEnum_StorageClass" }, + { "include": "#ValueEnum_Dim" }, + { "include": "#ValueEnum_SamplerAddressingMode" }, + { "include": "#ValueEnum_SamplerFilterMode" }, + { "include": "#ValueEnum_ImageFormat" }, + { "include": "#ValueEnum_ImageChannelOrder" }, + { "include": "#ValueEnum_ImageChannelDataType" }, + { "include": "#ValueEnum_FPRoundingMode" }, + { "include": "#ValueEnum_LinkageType" }, + { "include": "#ValueEnum_AccessQualifier" }, + { "include": "#ValueEnum_FunctionParameterAttribute" }, + { "include": "#ValueEnum_Decoration" }, + { "include": "#ValueEnum_BuiltIn" }, + { "include": "#ValueEnum_Scope" }, + { "include": "#ValueEnum_GroupOperation" }, + { "include": "#ValueEnum_KernelEnqueueFlags" }, + { "include": "#ValueEnum_Capability" }, + { "include": "#ValueEnum_RayQueryIntersection" }, + { "include": "#ValueEnum_RayQueryCommittedIntersectionType" }, + { "include": "#ValueEnum_RayQueryCandidateIntersectionType" }, + { "include": "#BitEnum_DebugInfoFlags" }, + { "include": "#ValueEnum_DebugBaseTypeAttributeEncoding" }, + { "include": "#ValueEnum_DebugCompositeType" }, + { "include": "#ValueEnum_DebugTypeQualifier" }, + { "include": "#ValueEnum_DebugOperation" }, + { "include": "#ValueEnum_DebugImportedEntity" }, + { "include": "#opcode" }, + { "include": "#extopcode" }, + { "include": "#identifier" }, + { "include": "#number" }, + { "include": "#string" }, + { "include": "#comment" }, + { "include": "#operator" } + ], + "repository": { + "BitEnum_ImageOperands": { + "match": "\\b(None|Bias|Lod|Grad|ConstOffset|Offset|ConstOffsets|Sample|MinLod|MakeTexelAvailable|MakeTexelAvailableKHR|MakeTexelVisible|MakeTexelVisibleKHR|NonPrivateTexel|NonPrivateTexelKHR|VolatileTexel|VolatileTexelKHR|SignExtend|ZeroExtend)\\b", + "name": "keyword.spirv" + }, + "BitEnum_FPFastMathMode": { + "match": "\\b(None|NotNaN|NotInf|NSZ|AllowRecip|Fast)\\b", + "name": "keyword.spirv" + }, + "BitEnum_SelectionControl": { + "match": "\\b(None|Flatten|DontFlatten)\\b", + "name": "keyword.spirv" + }, + "BitEnum_LoopControl": { + "match": "\\b(None|Unroll|DontUnroll|DependencyInfinite|DependencyLength|MinIterations|MaxIterations|IterationMultiple|PeelCount|PartialCount)\\b", + "name": "keyword.spirv" + }, + "BitEnum_FunctionControl": { + "match": "\\b(None|Inline|DontInline|Pure|Const)\\b", + "name": "keyword.spirv" + }, + "BitEnum_MemorySemantics": { + "match": "\\b(Relaxed|None|Acquire|Release|AcquireRelease|SequentiallyConsistent|UniformMemory|SubgroupMemory|WorkgroupMemory|CrossWorkgroupMemory|AtomicCounterMemory|ImageMemory|OutputMemory|OutputMemoryKHR|MakeAvailable|MakeAvailableKHR|MakeVisible|MakeVisibleKHR|Volatile)\\b", + "name": "keyword.spirv" + }, + "BitEnum_MemoryAccess": { + "match": "\\b(None|Volatile|Aligned|Nontemporal|MakePointerAvailable|MakePointerAvailableKHR|MakePointerVisible|MakePointerVisibleKHR|NonPrivatePointer|NonPrivatePointerKHR)\\b", + "name": "keyword.spirv" + }, + "BitEnum_KernelProfilingInfo": { + "match": "\\b(None|CmdExecTime)\\b", + "name": "keyword.spirv" + }, + "BitEnum_RayFlags": { + "match": "\\b(NoneKHR|OpaqueKHR|NoOpaqueKHR|TerminateOnFirstHitKHR|SkipClosestHitShaderKHR|CullBackFacingTrianglesKHR|CullFrontFacingTrianglesKHR|CullOpaqueKHR|CullNoOpaqueKHR|SkipTrianglesKHR|SkipAABBsKHR)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_SourceLanguage": { + "match": "\\b(Unknown|ESSL|GLSL|OpenCL_C|OpenCL_CPP|HLSL)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_ExecutionModel": { + "match": "\\b(Vertex|TessellationControl|TessellationEvaluation|Geometry|Fragment|GLCompute|Kernel|TaskNV|MeshNV|RayGenerationNV|RayGenerationKHR|IntersectionNV|IntersectionKHR|AnyHitNV|AnyHitKHR|ClosestHitNV|ClosestHitKHR|MissNV|MissKHR|CallableNV|CallableKHR)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_AddressingModel": { + "match": "\\b(Logical|Physical32|Physical64|PhysicalStorageBuffer64|PhysicalStorageBuffer64EXT)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_MemoryModel": { + "match": "\\b(Simple|GLSL450|OpenCL|Vulkan|VulkanKHR)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_ExecutionMode": { + "match": "\\b(Invocations|SpacingEqual|SpacingFractionalEven|SpacingFractionalOdd|VertexOrderCw|VertexOrderCcw|PixelCenterInteger|OriginUpperLeft|OriginLowerLeft|EarlyFragmentTests|PointMode|Xfb|DepthReplacing|DepthGreater|DepthLess|DepthUnchanged|LocalSize|LocalSizeHint|InputPoints|InputLines|InputLinesAdjacency|Triangles|InputTrianglesAdjacency|Quads|Isolines|OutputVertices|OutputPoints|OutputLineStrip|OutputTriangleStrip|VecTypeHint|ContractionOff|Initializer|Finalizer|SubgroupSize|SubgroupsPerWorkgroup|SubgroupsPerWorkgroupId|LocalSizeId|LocalSizeHintId|PostDepthCoverage|DenormPreserve|DenormFlushToZero|SignedZeroInfNanPreserve|RoundingModeRTE|RoundingModeRTZ|StencilRefReplacingEXT|OutputLinesNV|OutputPrimitivesNV|DerivativeGroupQuadsNV|DerivativeGroupLinearNV|OutputTrianglesNV|PixelInterlockOrderedEXT|PixelInterlockUnorderedEXT|SampleInterlockOrderedEXT|SampleInterlockUnorderedEXT|ShadingRateInterlockOrderedEXT|ShadingRateInterlockUnorderedEXT)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_StorageClass": { + "match": "\\b(UniformConstant|Input|Uniform|Output|Workgroup|CrossWorkgroup|Private|Function|Generic|PushConstant|AtomicCounter|Image|StorageBuffer|CallableDataNV|CallableDataKHR|IncomingCallableDataNV|IncomingCallableDataKHR|RayPayloadNV|RayPayloadKHR|HitAttributeNV|HitAttributeKHR|IncomingRayPayloadNV|IncomingRayPayloadKHR|ShaderRecordBufferNV|ShaderRecordBufferKHR|PhysicalStorageBuffer|PhysicalStorageBufferEXT)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_Dim": { + "match": "\\b(1D|2D|3D|Cube|Rect|Buffer|SubpassData)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_SamplerAddressingMode": { + "match": "\\b(None|ClampToEdge|Clamp|Repeat|RepeatMirrored)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_SamplerFilterMode": { + "match": "\\b(Nearest|Linear)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_ImageFormat": { + "match": "\\b(Unknown|Rgba32f|Rgba16f|R32f|Rgba8|Rgba8Snorm|Rg32f|Rg16f|R11fG11fB10f|R16f|Rgba16|Rgb10A2|Rg16|Rg8|R16|R8|Rgba16Snorm|Rg16Snorm|Rg8Snorm|R16Snorm|R8Snorm|Rgba32i|Rgba16i|Rgba8i|R32i|Rg32i|Rg16i|Rg8i|R16i|R8i|Rgba32ui|Rgba16ui|Rgba8ui|R32ui|Rgb10a2ui|Rg32ui|Rg16ui|Rg8ui|R16ui|R8ui)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_ImageChannelOrder": { + "match": "\\b(R|A|RG|RA|RGB|RGBA|BGRA|ARGB|Intensity|Luminance|Rx|RGx|RGBx|Depth|DepthStencil|sRGB|sRGBx|sRGBA|sBGRA|ABGR)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_ImageChannelDataType": { + "match": "\\b(SnormInt8|SnormInt16|UnormInt8|UnormInt16|UnormShort565|UnormShort555|UnormInt101010|SignedInt8|SignedInt16|SignedInt32|UnsignedInt8|UnsignedInt16|UnsignedInt32|HalfFloat|Float|UnormInt24|UnormInt101010_2)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_FPRoundingMode": { + "match": "\\b(RTE|RTZ|RTP|RTN)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_LinkageType": { + "match": "\\b(Export|Import)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_AccessQualifier": { + "match": "\\b(ReadOnly|WriteOnly|ReadWrite)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_FunctionParameterAttribute": { + "match": "\\b(Zext|Sext|ByVal|Sret|NoAlias|NoCapture|NoWrite|NoReadWrite)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_Decoration": { + "match": "\\b(RelaxedPrecision|SpecId|Block|BufferBlock|RowMajor|ColMajor|ArrayStride|MatrixStride|GLSLShared|GLSLPacked|CPacked|BuiltIn|NoPerspective|Flat|Patch|Centroid|Sample|Invariant|Restrict|Aliased|Volatile|Constant|Coherent|NonWritable|NonReadable|Uniform|UniformId|SaturatedConversion|Stream|Location|Component|Index|Binding|DescriptorSet|Offset|XfbBuffer|XfbStride|FuncParamAttr|FPRoundingMode|FPFastMathMode|LinkageAttributes|NoContraction|InputAttachmentIndex|Alignment|MaxByteOffset|AlignmentId|MaxByteOffsetId|NoSignedWrap|NoUnsignedWrap|ExplicitInterpAMD|OverrideCoverageNV|PassthroughNV|ViewportRelativeNV|SecondaryViewportRelativeNV|PerPrimitiveNV|PerViewNV|PerTaskNV|PerVertexNV|NonUniform|NonUniformEXT|RestrictPointer|RestrictPointerEXT|AliasedPointer|AliasedPointerEXT|CounterBuffer|HlslCounterBufferGOOGLE|UserSemantic|HlslSemanticGOOGLE|UserTypeGOOGLE)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_BuiltIn": { + "match": "\\b(Position|PointSize|ClipDistance|CullDistance|VertexId|InstanceId|PrimitiveId|InvocationId|Layer|ViewportIndex|TessLevelOuter|TessLevelInner|TessCoord|PatchVertices|FragCoord|PointCoord|FrontFacing|SampleId|SamplePosition|SampleMask|FragDepth|HelperInvocation|NumWorkgroups|WorkgroupSize|WorkgroupId|LocalInvocationId|GlobalInvocationId|LocalInvocationIndex|WorkDim|GlobalSize|EnqueuedWorkgroupSize|GlobalOffset|GlobalLinearId|SubgroupSize|SubgroupMaxSize|NumSubgroups|NumEnqueuedSubgroups|SubgroupId|SubgroupLocalInvocationId|VertexIndex|InstanceIndex|SubgroupEqMask|SubgroupGeMask|SubgroupGtMask|SubgroupLeMask|SubgroupLtMask|SubgroupEqMaskKHR|SubgroupGeMaskKHR|SubgroupGtMaskKHR|SubgroupLeMaskKHR|SubgroupLtMaskKHR|BaseVertex|BaseInstance|DrawIndex|DeviceIndex|ViewIndex|BaryCoordNoPerspAMD|BaryCoordNoPerspCentroidAMD|BaryCoordNoPerspSampleAMD|BaryCoordSmoothAMD|BaryCoordSmoothCentroidAMD|BaryCoordSmoothSampleAMD|BaryCoordPullModelAMD|FragStencilRefEXT|ViewportMaskNV|SecondaryPositionNV|SecondaryViewportMaskNV|PositionPerViewNV|ViewportMaskPerViewNV|FullyCoveredEXT|TaskCountNV|PrimitiveCountNV|PrimitiveIndicesNV|ClipDistancePerViewNV|CullDistancePerViewNV|LayerPerViewNV|MeshViewCountNV|MeshViewIndicesNV|BaryCoordNV|BaryCoordNoPerspNV|FragSizeEXT|FragmentSizeNV|FragInvocationCountEXT|InvocationsPerPixelNV|LaunchIdNV|LaunchIdKHR|LaunchSizeNV|LaunchSizeKHR|WorldRayOriginNV|WorldRayOriginKHR|WorldRayDirectionNV|WorldRayDirectionKHR|ObjectRayOriginNV|ObjectRayOriginKHR|ObjectRayDirectionNV|ObjectRayDirectionKHR|RayTminNV|RayTminKHR|RayTmaxNV|RayTmaxKHR|InstanceCustomIndexNV|InstanceCustomIndexKHR|ObjectToWorldNV|ObjectToWorldKHR|WorldToObjectNV|WorldToObjectKHR|HitTNV|HitTKHR|HitKindNV|HitKindKHR|IncomingRayFlagsNV|IncomingRayFlagsKHR|RayGeometryIndexKHR|WarpsPerSMNV|SMCountNV|WarpIDNV|SMIDNV)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_Scope": { + "match": "\\b(CrossDevice|Device|Workgroup|Subgroup|Invocation|QueueFamily|QueueFamilyKHR|ShaderCallKHR)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_GroupOperation": { + "match": "\\b(Reduce|InclusiveScan|ExclusiveScan|ClusteredReduce|PartitionedReduceNV|PartitionedInclusiveScanNV|PartitionedExclusiveScanNV)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_KernelEnqueueFlags": { + "match": "\\b(NoWait|WaitKernel|WaitWorkGroup)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_Capability": { + "match": "\\b(Matrix|Shader|Geometry|Tessellation|Addresses|Linkage|Kernel|Vector16|Float16Buffer|Float16|Float64|Int64|Int64Atomics|ImageBasic|ImageReadWrite|ImageMipmap|Pipes|Groups|DeviceEnqueue|LiteralSampler|AtomicStorage|Int16|TessellationPointSize|GeometryPointSize|ImageGatherExtended|StorageImageMultisample|UniformBufferArrayDynamicIndexing|SampledImageArrayDynamicIndexing|StorageBufferArrayDynamicIndexing|StorageImageArrayDynamicIndexing|ClipDistance|CullDistance|ImageCubeArray|SampleRateShading|ImageRect|SampledRect|GenericPointer|Int8|InputAttachment|SparseResidency|MinLod|Sampled1D|Image1D|SampledCubeArray|SampledBuffer|ImageBuffer|ImageMSArray|StorageImageExtendedFormats|ImageQuery|DerivativeControl|InterpolationFunction|TransformFeedback|GeometryStreams|StorageImageReadWithoutFormat|StorageImageWriteWithoutFormat|MultiViewport|SubgroupDispatch|NamedBarrier|PipeStorage|GroupNonUniform|GroupNonUniformVote|GroupNonUniformArithmetic|GroupNonUniformBallot|GroupNonUniformShuffle|GroupNonUniformShuffleRelative|GroupNonUniformClustered|GroupNonUniformQuad|ShaderLayer|ShaderViewportIndex|SubgroupBallotKHR|DrawParameters|SubgroupVoteKHR|StorageBuffer16BitAccess|StorageUniformBufferBlock16|UniformAndStorageBuffer16BitAccess|StorageUniform16|StoragePushConstant16|StorageInputOutput16|DeviceGroup|MultiView|VariablePointersStorageBuffer|VariablePointers|AtomicStorageOps|SampleMaskPostDepthCoverage|StorageBuffer8BitAccess|UniformAndStorageBuffer8BitAccess|StoragePushConstant8|DenormPreserve|DenormFlushToZero|SignedZeroInfNanPreserve|RoundingModeRTE|RoundingModeRTZ|RayQueryProvisionalKHR|RayTraversalPrimitiveCullingProvisionalKHR|Float16ImageAMD|ImageGatherBiasLodAMD|FragmentMaskAMD|StencilExportEXT|ImageReadWriteLodAMD|ShaderClockKHR|SampleMaskOverrideCoverageNV|GeometryShaderPassthroughNV|ShaderViewportIndexLayerEXT|ShaderViewportIndexLayerNV|ShaderViewportMaskNV|ShaderStereoViewNV|PerViewAttributesNV|FragmentFullyCoveredEXT|MeshShadingNV|ImageFootprintNV|FragmentBarycentricNV|ComputeDerivativeGroupQuadsNV|FragmentDensityEXT|ShadingRateNV|GroupNonUniformPartitionedNV|ShaderNonUniform|ShaderNonUniformEXT|RuntimeDescriptorArray|RuntimeDescriptorArrayEXT|InputAttachmentArrayDynamicIndexing|InputAttachmentArrayDynamicIndexingEXT|UniformTexelBufferArrayDynamicIndexing|UniformTexelBufferArrayDynamicIndexingEXT|StorageTexelBufferArrayDynamicIndexing|StorageTexelBufferArrayDynamicIndexingEXT|UniformBufferArrayNonUniformIndexing|UniformBufferArrayNonUniformIndexingEXT|SampledImageArrayNonUniformIndexing|SampledImageArrayNonUniformIndexingEXT|StorageBufferArrayNonUniformIndexing|StorageBufferArrayNonUniformIndexingEXT|StorageImageArrayNonUniformIndexing|StorageImageArrayNonUniformIndexingEXT|InputAttachmentArrayNonUniformIndexing|InputAttachmentArrayNonUniformIndexingEXT|UniformTexelBufferArrayNonUniformIndexing|UniformTexelBufferArrayNonUniformIndexingEXT|StorageTexelBufferArrayNonUniformIndexing|StorageTexelBufferArrayNonUniformIndexingEXT|RayTracingNV|VulkanMemoryModel|VulkanMemoryModelKHR|VulkanMemoryModelDeviceScope|VulkanMemoryModelDeviceScopeKHR|PhysicalStorageBufferAddresses|PhysicalStorageBufferAddressesEXT|ComputeDerivativeGroupLinearNV|RayTracingProvisionalKHR|CooperativeMatrixNV|FragmentShaderSampleInterlockEXT|FragmentShaderShadingRateInterlockEXT|ShaderSMBuiltinsNV|FragmentShaderPixelInterlockEXT|DemoteToHelperInvocationEXT|SubgroupShuffleINTEL|SubgroupBufferBlockIOINTEL|SubgroupImageBlockIOINTEL|SubgroupImageMediaBlockIOINTEL|IntegerFunctions2INTEL|SubgroupAvcMotionEstimationINTEL|SubgroupAvcMotionEstimationIntraINTEL|SubgroupAvcMotionEstimationChromaINTEL)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_RayQueryIntersection": { + "match": "\\b(RayQueryCandidateIntersectionKHR|RayQueryCommittedIntersectionKHR)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_RayQueryCommittedIntersectionType": { + "match": "\\b(RayQueryCommittedIntersectionNoneKHR|RayQueryCommittedIntersectionTriangleKHR|RayQueryCommittedIntersectionGeneratedKHR)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_RayQueryCandidateIntersectionType": { + "match": "\\b(RayQueryCandidateIntersectionTriangleKHR|RayQueryCandidateIntersectionAABBKHR)\\b", + "name": "keyword.spirv" + }, + "BitEnum_DebugInfoFlags": { + "match": "\\b(FlagIsProtected|FlagIsPrivate|FlagIsPublic|FlagIsLocal|FlagIsDefinition|FlagFwdDecl|FlagArtificial|FlagExplicit|FlagPrototyped|FlagObjectPointer|FlagStaticMember|FlagIndirectVariable|FlagLValueReference|FlagRValueReference|FlagIsOptimized|FlagIsEnumClass|FlagTypePassByValue|FlagTypePassByReference)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_DebugBaseTypeAttributeEncoding": { + "match": "\\b(Unspecified|Address|Boolean|Float|Signed|SignedChar|Unsigned|UnsignedChar)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_DebugCompositeType": { + "match": "\\b(Class|Structure|Union)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_DebugTypeQualifier": { + "match": "\\b(ConstType|VolatileType|RestrictType|AtomicType)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_DebugOperation": { + "match": "\\b(Deref|Plus|Minus|PlusUconst|BitPiece|Swap|Xderef|StackValue|Constu|Fragment)\\b", + "name": "keyword.spirv" + }, + "ValueEnum_DebugImportedEntity": { + "match": "\\b(ImportedModule|ImportedDeclaration)\\b", + "name": "keyword.spirv" + }, + "opcode": { + "match": "(Op[a-zA-Z]+)", + "name": "entity.name.function.spirv" + }, + "extopcode": { + "match": "(Round|RoundEven|Trunc|FAbs|SAbs|FSign|SSign|Floor|Ceil|Fract|Radians|Degrees|Sin|Cos|Tan|Asin|Acos|Atan|Sinh|Cosh|Tanh|Asinh|Acosh|Atanh|Atan2|Pow|Exp|Log|Exp2|Log2|Sqrt|InverseSqrt|Determinant|MatrixInverse|Modf|ModfStruct|FMin|UMin|SMin|FMax|UMax|SMax|FClamp|UClamp|SClamp|FMix|IMix|Step|SmoothStep|Fma|Frexp|FrexpStruct|Ldexp|PackSnorm4x8|PackUnorm4x8|PackSnorm2x16|PackUnorm2x16|PackHalf2x16|PackDouble2x32|UnpackSnorm2x16|UnpackUnorm2x16|UnpackHalf2x16|UnpackSnorm4x8|UnpackUnorm4x8|UnpackDouble2x32|Length|Distance|Cross|Normalize|FaceForward|Reflect|Refract|FindILsb|FindSMsb|FindUMsb|InterpolateAtCentroid|InterpolateAtSample|InterpolateAtOffset|NMin|NMax|NClamp|acos|acosh|acospi|asin|asinh|asinpi|atan|atan2|atanh|atanpi|atan2pi|cbrt|ceil|copysign|cos|cosh|cospi|erfc|erf|exp|exp2|exp10|expm1|fabs|fdim|floor|fma|fmax|fmin|fmod|fract|frexp|hypot|ilogb|ldexp|lgamma|lgamma_r|log|log2|log10|log1p|logb|mad|maxmag|minmag|modf|nan|nextafter|pow|pown|powr|remainder|remquo|rint|rootn|round|rsqrt|sin|sincos|sinh|sinpi|sqrt|tan|tanh|tanpi|tgamma|trunc|half_cos|half_divide|half_exp|half_exp2|half_exp10|half_log|half_log2|half_log10|half_powr|half_recip|half_rsqrt|half_sin|half_sqrt|half_tan|native_cos|native_divide|native_exp|native_exp2|native_exp10|native_log|native_log2|native_log10|native_powr|native_recip|native_rsqrt|native_sin|native_sqrt|native_tan|s_abs|s_abs_diff|s_add_sat|u_add_sat|s_hadd|u_hadd|s_rhadd|u_rhadd|s_clamp|u_clamp|clz|ctz|s_mad_hi|u_mad_sat|s_mad_sat|s_max|u_max|s_min|u_min|s_mul_hi|rotate|s_sub_sat|u_sub_sat|u_upsample|s_upsample|popcount|s_mad24|u_mad24|s_mul24|u_mul24|u_abs|u_abs_diff|u_mul_hi|u_mad_hi|fclamp|degrees|fmax_common|fmin_common|mix|radians|step|smoothstep|sign|cross|distance|length|normalize|fast_distance|fast_length|fast_normalize|bitselect|select|vloadn|vstoren|vload_half|vload_halfn|vstore_half|vstore_half_r|vstore_halfn|vstore_halfn_r|vloada_halfn|vstorea_halfn|vstorea_halfn_r|shuffle|shuffle2|printf|prefetch|DebugInfoNone|DebugCompilationUnit|DebugTypeBasic|DebugTypePointer|DebugTypeQualifier|DebugTypeArray|DebugTypeVector|DebugTypedef|DebugTypeFunction|DebugTypeEnum|DebugTypeComposite|DebugTypeMember|DebugTypeInheritance|DebugTypePtrToMember|DebugTypeTemplate|DebugTypeTemplateParameter|DebugTypeTemplateTemplateParameter|DebugTypeTemplateParameterPack|DebugGlobalVariable|DebugFunctionDeclaration|DebugFunction|DebugLexicalBlock|DebugLexicalBlockDiscriminator|DebugScope|DebugNoScope|DebugInlinedAt|DebugLocalVariable|DebugInlinedVariable|DebugDeclare|DebugValue|DebugOperation|DebugExpression|DebugMacroDef|DebugMacroUndef|DebugImportedEntity|DebugSource)", + "name": "entity.name.function.ext" + }, + "identifier": { + "match": "%[a-zA-Z0-9_]+", + "name": "variable.spirv" + }, + "number": { + "match": "\\b[0-9]+.?[0-9]*\\b", + "name": "constant.numeric.spirv" + }, + "comment": { + "match": ";[^\n]*", + "name": "comment.line.spirv" + }, + "operator": { + "match": "=", + "name": "keyword.operator.spirv" + }, + "string": { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.spirv" + } + }, + "end": "\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.spirv" + } + }, + "name": "string.quoted.double.spirv", + "patterns": [ { "include": "#string_escaped_char" } ] + }, + "string_escaped_char": { + "patterns": [ + { + "match": "\\\\([0-7]{3}|[abfnrtv\\\\'\"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})", + "name": "constant.character.escape.spirv" + }, { + "match": "\\\\[^0-7xuUabfnrtv\\'\"]", + "name": "invalid.illegal.unknown-escape.spirv" + } + ] + } + } +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/spirv.json.tmpl b/thirdparty/glslang/External/spirv-tools/utils/vscode/spirv.json.tmpl new file mode 100644 index 000000000000..f655e521d173 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/spirv.json.tmpl @@ -0,0 +1,72 @@ +{ + "scopeName": "source.spirv", + "name": "SPIR-V", + "comment": "Generated by {{GenerateArguments}}. Do not modify this file directly.", + "patterns": [ +{{range $o := .All.OperandKinds}}{{if len $o.Enumerants}} { "include": "#{{$o.Category}}_{{$o.Kind}}" }, +{{end}}{{end}} { "include": "#opcode" }, + { "include": "#extopcode" }, + { "include": "#identifier" }, + { "include": "#number" }, + { "include": "#string" }, + { "include": "#comment" }, + { "include": "#operator" } + ], + "repository": { {{range $o := .All.OperandKinds}}{{if len $o.Enumerants}} + "{{$o.Category}}_{{$o.Kind}}": { + "match": "\\b({{OperandKindsMatch $o}})\\b", + "name": "keyword.spirv" + },{{end}}{{end}} + "opcode": { + "match": "(Op[a-zA-Z]+)", + "name": "entity.name.function.spirv" + }, + "extopcode": { + "match": "({{AllExtOpcodes}})", + "name": "entity.name.function.ext" + }, + "identifier": { + "match": "%[a-zA-Z0-9_]+", + "name": "variable.spirv" + }, + "number": { + "match": "\\b[0-9]+.?[0-9]*\\b", + "name": "constant.numeric.spirv" + }, + "comment": { + "match": ";[^\n]*", + "name": "comment.line.spirv" + }, + "operator": { + "match": "=", + "name": "keyword.operator.spirv" + }, + "string": { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.spirv" + } + }, + "end": "\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.spirv" + } + }, + "name": "string.quoted.double.spirv", + "patterns": [ { "include": "#string_escaped_char" } ] + }, + "string_escaped_char": { + "patterns": [ + { + "match": "\\\\([0-7]{3}|[abfnrtv\\\\'\"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})", + "name": "constant.character.escape.spirv" + }, { + "match": "\\\\[^0-7xuUabfnrtv\\'\"]", + "name": "invalid.illegal.unknown-escape.spirv" + } + ] + } + } +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/grammar/grammar.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/grammar/grammar.go new file mode 100644 index 000000000000..857a193e3c92 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/grammar/grammar.go @@ -0,0 +1,81 @@ +// Copyright (C) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package grammar holds the JSON type definitions for the SPIR-V grammar schema. +// +// See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html +// for more information. +package grammar + +// Root is the top-level structure of the JSON grammar. +type Root struct { + MagicNumber string `json:"magic_number"` + MajorVersion int `json:"major_version"` + MinorVersion int `json:"minor_version"` + Revision int `json:"revision"` + Instructions []Instruction `json:"instructions"` + OperandKinds []OperandKind `json:"operand_kinds"` +} + +// Instruction holds information about a specific SPIR-V instruction. +type Instruction struct { + Opname string `json:"opname"` + Class string `json:"class"` + Opcode int `json:"opcode"` + Operands []Operand `json:"operands"` +} + +// Operand contains information about a logical operand for an instruction. +type Operand struct { + Kind string `json:"kind"` + Name string `json:"name"` + Quantifier Quantifier `json:"quantifier"` +} + +// OperandKind contains information about a specific operand kind. +type OperandKind struct { + Category string `json:"category"` + Kind string `json:"kind"` + Enumerants []Enumerant `json:"enumerants"` + Bases []string `json:"bases"` +} + +// Enumerant contains information about an enumerant in an enum. +type Enumerant struct { + Enumerant string `json:"enumerant"` + Value interface{} `json:"value"` + Capabilities []string `json:"capabilities"` + Parameters []Parameter `json:"parameters"` + Version string `json:"version"` +} + +// Parameter contains information about a logical parameter for an enumerant. +type Parameter struct { + Kind string `json:"kind"` + Name string `json:"name"` +} + +// Quantifier indicates the number of times the quantified term may appear. +type Quantifier string + +const ( + // Once indicates the quantified term may appear exactly once. + Once Quantifier = "" + // ZeroOrOnce indicates the quantified term may appear zero or one + // time; an optional term. + ZeroOrOnce Quantifier = "?" + // ZeroOrMany indicates the quantified term may appear any number of + // times. + ZeroOrMany Quantifier = "*" +) diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/langsvr.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/langsvr.go new file mode 100644 index 000000000000..b76e35f78d53 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/langsvr.go @@ -0,0 +1,534 @@ +// Copyright (C) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// langsvr implements a Language Server for the SPIRV assembly language. +package main + +import ( + "context" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "path" + "sort" + "strings" + "sync" + "unicode/utf8" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/parser" + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/schema" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/jsonrpc2" + lsp "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/protocol" +) + +const ( + enableDebugLogging = false +) + +// rSpy is a reader 'spy' that wraps an io.Reader, and logs all data that passes +// through it. +type rSpy struct { + prefix string + r io.Reader +} + +func (s rSpy) Read(p []byte) (n int, err error) { + n, err = s.r.Read(p) + log.Printf("%v %v", s.prefix, string(p[:n])) + return n, err +} + +// wSpy is a reader 'spy' that wraps an io.Writer, and logs all data that passes +// through it. +type wSpy struct { + prefix string + w io.Writer +} + +func (s wSpy) Write(p []byte) (n int, err error) { + n, err = s.w.Write(p) + log.Printf("%v %v", s.prefix, string(p)) + return n, err +} + +// main entry point. +func main() { + log.SetOutput(ioutil.Discard) + if enableDebugLogging { + // create a log file in the executable's directory. + if logfile, err := os.Create(path.Join(path.Dir(os.Args[0]), "log.txt")); err == nil { + defer logfile.Close() + log.SetOutput(logfile) + } + } + + log.Println("language server started") + + stream := jsonrpc2.NewHeaderStream(rSpy{"IDE", os.Stdin}, wSpy{"LS", os.Stdout}) + s := server{ + files: map[string]*file{}, + } + s.ctx, s.conn, s.client = lsp.NewServer(context.Background(), stream, &s) + if err := s.conn.Run(s.ctx); err != nil { + log.Panicln(err) + os.Exit(1) + } + + log.Println("language server stopped") +} + +type server struct { + ctx context.Context + conn *jsonrpc2.Conn + client lsp.Client + + files map[string]*file + filesMutex sync.Mutex +} + +// file represents a source file +type file struct { + fullRange parser.Range + res parser.Results +} + +// tokAt returns the parser token at the given position lp +func (f *file) tokAt(lp lsp.Position) *parser.Token { + toks := f.res.Tokens + p := parser.Position{Line: int(lp.Line) + 1, Column: int(lp.Character) + 1} + i := sort.Search(len(toks), func(i int) bool { return p.LessThan(toks[i].Range.End) }) + if i == len(toks) { + return nil + } + if toks[i].Range.Contains(p) { + return toks[i] + } + return nil +} + +func (s *server) DidChangeWorkspaceFolders(ctx context.Context, p *lsp.DidChangeWorkspaceFoldersParams) error { + log.Println("server.DidChangeWorkspaceFolders()") + return nil +} +func (s *server) Initialized(ctx context.Context, p *lsp.InitializedParams) error { + log.Println("server.Initialized()") + return nil +} +func (s *server) Exit(ctx context.Context) error { + log.Println("server.Exit()") + return nil +} +func (s *server) DidChangeConfiguration(ctx context.Context, p *lsp.DidChangeConfigurationParams) error { + log.Println("server.DidChangeConfiguration()") + return nil +} +func (s *server) DidOpen(ctx context.Context, p *lsp.DidOpenTextDocumentParams) error { + log.Println("server.DidOpen()") + return s.processFile(ctx, p.TextDocument.URI, p.TextDocument.Text) +} +func (s *server) DidChange(ctx context.Context, p *lsp.DidChangeTextDocumentParams) error { + log.Println("server.DidChange()") + return s.processFile(ctx, p.TextDocument.URI, p.ContentChanges[0].Text) +} +func (s *server) DidClose(ctx context.Context, p *lsp.DidCloseTextDocumentParams) error { + log.Println("server.DidClose()") + return nil +} +func (s *server) DidSave(ctx context.Context, p *lsp.DidSaveTextDocumentParams) error { + log.Println("server.DidSave()") + return nil +} +func (s *server) WillSave(ctx context.Context, p *lsp.WillSaveTextDocumentParams) error { + log.Println("server.WillSave()") + return nil +} +func (s *server) DidChangeWatchedFiles(ctx context.Context, p *lsp.DidChangeWatchedFilesParams) error { + log.Println("server.DidChangeWatchedFiles()") + return nil +} +func (s *server) Progress(ctx context.Context, p *lsp.ProgressParams) error { + log.Println("server.Progress()") + return nil +} +func (s *server) SetTraceNotification(ctx context.Context, p *lsp.SetTraceParams) error { + log.Println("server.SetTraceNotification()") + return nil +} +func (s *server) LogTraceNotification(ctx context.Context, p *lsp.LogTraceParams) error { + log.Println("server.LogTraceNotification()") + return nil +} +func (s *server) Implementation(ctx context.Context, p *lsp.ImplementationParams) ([]lsp.Location, error) { + log.Println("server.Implementation()") + return nil, nil +} +func (s *server) TypeDefinition(ctx context.Context, p *lsp.TypeDefinitionParams) ([]lsp.Location, error) { + log.Println("server.TypeDefinition()") + return nil, nil +} +func (s *server) DocumentColor(ctx context.Context, p *lsp.DocumentColorParams) ([]lsp.ColorInformation, error) { + log.Println("server.DocumentColor()") + return nil, nil +} +func (s *server) ColorPresentation(ctx context.Context, p *lsp.ColorPresentationParams) ([]lsp.ColorPresentation, error) { + log.Println("server.ColorPresentation()") + return nil, nil +} +func (s *server) FoldingRange(ctx context.Context, p *lsp.FoldingRangeParams) ([]lsp.FoldingRange, error) { + log.Println("server.FoldingRange()") + return nil, nil +} +func (s *server) Declaration(ctx context.Context, p *lsp.DeclarationParams) ([]lsp.DeclarationLink, error) { + log.Println("server.Declaration()") + return nil, nil +} +func (s *server) SelectionRange(ctx context.Context, p *lsp.SelectionRangeParams) ([]lsp.SelectionRange, error) { + log.Println("server.SelectionRange()") + return nil, nil +} +func (s *server) Initialize(ctx context.Context, p *lsp.ParamInitia) (*lsp.InitializeResult, error) { + log.Println("server.Initialize()") + res := lsp.InitializeResult{ + Capabilities: lsp.ServerCapabilities{ + TextDocumentSync: lsp.TextDocumentSyncOptions{ + OpenClose: true, + Change: lsp.Full, // TODO: Implement incremental + }, + HoverProvider: true, + DefinitionProvider: true, + ReferencesProvider: true, + RenameProvider: true, + DocumentFormattingProvider: true, + }, + } + return &res, nil +} +func (s *server) Shutdown(ctx context.Context) error { + log.Println("server.Shutdown()") + return nil +} +func (s *server) WillSaveWaitUntil(ctx context.Context, p *lsp.WillSaveTextDocumentParams) ([]lsp.TextEdit, error) { + log.Println("server.WillSaveWaitUntil()") + return nil, nil +} +func (s *server) Completion(ctx context.Context, p *lsp.CompletionParams) (*lsp.CompletionList, error) { + log.Println("server.Completion()") + return nil, nil +} +func (s *server) Resolve(ctx context.Context, p *lsp.CompletionItem) (*lsp.CompletionItem, error) { + log.Println("server.Resolve()") + return nil, nil +} +func (s *server) Hover(ctx context.Context, p *lsp.HoverParams) (*lsp.Hover, error) { + log.Println("server.Hover()") + f := s.getFile(p.TextDocument.URI) + if f == nil { + return nil, fmt.Errorf("Unknown file") + } + + if tok := f.tokAt(p.Position); tok != nil { + sb := strings.Builder{} + switch v := f.res.Mappings[tok].(type) { + default: + sb.WriteString(fmt.Sprintf("", v)) + case *parser.Instruction: + sb.WriteString(fmt.Sprintf("```\n%v\n```", v.Opcode.Opname)) + case *parser.Identifier: + sb.WriteString(fmt.Sprintf("```\n%v\n```", v.Definition.Range.Text(f.res.Lines))) + case *parser.Operand: + if v.Name != "" { + sb.WriteString(strings.Trim(v.Name, `'`)) + sb.WriteString("\n\n") + } + + switch v.Kind.Category { + case schema.OperandCategoryBitEnum: + case schema.OperandCategoryValueEnum: + sb.WriteString("```\n") + sb.WriteString(strings.Trim(v.Kind.Kind, `'`)) + sb.WriteString("\n```") + case schema.OperandCategoryID: + if s := tok.Text(f.res.Lines); s != "" { + if id, ok := f.res.Identifiers[s]; ok && id.Definition != nil { + sb.WriteString("```\n") + sb.WriteString(id.Definition.Range.Text(f.res.Lines)) + sb.WriteString("\n```") + } + } + case schema.OperandCategoryLiteral: + case schema.OperandCategoryComposite: + } + case nil: + } + + if sb.Len() > 0 { + res := lsp.Hover{ + Contents: lsp.MarkupContent{ + Kind: "markdown", + Value: sb.String(), + }, + } + return &res, nil + } + } + + return nil, nil +} +func (s *server) SignatureHelp(ctx context.Context, p *lsp.SignatureHelpParams) (*lsp.SignatureHelp, error) { + log.Println("server.SignatureHelp()") + return nil, nil +} +func (s *server) Definition(ctx context.Context, p *lsp.DefinitionParams) ([]lsp.Location, error) { + log.Println("server.Definition()") + if f := s.getFile(p.TextDocument.URI); f != nil { + if tok := f.tokAt(p.Position); tok != nil { + if s := tok.Text(f.res.Lines); s != "" { + if id, ok := f.res.Identifiers[s]; ok { + loc := lsp.Location{ + URI: p.TextDocument.URI, + Range: rangeToLSP(id.Definition.Range), + } + return []lsp.Location{loc}, nil + } + } + } + } + return nil, nil +} +func (s *server) References(ctx context.Context, p *lsp.ReferenceParams) ([]lsp.Location, error) { + log.Println("server.References()") + if f := s.getFile(p.TextDocument.URI); f != nil { + if tok := f.tokAt(p.Position); tok != nil { + if s := tok.Text(f.res.Lines); s != "" { + if id, ok := f.res.Identifiers[s]; ok { + locs := make([]lsp.Location, len(id.References)) + for i, r := range id.References { + locs[i] = lsp.Location{ + URI: p.TextDocument.URI, + Range: rangeToLSP(r.Range), + } + } + return locs, nil + } + } + } + } + return nil, nil +} +func (s *server) DocumentHighlight(ctx context.Context, p *lsp.DocumentHighlightParams) ([]lsp.DocumentHighlight, error) { + log.Println("server.DocumentHighlight()") + return nil, nil +} +func (s *server) DocumentSymbol(ctx context.Context, p *lsp.DocumentSymbolParams) ([]lsp.DocumentSymbol, error) { + log.Println("server.DocumentSymbol()") + return nil, nil +} +func (s *server) CodeAction(ctx context.Context, p *lsp.CodeActionParams) ([]lsp.CodeAction, error) { + log.Println("server.CodeAction()") + return nil, nil +} +func (s *server) Symbol(ctx context.Context, p *lsp.WorkspaceSymbolParams) ([]lsp.SymbolInformation, error) { + log.Println("server.Symbol()") + return nil, nil +} +func (s *server) CodeLens(ctx context.Context, p *lsp.CodeLensParams) ([]lsp.CodeLens, error) { + log.Println("server.CodeLens()") + return nil, nil +} +func (s *server) ResolveCodeLens(ctx context.Context, p *lsp.CodeLens) (*lsp.CodeLens, error) { + log.Println("server.ResolveCodeLens()") + return nil, nil +} +func (s *server) DocumentLink(ctx context.Context, p *lsp.DocumentLinkParams) ([]lsp.DocumentLink, error) { + log.Println("server.DocumentLink()") + return nil, nil +} +func (s *server) ResolveDocumentLink(ctx context.Context, p *lsp.DocumentLink) (*lsp.DocumentLink, error) { + log.Println("server.ResolveDocumentLink()") + return nil, nil +} +func (s *server) Formatting(ctx context.Context, p *lsp.DocumentFormattingParams) ([]lsp.TextEdit, error) { + log.Println("server.Formatting()") + if f := s.getFile(p.TextDocument.URI); f != nil { + // Start by measuring the distance from the start of each line to the + // first opcode on that line. + lineInstOffsets, maxInstOffset, instOffset, curOffset := []int{}, 0, 0, -1 + for _, t := range f.res.Tokens { + curOffset++ // whitespace between tokens + switch t.Type { + case parser.Ident: + if _, isInst := schema.Opcodes[t.Text(f.res.Lines)]; isInst && instOffset == 0 { + instOffset = curOffset + continue + } + case parser.Newline: + lineInstOffsets = append(lineInstOffsets, instOffset) + if instOffset > maxInstOffset { + maxInstOffset = instOffset + } + curOffset, instOffset = -1, 0 + default: + curOffset += utf8.RuneCountInString(t.Text(f.res.Lines)) + } + } + lineInstOffsets = append(lineInstOffsets, instOffset) + + // Now rewrite each of the lines, adding padding at the start of the + // line for alignment. + sb, newline := strings.Builder{}, true + for _, t := range f.res.Tokens { + if newline { + newline = false + indent := maxInstOffset - lineInstOffsets[0] + lineInstOffsets = lineInstOffsets[1:] + switch t.Type { + case parser.Newline, parser.Comment: + default: + for s := 0; s < indent; s++ { + sb.WriteRune(' ') + } + } + } else if t.Type != parser.Newline { + sb.WriteString(" ") + } + + sb.WriteString(t.Text(f.res.Lines)) + if t.Type == parser.Newline { + newline = true + } + } + + formatted := sb.String() + + // Every good file ends with a single new line. + formatted = strings.TrimRight(formatted, "\n") + "\n" + + return []lsp.TextEdit{ + { + Range: rangeToLSP(f.fullRange), + NewText: formatted, + }, + }, nil + } + return nil, nil +} +func (s *server) RangeFormatting(ctx context.Context, p *lsp.DocumentRangeFormattingParams) ([]lsp.TextEdit, error) { + log.Println("server.RangeFormatting()") + return nil, nil +} +func (s *server) OnTypeFormatting(ctx context.Context, p *lsp.DocumentOnTypeFormattingParams) ([]lsp.TextEdit, error) { + log.Println("server.OnTypeFormatting()") + return nil, nil +} +func (s *server) Rename(ctx context.Context, p *lsp.RenameParams) (*lsp.WorkspaceEdit, error) { + log.Println("server.Rename()") + if f := s.getFile(p.TextDocument.URI); f != nil { + if tok := f.tokAt(p.Position); tok != nil { + if s := tok.Text(f.res.Lines); s != "" { + if id, ok := f.res.Identifiers[s]; ok { + changes := make([]lsp.TextEdit, len(id.References)) + for i, r := range id.References { + changes[i].Range = rangeToLSP(r.Range) + changes[i].NewText = p.NewName + } + m := map[string][]lsp.TextEdit{} + m[p.TextDocument.URI] = changes + return &lsp.WorkspaceEdit{Changes: &m}, nil + } + } + } + } + return nil, nil +} +func (s *server) PrepareRename(ctx context.Context, p *lsp.PrepareRenameParams) (*lsp.Range, error) { + log.Println("server.PrepareRename()") + return nil, nil +} +func (s *server) ExecuteCommand(ctx context.Context, p *lsp.ExecuteCommandParams) (interface{}, error) { + log.Println("server.ExecuteCommand()") + return nil, nil +} + +func (s *server) processFile(ctx context.Context, uri, source string) error { + log.Println("server.DidOpen()") + res, err := parser.Parse(source) + if err != nil { + return err + } + fullRange := parser.Range{ + Start: parser.Position{Line: 1, Column: 1}, + End: parser.Position{Line: len(res.Lines), Column: utf8.RuneCountInString(res.Lines[len(res.Lines)-1]) + 1}, + } + + s.filesMutex.Lock() + s.files[uri] = &file{ + fullRange: fullRange, + res: res, + } + s.filesMutex.Unlock() + + dp := lsp.PublishDiagnosticsParams{URI: uri, Diagnostics: make([]lsp.Diagnostic, len(res.Diagnostics))} + for i, d := range res.Diagnostics { + dp.Diagnostics[i] = diagnosticToLSP(d) + } + s.client.PublishDiagnostics(ctx, &dp) + return nil +} + +func (s *server) getFile(uri string) *file { + s.filesMutex.Lock() + defer s.filesMutex.Unlock() + return s.files[uri] +} + +func diagnosticToLSP(d parser.Diagnostic) lsp.Diagnostic { + return lsp.Diagnostic{ + Range: rangeToLSP(d.Range), + Severity: severityToLSP(d.Severity), + Message: d.Message, + } +} + +func severityToLSP(s parser.Severity) lsp.DiagnosticSeverity { + switch s { + case parser.SeverityError: + return lsp.SeverityError + case parser.SeverityWarning: + return lsp.SeverityWarning + case parser.SeverityInformation: + return lsp.SeverityInformation + case parser.SeverityHint: + return lsp.SeverityHint + default: + log.Panicf("Invalid severity '%d'", int(s)) + return lsp.SeverityError + } +} + +func rangeToLSP(r parser.Range) lsp.Range { + return lsp.Range{ + Start: positionToLSP(r.Start), + End: positionToLSP(r.End), + } +} + +func positionToLSP(r parser.Position) lsp.Position { + return lsp.Position{ + Line: float64(r.Line - 1), + Character: float64(r.Column - 1), + } +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/LICENSE b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/README.md b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/README.md new file mode 100644 index 000000000000..c78f183f3476 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/README.md @@ -0,0 +1,5 @@ +This directory contains code forked from https://github.com/golang/tools/tree/master/internal/lsp. + +This code has been modified to remove unneeded features and dependencies. + +Submitted on behalf of a third-party: The Go Authors diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/handler.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/handler.go new file mode 100644 index 000000000000..20d484178f01 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/handler.go @@ -0,0 +1,134 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package jsonrpc2 + +import ( + "context" +) + +// Handler is the interface used to hook into the message handling of an rpc +// connection. +type Handler interface { + // Deliver is invoked to handle incoming requests. + // If the request returns false from IsNotify then the Handler must eventually + // call Reply on the Conn with the supplied request. + // Handlers are called synchronously, they should pass the work off to a go + // routine if they are going to take a long time. + // If Deliver returns true all subsequent handlers will be invoked with + // delivered set to true, and should not attempt to deliver the message. + Deliver(ctx context.Context, r *Request, delivered bool) bool + + // Cancel is invoked for cancelled outgoing requests. + // It is okay to use the connection to send notifications, but the context will + // be in the cancelled state, so you must do it with the background context + // instead. + // If Cancel returns true all subsequent handlers will be invoked with + // cancelled set to true, and should not attempt to cancel the message. + Cancel(ctx context.Context, conn *Conn, id ID, cancelled bool) bool + + // Log is invoked for all messages flowing through a Conn. + // direction indicates if the message being received or sent + // id is the message id, if not set it was a notification + // elapsed is the time between a call being seen and the response, and is + // negative for anything that is not a response. + // method is the method name specified in the message + // payload is the parameters for a call or notification, and the result for a + // response + + // Request is called near the start of processing any request. + Request(ctx context.Context, conn *Conn, direction Direction, r *WireRequest) context.Context + // Response is called near the start of processing any response. + Response(ctx context.Context, conn *Conn, direction Direction, r *WireResponse) context.Context + // Done is called when any request is fully processed. + // For calls, this means the response has also been processed, for notifies + // this is as soon as the message has been written to the stream. + // If err is set, it implies the request failed. + Done(ctx context.Context, err error) + // Read is called with a count each time some data is read from the stream. + // The read calls are delayed until after the data has been interpreted so + // that it can be attributed to a request/response. + Read(ctx context.Context, bytes int64) context.Context + // Wrote is called each time some data is written to the stream. + Wrote(ctx context.Context, bytes int64) context.Context + // Error is called with errors that cannot be delivered through the normal + // mechanisms, for instance a failure to process a notify cannot be delivered + // back to the other party. + Error(ctx context.Context, err error) +} + +// Direction is used to indicate to a logger whether the logged message was being +// sent or received. +type Direction bool + +const ( + // Send indicates the message is outgoing. + Send = Direction(true) + // Receive indicates the message is incoming. + Receive = Direction(false) +) + +func (d Direction) String() string { + switch d { + case Send: + return "send" + case Receive: + return "receive" + default: + panic("unreachable") + } +} + +type EmptyHandler struct{} + +func (EmptyHandler) Deliver(ctx context.Context, r *Request, delivered bool) bool { + return false +} + +func (EmptyHandler) Cancel(ctx context.Context, conn *Conn, id ID, cancelled bool) bool { + return false +} + +func (EmptyHandler) Request(ctx context.Context, conn *Conn, direction Direction, r *WireRequest) context.Context { + return ctx +} + +func (EmptyHandler) Response(ctx context.Context, conn *Conn, direction Direction, r *WireResponse) context.Context { + return ctx +} + +func (EmptyHandler) Done(ctx context.Context, err error) { +} + +func (EmptyHandler) Read(ctx context.Context, bytes int64) context.Context { + return ctx +} + +func (EmptyHandler) Wrote(ctx context.Context, bytes int64) context.Context { + return ctx +} + +func (EmptyHandler) Error(ctx context.Context, err error) {} + +type defaultHandler struct{ EmptyHandler } + +func (defaultHandler) Deliver(ctx context.Context, r *Request, delivered bool) bool { + if delivered { + return false + } + if !r.IsNotify() { + r.Reply(ctx, nil, NewErrorf(CodeMethodNotFound, "method %q not found", r.Method)) + } + return true +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/jsonrpc2.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/jsonrpc2.go new file mode 100644 index 000000000000..44dd2205ee4d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/jsonrpc2.go @@ -0,0 +1,416 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package jsonrpc2 is a minimal implementation of the JSON RPC 2 spec. +// https://www.jsonrpc.org/specification +// It is intended to be compatible with other implementations at the wire level. +package jsonrpc2 + +import ( + "context" + "encoding/json" + "fmt" + "sync" + "sync/atomic" +) + +// Conn is a JSON RPC 2 client server connection. +// Conn is bidirectional; it does not have a designated server or client end. +type Conn struct { + seq int64 // must only be accessed using atomic operations + handlers []Handler + stream Stream + err error + pendingMu sync.Mutex // protects the pending map + pending map[ID]chan *WireResponse + handlingMu sync.Mutex // protects the handling map + handling map[ID]*Request +} + +type requestState int + +const ( + requestWaiting = requestState(iota) + requestSerial + requestParallel + requestReplied + requestDone +) + +// Request is sent to a server to represent a Call or Notify operation. +type Request struct { + conn *Conn + cancel context.CancelFunc + state requestState + nextRequest chan struct{} + + // The Wire values of the request. + WireRequest +} + +// NewErrorf builds a Error struct for the supplied message and code. +// If args is not empty, message and args will be passed to Sprintf. +func NewErrorf(code int64, format string, args ...interface{}) *Error { + return &Error{ + Code: code, + Message: fmt.Sprintf(format, args...), + } +} + +// NewConn creates a new connection object around the supplied stream. +// You must call Run for the connection to be active. +func NewConn(s Stream) *Conn { + conn := &Conn{ + handlers: []Handler{defaultHandler{}}, + stream: s, + pending: make(map[ID]chan *WireResponse), + handling: make(map[ID]*Request), + } + return conn +} + +// AddHandler adds a new handler to the set the connection will invoke. +// Handlers are invoked in the reverse order of how they were added, this +// allows the most recent addition to be the first one to attempt to handle a +// message. +func (c *Conn) AddHandler(handler Handler) { + // prepend the new handlers so we use them first + c.handlers = append([]Handler{handler}, c.handlers...) +} + +// Cancel cancels a pending Call on the server side. +// The call is identified by its id. +// JSON RPC 2 does not specify a cancel message, so cancellation support is not +// directly wired in. This method allows a higher level protocol to choose how +// to propagate the cancel. +func (c *Conn) Cancel(id ID) { + c.handlingMu.Lock() + handling, found := c.handling[id] + c.handlingMu.Unlock() + if found { + handling.cancel() + } +} + +// Notify is called to send a notification request over the connection. +// It will return as soon as the notification has been sent, as no response is +// possible. +func (c *Conn) Notify(ctx context.Context, method string, params interface{}) (err error) { + jsonParams, err := marshalToRaw(params) + if err != nil { + return fmt.Errorf("marshalling notify parameters: %v", err) + } + request := &WireRequest{ + Method: method, + Params: jsonParams, + } + data, err := json.Marshal(request) + if err != nil { + return fmt.Errorf("marshalling notify request: %v", err) + } + for _, h := range c.handlers { + ctx = h.Request(ctx, c, Send, request) + } + defer func() { + for _, h := range c.handlers { + h.Done(ctx, err) + } + }() + n, err := c.stream.Write(ctx, data) + for _, h := range c.handlers { + ctx = h.Wrote(ctx, n) + } + return err +} + +// Call sends a request over the connection and then waits for a response. +// If the response is not an error, it will be decoded into result. +// result must be of a type you an pass to json.Unmarshal. +func (c *Conn) Call(ctx context.Context, method string, params, result interface{}) (err error) { + // generate a new request identifier + id := ID{Number: atomic.AddInt64(&c.seq, 1)} + jsonParams, err := marshalToRaw(params) + if err != nil { + return fmt.Errorf("marshalling call parameters: %v", err) + } + request := &WireRequest{ + ID: &id, + Method: method, + Params: jsonParams, + } + // marshal the request now it is complete + data, err := json.Marshal(request) + if err != nil { + return fmt.Errorf("marshalling call request: %v", err) + } + for _, h := range c.handlers { + ctx = h.Request(ctx, c, Send, request) + } + // we have to add ourselves to the pending map before we send, otherwise we + // are racing the response + rchan := make(chan *WireResponse) + c.pendingMu.Lock() + c.pending[id] = rchan + c.pendingMu.Unlock() + defer func() { + // clean up the pending response handler on the way out + c.pendingMu.Lock() + delete(c.pending, id) + c.pendingMu.Unlock() + for _, h := range c.handlers { + h.Done(ctx, err) + } + }() + // now we are ready to send + n, err := c.stream.Write(ctx, data) + for _, h := range c.handlers { + ctx = h.Wrote(ctx, n) + } + if err != nil { + // sending failed, we will never get a response, so don't leave it pending + return err + } + // now wait for the response + select { + case response := <-rchan: + for _, h := range c.handlers { + ctx = h.Response(ctx, c, Receive, response) + } + // is it an error response? + if response.Error != nil { + return response.Error + } + if result == nil || response.Result == nil { + return nil + } + if err := json.Unmarshal(*response.Result, result); err != nil { + return fmt.Errorf("unmarshalling result: %v", err) + } + return nil + case <-ctx.Done(): + // allow the handler to propagate the cancel + cancelled := false + for _, h := range c.handlers { + if h.Cancel(ctx, c, id, cancelled) { + cancelled = true + } + } + return ctx.Err() + } +} + +// Conn returns the connection that created this request. +func (r *Request) Conn() *Conn { return r.conn } + +// IsNotify returns true if this request is a notification. +func (r *Request) IsNotify() bool { + return r.ID == nil +} + +// Parallel indicates that the system is now allowed to process other requests +// in parallel with this one. +// It is safe to call any number of times, but must only be called from the +// request handling go routine. +// It is implied by both reply and by the handler returning. +func (r *Request) Parallel() { + if r.state >= requestParallel { + return + } + r.state = requestParallel + close(r.nextRequest) +} + +// Reply sends a reply to the given request. +// It is an error to call this if request was not a call. +// You must call this exactly once for any given request. +// It should only be called from the handler go routine. +// If err is set then result will be ignored. +// If the request has not yet dropped into parallel mode +// it will be before this function returns. +func (r *Request) Reply(ctx context.Context, result interface{}, err error) error { + if r.state >= requestReplied { + return fmt.Errorf("reply invoked more than once") + } + if r.IsNotify() { + return fmt.Errorf("reply not invoked with a valid call") + } + // reply ends the handling phase of a call, so if we are not yet + // parallel we should be now. The go routine is allowed to continue + // to do work after replying, which is why it is important to unlock + // the rpc system at this point. + r.Parallel() + r.state = requestReplied + + var raw *json.RawMessage + if err == nil { + raw, err = marshalToRaw(result) + } + response := &WireResponse{ + Result: raw, + ID: r.ID, + } + if err != nil { + if callErr, ok := err.(*Error); ok { + response.Error = callErr + } else { + response.Error = NewErrorf(0, "%s", err) + } + } + data, err := json.Marshal(response) + if err != nil { + return err + } + for _, h := range r.conn.handlers { + ctx = h.Response(ctx, r.conn, Send, response) + } + n, err := r.conn.stream.Write(ctx, data) + for _, h := range r.conn.handlers { + ctx = h.Wrote(ctx, n) + } + + if err != nil { + // TODO(iancottrell): if a stream write fails, we really need to shut down + // the whole stream + return err + } + return nil +} + +func (c *Conn) setHandling(r *Request, active bool) { + if r.ID == nil { + return + } + r.conn.handlingMu.Lock() + defer r.conn.handlingMu.Unlock() + if active { + r.conn.handling[*r.ID] = r + } else { + delete(r.conn.handling, *r.ID) + } +} + +// combined has all the fields of both Request and Response. +// We can decode this and then work out which it is. +type combined struct { + VersionTag VersionTag `json:"jsonrpc"` + ID *ID `json:"id,omitempty"` + Method string `json:"method"` + Params *json.RawMessage `json:"params,omitempty"` + Result *json.RawMessage `json:"result,omitempty"` + Error *Error `json:"error,omitempty"` +} + +// Run blocks until the connection is terminated, and returns any error that +// caused the termination. +// It must be called exactly once for each Conn. +// It returns only when the reader is closed or there is an error in the stream. +func (c *Conn) Run(runCtx context.Context) error { + // we need to make the next request "lock" in an unlocked state to allow + // the first incoming request to proceed. All later requests are unlocked + // by the preceding request going to parallel mode. + nextRequest := make(chan struct{}) + close(nextRequest) + for { + // get the data for a message + data, n, err := c.stream.Read(runCtx) + if err != nil { + // the stream failed, we cannot continue + return err + } + // read a combined message + msg := &combined{} + if err := json.Unmarshal(data, msg); err != nil { + // a badly formed message arrived, log it and continue + // we trust the stream to have isolated the error to just this message + for _, h := range c.handlers { + h.Error(runCtx, fmt.Errorf("unmarshal failed: %v", err)) + } + continue + } + // work out which kind of message we have + switch { + case msg.Method != "": + // if method is set it must be a request + reqCtx, cancelReq := context.WithCancel(runCtx) + thisRequest := nextRequest + nextRequest = make(chan struct{}) + req := &Request{ + conn: c, + cancel: cancelReq, + nextRequest: nextRequest, + WireRequest: WireRequest{ + VersionTag: msg.VersionTag, + Method: msg.Method, + Params: msg.Params, + ID: msg.ID, + }, + } + for _, h := range c.handlers { + reqCtx = h.Request(reqCtx, c, Receive, &req.WireRequest) + reqCtx = h.Read(reqCtx, n) + } + c.setHandling(req, true) + go func() { + <-thisRequest + req.state = requestSerial + defer func() { + c.setHandling(req, false) + if !req.IsNotify() && req.state < requestReplied { + req.Reply(reqCtx, nil, NewErrorf(CodeInternalError, "method %q did not reply", req.Method)) + } + req.Parallel() + for _, h := range c.handlers { + h.Done(reqCtx, err) + } + cancelReq() + }() + delivered := false + for _, h := range c.handlers { + if h.Deliver(reqCtx, req, delivered) { + delivered = true + } + } + }() + case msg.ID != nil: + // we have a response, get the pending entry from the map + c.pendingMu.Lock() + rchan := c.pending[*msg.ID] + if rchan != nil { + delete(c.pending, *msg.ID) + } + c.pendingMu.Unlock() + // and send the reply to the channel + response := &WireResponse{ + Result: msg.Result, + Error: msg.Error, + ID: msg.ID, + } + rchan <- response + close(rchan) + default: + for _, h := range c.handlers { + h.Error(runCtx, fmt.Errorf("message not a call, notify or response, ignoring")) + } + } + } +} + +func marshalToRaw(obj interface{}) (*json.RawMessage, error) { + data, err := json.Marshal(obj) + if err != nil { + return nil, err + } + raw := json.RawMessage(data) + return &raw, nil +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/stream.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/stream.go new file mode 100644 index 000000000000..2c6ad6dfdcf3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/stream.go @@ -0,0 +1,160 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package jsonrpc2 + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "io" + "strconv" + "strings" + "sync" +) + +// Stream abstracts the transport mechanics from the JSON RPC protocol. +// A Conn reads and writes messages using the stream it was provided on +// construction, and assumes that each call to Read or Write fully transfers +// a single message, or returns an error. +type Stream interface { + // Read gets the next message from the stream. + // It is never called concurrently. + Read(context.Context) ([]byte, int64, error) + // Write sends a message to the stream. + // It must be safe for concurrent use. + Write(context.Context, []byte) (int64, error) +} + +// NewStream returns a Stream built on top of an io.Reader and io.Writer +// The messages are sent with no wrapping, and rely on json decode consistency +// to determine message boundaries. +func NewStream(in io.Reader, out io.Writer) Stream { + return &plainStream{ + in: json.NewDecoder(in), + out: out, + } +} + +type plainStream struct { + in *json.Decoder + outMu sync.Mutex + out io.Writer +} + +func (s *plainStream) Read(ctx context.Context) ([]byte, int64, error) { + select { + case <-ctx.Done(): + return nil, 0, ctx.Err() + default: + } + var raw json.RawMessage + if err := s.in.Decode(&raw); err != nil { + return nil, 0, err + } + return raw, int64(len(raw)), nil +} + +func (s *plainStream) Write(ctx context.Context, data []byte) (int64, error) { + select { + case <-ctx.Done(): + return 0, ctx.Err() + default: + } + s.outMu.Lock() + n, err := s.out.Write(data) + s.outMu.Unlock() + return int64(n), err +} + +// NewHeaderStream returns a Stream built on top of an io.Reader and io.Writer +// The messages are sent with HTTP content length and MIME type headers. +// This is the format used by LSP and others. +func NewHeaderStream(in io.Reader, out io.Writer) Stream { + return &headerStream{ + in: bufio.NewReader(in), + out: out, + } +} + +type headerStream struct { + in *bufio.Reader + outMu sync.Mutex + out io.Writer +} + +func (s *headerStream) Read(ctx context.Context) ([]byte, int64, error) { + select { + case <-ctx.Done(): + return nil, 0, ctx.Err() + default: + } + var total, length int64 + // read the header, stop on the first empty line + for { + line, err := s.in.ReadString('\n') + total += int64(len(line)) + if err != nil { + return nil, total, fmt.Errorf("failed reading header line %q", err) + } + line = strings.TrimSpace(line) + // check we have a header line + if line == "" { + break + } + colon := strings.IndexRune(line, ':') + if colon < 0 { + return nil, total, fmt.Errorf("invalid header line %q", line) + } + name, value := line[:colon], strings.TrimSpace(line[colon+1:]) + switch name { + case "Content-Length": + if length, err = strconv.ParseInt(value, 10, 32); err != nil { + return nil, total, fmt.Errorf("failed parsing Content-Length: %v", value) + } + if length <= 0 { + return nil, total, fmt.Errorf("invalid Content-Length: %v", length) + } + default: + // ignoring unknown headers + } + } + if length == 0 { + return nil, total, fmt.Errorf("missing Content-Length header") + } + data := make([]byte, length) + if _, err := io.ReadFull(s.in, data); err != nil { + return nil, total, err + } + total += length + return data, total, nil +} + +func (s *headerStream) Write(ctx context.Context, data []byte) (int64, error) { + select { + case <-ctx.Done(): + return 0, ctx.Err() + default: + } + s.outMu.Lock() + defer s.outMu.Unlock() + n, err := fmt.Fprintf(s.out, "Content-Length: %v\r\n\r\n", len(data)) + total := int64(n) + if err == nil { + n, err = s.out.Write(data) + total += int64(n) + } + return total, err +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/wire.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/wire.go new file mode 100644 index 000000000000..fed9a25bc27a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/jsonrpc2/wire.go @@ -0,0 +1,148 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package jsonrpc2 + +import ( + "encoding/json" + "fmt" + "strconv" +) + +// this file contains the go forms of the wire specification +// see http://www.jsonrpc.org/specification for details + +const ( + // CodeUnknownError should be used for all non coded errors. + CodeUnknownError = -32001 + // CodeParseError is used when invalid JSON was received by the server. + CodeParseError = -32700 + //CodeInvalidRequest is used when the JSON sent is not a valid Request object. + CodeInvalidRequest = -32600 + // CodeMethodNotFound should be returned by the handler when the method does + // not exist / is not available. + CodeMethodNotFound = -32601 + // CodeInvalidParams should be returned by the handler when method + // parameter(s) were invalid. + CodeInvalidParams = -32602 + // CodeInternalError is not currently returned but defined for completeness. + CodeInternalError = -32603 + + //CodeServerOverloaded is returned when a message was refused due to a + //server being temporarily unable to accept any new messages. + CodeServerOverloaded = -32000 +) + +// WireRequest is sent to a server to represent a Call or Notify operation. +type WireRequest struct { + // VersionTag is always encoded as the string "2.0" + VersionTag VersionTag `json:"jsonrpc"` + // Method is a string containing the method name to invoke. + Method string `json:"method"` + // Params is either a struct or an array with the parameters of the method. + Params *json.RawMessage `json:"params,omitempty"` + // The id of this request, used to tie the Response back to the request. + // Will be either a string or a number. If not set, the Request is a notify, + // and no response is possible. + ID *ID `json:"id,omitempty"` +} + +// WireResponse is a reply to a Request. +// It will always have the ID field set to tie it back to a request, and will +// have either the Result or Error fields set depending on whether it is a +// success or failure response. +type WireResponse struct { + // VersionTag is always encoded as the string "2.0" + VersionTag VersionTag `json:"jsonrpc"` + // Result is the response value, and is required on success. + Result *json.RawMessage `json:"result,omitempty"` + // Error is a structured error response if the call fails. + Error *Error `json:"error,omitempty"` + // ID must be set and is the identifier of the Request this is a response to. + ID *ID `json:"id,omitempty"` +} + +// Error represents a structured error in a Response. +type Error struct { + // Code is an error code indicating the type of failure. + Code int64 `json:"code"` + // Message is a short description of the error. + Message string `json:"message"` + // Data is optional structured data containing additional information about the error. + Data *json.RawMessage `json:"data"` +} + +// VersionTag is a special 0 sized struct that encodes as the jsonrpc version +// tag. +// It will fail during decode if it is not the correct version tag in the +// stream. +type VersionTag struct{} + +// ID is a Request identifier. +// Only one of either the Name or Number members will be set, using the +// number form if the Name is the empty string. +type ID struct { + Name string + Number int64 +} + +func (err *Error) Error() string { + if err == nil { + return "" + } + return err.Message +} + +func (VersionTag) MarshalJSON() ([]byte, error) { + return json.Marshal("2.0") +} + +func (VersionTag) UnmarshalJSON(data []byte) error { + version := "" + if err := json.Unmarshal(data, &version); err != nil { + return err + } + if version != "2.0" { + return fmt.Errorf("Invalid RPC version %v", version) + } + return nil +} + +// String returns a string representation of the ID. +// The representation is non ambiguous, string forms are quoted, number forms +// are preceded by a # +func (id *ID) String() string { + if id == nil { + return "" + } + if id.Name != "" { + return strconv.Quote(id.Name) + } + return "#" + strconv.FormatInt(id.Number, 10) +} + +func (id *ID) MarshalJSON() ([]byte, error) { + if id.Name != "" { + return json.Marshal(id.Name) + } + return json.Marshal(id.Number) +} + +func (id *ID) UnmarshalJSON(data []byte) error { + *id = ID{} + if err := json.Unmarshal(data, &id.Number); err == nil { + return nil + } + return json.Unmarshal(data, &id.Name) +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/context.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/context.go new file mode 100644 index 000000000000..7833d40e1bab --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/context.go @@ -0,0 +1,29 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +import ( + "context" +) + +type contextKey int + +const ( + clientKey = contextKey(iota) +) + +func WithClient(ctx context.Context, client Client) context.Context { + return context.WithValue(ctx, clientKey, client) +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/doc.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/doc.go new file mode 100644 index 000000000000..3c9198d3b6a9 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/doc.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package protocol contains the structs that map directly to the wire format +// of the "Language Server Protocol". +// +// It is a literal transcription, with unmodified comments, and only the changes +// required to make it go code. +// Names are uppercased to export them. +// All fields have JSON tags added to correct the names. +// Fields marked with a ? are also marked as "omitempty" +// Fields that are "|| null" are made pointers +// Fields that are string or number are left as string +// Fields that are type "number" are made float64 +package protocol diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/enums.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/enums.go new file mode 100644 index 000000000000..db76ca39cc3a --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/enums.go @@ -0,0 +1,256 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +import ( + "fmt" +) + +var ( + namesTextDocumentSyncKind [int(Incremental) + 1]string + namesInitializeError [int(UnknownProtocolVersion) + 1]string + namesMessageType [int(Log) + 1]string + namesFileChangeType [int(Deleted) + 1]string + namesWatchKind [int(WatchDelete) + 1]string + namesCompletionTriggerKind [int(TriggerForIncompleteCompletions) + 1]string + namesDiagnosticSeverity [int(SeverityHint) + 1]string + namesDiagnosticTag [int(Unnecessary) + 1]string + namesCompletionItemKind [int(TypeParameterCompletion) + 1]string + namesInsertTextFormat [int(SnippetTextFormat) + 1]string + namesDocumentHighlightKind [int(Write) + 1]string + namesSymbolKind [int(TypeParameter) + 1]string + namesTextDocumentSaveReason [int(FocusOut) + 1]string +) + +func init() { + namesTextDocumentSyncKind[int(None)] = "None" + namesTextDocumentSyncKind[int(Full)] = "Full" + namesTextDocumentSyncKind[int(Incremental)] = "Incremental" + + namesInitializeError[int(UnknownProtocolVersion)] = "UnknownProtocolVersion" + + namesMessageType[int(Error)] = "Error" + namesMessageType[int(Warning)] = "Warning" + namesMessageType[int(Info)] = "Info" + namesMessageType[int(Log)] = "Log" + + namesFileChangeType[int(Created)] = "Created" + namesFileChangeType[int(Changed)] = "Changed" + namesFileChangeType[int(Deleted)] = "Deleted" + + namesWatchKind[int(WatchCreate)] = "WatchCreate" + namesWatchKind[int(WatchChange)] = "WatchChange" + namesWatchKind[int(WatchDelete)] = "WatchDelete" + + namesCompletionTriggerKind[int(Invoked)] = "Invoked" + namesCompletionTriggerKind[int(TriggerCharacter)] = "TriggerCharacter" + namesCompletionTriggerKind[int(TriggerForIncompleteCompletions)] = "TriggerForIncompleteCompletions" + + namesDiagnosticSeverity[int(SeverityError)] = "Error" + namesDiagnosticSeverity[int(SeverityWarning)] = "Warning" + namesDiagnosticSeverity[int(SeverityInformation)] = "Information" + namesDiagnosticSeverity[int(SeverityHint)] = "Hint" + + namesDiagnosticTag[int(Unnecessary)] = "Unnecessary" + + namesCompletionItemKind[int(TextCompletion)] = "text" + namesCompletionItemKind[int(MethodCompletion)] = "method" + namesCompletionItemKind[int(FunctionCompletion)] = "func" + namesCompletionItemKind[int(ConstructorCompletion)] = "constructor" + namesCompletionItemKind[int(FieldCompletion)] = "field" + namesCompletionItemKind[int(VariableCompletion)] = "var" + namesCompletionItemKind[int(ClassCompletion)] = "type" + namesCompletionItemKind[int(InterfaceCompletion)] = "interface" + namesCompletionItemKind[int(ModuleCompletion)] = "package" + namesCompletionItemKind[int(PropertyCompletion)] = "property" + namesCompletionItemKind[int(UnitCompletion)] = "unit" + namesCompletionItemKind[int(ValueCompletion)] = "value" + namesCompletionItemKind[int(EnumCompletion)] = "enum" + namesCompletionItemKind[int(KeywordCompletion)] = "keyword" + namesCompletionItemKind[int(SnippetCompletion)] = "snippet" + namesCompletionItemKind[int(ColorCompletion)] = "color" + namesCompletionItemKind[int(FileCompletion)] = "file" + namesCompletionItemKind[int(ReferenceCompletion)] = "reference" + namesCompletionItemKind[int(FolderCompletion)] = "folder" + namesCompletionItemKind[int(EnumMemberCompletion)] = "enumMember" + namesCompletionItemKind[int(ConstantCompletion)] = "const" + namesCompletionItemKind[int(StructCompletion)] = "struct" + namesCompletionItemKind[int(EventCompletion)] = "event" + namesCompletionItemKind[int(OperatorCompletion)] = "operator" + namesCompletionItemKind[int(TypeParameterCompletion)] = "typeParam" + + namesInsertTextFormat[int(PlainTextTextFormat)] = "PlainText" + namesInsertTextFormat[int(SnippetTextFormat)] = "Snippet" + + namesDocumentHighlightKind[int(Text)] = "Text" + namesDocumentHighlightKind[int(Read)] = "Read" + namesDocumentHighlightKind[int(Write)] = "Write" + + namesSymbolKind[int(File)] = "File" + namesSymbolKind[int(Module)] = "Module" + namesSymbolKind[int(Namespace)] = "Namespace" + namesSymbolKind[int(Package)] = "Package" + namesSymbolKind[int(Class)] = "Class" + namesSymbolKind[int(Method)] = "Method" + namesSymbolKind[int(Property)] = "Property" + namesSymbolKind[int(Field)] = "Field" + namesSymbolKind[int(Constructor)] = "Constructor" + namesSymbolKind[int(Enum)] = "Enum" + namesSymbolKind[int(Interface)] = "Interface" + namesSymbolKind[int(Function)] = "Function" + namesSymbolKind[int(Variable)] = "Variable" + namesSymbolKind[int(Constant)] = "Constant" + namesSymbolKind[int(String)] = "String" + namesSymbolKind[int(Number)] = "Number" + namesSymbolKind[int(Boolean)] = "Boolean" + namesSymbolKind[int(Array)] = "Array" + namesSymbolKind[int(Object)] = "Object" + namesSymbolKind[int(Key)] = "Key" + namesSymbolKind[int(Null)] = "Null" + namesSymbolKind[int(EnumMember)] = "EnumMember" + namesSymbolKind[int(Struct)] = "Struct" + namesSymbolKind[int(Event)] = "Event" + namesSymbolKind[int(Operator)] = "Operator" + namesSymbolKind[int(TypeParameter)] = "TypeParameter" + + namesTextDocumentSaveReason[int(Manual)] = "Manual" + namesTextDocumentSaveReason[int(AfterDelay)] = "AfterDelay" + namesTextDocumentSaveReason[int(FocusOut)] = "FocusOut" +} + +func formatEnum(f fmt.State, c rune, i int, names []string, unknown string) { + s := "" + if i >= 0 && i < len(names) { + s = names[i] + } + if s != "" { + fmt.Fprint(f, s) + } else { + fmt.Fprintf(f, "%s(%d)", unknown, i) + } +} + +func parseEnum(s string, names []string) int { + for i, name := range names { + if s == name { + return i + } + } + return 0 +} + +func (e TextDocumentSyncKind) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesTextDocumentSyncKind[:], "TextDocumentSyncKind") +} + +func ParseTextDocumentSyncKind(s string) TextDocumentSyncKind { + return TextDocumentSyncKind(parseEnum(s, namesTextDocumentSyncKind[:])) +} + +func (e InitializeError) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesInitializeError[:], "InitializeError") +} + +func ParseInitializeError(s string) InitializeError { + return InitializeError(parseEnum(s, namesInitializeError[:])) +} + +func (e MessageType) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesMessageType[:], "MessageType") +} + +func ParseMessageType(s string) MessageType { + return MessageType(parseEnum(s, namesMessageType[:])) +} + +func (e FileChangeType) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesFileChangeType[:], "FileChangeType") +} + +func ParseFileChangeType(s string) FileChangeType { + return FileChangeType(parseEnum(s, namesFileChangeType[:])) +} + +func (e WatchKind) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesWatchKind[:], "WatchKind") +} + +func ParseWatchKind(s string) WatchKind { + return WatchKind(parseEnum(s, namesWatchKind[:])) +} + +func (e CompletionTriggerKind) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesCompletionTriggerKind[:], "CompletionTriggerKind") +} + +func ParseCompletionTriggerKind(s string) CompletionTriggerKind { + return CompletionTriggerKind(parseEnum(s, namesCompletionTriggerKind[:])) +} + +func (e DiagnosticSeverity) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesDiagnosticSeverity[:], "DiagnosticSeverity") +} + +func ParseDiagnosticSeverity(s string) DiagnosticSeverity { + return DiagnosticSeverity(parseEnum(s, namesDiagnosticSeverity[:])) +} + +func (e DiagnosticTag) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesDiagnosticTag[:], "DiagnosticTag") +} + +func ParseDiagnosticTag(s string) DiagnosticTag { + return DiagnosticTag(parseEnum(s, namesDiagnosticTag[:])) +} + +func (e CompletionItemKind) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesCompletionItemKind[:], "CompletionItemKind") +} + +func ParseCompletionItemKind(s string) CompletionItemKind { + return CompletionItemKind(parseEnum(s, namesCompletionItemKind[:])) +} + +func (e InsertTextFormat) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesInsertTextFormat[:], "InsertTextFormat") +} + +func ParseInsertTextFormat(s string) InsertTextFormat { + return InsertTextFormat(parseEnum(s, namesInsertTextFormat[:])) +} + +func (e DocumentHighlightKind) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesDocumentHighlightKind[:], "DocumentHighlightKind") +} + +func ParseDocumentHighlightKind(s string) DocumentHighlightKind { + return DocumentHighlightKind(parseEnum(s, namesDocumentHighlightKind[:])) +} + +func (e SymbolKind) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesSymbolKind[:], "SymbolKind") +} + +func ParseSymbolKind(s string) SymbolKind { + return SymbolKind(parseEnum(s, namesSymbolKind[:])) +} + +func (e TextDocumentSaveReason) Format(f fmt.State, c rune) { + formatEnum(f, c, int(e), namesTextDocumentSaveReason[:], "TextDocumentSaveReason") +} + +func ParseTextDocumentSaveReason(s string) TextDocumentSaveReason { + return TextDocumentSaveReason(parseEnum(s, namesTextDocumentSaveReason[:])) +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/log.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/log.go new file mode 100644 index 000000000000..2fd7bbbdd711 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/log.go @@ -0,0 +1,258 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +import ( + "context" + "encoding/json" + "fmt" + "io" + "strings" + "sync" + "time" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/jsonrpc2" +) + +type loggingStream struct { + stream jsonrpc2.Stream + log io.Writer +} + +// LoggingStream returns a stream that does LSP protocol logging too +func LoggingStream(str jsonrpc2.Stream, w io.Writer) jsonrpc2.Stream { + return &loggingStream{str, w} +} + +func (s *loggingStream) Read(ctx context.Context) ([]byte, int64, error) { + data, count, err := s.stream.Read(ctx) + if err == nil { + logIn(s.log, data) + } + return data, count, err +} + +func (s *loggingStream) Write(ctx context.Context, data []byte) (int64, error) { + logOut(s.log, data) + count, err := s.stream.Write(ctx, data) + return count, err +} + +// Combined has all the fields of both Request and Response. +// We can decode this and then work out which it is. +type Combined struct { + VersionTag jsonrpc2.VersionTag `json:"jsonrpc"` + ID *jsonrpc2.ID `json:"id,omitempty"` + Method string `json:"method"` + Params *json.RawMessage `json:"params,omitempty"` + Result *json.RawMessage `json:"result,omitempty"` + Error *jsonrpc2.Error `json:"error,omitempty"` +} + +type req struct { + method string + start time.Time +} + +type mapped struct { + mu sync.Mutex + clientCalls map[string]req + serverCalls map[string]req +} + +var maps = &mapped{ + sync.Mutex{}, + make(map[string]req), + make(map[string]req), +} + +// these 4 methods are each used exactly once, but it seemed +// better to have the encapsulation rather than ad hoc mutex +// code in 4 places +func (m *mapped) client(id string, del bool) req { + m.mu.Lock() + defer m.mu.Unlock() + v := m.clientCalls[id] + if del { + delete(m.clientCalls, id) + } + return v +} + +func (m *mapped) server(id string, del bool) req { + m.mu.Lock() + defer m.mu.Unlock() + v := m.serverCalls[id] + if del { + delete(m.serverCalls, id) + } + return v +} + +func (m *mapped) setClient(id string, r req) { + m.mu.Lock() + defer m.mu.Unlock() + m.clientCalls[id] = r +} + +func (m *mapped) setServer(id string, r req) { + m.mu.Lock() + defer m.mu.Unlock() + m.serverCalls[id] = r +} + +const eor = "\r\n\r\n\r\n" + +func strID(x *jsonrpc2.ID) string { + if x == nil { + // should never happen, but we need a number + return "999999999" + } + if x.Name != "" { + return x.Name + } + return fmt.Sprintf("%d", x.Number) +} + +func logCommon(outfd io.Writer, data []byte) (*Combined, time.Time, string) { + if outfd == nil { + return nil, time.Time{}, "" + } + var v Combined + err := json.Unmarshal(data, &v) + if err != nil { + fmt.Fprintf(outfd, "Unmarshal %v\n", err) + panic(err) // do better + } + tm := time.Now() + tmfmt := tm.Format("15:04:05.000 PM") + return &v, tm, tmfmt +} + +// logOut and logIn could be combined. "received"<->"Sending", serverCalls<->clientCalls +// but it wouldn't be a lot shorter or clearer and "shutdown" is a special case + +// Writing a message to the client, log it +func logOut(outfd io.Writer, data []byte) { + v, tm, tmfmt := logCommon(outfd, data) + if v == nil { + return + } + if v.Error != nil { + id := strID(v.ID) + fmt.Fprintf(outfd, "[Error - %s] Received #%s %s%s", tmfmt, id, v.Error, eor) + return + } + buf := strings.Builder{} + id := strID(v.ID) + fmt.Fprintf(&buf, "[Trace - %s] ", tmfmt) // common beginning + if v.ID != nil && v.Method != "" && v.Params != nil { + fmt.Fprintf(&buf, "Received request '%s - (%s)'.\n", v.Method, id) + fmt.Fprintf(&buf, "Params: %s%s", *v.Params, eor) + maps.setServer(id, req{method: v.Method, start: tm}) + } else if v.ID != nil && v.Method == "" && v.Params == nil { + cc := maps.client(id, true) + elapsed := tm.Sub(cc.start) + fmt.Fprintf(&buf, "Received response '%s - (%s)' in %dms.\n", + cc.method, id, elapsed/time.Millisecond) + if v.Result == nil { + fmt.Fprintf(&buf, "Result: {}%s", eor) + } else { + fmt.Fprintf(&buf, "Result: %s%s", string(*v.Result), eor) + } + } else if v.ID == nil && v.Method != "" && v.Params != nil { + p := "null" + if v.Params != nil { + p = string(*v.Params) + } + fmt.Fprintf(&buf, "Received notification '%s'.\n", v.Method) + fmt.Fprintf(&buf, "Params: %s%s", p, eor) + } else { // for completeness, as it should never happen + buf = strings.Builder{} // undo common Trace + fmt.Fprintf(&buf, "[Error - %s] on write ID?%v method:%q Params:%v Result:%v Error:%v%s", + tmfmt, v.ID != nil, v.Method, v.Params != nil, + v.Result != nil, v.Error != nil, eor) + p := "null" + if v.Params != nil { + p = string(*v.Params) + } + r := "null" + if v.Result != nil { + r = string(*v.Result) + } + fmt.Fprintf(&buf, "%s\n%s\n%s%s", p, r, v.Error, eor) + } + outfd.Write([]byte(buf.String())) +} + +// Got a message from the client, log it +func logIn(outfd io.Writer, data []byte) { + v, tm, tmfmt := logCommon(outfd, data) + if v == nil { + return + } + // ID Method Params => Sending request + // ID !Method Result(might be null, but !Params) => Sending response (could we get an Error?) + // !ID Method Params => Sending notification + if v.Error != nil { // does this ever happen? + id := strID(v.ID) + fmt.Fprintf(outfd, "[Error - %s] Sent #%s %s%s", tmfmt, id, v.Error, eor) + return + } + buf := strings.Builder{} + id := strID(v.ID) + fmt.Fprintf(&buf, "[Trace - %s] ", tmfmt) // common beginning + if v.ID != nil && v.Method != "" && (v.Params != nil || v.Method == "shutdown") { + fmt.Fprintf(&buf, "Sending request '%s - (%s)'.\n", v.Method, id) + x := "{}" + if v.Params != nil { + x = string(*v.Params) + } + fmt.Fprintf(&buf, "Params: %s%s", x, eor) + maps.setClient(id, req{method: v.Method, start: tm}) + } else if v.ID != nil && v.Method == "" && v.Params == nil { + sc := maps.server(id, true) + elapsed := tm.Sub(sc.start) + fmt.Fprintf(&buf, "Sending response '%s - (%s)' took %dms.\n", + sc.method, id, elapsed/time.Millisecond) + if v.Result == nil { + fmt.Fprintf(&buf, "Result: {}%s", eor) + } else { + fmt.Fprintf(&buf, "Result: %s%s", string(*v.Result), eor) + } + } else if v.ID == nil && v.Method != "" { + p := "null" + if v.Params != nil { + p = string(*v.Params) + } + fmt.Fprintf(&buf, "Sending notification '%s'.\n", v.Method) + fmt.Fprintf(&buf, "Params: %s%s", p, eor) + } else { // for completeness, as it should never happen + buf = strings.Builder{} // undo common Trace + fmt.Fprintf(&buf, "[Error - %s] on read ID?%v method:%q Params:%v Result:%v Error:%v%s", + tmfmt, v.ID != nil, v.Method, v.Params != nil, + v.Result != nil, v.Error != nil, eor) + p := "null" + if v.Params != nil { + p = string(*v.Params) + } + r := "null" + if v.Result != nil { + r = string(*v.Result) + } + fmt.Fprintf(&buf, "%s\n%s\n%s%s", p, r, v.Error, eor) + } + outfd.Write([]byte(buf.String())) +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/protocol.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/protocol.go new file mode 100644 index 000000000000..886b0aaad893 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/protocol.go @@ -0,0 +1,86 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +import ( + "context" + "encoding/json" + "log" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/jsonrpc2" +) + +const ( + // RequestCancelledError should be used when a request is cancelled early. + RequestCancelledError = -32800 +) + +type DocumentUri = string + +type canceller struct{ jsonrpc2.EmptyHandler } + +type clientHandler struct { + canceller + client Client +} + +type serverHandler struct { + canceller + server Server +} + +func (canceller) Request(ctx context.Context, conn *jsonrpc2.Conn, direction jsonrpc2.Direction, r *jsonrpc2.WireRequest) context.Context { + if direction == jsonrpc2.Receive && r.Method == "$/cancelRequest" { + var params CancelParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + log.Printf("%v", err) + } else { + conn.Cancel(params.ID) + } + } + return ctx +} + +func (canceller) Cancel(ctx context.Context, conn *jsonrpc2.Conn, id jsonrpc2.ID, cancelled bool) bool { + if cancelled { + return false + } + conn.Notify(ctx, "$/cancelRequest", &CancelParams{ID: id}) + return true +} + +func NewClient(ctx context.Context, stream jsonrpc2.Stream, client Client) (context.Context, *jsonrpc2.Conn, Server) { + ctx = WithClient(ctx, client) + conn := jsonrpc2.NewConn(stream) + conn.AddHandler(&clientHandler{client: client}) + return ctx, conn, &serverDispatcher{Conn: conn} +} + +func NewServer(ctx context.Context, stream jsonrpc2.Stream, server Server) (context.Context, *jsonrpc2.Conn, Client) { + conn := jsonrpc2.NewConn(stream) + client := &clientDispatcher{Conn: conn} + ctx = WithClient(ctx, client) + conn.AddHandler(&serverHandler{server: server}) + return ctx, conn, client +} + +func sendParseError(ctx context.Context, req *jsonrpc2.Request, err error) { + if _, ok := err.(*jsonrpc2.Error); !ok { + err = jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err) + } + if err := req.Reply(ctx, nil, err); err != nil { + log.Printf("%v", err) + } +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/span.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/span.go new file mode 100644 index 000000000000..799c22882425 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/span.go @@ -0,0 +1,138 @@ +// Copyright 2018 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// this file contains protocol<->span converters + +package protocol + +import ( + "fmt" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/span" + + errors "golang.org/x/xerrors" +) + +type ColumnMapper struct { + URI span.URI + Converter *span.TokenConverter + Content []byte +} + +func NewURI(uri span.URI) string { + return string(uri) +} + +func (m *ColumnMapper) Location(s span.Span) (Location, error) { + rng, err := m.Range(s) + if err != nil { + return Location{}, err + } + return Location{URI: NewURI(s.URI()), Range: rng}, nil +} + +func (m *ColumnMapper) Range(s span.Span) (Range, error) { + if span.CompareURI(m.URI, s.URI()) != 0 { + return Range{}, errors.Errorf("column mapper is for file %q instead of %q", m.URI, s.URI()) + } + s, err := s.WithAll(m.Converter) + if err != nil { + return Range{}, err + } + start, err := m.Position(s.Start()) + if err != nil { + return Range{}, err + } + end, err := m.Position(s.End()) + if err != nil { + return Range{}, err + } + return Range{Start: start, End: end}, nil +} + +func (m *ColumnMapper) Position(p span.Point) (Position, error) { + chr, err := span.ToUTF16Column(p, m.Content) + if err != nil { + return Position{}, err + } + return Position{ + Line: float64(p.Line() - 1), + Character: float64(chr - 1), + }, nil +} + +func (m *ColumnMapper) Span(l Location) (span.Span, error) { + return m.RangeSpan(l.Range) +} + +func (m *ColumnMapper) RangeSpan(r Range) (span.Span, error) { + start, err := m.Point(r.Start) + if err != nil { + return span.Span{}, err + } + end, err := m.Point(r.End) + if err != nil { + return span.Span{}, err + } + return span.New(m.URI, start, end).WithAll(m.Converter) +} + +func (m *ColumnMapper) PointSpan(p Position) (span.Span, error) { + start, err := m.Point(p) + if err != nil { + return span.Span{}, err + } + return span.New(m.URI, start, start).WithAll(m.Converter) +} + +func (m *ColumnMapper) Point(p Position) (span.Point, error) { + line := int(p.Line) + 1 + offset, err := m.Converter.ToOffset(line, 1) + if err != nil { + return span.Point{}, err + } + lineStart := span.NewPoint(line, 1, offset) + return span.FromUTF16Column(lineStart, int(p.Character)+1, m.Content) +} + +func IsPoint(r Range) bool { + return r.Start.Line == r.End.Line && r.Start.Character == r.End.Character +} + +func CompareRange(a, b Range) int { + if r := ComparePosition(a.Start, b.Start); r != 0 { + return r + } + return ComparePosition(a.End, b.End) +} + +func ComparePosition(a, b Position) int { + if a.Line < b.Line { + return -1 + } + if a.Line > b.Line { + return 1 + } + if a.Character < b.Character { + return -1 + } + if a.Character > b.Character { + return 1 + } + return 0 +} + +func (r Range) Format(f fmt.State, _ rune) { + fmt.Fprintf(f, "%v:%v-%v:%v", r.Start.Line, r.Start.Character, r.End.Line, r.End.Character) +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsclient.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsclient.go new file mode 100644 index 000000000000..f68d63d0c027 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsclient.go @@ -0,0 +1,221 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +import ( + "context" + "encoding/json" + "log" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/jsonrpc2" +) + +type Client interface { + ShowMessage(context.Context, *ShowMessageParams) error + LogMessage(context.Context, *LogMessageParams) error + Event(context.Context, *interface{}) error + PublishDiagnostics(context.Context, *PublishDiagnosticsParams) error + WorkspaceFolders(context.Context) ([]WorkspaceFolder, error) + Configuration(context.Context, *ParamConfig) ([]interface{}, error) + RegisterCapability(context.Context, *RegistrationParams) error + UnregisterCapability(context.Context, *UnregistrationParams) error + ShowMessageRequest(context.Context, *ShowMessageRequestParams) (*MessageActionItem, error) + ApplyEdit(context.Context, *ApplyWorkspaceEditParams) (*ApplyWorkspaceEditResponse, error) +} + +func (h clientHandler) Deliver(ctx context.Context, r *jsonrpc2.Request, delivered bool) bool { + if delivered { + return false + } + if ctx.Err() != nil { + r.Reply(ctx, nil, jsonrpc2.NewErrorf(RequestCancelledError, "")) + return true + } + switch r.Method { + case "window/showMessage": // notif + var params ShowMessageParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.client.ShowMessage(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "window/logMessage": // notif + var params LogMessageParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.client.LogMessage(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "telemetry/event": // notif + var params interface{} + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.client.Event(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/publishDiagnostics": // notif + var params PublishDiagnosticsParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.client.PublishDiagnostics(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "workspace/workspaceFolders": // req + if r.Params != nil { + r.Reply(ctx, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params")) + return true + } + resp, err := h.client.WorkspaceFolders(ctx) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "workspace/configuration": // req + var params ParamConfig + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.client.Configuration(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "client/registerCapability": // req + var params RegistrationParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + err := h.client.RegisterCapability(ctx, ¶ms) + if err := r.Reply(ctx, nil, err); err != nil { + log.Printf("%v", err) + } + return true + case "client/unregisterCapability": // req + var params UnregistrationParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + err := h.client.UnregisterCapability(ctx, ¶ms) + if err := r.Reply(ctx, nil, err); err != nil { + log.Printf("%v", err) + } + return true + case "window/showMessageRequest": // req + var params ShowMessageRequestParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.client.ShowMessageRequest(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "workspace/applyEdit": // req + var params ApplyWorkspaceEditParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.client.ApplyEdit(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + + default: + return false + } +} + +type clientDispatcher struct { + *jsonrpc2.Conn +} + +func (s *clientDispatcher) ShowMessage(ctx context.Context, params *ShowMessageParams) error { + return s.Conn.Notify(ctx, "window/showMessage", params) +} + +func (s *clientDispatcher) LogMessage(ctx context.Context, params *LogMessageParams) error { + return s.Conn.Notify(ctx, "window/logMessage", params) +} + +func (s *clientDispatcher) Event(ctx context.Context, params *interface{}) error { + return s.Conn.Notify(ctx, "telemetry/event", params) +} + +func (s *clientDispatcher) PublishDiagnostics(ctx context.Context, params *PublishDiagnosticsParams) error { + return s.Conn.Notify(ctx, "textDocument/publishDiagnostics", params) +} +func (s *clientDispatcher) WorkspaceFolders(ctx context.Context) ([]WorkspaceFolder, error) { + var result []WorkspaceFolder + if err := s.Conn.Call(ctx, "workspace/workspaceFolders", nil, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *clientDispatcher) Configuration(ctx context.Context, params *ParamConfig) ([]interface{}, error) { + var result []interface{} + if err := s.Conn.Call(ctx, "workspace/configuration", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *clientDispatcher) RegisterCapability(ctx context.Context, params *RegistrationParams) error { + return s.Conn.Call(ctx, "client/registerCapability", params, nil) // Call, not Notify +} + +func (s *clientDispatcher) UnregisterCapability(ctx context.Context, params *UnregistrationParams) error { + return s.Conn.Call(ctx, "client/unregisterCapability", params, nil) // Call, not Notify +} + +func (s *clientDispatcher) ShowMessageRequest(ctx context.Context, params *ShowMessageRequestParams) (*MessageActionItem, error) { + var result MessageActionItem + if err := s.Conn.Call(ctx, "window/showMessageRequest", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *clientDispatcher) ApplyEdit(ctx context.Context, params *ApplyWorkspaceEditParams) (*ApplyWorkspaceEditResponse, error) { + var result ApplyWorkspaceEditResponse + if err := s.Conn.Call(ctx, "workspace/applyEdit", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Types constructed to avoid structs as formal argument types +type ParamConfig struct { + ConfigurationParams + PartialResultParams +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsprotocol.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsprotocol.go new file mode 100644 index 000000000000..e0a35946746c --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsprotocol.go @@ -0,0 +1,4630 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package protocol contains data types and code for LSP jsonrpcs +// generated automatically from vscode-languageserver-node +// commit: 36ac51f057215e6e2e0408384e07ecf564a938da +// last fetched Tue Sep 24 2019 17:44:28 GMT-0400 (Eastern Daylight Time) +package protocol + +// Code generated (see typescript/README.md) DO NOT EDIT. + +/*ImplementationClientCapabilities defined: + * Since 3.6.0 + */ +type ImplementationClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether implementation supports dynamic registration. If this is set to `true` + * the client supports the new `ImplementationRegistrationOptions` return value + * for the corresponding server capability as well. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*LinkSupport defined: + * The client supports additional metadata in the form of definition links. + * + * Since 3.14.0 + */ + LinkSupport bool `json:"linkSupport,omitempty"` +} + +// ImplementationOptions is +type ImplementationOptions struct { + WorkDoneProgressOptions +} + +// ImplementationRegistrationOptions is +type ImplementationRegistrationOptions struct { + TextDocumentRegistrationOptions + ImplementationOptions + StaticRegistrationOptions +} + +// ImplementationParams is +type ImplementationParams struct { + TextDocumentPositionParams + WorkDoneProgressParams + PartialResultParams +} + +/*TypeDefinitionClientCapabilities defined: + * Since 3.6.0 + */ +type TypeDefinitionClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether implementation supports dynamic registration. If this is set to `true` + * the client supports the new `TypeDefinitionRegistrationOptions` return value + * for the corresponding server capability as well. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*LinkSupport defined: + * The client supports additional metadata in the form of definition links. + * + * Since 3.14.0 + */ + LinkSupport bool `json:"linkSupport,omitempty"` +} + +// TypeDefinitionOptions is +type TypeDefinitionOptions struct { + WorkDoneProgressOptions +} + +// TypeDefinitionRegistrationOptions is +type TypeDefinitionRegistrationOptions struct { + TextDocumentRegistrationOptions + TypeDefinitionOptions + StaticRegistrationOptions +} + +// TypeDefinitionParams is +type TypeDefinitionParams struct { + TextDocumentPositionParams + WorkDoneProgressParams + PartialResultParams +} + +// WorkspaceFoldersInitializeParams is +type WorkspaceFoldersInitializeParams struct { + + /*WorkspaceFolders defined: + * The actual configured workspace folders. + */ + WorkspaceFolders []WorkspaceFolder `json:"workspaceFolders"` +} + +// WorkspaceFoldersClientCapabilities is +type WorkspaceFoldersClientCapabilities struct { + + /*Workspace defined: + * The workspace client capabilities + */ + Workspace *struct { + + /*WorkspaceFolders defined: + * The client has support for workspace folders + */ + WorkspaceFolders bool `json:"workspaceFolders,omitempty"` + } `json:"workspace,omitempty"` +} + +// WorkspaceFoldersServerCapabilities is +type WorkspaceFoldersServerCapabilities struct { + + /*Workspace defined: + * The workspace server capabilities + */ + Workspace *struct { + + // WorkspaceFolders is + WorkspaceFolders *struct { + + /*Supported defined: + * The Server has support for workspace folders + */ + Supported bool `json:"supported,omitempty"` + + /*ChangeNotifications defined: + * Whether the server wants to receive workspace folder + * change notifications. + * + * If a strings is provided the string is treated as a ID + * under which the notification is registered on the client + * side. The ID can be used to unregister for these events + * using the `client/unregisterCapability` request. + */ + ChangeNotifications string `json:"changeNotifications,omitempty"` // string | boolean + } `json:"workspaceFolders,omitempty"` + } `json:"workspace,omitempty"` +} + +// WorkspaceFolder is +type WorkspaceFolder struct { + + /*URI defined: + * The associated URI for this workspace folder. + */ + URI string `json:"uri"` + + /*Name defined: + * The name of the workspace folder. Used to refer to this + * workspace folder in the user interface. + */ + Name string `json:"name"` +} + +/*DidChangeWorkspaceFoldersParams defined: + * The parameters of a `workspace/didChangeWorkspaceFolders` notification. + */ +type DidChangeWorkspaceFoldersParams struct { + + /*Event defined: + * The actual workspace folder change event. + */ + Event WorkspaceFoldersChangeEvent `json:"event"` +} + +/*WorkspaceFoldersChangeEvent defined: + * The workspace folder change event. + */ +type WorkspaceFoldersChangeEvent struct { + + /*Added defined: + * The array of added workspace folders + */ + Added []WorkspaceFolder `json:"added"` + + /*Removed defined: + * The array of the removed workspace folders + */ + Removed []WorkspaceFolder `json:"removed"` +} + +// ConfigurationClientCapabilities is +type ConfigurationClientCapabilities struct { + + /*Workspace defined: + * The workspace client capabilities + */ + Workspace *struct { + + /*Configuration defined: + * The client supports `workspace/configuration` requests. + */ + Configuration bool `json:"configuration,omitempty"` + } `json:"workspace,omitempty"` +} + +// ConfigurationItem is +type ConfigurationItem struct { + + /*ScopeURI defined: + * The scope to get the configuration section for. + */ + ScopeURI string `json:"scopeUri,omitempty"` + + /*Section defined: + * The configuration section asked for. + */ + Section string `json:"section,omitempty"` +} + +/*ConfigurationParams defined: + * The parameters of a configuration request. + */ +type ConfigurationParams struct { + + // Items is + Items []ConfigurationItem `json:"items"` +} + +// DocumentColorClientCapabilities is +type DocumentColorClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether implementation supports dynamic registration. If this is set to `true` + * the client supports the new `DocumentColorRegistrationOptions` return value + * for the corresponding server capability as well. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +// DocumentColorOptions is +type DocumentColorOptions struct { + + /*ResolveProvider defined: + * Code lens has a resolve provider as well. + */ + ResolveProvider bool `json:"resolveProvider,omitempty"` + WorkDoneProgressOptions +} + +// DocumentColorRegistrationOptions is +type DocumentColorRegistrationOptions struct { + TextDocumentRegistrationOptions + StaticRegistrationOptions + DocumentColorOptions +} + +/*DocumentColorParams defined: + * Parameters for a [DocumentColorRequest](#DocumentColorRequest). + */ +type DocumentColorParams struct { + + /*TextDocument defined: + * The text document. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + WorkDoneProgressParams + PartialResultParams +} + +/*ColorPresentationParams defined: + * Parameters for a [ColorPresentationRequest](#ColorPresentationRequest). + */ +type ColorPresentationParams struct { + + /*TextDocument defined: + * The text document. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Color defined: + * The color to request presentations for. + */ + Color Color `json:"color"` + + /*Range defined: + * The range where the color would be inserted. Serves as a context. + */ + Range Range `json:"range"` + WorkDoneProgressParams + PartialResultParams +} + +// FoldingRangeClientCapabilities is +type FoldingRangeClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether implementation supports dynamic registration for folding range providers. If this is set to `true` + * the client supports the new `FoldingRangeRegistrationOptions` return value for the corresponding server + * capability as well. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*RangeLimit defined: + * The maximum number of folding ranges that the client prefers to receive per document. The value serves as a + * hint, servers are free to follow the limit. + */ + RangeLimit float64 `json:"rangeLimit,omitempty"` + + /*LineFoldingOnly defined: + * If set, the client signals that it only supports folding complete lines. If set, client will + * ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange. + */ + LineFoldingOnly bool `json:"lineFoldingOnly,omitempty"` +} + +// FoldingRangeOptions is +type FoldingRangeOptions struct { + WorkDoneProgressOptions +} + +// FoldingRangeRegistrationOptions is +type FoldingRangeRegistrationOptions struct { + TextDocumentRegistrationOptions + FoldingRangeOptions + StaticRegistrationOptions +} + +/*FoldingRange defined: + * Represents a folding range. + */ +type FoldingRange struct { + + /*StartLine defined: + * The zero-based line number from where the folded range starts. + */ + StartLine float64 `json:"startLine"` + + /*StartCharacter defined: + * The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line. + */ + StartCharacter float64 `json:"startCharacter,omitempty"` + + /*EndLine defined: + * The zero-based line number where the folded range ends. + */ + EndLine float64 `json:"endLine"` + + /*EndCharacter defined: + * The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line. + */ + EndCharacter float64 `json:"endCharacter,omitempty"` + + /*Kind defined: + * Describes the kind of the folding range such as `comment' or 'region'. The kind + * is used to categorize folding ranges and used by commands like 'Fold all comments'. See + * [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds. + */ + Kind string `json:"kind,omitempty"` +} + +/*FoldingRangeParams defined: + * Parameters for a [FoldingRangeRequest](#FoldingRangeRequest). + */ +type FoldingRangeParams struct { + + /*TextDocument defined: + * The text document. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + WorkDoneProgressParams + PartialResultParams +} + +/*DeclarationClientCapabilities defined: + * Since 3.14.0 + */ +type DeclarationClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether declaration supports dynamic registration. If this is set to `true` + * the client supports the new `DeclarationRegistrationOptions` return value + * for the corresponding server capability as well. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*LinkSupport defined: + * The client supports additional metadata in the form of declaration links. + */ + LinkSupport bool `json:"linkSupport,omitempty"` +} + +// DeclarationOptions is +type DeclarationOptions struct { + WorkDoneProgressOptions +} + +// DeclarationRegistrationOptions is +type DeclarationRegistrationOptions struct { + DeclarationOptions + TextDocumentRegistrationOptions + StaticRegistrationOptions +} + +// DeclarationParams is +type DeclarationParams struct { + TextDocumentPositionParams + WorkDoneProgressParams + PartialResultParams +} + +// SelectionRangeClientCapabilities is +type SelectionRangeClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether implementation supports dynamic registration for selection range providers. If this is set to `true` + * the client supports the new `SelectionRangeRegistrationOptions` return value for the corresponding server + * capability as well. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +// SelectionRangeOptions is +type SelectionRangeOptions struct { + WorkDoneProgressOptions +} + +// SelectionRangeRegistrationOptions is +type SelectionRangeRegistrationOptions struct { + SelectionRangeOptions + TextDocumentRegistrationOptions + StaticRegistrationOptions +} + +/*SelectionRangeParams defined: + * A parameter literal used in selection range requests. + */ +type SelectionRangeParams struct { + + /*TextDocument defined: + * The text document. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Positions defined: + * The positions inside the text document. + */ + Positions []Position `json:"positions"` + WorkDoneProgressParams + PartialResultParams +} + +/*Registration defined: + * General parameters to to register for an notification or to register a provider. + */ +type Registration struct { + + /*ID defined: + * The id used to register the request. The id can be used to deregister + * the request again. + */ + ID string `json:"id"` + + /*Method defined: + * The method to register for. + */ + Method string `json:"method"` + + /*RegisterOptions defined: + * Options necessary for the registration. + */ + RegisterOptions interface{} `json:"registerOptions,omitempty"` +} + +// RegistrationParams is +type RegistrationParams struct { + + // Registrations is + Registrations []Registration `json:"registrations"` +} + +/*Unregistration defined: + * General parameters to unregister a request or notification. + */ +type Unregistration struct { + + /*ID defined: + * The id used to unregister the request or notification. Usually an id + * provided during the register request. + */ + ID string `json:"id"` + + /*Method defined: + * The method to unregister for. + */ + Method string `json:"method"` +} + +// UnregistrationParams is +type UnregistrationParams struct { + + // Unregisterations is + Unregisterations []Unregistration `json:"unregisterations"` +} + +// WorkDoneProgressParams is +type WorkDoneProgressParams struct { + + /*WorkDoneToken defined: + * An optional token that a server can use to report work done progress. + */ + WorkDoneToken *ProgressToken `json:"workDoneToken,omitempty"` +} + +// PartialResultParams is +type PartialResultParams struct { + + /*PartialResultToken defined: + * An optional token that a server can use to report partial results (e.g. streaming) to + * the client. + */ + PartialResultToken *ProgressToken `json:"partialResultToken,omitempty"` +} + +/*TextDocumentPositionParams defined: + * A parameter literal used in requests to pass a text document and a position inside that + * document. + */ +type TextDocumentPositionParams struct { + + /*TextDocument defined: + * The text document. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Position defined: + * The position inside the text document. + */ + Position Position `json:"position"` +} + +/*WorkspaceClientCapabilities defined: + * Workspace specific client capabilities. + */ +type WorkspaceClientCapabilities struct { + + /*ApplyEdit defined: + * The client supports applying batch edits + * to the workspace by supporting the request + * 'workspace/applyEdit' + */ + ApplyEdit bool `json:"applyEdit,omitempty"` + + /*WorkspaceEdit defined: + * Capabilities specific to `WorkspaceEdit`s + */ + WorkspaceEdit *WorkspaceEditClientCapabilities `json:"workspaceEdit,omitempty"` + + /*DidChangeConfiguration defined: + * Capabilities specific to the `workspace/didChangeConfiguration` notification. + */ + DidChangeConfiguration *DidChangeConfigurationClientCapabilities `json:"didChangeConfiguration,omitempty"` + + /*DidChangeWatchedFiles defined: + * Capabilities specific to the `workspace/didChangeWatchedFiles` notification. + */ + DidChangeWatchedFiles *DidChangeWatchedFilesClientCapabilities `json:"didChangeWatchedFiles,omitempty"` + + /*Symbol defined: + * Capabilities specific to the `workspace/symbol` request. + */ + Symbol *WorkspaceSymbolClientCapabilities `json:"symbol,omitempty"` + + /*ExecuteCommand defined: + * Capabilities specific to the `workspace/executeCommand` request. + */ + ExecuteCommand *ExecuteCommandClientCapabilities `json:"executeCommand,omitempty"` +} + +/*TextDocumentClientCapabilities defined: + * Text document specific client capabilities. + */ +type TextDocumentClientCapabilities struct { + + /*Synchronization defined: + * Defines which synchronization capabilities the client supports. + */ + Synchronization *TextDocumentSyncClientCapabilities `json:"synchronization,omitempty"` + + /*Completion defined: + * Capabilities specific to the `textDocument/completion` + */ + Completion *CompletionClientCapabilities `json:"completion,omitempty"` + + /*Hover defined: + * Capabilities specific to the `textDocument/hover` + */ + Hover *HoverClientCapabilities `json:"hover,omitempty"` + + /*SignatureHelp defined: + * Capabilities specific to the `textDocument/signatureHelp` + */ + SignatureHelp *SignatureHelpClientCapabilities `json:"signatureHelp,omitempty"` + + /*Declaration defined: + * Capabilities specific to the `textDocument/declaration` + * + * @since 3.14.0 + */ + Declaration *DeclarationClientCapabilities `json:"declaration,omitempty"` + + /*Definition defined: + * Capabilities specific to the `textDocument/definition` + */ + Definition *DefinitionClientCapabilities `json:"definition,omitempty"` + + /*TypeDefinition defined: + * Capabilities specific to the `textDocument/typeDefinition` + * + * @since 3.6.0 + */ + TypeDefinition *TypeDefinitionClientCapabilities `json:"typeDefinition,omitempty"` + + /*Implementation defined: + * Capabilities specific to the `textDocument/implementation` + * + * @since 3.6.0 + */ + Implementation *ImplementationClientCapabilities `json:"implementation,omitempty"` + + /*References defined: + * Capabilities specific to the `textDocument/references` + */ + References *ReferenceClientCapabilities `json:"references,omitempty"` + + /*DocumentHighlight defined: + * Capabilities specific to the `textDocument/documentHighlight` + */ + DocumentHighlight *DocumentHighlightClientCapabilities `json:"documentHighlight,omitempty"` + + /*DocumentSymbol defined: + * Capabilities specific to the `textDocument/documentSymbol` + */ + DocumentSymbol *DocumentSymbolClientCapabilities `json:"documentSymbol,omitempty"` + + /*CodeAction defined: + * Capabilities specific to the `textDocument/codeAction` + */ + CodeAction *CodeActionClientCapabilities `json:"codeAction,omitempty"` + + /*CodeLens defined: + * Capabilities specific to the `textDocument/codeLens` + */ + CodeLens *CodeLensClientCapabilities `json:"codeLens,omitempty"` + + /*DocumentLink defined: + * Capabilities specific to the `textDocument/documentLink` + */ + DocumentLink *DocumentLinkClientCapabilities `json:"documentLink,omitempty"` + + /*ColorProvider defined: + * Capabilities specific to the `textDocument/documentColor` + */ + ColorProvider *DocumentColorClientCapabilities `json:"colorProvider,omitempty"` + + /*Formatting defined: + * Capabilities specific to the `textDocument/formatting` + */ + Formatting *DocumentFormattingClientCapabilities `json:"formatting,omitempty"` + + /*RangeFormatting defined: + * Capabilities specific to the `textDocument/rangeFormatting` + */ + RangeFormatting *DocumentRangeFormattingClientCapabilities `json:"rangeFormatting,omitempty"` + + /*OnTypeFormatting defined: + * Capabilities specific to the `textDocument/onTypeFormatting` + */ + OnTypeFormatting *DocumentOnTypeFormattingClientCapabilities `json:"onTypeFormatting,omitempty"` + + /*Rename defined: + * Capabilities specific to the `textDocument/rename` + */ + Rename *RenameClientCapabilities `json:"rename,omitempty"` + + /*FoldingRange defined: + * Capabilities specific to `textDocument/foldingRange` requests. + * + * @since 3.10.0 + */ + FoldingRange *FoldingRangeClientCapabilities `json:"foldingRange,omitempty"` + + /*SelectionRange defined: + * Capabilities specific to `textDocument/selectionRange` requests + * + * @since 3.15.0 + */ + SelectionRange *SelectionRangeClientCapabilities `json:"selectionRange,omitempty"` + + /*PublishDiagnostics defined: + * Capabilities specific to `textDocument/publishDiagnostics`. + */ + PublishDiagnostics *PublishDiagnosticsClientCapabilities `json:"publishDiagnostics,omitempty"` +} + +/*InnerClientCapabilities defined: + * Defines the capabilities provided by the client. + */ +type InnerClientCapabilities struct { + + /*Workspace defined: + * Workspace specific client capabilities. + */ + Workspace *WorkspaceClientCapabilities `json:"workspace,omitempty"` + + /*TextDocument defined: + * Text document specific client capabilities. + */ + TextDocument *TextDocumentClientCapabilities `json:"textDocument,omitempty"` + + /*Window defined: + * Window specific client capabilities. + */ + Window interface{} `json:"window,omitempty"` + + /*Experimental defined: + * Experimental client capabilities. + */ + Experimental interface{} `json:"experimental,omitempty"` +} + +// ClientCapabilities is +type ClientCapabilities struct { + + /*Workspace defined: + * Workspace specific client capabilities. + */ + Workspace struct { + + /*ApplyEdit defined: + * The client supports applying batch edits + * to the workspace by supporting the request + * 'workspace/applyEdit' + */ + ApplyEdit bool `json:"applyEdit,omitempty"` + + /*WorkspaceEdit defined: + * Capabilities specific to `WorkspaceEdit`s + */ + WorkspaceEdit WorkspaceEditClientCapabilities `json:"workspaceEdit,omitempty"` + + /*DidChangeConfiguration defined: + * Capabilities specific to the `workspace/didChangeConfiguration` notification. + */ + DidChangeConfiguration DidChangeConfigurationClientCapabilities `json:"didChangeConfiguration,omitempty"` + + /*DidChangeWatchedFiles defined: + * Capabilities specific to the `workspace/didChangeWatchedFiles` notification. + */ + DidChangeWatchedFiles DidChangeWatchedFilesClientCapabilities `json:"didChangeWatchedFiles,omitempty"` + + /*Symbol defined: + * Capabilities specific to the `workspace/symbol` request. + */ + Symbol WorkspaceSymbolClientCapabilities `json:"symbol,omitempty"` + + /*ExecuteCommand defined: + * Capabilities specific to the `workspace/executeCommand` request. + */ + ExecuteCommand ExecuteCommandClientCapabilities `json:"executeCommand,omitempty"` + + /*WorkspaceFolders defined: + * The client has support for workspace folders + */ + WorkspaceFolders bool `json:"workspaceFolders,omitempty"` + + /*Configuration defined: + * The client supports `workspace/configuration` requests. + */ + Configuration bool `json:"configuration,omitempty"` + } `json:"workspace,omitempty"` + + /*TextDocument defined: + * Text document specific client capabilities. + */ + TextDocument TextDocumentClientCapabilities `json:"textDocument,omitempty"` + + /*Window defined: + * Window specific client capabilities. + */ + Window interface{} `json:"window,omitempty"` + + /*Experimental defined: + * Experimental client capabilities. + */ + Experimental interface{} `json:"experimental,omitempty"` + + /*DynamicRegistration defined: + * Whether implementation supports dynamic registration for selection range providers. If this is set to `true` + * the client supports the new `SelectionRangeRegistrationOptions` return value for the corresponding server + * capability as well. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*StaticRegistrationOptions defined: + * Static registration options to be returned in the initialize + * request. + */ +type StaticRegistrationOptions struct { + + /*ID defined: + * The id used to register the request. The id can be used to deregister + * the request again. See also Registration#id. + */ + ID string `json:"id,omitempty"` +} + +/*TextDocumentRegistrationOptions defined: + * General text document registration options. + */ +type TextDocumentRegistrationOptions struct { + + /*DocumentSelector defined: + * A document selector to identify the scope of the registration. If set to null + * the document selector provided on the client side will be used. + */ + DocumentSelector DocumentSelector `json:"documentSelector"` +} + +/*SaveOptions defined: + * Save options. + */ +type SaveOptions struct { + + /*IncludeText defined: + * The client is supposed to include the content on save. + */ + IncludeText bool `json:"includeText,omitempty"` +} + +// WorkDoneProgressOptions is +type WorkDoneProgressOptions struct { + + // WorkDoneProgress is + WorkDoneProgress bool `json:"workDoneProgress,omitempty"` +} + +/*InnerServerCapabilities defined: + * Defines the capabilities provided by a language + * server. + */ +type InnerServerCapabilities struct { + + /*TextDocumentSync defined: + * Defines how text documents are synced. Is either a detailed structure defining each notification or + * for backwards compatibility the TextDocumentSyncKind number. + */ + TextDocumentSync interface{} `json:"textDocumentSync,omitempty"` // TextDocumentSyncOptions | TextDocumentSyncKind + + /*CompletionProvider defined: + * The server provides completion support. + */ + CompletionProvider *CompletionOptions `json:"completionProvider,omitempty"` + + /*HoverProvider defined: + * The server provides hover support. + */ + HoverProvider bool `json:"hoverProvider,omitempty"` // boolean | HoverOptions + + /*SignatureHelpProvider defined: + * The server provides signature help support. + */ + SignatureHelpProvider *SignatureHelpOptions `json:"signatureHelpProvider,omitempty"` + + /*DeclarationProvider defined: + * The server provides Goto Declaration support. + */ + DeclarationProvider bool `json:"declarationProvider,omitempty"` // boolean | DeclarationOptions | DeclarationRegistrationOptions + + /*DefinitionProvider defined: + * The server provides goto definition support. + */ + DefinitionProvider bool `json:"definitionProvider,omitempty"` // boolean | DefinitionOptions + + /*TypeDefinitionProvider defined: + * The server provides Goto Type Definition support. + */ + TypeDefinitionProvider bool `json:"typeDefinitionProvider,omitempty"` // boolean | TypeDefinitionOptions | TypeDefinitionRegistrationOptions + + /*ImplementationProvider defined: + * The server provides Goto Implementation support. + */ + ImplementationProvider bool `json:"implementationProvider,omitempty"` // boolean | ImplementationOptions | ImplementationRegistrationOptions + + /*ReferencesProvider defined: + * The server provides find references support. + */ + ReferencesProvider bool `json:"referencesProvider,omitempty"` // boolean | ReferenceOptions + + /*DocumentHighlightProvider defined: + * The server provides document highlight support. + */ + DocumentHighlightProvider bool `json:"documentHighlightProvider,omitempty"` // boolean | DocumentHighlightOptions + + /*DocumentSymbolProvider defined: + * The server provides document symbol support. + */ + DocumentSymbolProvider bool `json:"documentSymbolProvider,omitempty"` // boolean | DocumentSymbolOptions + + /*CodeActionProvider defined: + * The server provides code actions. CodeActionOptions may only be + * specified if the client states that it supports + * `codeActionLiteralSupport` in its initial `initialize` request. + */ + CodeActionProvider interface{} `json:"codeActionProvider,omitempty"` // boolean | CodeActionOptions + + /*CodeLensProvider defined: + * The server provides code lens. + */ + CodeLensProvider *CodeLensOptions `json:"codeLensProvider,omitempty"` + + /*DocumentLinkProvider defined: + * The server provides document link support. + */ + DocumentLinkProvider *DocumentLinkOptions `json:"documentLinkProvider,omitempty"` + + /*ColorProvider defined: + * The server provides color provider support. + */ + ColorProvider bool `json:"colorProvider,omitempty"` // boolean | DocumentColorOptions | DocumentColorRegistrationOptions + + /*WorkspaceSymbolProvider defined: + * The server provides workspace symbol support. + */ + WorkspaceSymbolProvider bool `json:"workspaceSymbolProvider,omitempty"` // boolean | WorkspaceSymbolOptions + + /*DocumentFormattingProvider defined: + * The server provides document formatting. + */ + DocumentFormattingProvider bool `json:"documentFormattingProvider,omitempty"` // boolean | DocumentFormattingOptions + + /*DocumentRangeFormattingProvider defined: + * The server provides document range formatting. + */ + DocumentRangeFormattingProvider bool `json:"documentRangeFormattingProvider,omitempty"` // boolean | DocumentRangeFormattingOptions + + /*DocumentOnTypeFormattingProvider defined: + * The server provides document formatting on typing. + */ + DocumentOnTypeFormattingProvider *DocumentOnTypeFormattingOptions `json:"documentOnTypeFormattingProvider,omitempty"` + + /*RenameProvider defined: + * The server provides rename support. RenameOptions may only be + * specified if the client states that it supports + * `prepareSupport` in its initial `initialize` request. + */ + RenameProvider interface{} `json:"renameProvider,omitempty"` // boolean | RenameOptions + + /*FoldingRangeProvider defined: + * The server provides folding provider support. + */ + FoldingRangeProvider bool `json:"foldingRangeProvider,omitempty"` // boolean | FoldingRangeOptions | FoldingRangeRegistrationOptions + + /*SelectionRangeProvider defined: + * The server provides selection range support. + */ + SelectionRangeProvider bool `json:"selectionRangeProvider,omitempty"` // boolean | SelectionRangeOptions | SelectionRangeRegistrationOptions + + /*ExecuteCommandProvider defined: + * The server provides execute command support. + */ + ExecuteCommandProvider *ExecuteCommandOptions `json:"executeCommandProvider,omitempty"` + + /*Experimental defined: + * Experimental server capabilities. + */ + Experimental interface{} `json:"experimental,omitempty"` +} + +// ServerCapabilities is +type ServerCapabilities struct { + + /*TextDocumentSync defined: + * Defines how text documents are synced. Is either a detailed structure defining each notification or + * for backwards compatibility the TextDocumentSyncKind number. + */ + TextDocumentSync interface{} `json:"textDocumentSync,omitempty"` // TextDocumentSyncOptions | TextDocumentSyncKind + + /*CompletionProvider defined: + * The server provides completion support. + */ + CompletionProvider *CompletionOptions `json:"completionProvider,omitempty"` + + /*HoverProvider defined: + * The server provides hover support. + */ + HoverProvider bool `json:"hoverProvider,omitempty"` // boolean | HoverOptions + + /*SignatureHelpProvider defined: + * The server provides signature help support. + */ + SignatureHelpProvider *SignatureHelpOptions `json:"signatureHelpProvider,omitempty"` + + /*DeclarationProvider defined: + * The server provides Goto Declaration support. + */ + DeclarationProvider bool `json:"declarationProvider,omitempty"` // boolean | DeclarationOptions | DeclarationRegistrationOptions + + /*DefinitionProvider defined: + * The server provides goto definition support. + */ + DefinitionProvider bool `json:"definitionProvider,omitempty"` // boolean | DefinitionOptions + + /*TypeDefinitionProvider defined: + * The server provides Goto Type Definition support. + */ + TypeDefinitionProvider bool `json:"typeDefinitionProvider,omitempty"` // boolean | TypeDefinitionOptions | TypeDefinitionRegistrationOptions + + /*ImplementationProvider defined: + * The server provides Goto Implementation support. + */ + ImplementationProvider bool `json:"implementationProvider,omitempty"` // boolean | ImplementationOptions | ImplementationRegistrationOptions + + /*ReferencesProvider defined: + * The server provides find references support. + */ + ReferencesProvider bool `json:"referencesProvider,omitempty"` // boolean | ReferenceOptions + + /*DocumentHighlightProvider defined: + * The server provides document highlight support. + */ + DocumentHighlightProvider bool `json:"documentHighlightProvider,omitempty"` // boolean | DocumentHighlightOptions + + /*DocumentSymbolProvider defined: + * The server provides document symbol support. + */ + DocumentSymbolProvider bool `json:"documentSymbolProvider,omitempty"` // boolean | DocumentSymbolOptions + + /*CodeActionProvider defined: + * The server provides code actions. CodeActionOptions may only be + * specified if the client states that it supports + * `codeActionLiteralSupport` in its initial `initialize` request. + */ + CodeActionProvider interface{} `json:"codeActionProvider,omitempty"` // boolean | CodeActionOptions + + /*CodeLensProvider defined: + * The server provides code lens. + */ + CodeLensProvider *CodeLensOptions `json:"codeLensProvider,omitempty"` + + /*DocumentLinkProvider defined: + * The server provides document link support. + */ + DocumentLinkProvider *DocumentLinkOptions `json:"documentLinkProvider,omitempty"` + + /*ColorProvider defined: + * The server provides color provider support. + */ + ColorProvider bool `json:"colorProvider,omitempty"` // boolean | DocumentColorOptions | DocumentColorRegistrationOptions + + /*WorkspaceSymbolProvider defined: + * The server provides workspace symbol support. + */ + WorkspaceSymbolProvider bool `json:"workspaceSymbolProvider,omitempty"` // boolean | WorkspaceSymbolOptions + + /*DocumentFormattingProvider defined: + * The server provides document formatting. + */ + DocumentFormattingProvider bool `json:"documentFormattingProvider,omitempty"` // boolean | DocumentFormattingOptions + + /*DocumentRangeFormattingProvider defined: + * The server provides document range formatting. + */ + DocumentRangeFormattingProvider bool `json:"documentRangeFormattingProvider,omitempty"` // boolean | DocumentRangeFormattingOptions + + /*DocumentOnTypeFormattingProvider defined: + * The server provides document formatting on typing. + */ + DocumentOnTypeFormattingProvider *DocumentOnTypeFormattingOptions `json:"documentOnTypeFormattingProvider,omitempty"` + + /*RenameProvider defined: + * The server provides rename support. RenameOptions may only be + * specified if the client states that it supports + * `prepareSupport` in its initial `initialize` request. + */ + RenameProvider interface{} `json:"renameProvider,omitempty"` // boolean | RenameOptions + + /*FoldingRangeProvider defined: + * The server provides folding provider support. + */ + FoldingRangeProvider bool `json:"foldingRangeProvider,omitempty"` // boolean | FoldingRangeOptions | FoldingRangeRegistrationOptions + + /*SelectionRangeProvider defined: + * The server provides selection range support. + */ + SelectionRangeProvider bool `json:"selectionRangeProvider,omitempty"` // boolean | SelectionRangeOptions | SelectionRangeRegistrationOptions + + /*ExecuteCommandProvider defined: + * The server provides execute command support. + */ + ExecuteCommandProvider *ExecuteCommandOptions `json:"executeCommandProvider,omitempty"` + + /*Experimental defined: + * Experimental server capabilities. + */ + Experimental interface{} `json:"experimental,omitempty"` + + /*Workspace defined: + * The workspace server capabilities + */ + Workspace *struct { + + // WorkspaceFolders is + WorkspaceFolders *struct { + + /*Supported defined: + * The Server has support for workspace folders + */ + Supported bool `json:"supported,omitempty"` + + /*ChangeNotifications defined: + * Whether the server wants to receive workspace folder + * change notifications. + * + * If a strings is provided the string is treated as a ID + * under which the notification is registered on the client + * side. The ID can be used to unregister for these events + * using the `client/unregisterCapability` request. + */ + ChangeNotifications string `json:"changeNotifications,omitempty"` // string | boolean + } `json:"workspaceFolders,omitempty"` + } `json:"workspace,omitempty"` +} + +/*InnerInitializeParams defined: + * The initialize parameters + */ +type InnerInitializeParams struct { + + /*ProcessID defined: + * The process Id of the parent process that started + * the server. + */ + ProcessID float64 `json:"processId"` + + /*ClientInfo defined: + * Information about the client + * + * @since 3.15.0 + */ + ClientInfo *struct { + + /*Name defined: + * The name of the client as defined by the client. + */ + Name string `json:"name"` + + /*Version defined: + * The client's version as defined by the client. + */ + Version string `json:"version,omitempty"` + } `json:"clientInfo,omitempty"` + + /*RootPath defined: + * The rootPath of the workspace. Is null + * if no folder is open. + * + * @deprecated in favour of rootUri. + */ + RootPath string `json:"rootPath,omitempty"` + + /*RootURI defined: + * The rootUri of the workspace. Is null if no + * folder is open. If both `rootPath` and `rootUri` are set + * `rootUri` wins. + * + * @deprecated in favour of workspaceFolders. + */ + RootURI DocumentURI `json:"rootUri"` + + /*Capabilities defined: + * The capabilities provided by the client (editor or tool) + */ + Capabilities ClientCapabilities `json:"capabilities"` + + /*InitializationOptions defined: + * User provided initialization options. + */ + InitializationOptions interface{} `json:"initializationOptions,omitempty"` + + /*Trace defined: + * The initial trace setting. If omitted trace is disabled ('off'). + */ + Trace string `json:"trace,omitempty"` // 'off' | 'messages' | 'verbose' + WorkDoneProgressParams +} + +// InitializeParams is +type InitializeParams struct { + + /*ProcessID defined: + * The process Id of the parent process that started + * the server. + */ + ProcessID float64 `json:"processId"` + + /*ClientInfo defined: + * Information about the client + * + * @since 3.15.0 + */ + ClientInfo *struct { + + /*Name defined: + * The name of the client as defined by the client. + */ + Name string `json:"name"` + + /*Version defined: + * The client's version as defined by the client. + */ + Version string `json:"version,omitempty"` + } `json:"clientInfo,omitempty"` + + /*RootPath defined: + * The rootPath of the workspace. Is null + * if no folder is open. + * + * @deprecated in favour of rootUri. + */ + RootPath string `json:"rootPath,omitempty"` + + /*RootURI defined: + * The rootUri of the workspace. Is null if no + * folder is open. If both `rootPath` and `rootUri` are set + * `rootUri` wins. + * + * @deprecated in favour of workspaceFolders. + */ + RootURI DocumentURI `json:"rootUri"` + + /*Capabilities defined: + * The capabilities provided by the client (editor or tool) + */ + Capabilities ClientCapabilities `json:"capabilities"` + + /*InitializationOptions defined: + * User provided initialization options. + */ + InitializationOptions interface{} `json:"initializationOptions,omitempty"` + + /*Trace defined: + * The initial trace setting. If omitted trace is disabled ('off'). + */ + Trace string `json:"trace,omitempty"` // 'off' | 'messages' | 'verbose' + + /*WorkspaceFolders defined: + * The actual configured workspace folders. + */ + WorkspaceFolders []WorkspaceFolder `json:"workspaceFolders"` +} + +/*InitializeResult defined: + * The result returned from an initialize request. + */ +type InitializeResult struct { + + /*Capabilities defined: + * The capabilities the language server provides. + */ + Capabilities ServerCapabilities `json:"capabilities"` + + /*ServerInfo defined: + * Information about the server. + * + * @since 3.15.0 + */ + ServerInfo *struct { + + /*Name defined: + * The name of the server as defined by the server. + */ + Name string `json:"name"` + + /*Version defined: + * The servers's version as defined by the server. + */ + Version string `json:"version,omitempty"` + } `json:"serverInfo,omitempty"` + + /*Custom defined: + * Custom initialization results. + */ + Custom map[string]interface{} `json:"custom"` // [custom: string]: any; +} + +// InitializedParams is +type InitializedParams struct { +} + +// DidChangeConfigurationClientCapabilities is +type DidChangeConfigurationClientCapabilities struct { + + /*DynamicRegistration defined: + * Did change configuration notification supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +// DidChangeConfigurationRegistrationOptions is +type DidChangeConfigurationRegistrationOptions struct { + + // Section is + Section string `json:"section,omitempty"` // string | string[] +} + +/*DidChangeConfigurationParams defined: + * The parameters of a change configuration notification. + */ +type DidChangeConfigurationParams struct { + + /*Settings defined: + * The actual changed settings + */ + Settings interface{} `json:"settings"` +} + +/*ShowMessageParams defined: + * The parameters of a notification message. + */ +type ShowMessageParams struct { + + /*Type defined: + * The message type. See {@link MessageType} + */ + Type MessageType `json:"type"` + + /*Message defined: + * The actual message + */ + Message string `json:"message"` +} + +// MessageActionItem is +type MessageActionItem struct { + + /*Title defined: + * A short title like 'Retry', 'Open Log' etc. + */ + Title string `json:"title"` +} + +// ShowMessageRequestParams is +type ShowMessageRequestParams struct { + + /*Type defined: + * The message type. See {@link MessageType} + */ + Type MessageType `json:"type"` + + /*Message defined: + * The actual message + */ + Message string `json:"message"` + + /*Actions defined: + * The message action items to present. + */ + Actions []MessageActionItem `json:"actions,omitempty"` +} + +/*LogMessageParams defined: + * The log message parameters. + */ +type LogMessageParams struct { + + /*Type defined: + * The message type. See {@link MessageType} + */ + Type MessageType `json:"type"` + + /*Message defined: + * The actual message + */ + Message string `json:"message"` +} + +// TextDocumentSyncClientCapabilities is +type TextDocumentSyncClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether text document synchronization supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*WillSave defined: + * The client supports sending will save notifications. + */ + WillSave bool `json:"willSave,omitempty"` + + /*WillSaveWaitUntil defined: + * The client supports sending a will save request and + * waits for a response providing text edits which will + * be applied to the document before it is saved. + */ + WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"` + + /*DidSave defined: + * The client supports did save notifications. + */ + DidSave bool `json:"didSave,omitempty"` +} + +// TextDocumentSyncOptions is +type TextDocumentSyncOptions struct { + + /*OpenClose defined: + * Open and close notifications are sent to the server. If omitted open close notification should not + * be sent. + */ + OpenClose bool `json:"openClose,omitempty"` + + /*Change defined: + * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full + * and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None. + */ + Change TextDocumentSyncKind `json:"change,omitempty"` + + /*WillSave defined: + * If present will save notifications are sent to the server. If omitted the notification should not be + * sent. + */ + WillSave bool `json:"willSave,omitempty"` + + /*WillSaveWaitUntil defined: + * If present will save wait until requests are sent to the server. If omitted the request should not be + * sent. + */ + WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"` + + /*Save defined: + * If present save notifications are sent to the server. If omitted the notification should not be + * sent. + */ + Save *SaveOptions `json:"save,omitempty"` +} + +/*DidOpenTextDocumentParams defined: + * The parameters send in a open text document notification + */ +type DidOpenTextDocumentParams struct { + + /*TextDocument defined: + * The document that was opened. + */ + TextDocument TextDocumentItem `json:"textDocument"` +} + +/*DidChangeTextDocumentParams defined: + * The change text document notification's parameters. + */ +type DidChangeTextDocumentParams struct { + + /*TextDocument defined: + * The document that did change. The version number points + * to the version after all provided content changes have + * been applied. + */ + TextDocument VersionedTextDocumentIdentifier `json:"textDocument"` + + /*ContentChanges defined: + * The actual content changes. The content changes describe single state changes + * to the document. So if there are two content changes c1 and c2 for a document + * in state S then c1 move the document to S' and c2 to S''. + */ + ContentChanges []TextDocumentContentChangeEvent `json:"contentChanges"` +} + +/*TextDocumentChangeRegistrationOptions defined: + * Describe options to be used when registered for text document change events. + */ +type TextDocumentChangeRegistrationOptions struct { + + /*SyncKind defined: + * How documents are synced to the server. + */ + SyncKind TextDocumentSyncKind `json:"syncKind"` + TextDocumentRegistrationOptions +} + +/*DidCloseTextDocumentParams defined: + * The parameters send in a close text document notification + */ +type DidCloseTextDocumentParams struct { + + /*TextDocument defined: + * The document that was closed. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` +} + +/*DidSaveTextDocumentParams defined: + * The parameters send in a save text document notification + */ +type DidSaveTextDocumentParams struct { + + /*TextDocument defined: + * The document that was closed. + */ + TextDocument VersionedTextDocumentIdentifier `json:"textDocument"` + + /*Text defined: + * Optional the content when saved. Depends on the includeText value + * when the save notification was requested. + */ + Text string `json:"text,omitempty"` +} + +/*TextDocumentSaveRegistrationOptions defined: + * Save registration options. + */ +type TextDocumentSaveRegistrationOptions struct { + TextDocumentRegistrationOptions + SaveOptions +} + +/*WillSaveTextDocumentParams defined: + * The parameters send in a will save text document notification. + */ +type WillSaveTextDocumentParams struct { + + /*TextDocument defined: + * The document that will be saved. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Reason defined: + * The 'TextDocumentSaveReason'. + */ + Reason TextDocumentSaveReason `json:"reason"` +} + +// DidChangeWatchedFilesClientCapabilities is +type DidChangeWatchedFilesClientCapabilities struct { + + /*DynamicRegistration defined: + * Did change watched files notification supports dynamic registration. Please note + * that the current protocol doesn't support static configuration for file changes + * from the server side. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*DidChangeWatchedFilesParams defined: + * The watched files change notification's parameters. + */ +type DidChangeWatchedFilesParams struct { + + /*Changes defined: + * The actual file events. + */ + Changes []FileEvent `json:"changes"` +} + +/*FileEvent defined: + * An event describing a file change. + */ +type FileEvent struct { + + /*URI defined: + * The file's uri. + */ + URI DocumentURI `json:"uri"` + + /*Type defined: + * The change type. + */ + Type FileChangeType `json:"type"` +} + +/*DidChangeWatchedFilesRegistrationOptions defined: + * Describe options to be used when registered for text document change events. + */ +type DidChangeWatchedFilesRegistrationOptions struct { + + /*Watchers defined: + * The watchers to register. + */ + Watchers []FileSystemWatcher `json:"watchers"` +} + +// FileSystemWatcher is +type FileSystemWatcher struct { + + /*GlobPattern defined: + * The glob pattern to watch. Glob patterns can have the following syntax: + * - `*` to match one or more characters in a path segment + * - `?` to match on one character in a path segment + * - `**` to match any number of path segments, including none + * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) + * - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) + * - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`) + */ + GlobPattern string `json:"globPattern"` + + /*Kind defined: + * The kind of events of interest. If omitted it defaults + * to WatchKind.Create | WatchKind.Change | WatchKind.Delete + * which is 7. + */ + Kind float64 `json:"kind,omitempty"` +} + +/*PublishDiagnosticsClientCapabilities defined: + * The publish diagnostic client capabilities. + */ +type PublishDiagnosticsClientCapabilities struct { + + /*RelatedInformation defined: + * Whether the clients accepts diagnostics with related information. + */ + RelatedInformation bool `json:"relatedInformation,omitempty"` + + /*TagSupport defined: + * Client supports the tag property to provide meta data about a diagnostic. + * Clients supporting tags have to handle unknown tags gracefully. + * + * @since 3.15.0 + */ + TagSupport *struct { + + /*ValueSet defined: + * The tags supported by the client. + */ + ValueSet []DiagnosticTag `json:"valueSet"` + } `json:"tagSupport,omitempty"` +} + +/*PublishDiagnosticsParams defined: + * The publish diagnostic notification's parameters. + */ +type PublishDiagnosticsParams struct { + + /*URI defined: + * The URI for which diagnostic information is reported. + */ + URI DocumentURI `json:"uri"` + + /*Version defined: + * Optional the version number of the document the diagnostics are published for. + * + * @since 3.15.0 + */ + Version float64 `json:"version,omitempty"` + + /*Diagnostics defined: + * An array of diagnostic information items. + */ + Diagnostics []Diagnostic `json:"diagnostics"` +} + +/*CompletionClientCapabilities defined: + * Completion client capabilities + */ +type CompletionClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether completion supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*CompletionItem defined: + * The client supports the following `CompletionItem` specific + * capabilities. + */ + CompletionItem *struct { + + /*SnippetSupport defined: + * Client supports snippets as insert text. + * + * A snippet can define tab stops and placeholders with `$1`, `$2` + * and `${3:foo}`. `$0` defines the final tab stop, it defaults to + * the end of the snippet. Placeholders with equal identifiers are linked, + * that is typing in one will update others too. + */ + SnippetSupport bool `json:"snippetSupport,omitempty"` + + /*CommitCharactersSupport defined: + * Client supports commit characters on a completion item. + */ + CommitCharactersSupport bool `json:"commitCharactersSupport,omitempty"` + + /*DocumentationFormat defined: + * Client supports the follow content formats for the documentation + * property. The order describes the preferred format of the client. + */ + DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"` + + /*DeprecatedSupport defined: + * Client supports the deprecated property on a completion item. + */ + DeprecatedSupport bool `json:"deprecatedSupport,omitempty"` + + /*PreselectSupport defined: + * Client supports the preselect property on a completion item. + */ + PreselectSupport bool `json:"preselectSupport,omitempty"` + + /*TagSupport defined: + * Client supports the tag property on a completion item. Clients supporting + * tags have to handle unknown tags gracefully. Clients especially need to + * preserve unknown tags when sending a completion item back to the server in + * a resolve call. + * + * @since 3.15.0 + */ + TagSupport *struct { + + /*ValueSet defined: + * The tags supported by the client. + */ + ValueSet []CompletionItemTag `json:"valueSet"` + } `json:"tagSupport,omitempty"` + } `json:"completionItem,omitempty"` + + // CompletionItemKind is + CompletionItemKind *struct { + + /*ValueSet defined: + * The completion item kind values the client supports. When this + * property exists the client also guarantees that it will + * handle values outside its set gracefully and falls back + * to a default value when unknown. + * + * If this property is not present the client only supports + * the completion items kinds from `Text` to `Reference` as defined in + * the initial version of the protocol. + */ + ValueSet []CompletionItemKind `json:"valueSet,omitempty"` + } `json:"completionItemKind,omitempty"` + + /*ContextSupport defined: + * The client supports to send additional context information for a + * `textDocument/completion` requestion. + */ + ContextSupport bool `json:"contextSupport,omitempty"` +} + +/*CompletionContext defined: + * Contains additional information about the context in which a completion request is triggered. + */ +type CompletionContext struct { + + /*TriggerKind defined: + * How the completion was triggered. + */ + TriggerKind CompletionTriggerKind `json:"triggerKind"` + + /*TriggerCharacter defined: + * The trigger character (a single character) that has trigger code complete. + * Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` + */ + TriggerCharacter string `json:"triggerCharacter,omitempty"` +} + +/*CompletionParams defined: + * Completion parameters + */ +type CompletionParams struct { + + /*Context defined: + * The completion context. This is only available it the client specifies + * to send this using the client capability `textDocument.completion.contextSupport === true` + */ + Context *CompletionContext `json:"context,omitempty"` + TextDocumentPositionParams + WorkDoneProgressParams + PartialResultParams +} + +/*CompletionOptions defined: + * Completion options. + */ +type CompletionOptions struct { + + /*TriggerCharacters defined: + * Most tools trigger completion request automatically without explicitly requesting + * it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user + * starts to type an identifier. For example if the user types `c` in a JavaScript file + * code complete will automatically pop up present `console` besides others as a + * completion item. Characters that make up identifiers don't need to be listed here. + * + * If code complete should automatically be trigger on characters not being valid inside + * an identifier (for example `.` in JavaScript) list them in `triggerCharacters`. + */ + TriggerCharacters []string `json:"triggerCharacters,omitempty"` + + /*AllCommitCharacters defined: + * The list of all possible characters that commit a completion. This field can be used + * if clients don't support individual commit characters per completion item. See + * `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport` + * + * @since 3.2.0 + */ + AllCommitCharacters []string `json:"allCommitCharacters,omitempty"` + + /*ResolveProvider defined: + * The server provides support to resolve additional + * information for a completion item. + */ + ResolveProvider bool `json:"resolveProvider,omitempty"` + WorkDoneProgressOptions +} + +/*CompletionRegistrationOptions defined: + * Registration options for a [CompletionRequest](#CompletionRequest). + */ +type CompletionRegistrationOptions struct { + TextDocumentRegistrationOptions + CompletionOptions +} + +// HoverClientCapabilities is +type HoverClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether hover supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*ContentFormat defined: + * Client supports the follow content formats for the content + * property. The order describes the preferred format of the client. + */ + ContentFormat []MarkupKind `json:"contentFormat,omitempty"` +} + +/*HoverOptions defined: + * Hover options. + */ +type HoverOptions struct { + WorkDoneProgressOptions +} + +/*HoverParams defined: + * Parameters for a [HoverRequest](#HoverRequest). + */ +type HoverParams struct { + TextDocumentPositionParams + WorkDoneProgressParams +} + +/*HoverRegistrationOptions defined: + * Registration options for a [HoverRequest](#HoverRequest). + */ +type HoverRegistrationOptions struct { + TextDocumentRegistrationOptions + HoverOptions +} + +/*SignatureHelpClientCapabilities defined: + * Client Capabilities for a [SignatureHelpRequest](#SignatureHelpRequest). + */ +type SignatureHelpClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether signature help supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*SignatureInformation defined: + * The client supports the following `SignatureInformation` + * specific properties. + */ + SignatureInformation *struct { + + /*DocumentationFormat defined: + * Client supports the follow content formats for the documentation + * property. The order describes the preferred format of the client. + */ + DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"` + + /*ParameterInformation defined: + * Client capabilities specific to parameter information. + */ + ParameterInformation *struct { + + /*LabelOffsetSupport defined: + * The client supports processing label offsets instead of a + * simple label string. + * + * @since 3.14.0 + */ + LabelOffsetSupport bool `json:"labelOffsetSupport,omitempty"` + } `json:"parameterInformation,omitempty"` + } `json:"signatureInformation,omitempty"` + + /*ContextSupport defined: + * The client supports to send additional context information for a + * `textDocument/signatureHelp` request. A client that opts into + * contextSupport will also support the `retriggerCharacters` on + * `SignatureHelpOptions`. + * + * @since 3.15.0 + */ + ContextSupport bool `json:"contextSupport,omitempty"` +} + +/*SignatureHelpOptions defined: + * Server Capabilities for a [SignatureHelpRequest](#SignatureHelpRequest). + */ +type SignatureHelpOptions struct { + + /*TriggerCharacters defined: + * List of characters that trigger signature help. + */ + TriggerCharacters []string `json:"triggerCharacters,omitempty"` + + /*RetriggerCharacters defined: + * List of characters that re-trigger signature help. + * + * These trigger characters are only active when signature help is already showing. All trigger characters + * are also counted as re-trigger characters. + * + * @since 3.15.0 + */ + RetriggerCharacters []string `json:"retriggerCharacters,omitempty"` + WorkDoneProgressOptions +} + +/*SignatureHelpContext defined: + * Additional information about the context in which a signature help request was triggered. + * + * @since 3.15.0 + */ +type SignatureHelpContext struct { + + /*TriggerKind defined: + * Action that caused signature help to be triggered. + */ + TriggerKind SignatureHelpTriggerKind `json:"triggerKind"` + + /*TriggerCharacter defined: + * Character that caused signature help to be triggered. + * + * This is undefined when `triggerKind !== SignatureHelpTriggerKind.TriggerCharacter` + */ + TriggerCharacter string `json:"triggerCharacter,omitempty"` + + /*IsRetrigger defined: + * `true` if signature help was already showing when it was triggered. + * + * Retriggers occur when the signature help is already active and can be caused by actions such as + * typing a trigger character, a cursor move, or document content changes. + */ + IsRetrigger bool `json:"isRetrigger"` + + /*ActiveSignatureHelp defined: + * The currently active `SignatureHelp`. + * + * The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field updated based on + * the user navigating through available signatures. + */ + ActiveSignatureHelp *SignatureHelp `json:"activeSignatureHelp,omitempty"` +} + +/*SignatureHelpParams defined: + * Parameters for a [SignatureHelpRequest](#SignatureHelpRequest). + */ +type SignatureHelpParams struct { + + /*Context defined: + * The signature help context. This is only available if the client specifies + * to send this using the client capability `textDocument.signatureHelp.contextSupport === true` + * + * @since 3.15.0 + */ + Context *SignatureHelpContext `json:"context,omitempty"` + TextDocumentPositionParams + WorkDoneProgressParams +} + +/*SignatureHelpRegistrationOptions defined: + * Registration options for a [SignatureHelpRequest](#SignatureHelpRequest). + */ +type SignatureHelpRegistrationOptions struct { + TextDocumentRegistrationOptions + SignatureHelpOptions +} + +/*DefinitionClientCapabilities defined: + * Client Capabilities for a [DefinitionRequest](#DefinitionRequest). + */ +type DefinitionClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether definition supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*LinkSupport defined: + * The client supports additional metadata in the form of definition links. + * + * @since 3.14.0 + */ + LinkSupport bool `json:"linkSupport,omitempty"` +} + +/*DefinitionOptions defined: + * Server Capabilities for a [DefinitionRequest](#DefinitionRequest). + */ +type DefinitionOptions struct { + WorkDoneProgressOptions +} + +/*DefinitionParams defined: + * Parameters for a [DefinitionRequest](#DefinitionRequest). + */ +type DefinitionParams struct { + TextDocumentPositionParams + WorkDoneProgressParams + PartialResultParams +} + +/*DefinitionRegistrationOptions defined: + * Registration options for a [DefinitionRequest](#DefinitionRequest). + */ +type DefinitionRegistrationOptions struct { + TextDocumentRegistrationOptions + DefinitionOptions +} + +/*ReferenceClientCapabilities defined: + * Client Capabilities for a [ReferencesRequest](#ReferencesRequest). + */ +type ReferenceClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether references supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*ReferenceParams defined: + * Parameters for a [ReferencesRequest](#ReferencesRequest). + */ +type ReferenceParams struct { + + // Context is + Context ReferenceContext `json:"context"` + TextDocumentPositionParams + WorkDoneProgressParams + PartialResultParams +} + +/*ReferenceOptions defined: + * Reference options. + */ +type ReferenceOptions struct { + WorkDoneProgressOptions +} + +/*ReferenceRegistrationOptions defined: + * Registration options for a [ReferencesRequest](#ReferencesRequest). + */ +type ReferenceRegistrationOptions struct { + TextDocumentRegistrationOptions + ReferenceOptions +} + +/*DocumentHighlightClientCapabilities defined: + * Client Capabilities for a [DocumentHighlightRequest](#DocumentHighlightRequest). + */ +type DocumentHighlightClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether document highlight supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*DocumentHighlightParams defined: + * Parameters for a [DocumentHighlightRequest](#DocumentHighlightRequest). + */ +type DocumentHighlightParams struct { + TextDocumentPositionParams + WorkDoneProgressParams + PartialResultParams +} + +/*DocumentHighlightOptions defined: + * Provider options for a [DocumentHighlightRequest](#DocumentHighlightRequest). + */ +type DocumentHighlightOptions struct { + WorkDoneProgressOptions +} + +/*DocumentHighlightRegistrationOptions defined: + * Registration options for a [DocumentHighlightRequest](#DocumentHighlightRequest). + */ +type DocumentHighlightRegistrationOptions struct { + TextDocumentRegistrationOptions + DocumentHighlightOptions +} + +/*DocumentSymbolClientCapabilities defined: + * Client Capabilities for a [DocumentSymbolRequest](#DocumentSymbolRequest). + */ +type DocumentSymbolClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether document symbol supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*SymbolKind defined: + * Specific capabilities for the `SymbolKind`. + */ + SymbolKind *struct { + + /*ValueSet defined: + * The symbol kind values the client supports. When this + * property exists the client also guarantees that it will + * handle values outside its set gracefully and falls back + * to a default value when unknown. + * + * If this property is not present the client only supports + * the symbol kinds from `File` to `Array` as defined in + * the initial version of the protocol. + */ + ValueSet []SymbolKind `json:"valueSet,omitempty"` + } `json:"symbolKind,omitempty"` + + /*HierarchicalDocumentSymbolSupport defined: + * The client support hierarchical document symbols. + */ + HierarchicalDocumentSymbolSupport bool `json:"hierarchicalDocumentSymbolSupport,omitempty"` +} + +/*DocumentSymbolParams defined: + * Parameters for a [DocumentSymbolRequest](#DocumentSymbolRequest). + */ +type DocumentSymbolParams struct { + + /*TextDocument defined: + * The text document. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + WorkDoneProgressParams + PartialResultParams +} + +/*DocumentSymbolOptions defined: + * Provider options for a [DocumentSymbolRequest](#DocumentSymbolRequest). + */ +type DocumentSymbolOptions struct { + WorkDoneProgressOptions +} + +/*DocumentSymbolRegistrationOptions defined: + * Registration options for a [DocumentSymbolRequest](#DocumentSymbolRequest). + */ +type DocumentSymbolRegistrationOptions struct { + TextDocumentRegistrationOptions + DocumentSymbolOptions +} + +/*CodeActionClientCapabilities defined: + * The Client Capabilities of a [CodeActionRequest](#CodeActionRequest). + */ +type CodeActionClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether code action supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*CodeActionLiteralSupport defined: + * The client support code action literals as a valid + * response of the `textDocument/codeAction` request. + * + * @since 3.8.0 + */ + CodeActionLiteralSupport *struct { + + /*CodeActionKind defined: + * The code action kind is support with the following value + * set. + */ + CodeActionKind struct { + + /*ValueSet defined: + * The code action kind values the client supports. When this + * property exists the client also guarantees that it will + * handle values outside its set gracefully and falls back + * to a default value when unknown. + */ + ValueSet []CodeActionKind `json:"valueSet"` + } `json:"codeActionKind"` + } `json:"codeActionLiteralSupport,omitempty"` + + /*IsPreferredSupport defined: + * Whether code action supports the `isPreferred` property. + * @since 3.15.0 + */ + IsPreferredSupport bool `json:"isPreferredSupport,omitempty"` +} + +/*CodeActionParams defined: + * The parameters of a [CodeActionRequest](#CodeActionRequest). + */ +type CodeActionParams struct { + + /*TextDocument defined: + * The document in which the command was invoked. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Range defined: + * The range for which the command was invoked. + */ + Range Range `json:"range"` + + /*Context defined: + * Context carrying additional information. + */ + Context CodeActionContext `json:"context"` + WorkDoneProgressParams + PartialResultParams +} + +/*CodeActionOptions defined: + * Provider options for a [CodeActionRequest](#CodeActionRequest). + */ +type CodeActionOptions struct { + + /*CodeActionKinds defined: + * CodeActionKinds that this server may return. + * + * The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server + * may list out every specific kind they provide. + */ + CodeActionKinds []CodeActionKind `json:"codeActionKinds,omitempty"` + WorkDoneProgressOptions +} + +/*CodeActionRegistrationOptions defined: + * Registration options for a [CodeActionRequest](#CodeActionRequest). + */ +type CodeActionRegistrationOptions struct { + TextDocumentRegistrationOptions + CodeActionOptions +} + +/*WorkspaceSymbolClientCapabilities defined: + * Client capabilities for a [WorkspaceSymbolRequest](#WorkspaceSymbolRequest). + */ +type WorkspaceSymbolClientCapabilities struct { + + /*DynamicRegistration defined: + * Symbol request supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*SymbolKind defined: + * Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. + */ + SymbolKind *struct { + + /*ValueSet defined: + * The symbol kind values the client supports. When this + * property exists the client also guarantees that it will + * handle values outside its set gracefully and falls back + * to a default value when unknown. + * + * If this property is not present the client only supports + * the symbol kinds from `File` to `Array` as defined in + * the initial version of the protocol. + */ + ValueSet []SymbolKind `json:"valueSet,omitempty"` + } `json:"symbolKind,omitempty"` +} + +/*WorkspaceSymbolParams defined: + * The parameters of a [WorkspaceSymbolRequest](#WorkspaceSymbolRequest). + */ +type WorkspaceSymbolParams struct { + + /*Query defined: + * A query string to filter symbols by. Clients may send an empty + * string here to request all symbols. + */ + Query string `json:"query"` + WorkDoneProgressParams + PartialResultParams +} + +/*WorkspaceSymbolOptions defined: + * Server capabilities for a [WorkspaceSymbolRequest](#WorkspaceSymbolRequest). + */ +type WorkspaceSymbolOptions struct { + WorkDoneProgressOptions +} + +/*WorkspaceSymbolRegistrationOptions defined: + * Registration options for a [WorkspaceSymbolRequest](#WorkspaceSymbolRequest). + */ +type WorkspaceSymbolRegistrationOptions struct { + WorkspaceSymbolOptions +} + +/*CodeLensClientCapabilities defined: + * The client capabilities of a [CodeLensRequest](#CodeLensRequest). + */ +type CodeLensClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether code lens supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*CodeLensParams defined: + * The parameters of a [CodeLensRequest](#CodeLensRequest). + */ +type CodeLensParams struct { + + /*TextDocument defined: + * The document to request code lens for. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + WorkDoneProgressParams + PartialResultParams +} + +/*CodeLensOptions defined: + * Code Lens provider options of a [CodeLensRequest](#CodeLensRequest). + */ +type CodeLensOptions struct { + + /*ResolveProvider defined: + * Code lens has a resolve provider as well. + */ + ResolveProvider bool `json:"resolveProvider,omitempty"` + WorkDoneProgressOptions +} + +/*CodeLensRegistrationOptions defined: + * Registration options for a [CodeLensRequest](#CodeLensRequest). + */ +type CodeLensRegistrationOptions struct { + TextDocumentRegistrationOptions + CodeLensOptions +} + +/*DocumentLinkClientCapabilities defined: + * The client capabilities of a [DocumentLinkRequest](#DocumentLinkRequest). + */ +type DocumentLinkClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether document link supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*TooltipSupport defined: + * Whether the client support the `tooltip` property on `DocumentLink`. + * + * @since 3.15.0 + */ + TooltipSupport bool `json:"tooltipSupport,omitempty"` +} + +/*DocumentLinkParams defined: + * The parameters of a [DocumentLinkRequest](#DocumentLinkRequest). + */ +type DocumentLinkParams struct { + + /*TextDocument defined: + * The document to provide document links for. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + WorkDoneProgressParams + PartialResultParams +} + +/*DocumentLinkOptions defined: + * Provider options for a [DocumentLinkRequest](#DocumentLinkRequest). + */ +type DocumentLinkOptions struct { + + /*ResolveProvider defined: + * Document links have a resolve provider as well. + */ + ResolveProvider bool `json:"resolveProvider,omitempty"` + WorkDoneProgressOptions +} + +/*DocumentLinkRegistrationOptions defined: + * Registration options for a [DocumentLinkRequest](#DocumentLinkRequest). + */ +type DocumentLinkRegistrationOptions struct { + TextDocumentRegistrationOptions + DocumentLinkOptions +} + +/*DocumentFormattingClientCapabilities defined: + * Client capabilities of a [DocumentFormattingRequest](#DocumentFormattingRequest). + */ +type DocumentFormattingClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether formatting supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*DocumentFormattingParams defined: + * The parameters of a [DocumentFormattingRequest](#DocumentFormattingRequest). + */ +type DocumentFormattingParams struct { + + /*TextDocument defined: + * The document to format. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Options defined: + * The format options + */ + Options FormattingOptions `json:"options"` + WorkDoneProgressParams +} + +/*DocumentFormattingOptions defined: + * Provider options for a [DocumentFormattingRequest](#DocumentFormattingRequest). + */ +type DocumentFormattingOptions struct { + WorkDoneProgressOptions +} + +/*DocumentFormattingRegistrationOptions defined: + * Registration options for a [DocumentFormattingRequest](#DocumentFormattingRequest). + */ +type DocumentFormattingRegistrationOptions struct { + TextDocumentRegistrationOptions + DocumentFormattingOptions +} + +/*DocumentRangeFormattingClientCapabilities defined: + * Client capabilities of a [DocumentRangeFormattingRequest](#DocumentRangeFormattingRequest). + */ +type DocumentRangeFormattingClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether range formatting supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*DocumentRangeFormattingParams defined: + * The parameters of a [DocumentRangeFormattingRequest](#DocumentRangeFormattingRequest). + */ +type DocumentRangeFormattingParams struct { + + /*TextDocument defined: + * The document to format. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Range defined: + * The range to format + */ + Range Range `json:"range"` + + /*Options defined: + * The format options + */ + Options FormattingOptions `json:"options"` + WorkDoneProgressParams +} + +/*DocumentRangeFormattingOptions defined: + * Provider options for a [DocumentRangeFormattingRequest](#DocumentRangeFormattingRequest). + */ +type DocumentRangeFormattingOptions struct { + WorkDoneProgressOptions +} + +/*DocumentRangeFormattingRegistrationOptions defined: + * Registration options for a [DocumentRangeFormattingRequest](#DocumentRangeFormattingRequest). + */ +type DocumentRangeFormattingRegistrationOptions struct { + TextDocumentRegistrationOptions + DocumentRangeFormattingOptions +} + +/*DocumentOnTypeFormattingClientCapabilities defined: + * Client capabilities of a [DocumentOnTypeFormattingRequest](#DocumentOnTypeFormattingRequest). + */ +type DocumentOnTypeFormattingClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether on type formatting supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*DocumentOnTypeFormattingParams defined: + * The parameters of a [DocumentOnTypeFormattingRequest](#DocumentOnTypeFormattingRequest). + */ +type DocumentOnTypeFormattingParams struct { + + /*TextDocument defined: + * The document to format. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Position defined: + * The position at which this request was send. + */ + Position Position `json:"position"` + + /*Ch defined: + * The character that has been typed. + */ + Ch string `json:"ch"` + + /*Options defined: + * The format options. + */ + Options FormattingOptions `json:"options"` +} + +/*DocumentOnTypeFormattingOptions defined: + * Provider options for a [DocumentOnTypeFormattingRequest](#DocumentOnTypeFormattingRequest). + */ +type DocumentOnTypeFormattingOptions struct { + + /*FirstTriggerCharacter defined: + * A character on which formatting should be triggered, like `}`. + */ + FirstTriggerCharacter string `json:"firstTriggerCharacter"` + + /*MoreTriggerCharacter defined: + * More trigger characters. + */ + MoreTriggerCharacter []string `json:"moreTriggerCharacter,omitempty"` +} + +/*DocumentOnTypeFormattingRegistrationOptions defined: + * Registration options for a [DocumentOnTypeFormattingRequest](#DocumentOnTypeFormattingRequest). + */ +type DocumentOnTypeFormattingRegistrationOptions struct { + TextDocumentRegistrationOptions + DocumentOnTypeFormattingOptions +} + +// RenameClientCapabilities is +type RenameClientCapabilities struct { + + /*DynamicRegistration defined: + * Whether rename supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + + /*PrepareSupport defined: + * Client supports testing for validity of rename operations + * before execution. + * + * @since version 3.12.0 + */ + PrepareSupport bool `json:"prepareSupport,omitempty"` +} + +/*RenameParams defined: + * The parameters of a [RenameRequest](#RenameRequest). + */ +type RenameParams struct { + + /*TextDocument defined: + * The document to rename. + */ + TextDocument TextDocumentIdentifier `json:"textDocument"` + + /*Position defined: + * The position at which this request was sent. + */ + Position Position `json:"position"` + + /*NewName defined: + * The new name of the symbol. If the given name is not valid the + * request must return a [ResponseError](#ResponseError) with an + * appropriate message set. + */ + NewName string `json:"newName"` + WorkDoneProgressParams +} + +/*RenameOptions defined: + * Provider options for a [RenameRequest](#RenameRequest). + */ +type RenameOptions struct { + + /*PrepareProvider defined: + * Renames should be checked and tested before being executed. + * + * @since version 3.12.0 + */ + PrepareProvider bool `json:"prepareProvider,omitempty"` + WorkDoneProgressOptions +} + +/*RenameRegistrationOptions defined: + * Registration options for a [RenameRequest](#RenameRequest). + */ +type RenameRegistrationOptions struct { + TextDocumentRegistrationOptions + RenameOptions +} + +// PrepareRenameParams is +type PrepareRenameParams struct { + TextDocumentPositionParams + WorkDoneProgressParams +} + +/*ExecuteCommandClientCapabilities defined: + * The client capabilities of a [ExecuteCommandRequest](#ExecuteCommandRequest). + */ +type ExecuteCommandClientCapabilities struct { + + /*DynamicRegistration defined: + * Execute command supports dynamic registration. + */ + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +/*ExecuteCommandParams defined: + * The parameters of a [ExecuteCommandRequest](#ExecuteCommandRequest). + */ +type ExecuteCommandParams struct { + + /*Command defined: + * The identifier of the actual command handler. + */ + Command string `json:"command"` + + /*Arguments defined: + * Arguments that the command should be invoked with. + */ + Arguments []interface{} `json:"arguments,omitempty"` + WorkDoneProgressParams +} + +/*ExecuteCommandOptions defined: + * The server capabilities of a [ExecuteCommandRequest](#ExecuteCommandRequest). + */ +type ExecuteCommandOptions struct { + + /*Commands defined: + * The commands to be executed on the server + */ + Commands []string `json:"commands"` + WorkDoneProgressOptions +} + +/*ExecuteCommandRegistrationOptions defined: + * Registration options for a [ExecuteCommandRequest](#ExecuteCommandRequest). + */ +type ExecuteCommandRegistrationOptions struct { + ExecuteCommandOptions +} + +// WorkspaceEditClientCapabilities is +type WorkspaceEditClientCapabilities struct { + + /*DocumentChanges defined: + * The client supports versioned document changes in `WorkspaceEdit`s + */ + DocumentChanges bool `json:"documentChanges,omitempty"` + + /*ResourceOperations defined: + * The resource operations the client supports. Clients should at least + * support 'create', 'rename' and 'delete' files and folders. + * + * @since 3.13.0 + */ + ResourceOperations []ResourceOperationKind `json:"resourceOperations,omitempty"` + + /*FailureHandling defined: + * The failure handling strategy of a client if applying the workspace edit + * fails. + * + * @since 3.13.0 + */ + FailureHandling FailureHandlingKind `json:"failureHandling,omitempty"` +} + +/*ApplyWorkspaceEditParams defined: + * The parameters passed via a apply workspace edit request. + */ +type ApplyWorkspaceEditParams struct { + + /*Label defined: + * An optional label of the workspace edit. This label is + * presented in the user interface for example on an undo + * stack to undo the workspace edit. + */ + Label string `json:"label,omitempty"` + + /*Edit defined: + * The edits to apply. + */ + Edit WorkspaceEdit `json:"edit"` +} + +/*ApplyWorkspaceEditResponse defined: + * A response returned from the apply workspace edit request. + */ +type ApplyWorkspaceEditResponse struct { + + /*Applied defined: + * Indicates whether the edit was applied or not. + */ + Applied bool `json:"applied"` + + /*FailureReason defined: + * An optional textual description for why the edit was not applied. + * This may be used by the server for diagnostic logging or to provide + * a suitable error for a request that triggered the edit. + */ + FailureReason string `json:"failureReason,omitempty"` + + /*FailedChange defined: + * Depending on the client's failure handling strategy `failedChange` might + * contain the index of the change that failed. This property is only available + * if the client signals a `failureHandlingStrategy` in its client capabilities. + */ + FailedChange float64 `json:"failedChange,omitempty"` +} + +/*Position defined: + * Position in a text document expressed as zero-based line and character offset. + * The offsets are based on a UTF-16 string representation. So a string of the form + * `a𐐀b` the character offset of the character `a` is 0, the character offset of `𐐀` + * is 1 and the character offset of b is 3 since `𐐀` is represented using two code + * units in UTF-16. + * + * Positions are line end character agnostic. So you can not specify a position that + * denotes `\r|\n` or `\n|` where `|` represents the character offset. + */ +type Position struct { + + /*Line defined: + * Line position in a document (zero-based). + * If a line number is greater than the number of lines in a document, it defaults back to the number of lines in the document. + * If a line number is negative, it defaults to 0. + */ + Line float64 `json:"line"` + + /*Character defined: + * Character offset on a line in a document (zero-based). Assuming that the line is + * represented as a string, the `character` value represents the gap between the + * `character` and `character + 1`. + * + * If the character value is greater than the line length it defaults back to the + * line length. + * If a line number is negative, it defaults to 0. + */ + Character float64 `json:"character"` +} + +/*Range defined: + * A range in a text document expressed as (zero-based) start and end positions. + * + * If you want to specify a range that contains a line including the line ending + * character(s) then use an end position denoting the start of the next line. + * For example: + * ```ts + * { + * start: { line: 5, character: 23 } + * end : { line 6, character : 0 } + * } + * ``` + */ +type Range struct { + + /*Start defined: + * The range's start position + */ + Start Position `json:"start"` + + /*End defined: + * The range's end position. + */ + End Position `json:"end"` +} + +/*Location defined: + * Represents a location inside a resource, such as a line + * inside a text file. + */ +type Location struct { + + // URI is + URI DocumentURI `json:"uri"` + + // Range is + Range Range `json:"range"` +} + +/*LocationLink defined: + * Represents the connection of two locations. Provides additional metadata over normal [locations](#Location), + * including an origin range. + */ +type LocationLink struct { + + /*OriginSelectionRange defined: + * Span of the origin of this link. + * + * Used as the underlined span for mouse definition hover. Defaults to the word range at + * the definition position. + */ + OriginSelectionRange *Range `json:"originSelectionRange,omitempty"` + + /*TargetURI defined: + * The target resource identifier of this link. + */ + TargetURI DocumentURI `json:"targetUri"` + + /*TargetRange defined: + * The full target range of this link. If the target for example is a symbol then target range is the + * range enclosing this symbol not including leading/trailing whitespace but everything else + * like comments. This information is typically used to highlight the range in the editor. + */ + TargetRange Range `json:"targetRange"` + + /*TargetSelectionRange defined: + * The range that should be selected and revealed when this link is being followed, e.g the name of a function. + * Must be contained by the `targetRange`. See also `DocumentSymbol#range` + */ + TargetSelectionRange Range `json:"targetSelectionRange"` +} + +/*Color defined: + * Represents a color in RGBA space. + */ +type Color struct { + + /*Red defined: + * The red component of this color in the range [0-1]. + */ + Red float64 `json:"red"` + + /*Green defined: + * The green component of this color in the range [0-1]. + */ + Green float64 `json:"green"` + + /*Blue defined: + * The blue component of this color in the range [0-1]. + */ + Blue float64 `json:"blue"` + + /*Alpha defined: + * The alpha component of this color in the range [0-1]. + */ + Alpha float64 `json:"alpha"` +} + +/*ColorInformation defined: + * Represents a color range from a document. + */ +type ColorInformation struct { + + /*Range defined: + * The range in the document where this color appears. + */ + Range Range `json:"range"` + + /*Color defined: + * The actual color value for this color range. + */ + Color Color `json:"color"` +} + +// ColorPresentation is +type ColorPresentation struct { + + /*Label defined: + * The label of this color presentation. It will be shown on the color + * picker header. By default this is also the text that is inserted when selecting + * this color presentation. + */ + Label string `json:"label"` + + /*TextEdit defined: + * An [edit](#TextEdit) which is applied to a document when selecting + * this presentation for the color. When `falsy` the [label](#ColorPresentation.label) + * is used. + */ + TextEdit *TextEdit `json:"textEdit,omitempty"` + + /*AdditionalTextEdits defined: + * An optional array of additional [text edits](#TextEdit) that are applied when + * selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves. + */ + AdditionalTextEdits []TextEdit `json:"additionalTextEdits,omitempty"` +} + +/*DiagnosticRelatedInformation defined: + * Represents a related message and source code location for a diagnostic. This should be + * used to point to code locations that cause or related to a diagnostics, e.g when duplicating + * a symbol in a scope. + */ +type DiagnosticRelatedInformation struct { + + /*Location defined: + * The location of this related diagnostic information. + */ + Location Location `json:"location"` + + /*Message defined: + * The message of this related diagnostic information. + */ + Message string `json:"message"` +} + +/*Diagnostic defined: + * Represents a diagnostic, such as a compiler error or warning. Diagnostic objects + * are only valid in the scope of a resource. + */ +type Diagnostic struct { + + /*Range defined: + * The range at which the message applies + */ + Range Range `json:"range"` + + /*Severity defined: + * The diagnostic's severity. Can be omitted. If omitted it is up to the + * client to interpret diagnostics as error, warning, info or hint. + */ + Severity DiagnosticSeverity `json:"severity,omitempty"` + + /*Code defined: + * The diagnostic's code, which usually appear in the user interface. + */ + Code interface{} `json:"code,omitempty"` // number | string + + /*Source defined: + * A human-readable string describing the source of this + * diagnostic, e.g. 'typescript' or 'super lint'. It usually + * appears in the user interface. + */ + Source string `json:"source,omitempty"` + + /*Message defined: + * The diagnostic's message. It usually appears in the user interface + */ + Message string `json:"message"` + + /*Tags defined: + * Additional metadata about the diagnostic. + */ + Tags []DiagnosticTag `json:"tags,omitempty"` + + /*RelatedInformation defined: + * An array of related diagnostic information, e.g. when symbol-names within + * a scope collide all definitions can be marked via this property. + */ + RelatedInformation []DiagnosticRelatedInformation `json:"relatedInformation,omitempty"` +} + +/*Command defined: + * Represents a reference to a command. Provides a title which + * will be used to represent a command in the UI and, optionally, + * an array of arguments which will be passed to the command handler + * function when invoked. + */ +type Command struct { + + /*Title defined: + * Title of the command, like `save`. + */ + Title string `json:"title"` + + /*Command defined: + * The identifier of the actual command handler. + */ + Command string `json:"command"` + + /*Arguments defined: + * Arguments that the command handler should be + * invoked with. + */ + Arguments []interface{} `json:"arguments,omitempty"` +} + +/*TextEdit defined: + * A text edit applicable to a text document. + */ +type TextEdit struct { + + /*Range defined: + * The range of the text document to be manipulated. To insert + * text into a document create a range where start === end. + */ + Range Range `json:"range"` + + /*NewText defined: + * The string to be inserted. For delete operations use an + * empty string. + */ + NewText string `json:"newText"` +} + +/*TextDocumentEdit defined: + * Describes textual changes on a text document. + */ +type TextDocumentEdit struct { + + /*TextDocument defined: + * The text document to change. + */ + TextDocument VersionedTextDocumentIdentifier `json:"textDocument"` + + /*Edits defined: + * The edits to be applied. + */ + Edits []TextEdit `json:"edits"` +} + +// ResourceOperation is +type ResourceOperation struct { + + // Kind is + Kind string `json:"kind"` +} + +/*CreateFileOptions defined: + * Options to create a file. + */ +type CreateFileOptions struct { + + /*Overwrite defined: + * Overwrite existing file. Overwrite wins over `ignoreIfExists` + */ + Overwrite bool `json:"overwrite,omitempty"` + + /*IgnoreIfExists defined: + * Ignore if exists. + */ + IgnoreIfExists bool `json:"ignoreIfExists,omitempty"` +} + +/*CreateFile defined: + * Create file operation. + */ +type CreateFile struct { + + /*Kind defined: + * A create + */ + Kind string `json:"kind"` // 'create' + + /*URI defined: + * The resource to create. + */ + URI DocumentURI `json:"uri"` + + /*Options defined: + * Additional options + */ + Options *CreateFileOptions `json:"options,omitempty"` +} + +/*RenameFileOptions defined: + * Rename file options + */ +type RenameFileOptions struct { + + /*Overwrite defined: + * Overwrite target if existing. Overwrite wins over `ignoreIfExists` + */ + Overwrite bool `json:"overwrite,omitempty"` + + /*IgnoreIfExists defined: + * Ignores if target exists. + */ + IgnoreIfExists bool `json:"ignoreIfExists,omitempty"` +} + +/*RenameFile defined: + * Rename file operation + */ +type RenameFile struct { + + /*Kind defined: + * A rename + */ + Kind string `json:"kind"` // 'rename' + + /*OldURI defined: + * The old (existing) location. + */ + OldURI DocumentURI `json:"oldUri"` + + /*NewURI defined: + * The new location. + */ + NewURI DocumentURI `json:"newUri"` + + /*Options defined: + * Rename options. + */ + Options *RenameFileOptions `json:"options,omitempty"` +} + +/*DeleteFileOptions defined: + * Delete file options + */ +type DeleteFileOptions struct { + + /*Recursive defined: + * Delete the content recursively if a folder is denoted. + */ + Recursive bool `json:"recursive,omitempty"` + + /*IgnoreIfNotExists defined: + * Ignore the operation if the file doesn't exist. + */ + IgnoreIfNotExists bool `json:"ignoreIfNotExists,omitempty"` +} + +/*DeleteFile defined: + * Delete file operation + */ +type DeleteFile struct { + + /*Kind defined: + * A delete + */ + Kind string `json:"kind"` // 'delete' + + /*URI defined: + * The file to delete. + */ + URI DocumentURI `json:"uri"` + + /*Options defined: + * Delete options. + */ + Options *DeleteFileOptions `json:"options,omitempty"` +} + +/*WorkspaceEdit defined: + * A workspace edit represents changes to many resources managed in the workspace. The edit + * should either provide `changes` or `documentChanges`. If documentChanges are present + * they are preferred over `changes` if the client can handle versioned document edits. + */ +type WorkspaceEdit struct { + + /*Changes defined: + * Holds changes to existing resources. + */ + Changes *map[string][]TextEdit `json:"changes,omitempty"` // [uri: string]: TextEdit[]; + + /*DocumentChanges defined: + * Depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes + * are either an array of `TextDocumentEdit`s to express changes to n different text documents + * where each text document edit addresses a specific version of a text document. Or it can contain + * above `TextDocumentEdit`s mixed with create, rename and delete file / folder operations. + * + * Whether a client supports versioned document edits is expressed via + * `workspace.workspaceEdit.documentChanges` client capability. + * + * If a client neither supports `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then + * only plain `TextEdit`s using the `changes` property are supported. + */ + DocumentChanges []TextDocumentEdit `json:"documentChanges,omitempty"` // (TextDocumentEdit | CreateFile | RenameFile | DeleteFile) +} + +/*TextEditChange defined: + * A change to capture text edits for existing resources. + */ +type TextEditChange struct { +} + +/*TextDocumentIdentifier defined: + * A literal to identify a text document in the client. + */ +type TextDocumentIdentifier struct { + + /*URI defined: + * The text document's uri. + */ + URI DocumentURI `json:"uri"` +} + +/*VersionedTextDocumentIdentifier defined: + * An identifier to denote a specific version of a text document. + */ +type VersionedTextDocumentIdentifier struct { + + /*Version defined: + * The version number of this document. If a versioned text document identifier + * is sent from the server to the client and the file is not open in the editor + * (the server has not received an open notification before) the server can send + * `null` to indicate that the version is unknown and the content on disk is the + * truth (as speced with document content ownership). + */ + Version float64 `json:"version"` + TextDocumentIdentifier +} + +/*TextDocumentItem defined: + * An item to transfer a text document from the client to the + * server. + */ +type TextDocumentItem struct { + + /*URI defined: + * The text document's uri. + */ + URI DocumentURI `json:"uri"` + + /*LanguageID defined: + * The text document's language identifier + */ + LanguageID string `json:"languageId"` + + /*Version defined: + * The version number of this document (it will increase after each + * change, including undo/redo). + */ + Version float64 `json:"version"` + + /*Text defined: + * The content of the opened text document. + */ + Text string `json:"text"` +} + +/*MarkupContent defined: + * A `MarkupContent` literal represents a string value which content is interpreted base on its + * kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds. + * + * If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues. + * See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting + * + * Here is an example how such a string can be constructed using JavaScript / TypeScript: + * ```ts + * let markdown: MarkdownContent = { + * kind: MarkupKind.Markdown, + * value: [ + * '# Header', + * 'Some text', + * '```typescript', + * 'someCode();', + * '```' + * ].join('\n') + * }; + * ``` + * + * *Please Note* that clients might sanitize the return markdown. A client could decide to + * remove HTML from the markdown to avoid script execution. + */ +type MarkupContent struct { + + /*Kind defined: + * The type of the Markup + */ + Kind MarkupKind `json:"kind"` + + /*Value defined: + * The content itself + */ + Value string `json:"value"` +} + +/*CompletionItem defined: + * A completion item represents a text snippet that is + * proposed to complete text that is being typed. + */ +type CompletionItem struct { + + /*Label defined: + * The label of this completion item. By default + * also the text that is inserted when selecting + * this completion. + */ + Label string `json:"label"` + + /*Kind defined: + * The kind of this completion item. Based of the kind + * an icon is chosen by the editor. + */ + Kind CompletionItemKind `json:"kind,omitempty"` + + /*Tags defined: + * Tags for this completion item. + * + * @since 3.15.0 + */ + Tags []CompletionItemTag `json:"tags,omitempty"` + + /*Detail defined: + * A human-readable string with additional information + * about this item, like type or symbol information. + */ + Detail string `json:"detail,omitempty"` + + /*Documentation defined: + * A human-readable string that represents a doc-comment. + */ + Documentation string `json:"documentation,omitempty"` // string | MarkupContent + + /*Deprecated defined: + * Indicates if this item is deprecated. + * @deprecated Use `tags` instead. + */ + Deprecated bool `json:"deprecated,omitempty"` + + /*Preselect defined: + * Select this item when showing. + * + * *Note* that only one completion item can be selected and that the + * tool / client decides which item that is. The rule is that the *first* + * item of those that match best is selected. + */ + Preselect bool `json:"preselect,omitempty"` + + /*SortText defined: + * A string that should be used when comparing this item + * with other items. When `falsy` the [label](#CompletionItem.label) + * is used. + */ + SortText string `json:"sortText,omitempty"` + + /*FilterText defined: + * A string that should be used when filtering a set of + * completion items. When `falsy` the [label](#CompletionItem.label) + * is used. + */ + FilterText string `json:"filterText,omitempty"` + + /*InsertText defined: + * A string that should be inserted into a document when selecting + * this completion. When `falsy` the [label](#CompletionItem.label) + * is used. + * + * The `insertText` is subject to interpretation by the client side. + * Some tools might not take the string literally. For example + * VS Code when code complete is requested in this example `con` + * and a completion item with an `insertText` of `console` is provided it + * will only insert `sole`. Therefore it is recommended to use `textEdit` instead + * since it avoids additional client side interpretation. + */ + InsertText string `json:"insertText,omitempty"` + + /*InsertTextFormat defined: + * The format of the insert text. The format applies to both the `insertText` property + * and the `newText` property of a provided `textEdit`. + */ + InsertTextFormat InsertTextFormat `json:"insertTextFormat,omitempty"` + + /*TextEdit defined: + * An [edit](#TextEdit) which is applied to a document when selecting + * this completion. When an edit is provided the value of + * [insertText](#CompletionItem.insertText) is ignored. + * + * *Note:* The text edit's range must be a [single line] and it must contain the position + * at which completion has been requested. + */ + TextEdit *TextEdit `json:"textEdit,omitempty"` + + /*AdditionalTextEdits defined: + * An optional array of additional [text edits](#TextEdit) that are applied when + * selecting this completion. Edits must not overlap (including the same insert position) + * with the main [edit](#CompletionItem.textEdit) nor with themselves. + * + * Additional text edits should be used to change text unrelated to the current cursor position + * (for example adding an import statement at the top of the file if the completion item will + * insert an unqualified type). + */ + AdditionalTextEdits []TextEdit `json:"additionalTextEdits,omitempty"` + + /*CommitCharacters defined: + * An optional set of characters that when pressed while this completion is active will accept it first and + * then type that character. *Note* that all commit characters should have `length=1` and that superfluous + * characters will be ignored. + */ + CommitCharacters []string `json:"commitCharacters,omitempty"` + + /*Command defined: + * An optional [command](#Command) that is executed *after* inserting this completion. *Note* that + * additional modifications to the current document should be described with the + * [additionalTextEdits](#CompletionItem.additionalTextEdits)-property. + */ + Command *Command `json:"command,omitempty"` + + /*Data defined: + * An data entry field that is preserved on a completion item between + * a [CompletionRequest](#CompletionRequest) and a [CompletionResolveRequest] + * (#CompletionResolveRequest) + */ + Data interface{} `json:"data,omitempty"` +} + +/*CompletionList defined: + * Represents a collection of [completion items](#CompletionItem) to be presented + * in the editor. + */ +type CompletionList struct { + + /*IsIncomplete defined: + * This list it not complete. Further typing results in recomputing this list. + */ + IsIncomplete bool `json:"isIncomplete"` + + /*Items defined: + * The completion items. + */ + Items []CompletionItem `json:"items"` +} + +/*Hover defined: + * The result of a hover request. + */ +type Hover struct { + + /*Contents defined: + * The hover's content + */ + Contents MarkupContent `json:"contents"` // MarkupContent | MarkedString | MarkedString[] + + /*Range defined: + * An optional range + */ + Range *Range `json:"range,omitempty"` +} + +/*ParameterInformation defined: + * Represents a parameter of a callable-signature. A parameter can + * have a label and a doc-comment. + */ +type ParameterInformation struct { + + /*Label defined: + * The label of this parameter information. + * + * Either a string or an inclusive start and exclusive end offsets within its containing + * signature label. (see SignatureInformation.label). The offsets are based on a UTF-16 + * string representation as `Position` and `Range` does. + * + * *Note*: a label of type string should be a substring of its containing signature label. + * Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`. + */ + Label string `json:"label"` // string | [number, number] + + /*Documentation defined: + * The human-readable doc-comment of this signature. Will be shown + * in the UI but can be omitted. + */ + Documentation string `json:"documentation,omitempty"` // string | MarkupContent +} + +/*SignatureInformation defined: + * Represents the signature of something callable. A signature + * can have a label, like a function-name, a doc-comment, and + * a set of parameters. + */ +type SignatureInformation struct { + + /*Label defined: + * The label of this signature. Will be shown in + * the UI. + */ + Label string `json:"label"` + + /*Documentation defined: + * The human-readable doc-comment of this signature. Will be shown + * in the UI but can be omitted. + */ + Documentation string `json:"documentation,omitempty"` // string | MarkupContent + + /*Parameters defined: + * The parameters of this signature. + */ + Parameters []ParameterInformation `json:"parameters,omitempty"` +} + +/*SignatureHelp defined: + * Signature help represents the signature of something + * callable. There can be multiple signature but only one + * active and only one active parameter. + */ +type SignatureHelp struct { + + /*Signatures defined: + * One or more signatures. + */ + Signatures []SignatureInformation `json:"signatures"` + + /*ActiveSignature defined: + * The active signature. Set to `null` if no + * signatures exist. + */ + ActiveSignature float64 `json:"activeSignature"` + + /*ActiveParameter defined: + * The active parameter of the active signature. Set to `null` + * if the active signature has no parameters. + */ + ActiveParameter float64 `json:"activeParameter"` +} + +/*ReferenceContext defined: + * Value-object that contains additional information when + * requesting references. + */ +type ReferenceContext struct { + + /*IncludeDeclaration defined: + * Include the declaration of the current symbol. + */ + IncludeDeclaration bool `json:"includeDeclaration"` +} + +/*DocumentHighlight defined: + * A document highlight is a range inside a text document which deserves + * special attention. Usually a document highlight is visualized by changing + * the background color of its range. + */ +type DocumentHighlight struct { + + /*Range defined: + * The range this highlight applies to. + */ + Range Range `json:"range"` + + /*Kind defined: + * The highlight kind, default is [text](#DocumentHighlightKind.Text). + */ + Kind *DocumentHighlightKind `json:"kind,omitempty"` +} + +/*SymbolInformation defined: + * Represents information about programming constructs like variables, classes, + * interfaces etc. + */ +type SymbolInformation struct { + + /*Name defined: + * The name of this symbol. + */ + Name string `json:"name"` + + /*Kind defined: + * The kind of this symbol. + */ + Kind SymbolKind `json:"kind"` + + /*Deprecated defined: + * Indicates if this symbol is deprecated. + */ + Deprecated bool `json:"deprecated,omitempty"` + + /*Location defined: + * The location of this symbol. The location's range is used by a tool + * to reveal the location in the editor. If the symbol is selected in the + * tool the range's start information is used to position the cursor. So + * the range usually spans more than the actual symbol's name and does + * normally include thinks like visibility modifiers. + * + * The range doesn't have to denote a node range in the sense of a abstract + * syntax tree. It can therefore not be used to re-construct a hierarchy of + * the symbols. + */ + Location Location `json:"location"` + + /*ContainerName defined: + * The name of the symbol containing this symbol. This information is for + * user interface purposes (e.g. to render a qualifier in the user interface + * if necessary). It can't be used to re-infer a hierarchy for the document + * symbols. + */ + ContainerName string `json:"containerName,omitempty"` +} + +/*DocumentSymbol defined: + * Represents programming constructs like variables, classes, interfaces etc. + * that appear in a document. Document symbols can be hierarchical and they + * have two ranges: one that encloses its definition and one that points to + * its most interesting range, e.g. the range of an identifier. + */ +type DocumentSymbol struct { + + /*Name defined: + * The name of this symbol. Will be displayed in the user interface and therefore must not be + * an empty string or a string only consisting of white spaces. + */ + Name string `json:"name"` + + /*Detail defined: + * More detail for this symbol, e.g the signature of a function. + */ + Detail string `json:"detail,omitempty"` + + /*Kind defined: + * The kind of this symbol. + */ + Kind SymbolKind `json:"kind"` + + /*Deprecated defined: + * Indicates if this symbol is deprecated. + */ + Deprecated bool `json:"deprecated,omitempty"` + + /*Range defined: + * The range enclosing this symbol not including leading/trailing whitespace but everything else + * like comments. This information is typically used to determine if the clients cursor is + * inside the symbol to reveal in the symbol in the UI. + */ + Range Range `json:"range"` + + /*SelectionRange defined: + * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function. + * Must be contained by the `range`. + */ + SelectionRange Range `json:"selectionRange"` + + /*Children defined: + * Children of this symbol, e.g. properties of a class. + */ + Children []DocumentSymbol `json:"children,omitempty"` +} + +/*CodeActionContext defined: + * Contains additional diagnostic information about the context in which + * a [code action](#CodeActionProvider.provideCodeActions) is run. + */ +type CodeActionContext struct { + + /*Diagnostics defined: + * An array of diagnostics known on the client side overlapping the range provided to the + * `textDocument/codeAction` request. They are provided so that the server knows which + * errors are currently presented to the user for the given range. There is no guarantee + * that these accurately reflect the error state of the resource. The primary parameter + * to compute code actions is the provided range. + */ + Diagnostics []Diagnostic `json:"diagnostics"` + + /*Only defined: + * Requested kind of actions to return. + * + * Actions not of this kind are filtered out by the client before being shown. So servers + * can omit computing them. + */ + Only []CodeActionKind `json:"only,omitempty"` +} + +/*CodeAction defined: + * A code action represents a change that can be performed in code, e.g. to fix a problem or + * to refactor code. + * + * A CodeAction must set either `edit` and/or a `command`. If both are supplied, the `edit` is applied first, then the `command` is executed. + */ +type CodeAction struct { + + /*Title defined: + * A short, human-readable, title for this code action. + */ + Title string `json:"title"` + + /*Kind defined: + * The kind of the code action. + * + * Used to filter code actions. + */ + Kind CodeActionKind `json:"kind,omitempty"` + + /*Diagnostics defined: + * The diagnostics that this code action resolves. + */ + Diagnostics []Diagnostic `json:"diagnostics,omitempty"` + + /*IsPreferred defined: + * Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted + * by keybindings. + * + * A quick fix should be marked preferred if it properly addresses the underlying error. + * A refactoring should be marked preferred if it is the most reasonable choice of actions to take. + * + * @since 3.15.0 + */ + IsPreferred bool `json:"isPreferred,omitempty"` + + /*Edit defined: + * The workspace edit this code action performs. + */ + Edit *WorkspaceEdit `json:"edit,omitempty"` + + /*Command defined: + * A command this code action executes. If a code action + * provides a edit and a command, first the edit is + * executed and then the command. + */ + Command *Command `json:"command,omitempty"` +} + +/*CodeLens defined: + * A code lens represents a [command](#Command) that should be shown along with + * source text, like the number of references, a way to run tests, etc. + * + * A code lens is _unresolved_ when no command is associated to it. For performance + * reasons the creation of a code lens and resolving should be done to two stages. + */ +type CodeLens struct { + + /*Range defined: + * The range in which this code lens is valid. Should only span a single line. + */ + Range Range `json:"range"` + + /*Command defined: + * The command this code lens represents. + */ + Command *Command `json:"command,omitempty"` + + /*Data defined: + * An data entry field that is preserved on a code lens item between + * a [CodeLensRequest](#CodeLensRequest) and a [CodeLensResolveRequest] + * (#CodeLensResolveRequest) + */ + Data interface{} `json:"data,omitempty"` +} + +/*FormattingOptions defined: + * Value-object describing what options formatting should use. + */ +type FormattingOptions struct { + + /*TabSize defined: + * Size of a tab in spaces. + */ + TabSize float64 `json:"tabSize"` + + /*InsertSpaces defined: + * Prefer spaces over tabs. + */ + InsertSpaces bool `json:"insertSpaces"` + + /*TrimTrailingWhitespace defined: + * Trim trailing whitespaces on a line. + * + * @since 3.15.0 + */ + TrimTrailingWhitespace bool `json:"trimTrailingWhitespace,omitempty"` + + /*InsertFinalNewline defined: + * Insert a newline character at the end of the file if one does not exist. + * + * @since 3.15.0 + */ + InsertFinalNewline bool `json:"insertFinalNewline,omitempty"` + + /*TrimFinalNewlines defined: + * Trim all newlines after the final newline at the end of the file. + * + * @since 3.15.0 + */ + TrimFinalNewlines bool `json:"trimFinalNewlines,omitempty"` + + /*Key defined: + * Signature for further properties. + */ + Key map[string]bool `json:"key"` // [key: string]: boolean | number | string | undefined; +} + +/*DocumentLink defined: + * A document link is a range in a text document that links to an internal or external resource, like another + * text document or a web site. + */ +type DocumentLink struct { + + /*Range defined: + * The range this link applies to. + */ + Range Range `json:"range"` + + /*Target defined: + * The uri this link points to. + */ + Target string `json:"target,omitempty"` + + /*Tooltip defined: + * The tooltip text when you hover over this link. + * + * If a tooltip is provided, is will be displayed in a string that includes instructions on how to + * trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS, + * user settings, and localization. + * + * @since 3.15.0 + */ + Tooltip string `json:"tooltip,omitempty"` + + /*Data defined: + * A data entry field that is preserved on a document link between a + * DocumentLinkRequest and a DocumentLinkResolveRequest. + */ + Data interface{} `json:"data,omitempty"` +} + +/*SelectionRange defined: + * A selection range represents a part of a selection hierarchy. A selection range + * may have a parent selection range that contains it. + */ +type SelectionRange struct { + + /*Range defined: + * The [range](#Range) of this selection range. + */ + Range Range `json:"range"` + + /*Parent defined: + * The parent selection range containing this range. Therefore `parent.range` must contain `this.range`. + */ + Parent *SelectionRange `json:"parent,omitempty"` +} + +/*TextDocument defined: + * A simple text document. Not to be implemented. + */ +type TextDocument struct { + + /*URI defined: + * The associated URI for this document. Most documents have the __file__-scheme, indicating that they + * represent files on disk. However, some documents may have other schemes indicating that they are not + * available on disk. + * + * @readonly + */ + URI DocumentURI `json:"uri"` + + /*LanguageID defined: + * The identifier of the language associated with this document. + * + * @readonly + */ + LanguageID string `json:"languageId"` + + /*Version defined: + * The version number of this document (it will increase after each + * change, including undo/redo). + * + * @readonly + */ + Version float64 `json:"version"` + + /*LineCount defined: + * The number of lines in this document. + * + * @readonly + */ + LineCount float64 `json:"lineCount"` +} + +/*TextDocumentChangeEvent defined: + * Event to signal changes to a simple text document. + */ +type TextDocumentChangeEvent struct { + + /*Document defined: + * The document that has changed. + */ + Document TextDocument `json:"document"` +} + +// TextDocumentWillSaveEvent is +type TextDocumentWillSaveEvent struct { + + /*Document defined: + * The document that will be saved + */ + Document TextDocument `json:"document"` + + /*Reason defined: + * The reason why save was triggered. + */ + Reason TextDocumentSaveReason `json:"reason"` +} + +/*TextDocumentContentChangeEvent defined: + * An event describing a change to a text document. If range and rangeLength are omitted + * the new text is considered to be the full content of the document. + */ +type TextDocumentContentChangeEvent struct { + + /*Range defined: + * The range of the document that changed. + */ + Range *Range `json:"range,omitempty"` + + /*RangeLength defined: + * The length of the range that got replaced. + */ + RangeLength float64 `json:"rangeLength,omitempty"` + + /*Text defined: + * The new text of the document. + */ + Text string `json:"text"` +} + +// ProgressParams is +type ProgressParams struct { + + /*Token defined: + * The progress token provided by the client or server. + */ + Token ProgressToken `json:"token"` + + /*Value defined: + * The progress data. + */ + Value interface{} `json:"value"` +} + +// SetTraceParams is +type SetTraceParams struct { + + // Value is + Value TraceValues `json:"value"` +} + +// LogTraceParams is +type LogTraceParams struct { + + // Message is + Message string `json:"message"` + + // Verbose is + Verbose string `json:"verbose,omitempty"` +} + +// Tracer is +type Tracer struct { +} + +// FoldingRangeKind defines constants +type FoldingRangeKind string + +// ResourceOperationKind defines constants +type ResourceOperationKind string + +// FailureHandlingKind defines constants +type FailureHandlingKind string + +// InitializeError defines constants +type InitializeError float64 + +// MessageType defines constants +type MessageType float64 + +// TextDocumentSyncKind defines constants +type TextDocumentSyncKind float64 + +// FileChangeType defines constants +type FileChangeType float64 + +// WatchKind defines constants +type WatchKind float64 + +// CompletionTriggerKind defines constants +type CompletionTriggerKind float64 + +// SignatureHelpTriggerKind defines constants +type SignatureHelpTriggerKind float64 + +// DiagnosticSeverity defines constants +type DiagnosticSeverity float64 + +// DiagnosticTag defines constants +type DiagnosticTag float64 + +// MarkupKind defines constants +type MarkupKind string + +// CompletionItemKind defines constants +type CompletionItemKind float64 + +// InsertTextFormat defines constants +type InsertTextFormat float64 + +// CompletionItemTag defines constants +type CompletionItemTag float64 + +// DocumentHighlightKind defines constants +type DocumentHighlightKind float64 + +// SymbolKind defines constants +type SymbolKind float64 + +// CodeActionKind defines constants +type CodeActionKind string + +// TextDocumentSaveReason defines constants +type TextDocumentSaveReason float64 + +// ErrorCodes defines constants +type ErrorCodes float64 + +// Touch defines constants +type Touch float64 + +// Trace defines constants +type Trace string + +// TraceFormat defines constants +type TraceFormat string + +// ConnectionErrors defines constants +type ConnectionErrors float64 + +// ConnectionState defines constants +type ConnectionState float64 + +const ( + + /*Comment defined: + * Folding range for a comment + */ + Comment FoldingRangeKind = "comment" + + /*Imports defined: + * Folding range for a imports or includes + */ + Imports FoldingRangeKind = "imports" + + /*Region defined: + * Folding range for a region (e.g. `#region`) + */ + Region FoldingRangeKind = "region" + + /*Create defined: + * Supports creating new files and folders. + */ + Create ResourceOperationKind = "create" + + /*Rename defined: + * Supports renaming existing files and folders. + */ + Rename ResourceOperationKind = "rename" + + /*Delete defined: + * Supports deleting existing files and folders. + */ + Delete ResourceOperationKind = "delete" + + /*Abort defined: + * Applying the workspace change is simply aborted if one of the changes provided + * fails. All operations executed before the failing operation stay executed. + */ + Abort FailureHandlingKind = "abort" + + /*Transactional defined: + * All operations are executed transactional. That means they either all + * succeed or no changes at all are applied to the workspace. + */ + Transactional FailureHandlingKind = "transactional" + + /*TextOnlyTransactional defined: + * If the workspace edit contains only textual file changes they are executed transactional. + * If resource changes (create, rename or delete file) are part of the change the failure + * handling strategy is abort. + */ + TextOnlyTransactional FailureHandlingKind = "textOnlyTransactional" + + /*Undo defined: + * The client tries to undo the operations already executed. But there is no + * guarantee that this is succeeding. + */ + Undo FailureHandlingKind = "undo" + + /*UnknownProtocolVersion defined: + * If the protocol version provided by the client can't be handled by the server. + * @deprecated This initialize error got replaced by client capabilities. There is + * no version handshake in version 3.0x + */ + UnknownProtocolVersion InitializeError = 1 + + /*Error defined: + * An error message. + */ + Error MessageType = 1 + + /*Warning defined: + * A warning message. + */ + Warning MessageType = 2 + + /*Info defined: + * An information message. + */ + Info MessageType = 3 + + /*Log defined: + * A log message. + */ + Log MessageType = 4 + + /*None defined: + * Documents should not be synced at all. + */ + None TextDocumentSyncKind = 0 + + /*Full defined: + * Documents are synced by always sending the full content + * of the document. + */ + Full TextDocumentSyncKind = 1 + + /*Incremental defined: + * Documents are synced by sending the full content on open. + * After that only incremental updates to the document are + * send. + */ + Incremental TextDocumentSyncKind = 2 + + /*Created defined: + * The file got created. + */ + Created FileChangeType = 1 + + /*Changed defined: + * The file got changed. + */ + Changed FileChangeType = 2 + + /*Deleted defined: + * The file got deleted. + */ + Deleted FileChangeType = 3 + + /*WatchCreate defined: + * Interested in create events. + */ + WatchCreate WatchKind = 1 + + /*WatchChange defined: + * Interested in change events + */ + WatchChange WatchKind = 2 + + /*WatchDelete defined: + * Interested in delete events + */ + WatchDelete WatchKind = 4 + + /*Invoked defined: + * Completion was triggered by typing an identifier (24x7 code + * complete), manual invocation (e.g Ctrl+Space) or via API. + */ + Invoked CompletionTriggerKind = 1 + + /*TriggerCharacter defined: + * Completion was triggered by a trigger character specified by + * the `triggerCharacters` properties of the `CompletionRegistrationOptions`. + */ + TriggerCharacter CompletionTriggerKind = 2 + + /*TriggerForIncompleteCompletions defined: + * Completion was re-triggered as current completion list is incomplete + */ + TriggerForIncompleteCompletions CompletionTriggerKind = 3 + + /*ContentChange defined: + * Signature help was triggered by the cursor moving or by the document content changing. + */ + ContentChange SignatureHelpTriggerKind = 3 + + /*SeverityError defined: + * Reports an error. + */ + SeverityError DiagnosticSeverity = 1 + + /*SeverityWarning defined: + * Reports a warning. + */ + SeverityWarning DiagnosticSeverity = 2 + + /*SeverityInformation defined: + * Reports an information. + */ + SeverityInformation DiagnosticSeverity = 3 + + /*SeverityHint defined: + * Reports a hint. + */ + SeverityHint DiagnosticSeverity = 4 + + /*Unnecessary defined: + * Unused or unnecessary code. + * + * Clients are allowed to render diagnostics with this tag faded out instead of having + * an error squiggle. + */ + Unnecessary DiagnosticTag = 1 + + /*Deprecated defined: + * Deprecated or obsolete code. + * + * Clients are allowed to rendered diagnostics with this tag strike through. + */ + Deprecated DiagnosticTag = 2 + + /*PlainText defined: + * Plain text is supported as a content format + */ + PlainText MarkupKind = "plaintext" + + /*Markdown defined: + * Markdown is supported as a content format + */ + Markdown MarkupKind = "markdown" + + // TextCompletion is + TextCompletion CompletionItemKind = 1 + + // MethodCompletion is + MethodCompletion CompletionItemKind = 2 + + // FunctionCompletion is + FunctionCompletion CompletionItemKind = 3 + + // ConstructorCompletion is + ConstructorCompletion CompletionItemKind = 4 + + // FieldCompletion is + FieldCompletion CompletionItemKind = 5 + + // VariableCompletion is + VariableCompletion CompletionItemKind = 6 + + // ClassCompletion is + ClassCompletion CompletionItemKind = 7 + + // InterfaceCompletion is + InterfaceCompletion CompletionItemKind = 8 + + // ModuleCompletion is + ModuleCompletion CompletionItemKind = 9 + + // PropertyCompletion is + PropertyCompletion CompletionItemKind = 10 + + // UnitCompletion is + UnitCompletion CompletionItemKind = 11 + + // ValueCompletion is + ValueCompletion CompletionItemKind = 12 + + // EnumCompletion is + EnumCompletion CompletionItemKind = 13 + + // KeywordCompletion is + KeywordCompletion CompletionItemKind = 14 + + // SnippetCompletion is + SnippetCompletion CompletionItemKind = 15 + + // ColorCompletion is + ColorCompletion CompletionItemKind = 16 + + // FileCompletion is + FileCompletion CompletionItemKind = 17 + + // ReferenceCompletion is + ReferenceCompletion CompletionItemKind = 18 + + // FolderCompletion is + FolderCompletion CompletionItemKind = 19 + + // EnumMemberCompletion is + EnumMemberCompletion CompletionItemKind = 20 + + // ConstantCompletion is + ConstantCompletion CompletionItemKind = 21 + + // StructCompletion is + StructCompletion CompletionItemKind = 22 + + // EventCompletion is + EventCompletion CompletionItemKind = 23 + + // OperatorCompletion is + OperatorCompletion CompletionItemKind = 24 + + // TypeParameterCompletion is + TypeParameterCompletion CompletionItemKind = 25 + + /*PlainTextTextFormat defined: + * The primary text to be inserted is treated as a plain string. + */ + PlainTextTextFormat InsertTextFormat = 1 + + /*SnippetTextFormat defined: + * The primary text to be inserted is treated as a snippet. + * + * A snippet can define tab stops and placeholders with `$1`, `$2` + * and `${3:foo}`. `$0` defines the final tab stop, it defaults to + * the end of the snippet. Placeholders with equal identifiers are linked, + * that is typing in one will update others too. + * + * See also: https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md + */ + SnippetTextFormat InsertTextFormat = 2 + + /*Text defined: + * A textual occurrence. + */ + Text DocumentHighlightKind = 1 + + /*Read defined: + * Read-access of a symbol, like reading a variable. + */ + Read DocumentHighlightKind = 2 + + /*Write defined: + * Write-access of a symbol, like writing to a variable. + */ + Write DocumentHighlightKind = 3 + + // File is + File SymbolKind = 1 + + // Module is + Module SymbolKind = 2 + + // Namespace is + Namespace SymbolKind = 3 + + // Package is + Package SymbolKind = 4 + + // Class is + Class SymbolKind = 5 + + // Method is + Method SymbolKind = 6 + + // Property is + Property SymbolKind = 7 + + // Field is + Field SymbolKind = 8 + + // Constructor is + Constructor SymbolKind = 9 + + // Enum is + Enum SymbolKind = 10 + + // Interface is + Interface SymbolKind = 11 + + // Function is + Function SymbolKind = 12 + + // Variable is + Variable SymbolKind = 13 + + // Constant is + Constant SymbolKind = 14 + + // String is + String SymbolKind = 15 + + // Number is + Number SymbolKind = 16 + + // Boolean is + Boolean SymbolKind = 17 + + // Array is + Array SymbolKind = 18 + + // Object is + Object SymbolKind = 19 + + // Key is + Key SymbolKind = 20 + + // Null is + Null SymbolKind = 21 + + // EnumMember is + EnumMember SymbolKind = 22 + + // Struct is + Struct SymbolKind = 23 + + // Event is + Event SymbolKind = 24 + + // Operator is + Operator SymbolKind = 25 + + // TypeParameter is + TypeParameter SymbolKind = 26 + + /*Empty defined: + * Empty kind. + */ + Empty CodeActionKind = "" + + /*QuickFix defined: + * Base kind for quickfix actions: 'quickfix' + */ + QuickFix CodeActionKind = "quickfix" + + /*Refactor defined: + * Base kind for refactoring actions: 'refactor' + */ + Refactor CodeActionKind = "refactor" + + /*RefactorExtract defined: + * Base kind for refactoring extraction actions: 'refactor.extract' + * + * Example extract actions: + * + * - Extract method + * - Extract function + * - Extract variable + * - Extract interface from class + * - ... + */ + RefactorExtract CodeActionKind = "refactor.extract" + + /*RefactorInline defined: + * Base kind for refactoring inline actions: 'refactor.inline' + * + * Example inline actions: + * + * - Inline function + * - Inline variable + * - Inline constant + * - ... + */ + RefactorInline CodeActionKind = "refactor.inline" + + /*RefactorRewrite defined: + * Base kind for refactoring rewrite actions: 'refactor.rewrite' + * + * Example rewrite actions: + * + * - Convert JavaScript function to class + * - Add or remove parameter + * - Encapsulate field + * - Make method static + * - Move method to base class + * - ... + */ + RefactorRewrite CodeActionKind = "refactor.rewrite" + + /*Source defined: + * Base kind for source actions: `source` + * + * Source code actions apply to the entire file. + */ + Source CodeActionKind = "source" + + /*SourceOrganizeImports defined: + * Base kind for an organize imports source action: `source.organizeImports` + */ + SourceOrganizeImports CodeActionKind = "source.organizeImports" + + /*Manual defined: + * Manually triggered, e.g. by the user pressing save, by starting debugging, + * or by an API call. + */ + Manual TextDocumentSaveReason = 1 + + /*AfterDelay defined: + * Automatic after a delay. + */ + AfterDelay TextDocumentSaveReason = 2 + + /*FocusOut defined: + * When the editor lost focus. + */ + FocusOut TextDocumentSaveReason = 3 + + // MessageWriteError is + MessageWriteError ErrorCodes = 1 + + // MessageReadError is + MessageReadError ErrorCodes = 2 + + // First is + First Touch = 1 + + // Last is + Last Touch = 2 + + // JSON is + JSON TraceFormat = "json" + + /*Closed defined: + * The connection is closed. + */ + Closed ConnectionErrors = 1 + + /*Disposed defined: + * The connection got disposed. + */ + Disposed ConnectionErrors = 2 + + /*AlreadyListening defined: + * The connection is already in listening mode. + */ + AlreadyListening ConnectionErrors = 3 + + // New is + New ConnectionState = 1 + + // Listening is + Listening ConnectionState = 2 +) + +// DocumentFilter is a type +/** + * A document filter denotes a document by different properties like + * the [language](#TextDocument.languageId), the [scheme](#Uri.scheme) of + * its resource, or a glob-pattern that is applied to the [path](#TextDocument.fileName). + * + * Glob patterns can have the following syntax: + * - `*` to match one or more characters in a path segment + * - `?` to match on one character in a path segment + * - `**` to match any number of path segments, including none + * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) + * - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) + * - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`) + * + * @sample A language filter that applies to typescript files on disk: `{ language: 'typescript', scheme: 'file' }` + * @sample A language filter that applies to all package.json paths: `{ language: 'json', pattern: '**package.json' }` + */ +type DocumentFilter = struct { + + /*Language defined: A language id, like `typescript`. */ + Language string `json:"language,omitempty"` + + /*Scheme defined: A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */ + Scheme string `json:"scheme,omitempty"` + + /*Pattern defined: A glob pattern, like `*.{ts,js}`. */ + Pattern string `json:"pattern,omitempty"` +} + +// DocumentSelector is a type +/** + * A document selector is the combination of one or many document filters. + * + * @sample `let sel:DocumentSelector = [{ language: 'typescript' }, { language: 'json', pattern: '**∕tsconfig.json' }]`; + */ +type DocumentSelector = []DocumentFilter + +// DocumentURI is a type +/** + * A tagging type for string properties that are actually URIs. + */ +type DocumentURI = string + +// MarkedString is a type +/** + * MarkedString can be used to render human readable text. It is either a markdown string + * or a code-block that provides a language and a code snippet. The language identifier + * is semantically equal to the optional language identifier in fenced code blocks in GitHub + * issues. See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting + * + * The pair of a language and a value is an equivalent to markdown: + * ```${language} + * ${value} + * ``` + * + * Note that markdown strings will be sanitized - that means html will be escaped. + * @deprecated use MarkupContent instead. + */ +type MarkedString = string + +// DefinitionLink is a type +/** + * Information about where a symbol is defined. + * + * Provides additional metadata over normal [location](#Location) definitions, including the range of + * the defining symbol + */ +type DefinitionLink = LocationLink + +// DeclarationLink is a type +/** + * Information about where a symbol is declared. + * + * Provides additional metadata over normal [location](#Location) declarations, including the range of + * the declaring symbol. + * + * Servers should prefer returning `DeclarationLink` over `Declaration` if supported + * by the client. + */ +type DeclarationLink = LocationLink + +// LSPMessageType is a type +/** + * A LSP Log Entry. + */ +type LSPMessageType = string + +// ProgressToken is a type +type ProgressToken = interface{} // number | string +// TraceValues is a type +type TraceValues = string diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsserver.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsserver.go new file mode 100644 index 000000000000..37e8c6a75e9b --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/protocol/tsserver.go @@ -0,0 +1,842 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +import ( + "context" + "encoding/json" + "log" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/jsonrpc2" +) + +type Server interface { + DidChangeWorkspaceFolders(context.Context, *DidChangeWorkspaceFoldersParams) error + Initialized(context.Context, *InitializedParams) error + Exit(context.Context) error + DidChangeConfiguration(context.Context, *DidChangeConfigurationParams) error + DidOpen(context.Context, *DidOpenTextDocumentParams) error + DidChange(context.Context, *DidChangeTextDocumentParams) error + DidClose(context.Context, *DidCloseTextDocumentParams) error + DidSave(context.Context, *DidSaveTextDocumentParams) error + WillSave(context.Context, *WillSaveTextDocumentParams) error + DidChangeWatchedFiles(context.Context, *DidChangeWatchedFilesParams) error + Progress(context.Context, *ProgressParams) error + SetTraceNotification(context.Context, *SetTraceParams) error + LogTraceNotification(context.Context, *LogTraceParams) error + Implementation(context.Context, *ImplementationParams) ([]Location, error) + TypeDefinition(context.Context, *TypeDefinitionParams) ([]Location, error) + DocumentColor(context.Context, *DocumentColorParams) ([]ColorInformation, error) + ColorPresentation(context.Context, *ColorPresentationParams) ([]ColorPresentation, error) + FoldingRange(context.Context, *FoldingRangeParams) ([]FoldingRange, error) + Declaration(context.Context, *DeclarationParams) ([]DeclarationLink, error) + SelectionRange(context.Context, *SelectionRangeParams) ([]SelectionRange, error) + Initialize(context.Context, *ParamInitia) (*InitializeResult, error) + Shutdown(context.Context) error + WillSaveWaitUntil(context.Context, *WillSaveTextDocumentParams) ([]TextEdit, error) + Completion(context.Context, *CompletionParams) (*CompletionList, error) + Resolve(context.Context, *CompletionItem) (*CompletionItem, error) + Hover(context.Context, *HoverParams) (*Hover, error) + SignatureHelp(context.Context, *SignatureHelpParams) (*SignatureHelp, error) + Definition(context.Context, *DefinitionParams) ([]Location, error) + References(context.Context, *ReferenceParams) ([]Location, error) + DocumentHighlight(context.Context, *DocumentHighlightParams) ([]DocumentHighlight, error) + DocumentSymbol(context.Context, *DocumentSymbolParams) ([]DocumentSymbol, error) + CodeAction(context.Context, *CodeActionParams) ([]CodeAction, error) + Symbol(context.Context, *WorkspaceSymbolParams) ([]SymbolInformation, error) + CodeLens(context.Context, *CodeLensParams) ([]CodeLens, error) + ResolveCodeLens(context.Context, *CodeLens) (*CodeLens, error) + DocumentLink(context.Context, *DocumentLinkParams) ([]DocumentLink, error) + ResolveDocumentLink(context.Context, *DocumentLink) (*DocumentLink, error) + Formatting(context.Context, *DocumentFormattingParams) ([]TextEdit, error) + RangeFormatting(context.Context, *DocumentRangeFormattingParams) ([]TextEdit, error) + OnTypeFormatting(context.Context, *DocumentOnTypeFormattingParams) ([]TextEdit, error) + Rename(context.Context, *RenameParams) (*WorkspaceEdit, error) + PrepareRename(context.Context, *PrepareRenameParams) (*Range, error) + ExecuteCommand(context.Context, *ExecuteCommandParams) (interface{}, error) +} + +func (h serverHandler) Deliver(ctx context.Context, r *jsonrpc2.Request, delivered bool) bool { + if delivered { + return false + } + if ctx.Err() != nil { + r.Reply(ctx, nil, jsonrpc2.NewErrorf(RequestCancelledError, "")) + return true + } + switch r.Method { + case "workspace/didChangeWorkspaceFolders": // notif + var params DidChangeWorkspaceFoldersParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.DidChangeWorkspaceFolders(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "initialized": // notif + var params InitializedParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.Initialized(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "exit": // notif + if err := h.server.Exit(ctx); err != nil { + log.Printf("%v", err) + } + return true + case "workspace/didChangeConfiguration": // notif + var params DidChangeConfigurationParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.DidChangeConfiguration(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/didOpen": // notif + var params DidOpenTextDocumentParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.DidOpen(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/didChange": // notif + var params DidChangeTextDocumentParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.DidChange(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/didClose": // notif + var params DidCloseTextDocumentParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.DidClose(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/didSave": // notif + var params DidSaveTextDocumentParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.DidSave(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/willSave": // notif + var params WillSaveTextDocumentParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.WillSave(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "workspace/didChangeWatchedFiles": // notif + var params DidChangeWatchedFilesParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.DidChangeWatchedFiles(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "$/progress": // notif + var params ProgressParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.Progress(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "$/setTraceNotification": // notif + var params SetTraceParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.SetTraceNotification(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "$/logTraceNotification": // notif + var params LogTraceParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + if err := h.server.LogTraceNotification(ctx, ¶ms); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/implementation": // req + var params ImplementationParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Implementation(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/typeDefinition": // req + var params TypeDefinitionParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.TypeDefinition(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/documentColor": // req + var params DocumentColorParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.DocumentColor(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/colorPresentation": // req + var params ColorPresentationParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.ColorPresentation(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/foldingRange": // req + var params FoldingRangeParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.FoldingRange(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/declaration": // req + var params DeclarationParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Declaration(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/selectionRange": // req + var params SelectionRangeParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.SelectionRange(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "initialize": // req + var params ParamInitia + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Initialize(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "shutdown": // req + if r.Params != nil { + r.Reply(ctx, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params")) + return true + } + err := h.server.Shutdown(ctx) + if err := r.Reply(ctx, nil, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/willSaveWaitUntil": // req + var params WillSaveTextDocumentParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.WillSaveWaitUntil(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/completion": // req + var params CompletionParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Completion(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "completionItem/resolve": // req + var params CompletionItem + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Resolve(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/hover": // req + var params HoverParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Hover(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/signatureHelp": // req + var params SignatureHelpParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.SignatureHelp(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/definition": // req + var params DefinitionParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Definition(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/references": // req + var params ReferenceParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.References(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/documentHighlight": // req + var params DocumentHighlightParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.DocumentHighlight(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/documentSymbol": // req + var params DocumentSymbolParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.DocumentSymbol(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/codeAction": // req + var params CodeActionParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.CodeAction(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "workspace/symbol": // req + var params WorkspaceSymbolParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Symbol(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/codeLens": // req + var params CodeLensParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.CodeLens(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "codeLens/resolve": // req + var params CodeLens + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.ResolveCodeLens(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/documentLink": // req + var params DocumentLinkParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.DocumentLink(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "documentLink/resolve": // req + var params DocumentLink + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.ResolveDocumentLink(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/formatting": // req + var params DocumentFormattingParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Formatting(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/rangeFormatting": // req + var params DocumentRangeFormattingParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.RangeFormatting(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/onTypeFormatting": // req + var params DocumentOnTypeFormattingParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.OnTypeFormatting(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/rename": // req + var params RenameParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.Rename(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "textDocument/prepareRename": // req + var params PrepareRenameParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.PrepareRename(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + case "workspace/executeCommand": // req + var params ExecuteCommandParams + if err := json.Unmarshal(*r.Params, ¶ms); err != nil { + sendParseError(ctx, r, err) + return true + } + resp, err := h.server.ExecuteCommand(ctx, ¶ms) + if err := r.Reply(ctx, resp, err); err != nil { + log.Printf("%v", err) + } + return true + + default: + return false + } +} + +type serverDispatcher struct { + *jsonrpc2.Conn +} + +func (s *serverDispatcher) DidChangeWorkspaceFolders(ctx context.Context, params *DidChangeWorkspaceFoldersParams) error { + return s.Conn.Notify(ctx, "workspace/didChangeWorkspaceFolders", params) +} + +func (s *serverDispatcher) Initialized(ctx context.Context, params *InitializedParams) error { + return s.Conn.Notify(ctx, "initialized", params) +} + +func (s *serverDispatcher) Exit(ctx context.Context) error { + return s.Conn.Notify(ctx, "exit", nil) +} + +func (s *serverDispatcher) DidChangeConfiguration(ctx context.Context, params *DidChangeConfigurationParams) error { + return s.Conn.Notify(ctx, "workspace/didChangeConfiguration", params) +} + +func (s *serverDispatcher) DidOpen(ctx context.Context, params *DidOpenTextDocumentParams) error { + return s.Conn.Notify(ctx, "textDocument/didOpen", params) +} + +func (s *serverDispatcher) DidChange(ctx context.Context, params *DidChangeTextDocumentParams) error { + return s.Conn.Notify(ctx, "textDocument/didChange", params) +} + +func (s *serverDispatcher) DidClose(ctx context.Context, params *DidCloseTextDocumentParams) error { + return s.Conn.Notify(ctx, "textDocument/didClose", params) +} + +func (s *serverDispatcher) DidSave(ctx context.Context, params *DidSaveTextDocumentParams) error { + return s.Conn.Notify(ctx, "textDocument/didSave", params) +} + +func (s *serverDispatcher) WillSave(ctx context.Context, params *WillSaveTextDocumentParams) error { + return s.Conn.Notify(ctx, "textDocument/willSave", params) +} + +func (s *serverDispatcher) DidChangeWatchedFiles(ctx context.Context, params *DidChangeWatchedFilesParams) error { + return s.Conn.Notify(ctx, "workspace/didChangeWatchedFiles", params) +} + +func (s *serverDispatcher) Progress(ctx context.Context, params *ProgressParams) error { + return s.Conn.Notify(ctx, "$/progress", params) +} + +func (s *serverDispatcher) SetTraceNotification(ctx context.Context, params *SetTraceParams) error { + return s.Conn.Notify(ctx, "$/setTraceNotification", params) +} + +func (s *serverDispatcher) LogTraceNotification(ctx context.Context, params *LogTraceParams) error { + return s.Conn.Notify(ctx, "$/logTraceNotification", params) +} +func (s *serverDispatcher) Implementation(ctx context.Context, params *ImplementationParams) ([]Location, error) { + var result []Location + if err := s.Conn.Call(ctx, "textDocument/implementation", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) TypeDefinition(ctx context.Context, params *TypeDefinitionParams) ([]Location, error) { + var result []Location + if err := s.Conn.Call(ctx, "textDocument/typeDefinition", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) DocumentColor(ctx context.Context, params *DocumentColorParams) ([]ColorInformation, error) { + var result []ColorInformation + if err := s.Conn.Call(ctx, "textDocument/documentColor", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) ColorPresentation(ctx context.Context, params *ColorPresentationParams) ([]ColorPresentation, error) { + var result []ColorPresentation + if err := s.Conn.Call(ctx, "textDocument/colorPresentation", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) FoldingRange(ctx context.Context, params *FoldingRangeParams) ([]FoldingRange, error) { + var result []FoldingRange + if err := s.Conn.Call(ctx, "textDocument/foldingRange", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) Declaration(ctx context.Context, params *DeclarationParams) ([]DeclarationLink, error) { + var result []DeclarationLink + if err := s.Conn.Call(ctx, "textDocument/declaration", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) SelectionRange(ctx context.Context, params *SelectionRangeParams) ([]SelectionRange, error) { + var result []SelectionRange + if err := s.Conn.Call(ctx, "textDocument/selectionRange", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) Initialize(ctx context.Context, params *ParamInitia) (*InitializeResult, error) { + var result InitializeResult + if err := s.Conn.Call(ctx, "initialize", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) Shutdown(ctx context.Context) error { + return s.Conn.Call(ctx, "shutdown", nil, nil) +} + +func (s *serverDispatcher) WillSaveWaitUntil(ctx context.Context, params *WillSaveTextDocumentParams) ([]TextEdit, error) { + var result []TextEdit + if err := s.Conn.Call(ctx, "textDocument/willSaveWaitUntil", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) Completion(ctx context.Context, params *CompletionParams) (*CompletionList, error) { + var result CompletionList + if err := s.Conn.Call(ctx, "textDocument/completion", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) Resolve(ctx context.Context, params *CompletionItem) (*CompletionItem, error) { + var result CompletionItem + if err := s.Conn.Call(ctx, "completionItem/resolve", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) Hover(ctx context.Context, params *HoverParams) (*Hover, error) { + var result Hover + if err := s.Conn.Call(ctx, "textDocument/hover", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) SignatureHelp(ctx context.Context, params *SignatureHelpParams) (*SignatureHelp, error) { + var result SignatureHelp + if err := s.Conn.Call(ctx, "textDocument/signatureHelp", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) Definition(ctx context.Context, params *DefinitionParams) ([]Location, error) { + var result []Location + if err := s.Conn.Call(ctx, "textDocument/definition", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) References(ctx context.Context, params *ReferenceParams) ([]Location, error) { + var result []Location + if err := s.Conn.Call(ctx, "textDocument/references", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) DocumentHighlight(ctx context.Context, params *DocumentHighlightParams) ([]DocumentHighlight, error) { + var result []DocumentHighlight + if err := s.Conn.Call(ctx, "textDocument/documentHighlight", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) DocumentSymbol(ctx context.Context, params *DocumentSymbolParams) ([]DocumentSymbol, error) { + var result []DocumentSymbol + if err := s.Conn.Call(ctx, "textDocument/documentSymbol", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) CodeAction(ctx context.Context, params *CodeActionParams) ([]CodeAction, error) { + var result []CodeAction + if err := s.Conn.Call(ctx, "textDocument/codeAction", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) Symbol(ctx context.Context, params *WorkspaceSymbolParams) ([]SymbolInformation, error) { + var result []SymbolInformation + if err := s.Conn.Call(ctx, "workspace/symbol", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) CodeLens(ctx context.Context, params *CodeLensParams) ([]CodeLens, error) { + var result []CodeLens + if err := s.Conn.Call(ctx, "textDocument/codeLens", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) ResolveCodeLens(ctx context.Context, params *CodeLens) (*CodeLens, error) { + var result CodeLens + if err := s.Conn.Call(ctx, "codeLens/resolve", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) DocumentLink(ctx context.Context, params *DocumentLinkParams) ([]DocumentLink, error) { + var result []DocumentLink + if err := s.Conn.Call(ctx, "textDocument/documentLink", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) ResolveDocumentLink(ctx context.Context, params *DocumentLink) (*DocumentLink, error) { + var result DocumentLink + if err := s.Conn.Call(ctx, "documentLink/resolve", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) Formatting(ctx context.Context, params *DocumentFormattingParams) ([]TextEdit, error) { + var result []TextEdit + if err := s.Conn.Call(ctx, "textDocument/formatting", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) RangeFormatting(ctx context.Context, params *DocumentRangeFormattingParams) ([]TextEdit, error) { + var result []TextEdit + if err := s.Conn.Call(ctx, "textDocument/rangeFormatting", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) OnTypeFormatting(ctx context.Context, params *DocumentOnTypeFormattingParams) ([]TextEdit, error) { + var result []TextEdit + if err := s.Conn.Call(ctx, "textDocument/onTypeFormatting", params, &result); err != nil { + return nil, err + } + return result, nil +} + +func (s *serverDispatcher) Rename(ctx context.Context, params *RenameParams) (*WorkspaceEdit, error) { + var result WorkspaceEdit + if err := s.Conn.Call(ctx, "textDocument/rename", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) PrepareRename(ctx context.Context, params *PrepareRenameParams) (*Range, error) { + var result Range + if err := s.Conn.Call(ctx, "textDocument/prepareRename", params, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (s *serverDispatcher) ExecuteCommand(ctx context.Context, params *ExecuteCommandParams) (interface{}, error) { + var result interface{} + if err := s.Conn.Call(ctx, "workspace/executeCommand", params, &result); err != nil { + return nil, err + } + return result, nil +} + +type CancelParams struct { + /** + * The request id to cancel. + */ + ID jsonrpc2.ID `json:"id"` +} + +// Types constructed to avoid structs as formal argument types +type ParamInitia struct { + InitializeParams + WorkDoneProgressParams +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/parse.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/parse.go new file mode 100644 index 000000000000..ec393c2a75f2 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/parse.go @@ -0,0 +1,110 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package span + +import ( + "strconv" + "strings" + "unicode/utf8" +) + +// Parse returns the location represented by the input. +// All inputs are valid locations, as they can always be a pure filename. +// The returned span will be normalized, and thus if printed may produce a +// different string. +func Parse(input string) Span { + // :0:0#0-0:0#0 + valid := input + var hold, offset int + hadCol := false + suf := rstripSuffix(input) + if suf.sep == "#" { + offset = suf.num + suf = rstripSuffix(suf.remains) + } + if suf.sep == ":" { + valid = suf.remains + hold = suf.num + hadCol = true + suf = rstripSuffix(suf.remains) + } + switch { + case suf.sep == ":": + return New(NewURI(suf.remains), NewPoint(suf.num, hold, offset), Point{}) + case suf.sep == "-": + // we have a span, fall out of the case to continue + default: + // separator not valid, rewind to either the : or the start + return New(NewURI(valid), NewPoint(hold, 0, offset), Point{}) + } + // only the span form can get here + // at this point we still don't know what the numbers we have mean + // if have not yet seen a : then we might have either a line or a column depending + // on whether start has a column or not + // we build an end point and will fix it later if needed + end := NewPoint(suf.num, hold, offset) + hold, offset = 0, 0 + suf = rstripSuffix(suf.remains) + if suf.sep == "#" { + offset = suf.num + suf = rstripSuffix(suf.remains) + } + if suf.sep != ":" { + // turns out we don't have a span after all, rewind + return New(NewURI(valid), end, Point{}) + } + valid = suf.remains + hold = suf.num + suf = rstripSuffix(suf.remains) + if suf.sep != ":" { + // line#offset only + return New(NewURI(valid), NewPoint(hold, 0, offset), end) + } + // we have a column, so if end only had one number, it is also the column + if !hadCol { + end = NewPoint(suf.num, end.v.Line, end.v.Offset) + } + return New(NewURI(suf.remains), NewPoint(suf.num, hold, offset), end) +} + +type suffix struct { + remains string + sep string + num int +} + +func rstripSuffix(input string) suffix { + if len(input) == 0 { + return suffix{"", "", -1} + } + remains := input + num := -1 + // first see if we have a number at the end + last := strings.LastIndexFunc(remains, func(r rune) bool { return r < '0' || r > '9' }) + if last >= 0 && last < len(remains)-1 { + number, err := strconv.ParseInt(remains[last+1:], 10, 64) + if err == nil { + num = int(number) + remains = remains[:last+1] + } + } + // now see if we have a trailing separator + r, w := utf8.DecodeLastRuneInString(remains) + if r != ':' && r != '#' && r == '#' { + return suffix{input, "", -1} + } + remains = remains[:len(remains)-w] + return suffix{remains, string(r), num} +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/span.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/span.go new file mode 100644 index 000000000000..aefd4f3fad91 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/span.go @@ -0,0 +1,295 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package span contains support for representing with positions and ranges in +// text files. +package span + +import ( + "encoding/json" + "fmt" + "path" +) + +// Span represents a source code range in standardized form. +type Span struct { + v span +} + +// Point represents a single point within a file. +// In general this should only be used as part of a Span, as on its own it +// does not carry enough information. +type Point struct { + v point +} + +type span struct { + URI URI `json:"uri"` + Start point `json:"start"` + End point `json:"end"` +} + +type point struct { + Line int `json:"line"` + Column int `json:"column"` + Offset int `json:"offset"` +} + +// Invalid is a span that reports false from IsValid +var Invalid = Span{v: span{Start: invalidPoint.v, End: invalidPoint.v}} + +var invalidPoint = Point{v: point{Line: 0, Column: 0, Offset: -1}} + +// Converter is the interface to an object that can convert between line:column +// and offset forms for a single file. +type Converter interface { + //ToPosition converts from an offset to a line:column pair. + ToPosition(offset int) (int, int, error) + //ToOffset converts from a line:column pair to an offset. + ToOffset(line, col int) (int, error) +} + +func New(uri URI, start Point, end Point) Span { + s := Span{v: span{URI: uri, Start: start.v, End: end.v}} + s.v.clean() + return s +} + +func NewPoint(line, col, offset int) Point { + p := Point{v: point{Line: line, Column: col, Offset: offset}} + p.v.clean() + return p +} + +func Compare(a, b Span) int { + if r := CompareURI(a.URI(), b.URI()); r != 0 { + return r + } + if r := comparePoint(a.v.Start, b.v.Start); r != 0 { + return r + } + return comparePoint(a.v.End, b.v.End) +} + +func ComparePoint(a, b Point) int { + return comparePoint(a.v, b.v) +} + +func comparePoint(a, b point) int { + if !a.hasPosition() { + if a.Offset < b.Offset { + return -1 + } + if a.Offset > b.Offset { + return 1 + } + return 0 + } + if a.Line < b.Line { + return -1 + } + if a.Line > b.Line { + return 1 + } + if a.Column < b.Column { + return -1 + } + if a.Column > b.Column { + return 1 + } + return 0 +} + +func (s Span) HasPosition() bool { return s.v.Start.hasPosition() } +func (s Span) HasOffset() bool { return s.v.Start.hasOffset() } +func (s Span) IsValid() bool { return s.v.Start.isValid() } +func (s Span) IsPoint() bool { return s.v.Start == s.v.End } +func (s Span) URI() URI { return s.v.URI } +func (s Span) Start() Point { return Point{s.v.Start} } +func (s Span) End() Point { return Point{s.v.End} } +func (s *Span) MarshalJSON() ([]byte, error) { return json.Marshal(&s.v) } +func (s *Span) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &s.v) } + +func (p Point) HasPosition() bool { return p.v.hasPosition() } +func (p Point) HasOffset() bool { return p.v.hasOffset() } +func (p Point) IsValid() bool { return p.v.isValid() } +func (p *Point) MarshalJSON() ([]byte, error) { return json.Marshal(&p.v) } +func (p *Point) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &p.v) } +func (p Point) Line() int { + if !p.v.hasPosition() { + panic(fmt.Errorf("position not set in %v", p.v)) + } + return p.v.Line +} +func (p Point) Column() int { + if !p.v.hasPosition() { + panic(fmt.Errorf("position not set in %v", p.v)) + } + return p.v.Column +} +func (p Point) Offset() int { + if !p.v.hasOffset() { + panic(fmt.Errorf("offset not set in %v", p.v)) + } + return p.v.Offset +} + +func (p point) hasPosition() bool { return p.Line > 0 } +func (p point) hasOffset() bool { return p.Offset >= 0 } +func (p point) isValid() bool { return p.hasPosition() || p.hasOffset() } +func (p point) isZero() bool { + return (p.Line == 1 && p.Column == 1) || (!p.hasPosition() && p.Offset == 0) +} + +func (s *span) clean() { + //this presumes the points are already clean + if !s.End.isValid() || (s.End == point{}) { + s.End = s.Start + } +} + +func (p *point) clean() { + if p.Line < 0 { + p.Line = 0 + } + if p.Column <= 0 { + if p.Line > 0 { + p.Column = 1 + } else { + p.Column = 0 + } + } + if p.Offset == 0 && (p.Line > 1 || p.Column > 1) { + p.Offset = -1 + } +} + +// Format implements fmt.Formatter to print the Location in a standard form. +// The format produced is one that can be read back in using Parse. +func (s Span) Format(f fmt.State, c rune) { + fullForm := f.Flag('+') + preferOffset := f.Flag('#') + // we should always have a uri, simplify if it is file format + //TODO: make sure the end of the uri is unambiguous + uri := string(s.v.URI) + if c == 'f' { + uri = path.Base(uri) + } else if !fullForm { + uri = s.v.URI.Filename() + } + fmt.Fprint(f, uri) + if !s.IsValid() || (!fullForm && s.v.Start.isZero() && s.v.End.isZero()) { + return + } + // see which bits of start to write + printOffset := s.HasOffset() && (fullForm || preferOffset || !s.HasPosition()) + printLine := s.HasPosition() && (fullForm || !printOffset) + printColumn := printLine && (fullForm || (s.v.Start.Column > 1 || s.v.End.Column > 1)) + fmt.Fprint(f, ":") + if printLine { + fmt.Fprintf(f, "%d", s.v.Start.Line) + } + if printColumn { + fmt.Fprintf(f, ":%d", s.v.Start.Column) + } + if printOffset { + fmt.Fprintf(f, "#%d", s.v.Start.Offset) + } + // start is written, do we need end? + if s.IsPoint() { + return + } + // we don't print the line if it did not change + printLine = fullForm || (printLine && s.v.End.Line > s.v.Start.Line) + fmt.Fprint(f, "-") + if printLine { + fmt.Fprintf(f, "%d", s.v.End.Line) + } + if printColumn { + if printLine { + fmt.Fprint(f, ":") + } + fmt.Fprintf(f, "%d", s.v.End.Column) + } + if printOffset { + fmt.Fprintf(f, "#%d", s.v.End.Offset) + } +} + +func (s Span) WithPosition(c Converter) (Span, error) { + if err := s.update(c, true, false); err != nil { + return Span{}, err + } + return s, nil +} + +func (s Span) WithOffset(c Converter) (Span, error) { + if err := s.update(c, false, true); err != nil { + return Span{}, err + } + return s, nil +} + +func (s Span) WithAll(c Converter) (Span, error) { + if err := s.update(c, true, true); err != nil { + return Span{}, err + } + return s, nil +} + +func (s *Span) update(c Converter, withPos, withOffset bool) error { + if !s.IsValid() { + return fmt.Errorf("cannot add information to an invalid span") + } + if withPos && !s.HasPosition() { + if err := s.v.Start.updatePosition(c); err != nil { + return err + } + if s.v.End.Offset == s.v.Start.Offset { + s.v.End = s.v.Start + } else if err := s.v.End.updatePosition(c); err != nil { + return err + } + } + if withOffset && (!s.HasOffset() || (s.v.End.hasPosition() && !s.v.End.hasOffset())) { + if err := s.v.Start.updateOffset(c); err != nil { + return err + } + if s.v.End.Line == s.v.Start.Line && s.v.End.Column == s.v.Start.Column { + s.v.End.Offset = s.v.Start.Offset + } else if err := s.v.End.updateOffset(c); err != nil { + return err + } + } + return nil +} + +func (p *point) updatePosition(c Converter) error { + line, col, err := c.ToPosition(p.Offset) + if err != nil { + return err + } + p.Line = line + p.Column = col + return nil +} + +func (p *point) updateOffset(c Converter) error { + offset, err := c.ToOffset(p.Line, p.Column) + if err != nil { + return err + } + p.Offset = offset + return nil +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token.go new file mode 100644 index 000000000000..f5a38708f76d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token.go @@ -0,0 +1,161 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package span + +import ( + "fmt" + "go/token" +) + +// Range represents a source code range in token.Pos form. +// It also carries the FileSet that produced the positions, so that it is +// self contained. +type Range struct { + FileSet *token.FileSet + Start token.Pos + End token.Pos +} + +// TokenConverter is a Converter backed by a token file set and file. +// It uses the file set methods to work out the conversions, which +// makes it fast and does not require the file contents. +type TokenConverter struct { + fset *token.FileSet + file *token.File +} + +// NewRange creates a new Range from a FileSet and two positions. +// To represent a point pass a 0 as the end pos. +func NewRange(fset *token.FileSet, start, end token.Pos) Range { + return Range{ + FileSet: fset, + Start: start, + End: end, + } +} + +// NewTokenConverter returns an implementation of Converter backed by a +// token.File. +func NewTokenConverter(fset *token.FileSet, f *token.File) *TokenConverter { + return &TokenConverter{fset: fset, file: f} +} + +// NewContentConverter returns an implementation of Converter for the +// given file content. +func NewContentConverter(filename string, content []byte) *TokenConverter { + fset := token.NewFileSet() + f := fset.AddFile(filename, -1, len(content)) + f.SetLinesForContent(content) + return &TokenConverter{fset: fset, file: f} +} + +// IsPoint returns true if the range represents a single point. +func (r Range) IsPoint() bool { + return r.Start == r.End +} + +// Span converts a Range to a Span that represents the Range. +// It will fill in all the members of the Span, calculating the line and column +// information. +func (r Range) Span() (Span, error) { + f := r.FileSet.File(r.Start) + if f == nil { + return Span{}, fmt.Errorf("file not found in FileSet") + } + s := Span{v: span{URI: FileURI(f.Name())}} + var err error + s.v.Start.Offset, err = offset(f, r.Start) + if err != nil { + return Span{}, err + } + if r.End.IsValid() { + s.v.End.Offset, err = offset(f, r.End) + if err != nil { + return Span{}, err + } + } + s.v.Start.clean() + s.v.End.clean() + s.v.clean() + converter := NewTokenConverter(r.FileSet, f) + return s.WithPosition(converter) +} + +// offset is a copy of the Offset function in go/token, but with the adjustment +// that it does not panic on invalid positions. +func offset(f *token.File, pos token.Pos) (int, error) { + if int(pos) < f.Base() || int(pos) > f.Base()+f.Size() { + return 0, fmt.Errorf("invalid pos") + } + return int(pos) - f.Base(), nil +} + +// Range converts a Span to a Range that represents the Span for the supplied +// File. +func (s Span) Range(converter *TokenConverter) (Range, error) { + s, err := s.WithOffset(converter) + if err != nil { + return Range{}, err + } + // go/token will panic if the offset is larger than the file's size, + // so check here to avoid panicking. + if s.Start().Offset() > converter.file.Size() { + return Range{}, fmt.Errorf("start offset %v is past the end of the file %v", s.Start(), converter.file.Size()) + } + if s.End().Offset() > converter.file.Size() { + return Range{}, fmt.Errorf("end offset %v is past the end of the file %v", s.End(), converter.file.Size()) + } + return Range{ + FileSet: converter.fset, + Start: converter.file.Pos(s.Start().Offset()), + End: converter.file.Pos(s.End().Offset()), + }, nil +} + +func (l *TokenConverter) ToPosition(offset int) (int, int, error) { + if offset > l.file.Size() { + return 0, 0, fmt.Errorf("offset %v is past the end of the file %v", offset, l.file.Size()) + } + pos := l.file.Pos(offset) + p := l.fset.Position(pos) + if offset == l.file.Size() { + return p.Line + 1, 1, nil + } + return p.Line, p.Column, nil +} + +func (l *TokenConverter) ToOffset(line, col int) (int, error) { + if line < 0 { + return -1, fmt.Errorf("line is not valid") + } + lineMax := l.file.LineCount() + 1 + if line > lineMax { + return -1, fmt.Errorf("line is beyond end of file %v", lineMax) + } else if line == lineMax { + if col > 1 { + return -1, fmt.Errorf("column is beyond end of file") + } + // at the end of the file, allowing for a trailing eol + return l.file.Size(), nil + } + pos := lineStart(l.file, line) + if !pos.IsValid() { + return -1, fmt.Errorf("line is not in file") + } + // we assume that column is in bytes here, and that the first byte of a + // line is at column 1 + pos += token.Pos(col - 1) + return offset(l.file, pos) +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token111.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token111.go new file mode 100644 index 000000000000..768419a70104 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token111.go @@ -0,0 +1,49 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !go1.12 + +package span + +import ( + "go/token" +) + +// lineStart is the pre-Go 1.12 version of (*token.File).LineStart. For Go +// versions <= 1.11, we borrow logic from the analysisutil package. +// TODO(rstambler): Delete this file when we no longer support Go 1.11. +func lineStart(f *token.File, line int) token.Pos { + // Use binary search to find the start offset of this line. + + min := 0 // inclusive + max := f.Size() // exclusive + for { + offset := (min + max) / 2 + pos := f.Pos(offset) + posn := f.Position(pos) + if posn.Line == line { + return pos - (token.Pos(posn.Column) - 1) + } + + if min+1 >= max { + return token.NoPos + } + + if posn.Line < line { + min = offset + } else { + max = offset + } + } +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token112.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token112.go new file mode 100644 index 000000000000..abff500d2bbf --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/token112.go @@ -0,0 +1,26 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build go1.12 + +package span + +import ( + "go/token" +) + +// TODO(rstambler): Delete this file when we no longer support Go 1.11. +func lineStart(f *token.File, line int) token.Pos { + return f.LineStart(line) +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/uri.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/uri.go new file mode 100644 index 000000000000..525518bef250 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/uri.go @@ -0,0 +1,162 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package span + +import ( + "fmt" + "net/url" + "os" + "path" + "path/filepath" + "runtime" + "strings" + "unicode" +) + +const fileScheme = "file" + +// URI represents the full URI for a file. +type URI string + +// Filename returns the file path for the given URI. +// It is an error to call this on a URI that is not a valid filename. +func (uri URI) Filename() string { + filename, err := filename(uri) + if err != nil { + panic(err) + } + return filepath.FromSlash(filename) +} + +func filename(uri URI) (string, error) { + if uri == "" { + return "", nil + } + u, err := url.ParseRequestURI(string(uri)) + if err != nil { + return "", err + } + if u.Scheme != fileScheme { + return "", fmt.Errorf("only file URIs are supported, got %q from %q", u.Scheme, uri) + } + if isWindowsDriveURI(u.Path) { + u.Path = u.Path[1:] + } + return u.Path, nil +} + +// NewURI returns a span URI for the string. +// It will attempt to detect if the string is a file path or uri. +func NewURI(s string) URI { + if u, err := url.PathUnescape(s); err == nil { + s = u + } + if strings.HasPrefix(s, fileScheme+"://") { + return URI(s) + } + return FileURI(s) +} + +func CompareURI(a, b URI) int { + if equalURI(a, b) { + return 0 + } + if a < b { + return -1 + } + return 1 +} + +func equalURI(a, b URI) bool { + if a == b { + return true + } + // If we have the same URI basename, we may still have the same file URIs. + if !strings.EqualFold(path.Base(string(a)), path.Base(string(b))) { + return false + } + fa, err := filename(a) + if err != nil { + return false + } + fb, err := filename(b) + if err != nil { + return false + } + // Stat the files to check if they are equal. + infoa, err := os.Stat(filepath.FromSlash(fa)) + if err != nil { + return false + } + infob, err := os.Stat(filepath.FromSlash(fb)) + if err != nil { + return false + } + return os.SameFile(infoa, infob) +} + +// FileURI returns a span URI for the supplied file path. +// It will always have the file scheme. +func FileURI(path string) URI { + if path == "" { + return "" + } + // Handle standard library paths that contain the literal "$GOROOT". + // TODO(rstambler): The go/packages API should allow one to determine a user's $GOROOT. + const prefix = "$GOROOT" + if len(path) >= len(prefix) && strings.EqualFold(prefix, path[:len(prefix)]) { + suffix := path[len(prefix):] + path = runtime.GOROOT() + suffix + } + if !isWindowsDrivePath(path) { + if abs, err := filepath.Abs(path); err == nil { + path = abs + } + } + // Check the file path again, in case it became absolute. + if isWindowsDrivePath(path) { + path = "/" + path + } + path = filepath.ToSlash(path) + u := url.URL{ + Scheme: fileScheme, + Path: path, + } + uri := u.String() + if unescaped, err := url.PathUnescape(uri); err == nil { + uri = unescaped + } + return URI(uri) +} + +// isWindowsDrivePath returns true if the file path is of the form used by +// Windows. We check if the path begins with a drive letter, followed by a ":". +func isWindowsDrivePath(path string) bool { + if len(path) < 4 { + return false + } + return unicode.IsLetter(rune(path[0])) && path[1] == ':' +} + +// isWindowsDriveURI returns true if the file URI is of the format used by +// Windows URIs. The url.Parse package does not specially handle Windows paths +// (see https://golang.org/issue/6027). We check if the URI path has +// a drive prefix (e.g. "/C:"). If so, we trim the leading "/". +func isWindowsDriveURI(uri string) bool { + if len(uri) < 4 { + return false + } + return uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':' +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/utf16.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/utf16.go new file mode 100644 index 000000000000..6821851d18cd --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/lsp/span/utf16.go @@ -0,0 +1,104 @@ +// Copyright 2019 The Go Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package span + +import ( + "fmt" + "unicode/utf16" + "unicode/utf8" +) + +// ToUTF16Column calculates the utf16 column expressed by the point given the +// supplied file contents. +// This is used to convert from the native (always in bytes) column +// representation and the utf16 counts used by some editors. +func ToUTF16Column(p Point, content []byte) (int, error) { + if content == nil { + return -1, fmt.Errorf("ToUTF16Column: missing content") + } + if !p.HasPosition() { + return -1, fmt.Errorf("ToUTF16Column: point is missing position") + } + if !p.HasOffset() { + return -1, fmt.Errorf("ToUTF16Column: point is missing offset") + } + offset := p.Offset() // 0-based + colZero := p.Column() - 1 // 0-based + if colZero == 0 { + // 0-based column 0, so it must be chr 1 + return 1, nil + } else if colZero < 0 { + return -1, fmt.Errorf("ToUTF16Column: column is invalid (%v)", colZero) + } + // work out the offset at the start of the line using the column + lineOffset := offset - colZero + if lineOffset < 0 || offset > len(content) { + return -1, fmt.Errorf("ToUTF16Column: offsets %v-%v outside file contents (%v)", lineOffset, offset, len(content)) + } + // Use the offset to pick out the line start. + // This cannot panic: offset > len(content) and lineOffset < offset. + start := content[lineOffset:] + + // Now, truncate down to the supplied column. + start = start[:colZero] + + // and count the number of utf16 characters + // in theory we could do this by hand more efficiently... + return len(utf16.Encode([]rune(string(start)))) + 1, nil +} + +// FromUTF16Column advances the point by the utf16 character offset given the +// supplied line contents. +// This is used to convert from the utf16 counts used by some editors to the +// native (always in bytes) column representation. +func FromUTF16Column(p Point, chr int, content []byte) (Point, error) { + if !p.HasOffset() { + return Point{}, fmt.Errorf("FromUTF16Column: point is missing offset") + } + // if chr is 1 then no adjustment needed + if chr <= 1 { + return p, nil + } + if p.Offset() >= len(content) { + return p, fmt.Errorf("FromUTF16Column: offset (%v) greater than length of content (%v)", p.Offset(), len(content)) + } + remains := content[p.Offset():] + // scan forward the specified number of characters + for count := 1; count < chr; count++ { + if len(remains) <= 0 { + return Point{}, fmt.Errorf("FromUTF16Column: chr goes beyond the content") + } + r, w := utf8.DecodeRune(remains) + if r == '\n' { + // Per the LSP spec: + // + // > If the character value is greater than the line length it + // > defaults back to the line length. + break + } + remains = remains[w:] + if r >= 0x10000 { + // a two point rune + count++ + // if we finished in a two point rune, do not advance past the first + if count >= chr { + break + } + } + p.v.Column += w + p.v.Offset += w + } + return p, nil +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/parser/parser.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/parser/parser.go new file mode 100644 index 000000000000..4c0fa8f78706 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/parser/parser.go @@ -0,0 +1,818 @@ +// Copyright (C) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package parser implements a SPIR-V assembly parser. +package parser + +import ( + "fmt" + "io" + "log" + "strings" + "unicode" + "unicode/utf8" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/schema" +) + +// Type is an enumerator of token types. +type Type int + +// Type enumerators +const ( + Ident Type = iota // Foo + PIdent // %32, %foo + Integer + Float + String + Operator + Comment + Newline +) + +func (t Type) String() string { + switch t { + case Ident: + return "Ident" + case PIdent: + return "PIdent" + case Integer: + return "Integer" + case Float: + return "Float" + case String: + return "String" + case Operator: + return "Operator" + case Comment: + return "Comment" + default: + return "" + } +} + +// Token represents a single lexed token. +type Token struct { + Type Type + Range Range +} + +func (t Token) String() string { return fmt.Sprintf("{%v %v}", t.Type, t.Range) } + +// Text returns the tokens text from the source. +func (t Token) Text(lines []string) string { return t.Range.Text(lines) } + +// Range represents an interval in a text file. +type Range struct { + Start Position + End Position +} + +func (r Range) String() string { return fmt.Sprintf("[%v %v]", r.Start, r.End) } + +// Text returns the text for the given Range in the provided lines. +func (r Range) Text(lines []string) string { + sl, sc := r.Start.Line-1, r.Start.Column-1 + if sl < 0 || sc < 0 || sl > len(lines) || sc > len(lines[sl]) { + return fmt.Sprintf("", r.Start) + } + el, ec := r.End.Line-1, r.End.Column-1 + if el < 0 || ec < 0 || el > len(lines) || ec > len(lines[sl]) { + return fmt.Sprintf("", r.End) + } + + sb := strings.Builder{} + if sl != el { + sb.WriteString(lines[sl][sc:]) + for l := sl + 1; l < el; l++ { + sb.WriteString(lines[l]) + } + sb.WriteString(lines[el][:ec]) + } else { + sb.WriteString(lines[sl][sc:ec]) + } + return sb.String() +} + +// Contains returns true if p is in r. +func (r Range) Contains(p Position) bool { + return !(p.LessThan(r.Start) || p.GreaterThan(r.End)) +} + +func (r *Range) grow(o Range) { + if !r.Start.IsValid() || o.Start.LessThan(r.Start) { + r.Start = o.Start + } + if !r.End.IsValid() || o.End.GreaterThan(r.End) { + r.End = o.End + } +} + +// Position holds a line and column position in a text file. +type Position struct { + Line, Column int +} + +func (p Position) String() string { return fmt.Sprintf("%v:%v", p.Line, p.Column) } + +// IsValid returns true if the position has a line and column greater than 1. +func (p Position) IsValid() bool { return p.Line > 0 && p.Column > 0 } + +// LessThan returns true iff o is before p. +func (p Position) LessThan(o Position) bool { + switch { + case !p.IsValid() || !o.IsValid(): + return false + case p.Line < o.Line: + return true + case p.Line > o.Line: + return false + case p.Column < o.Column: + return true + default: + return false + } +} + +// GreaterThan returns true iff o is greater than p. +func (p Position) GreaterThan(o Position) bool { + switch { + case !p.IsValid() || !o.IsValid(): + return false + case p.Line > o.Line: + return true + case p.Line < o.Line: + return false + case p.Column > o.Column: + return true + default: + return false + } +} + +type lexer struct { + source string + lexerState + diags []Diagnostic + e error +} + +type lexerState struct { + offset int // byte offset in source + toks []*Token // all the lexed tokens + pos Position // current position +} + +// err appends an fmt.Printf style error into l.diags for the given token. +func (l *lexer) err(tok *Token, msg string, args ...interface{}) { + rng := Range{} + if tok != nil { + rng = tok.Range + } + l.diags = append(l.diags, Diagnostic{ + Range: rng, + Severity: SeverityError, + Message: fmt.Sprintf(msg, args...), + }) +} + +// next returns the next rune, or io.EOF if the last rune has already been +// consumed. +func (l *lexer) next() rune { + if l.offset >= len(l.source) { + l.e = io.EOF + return 0 + } + r, n := utf8.DecodeRuneInString(l.source[l.offset:]) + l.offset += n + if n == 0 { + l.e = io.EOF + return 0 + } + if r == '\n' { + l.pos.Line++ + l.pos.Column = 1 + } else { + l.pos.Column++ + } + return r +} + +// save returns the current lexerState. +func (l *lexer) save() lexerState { + return l.lexerState +} + +// restore restores the current lexer state with s. +func (l *lexer) restore(s lexerState) { + l.lexerState = s +} + +// pident processes the PIdent token at the current position. +// The lexer *must* know the next token is a PIdent before calling. +func (l *lexer) pident() { + tok := &Token{Type: PIdent, Range: Range{Start: l.pos, End: l.pos}} + if r := l.next(); r != '%' { + log.Fatalf("lexer expected '%%', got '%v'", r) + return + } + for l.e == nil { + s := l.save() + r := l.next() + if !isAlphaNumeric(r) && r != '_' { + l.restore(s) + break + } + } + tok.Range.End = l.pos + l.toks = append(l.toks, tok) +} + +// numberOrIdent processes the Ident, Float or Integer token at the current +// position. +func (l *lexer) numberOrIdent() { + const Unknown Type = -1 + tok := &Token{Type: Unknown, Range: Range{Start: l.pos, End: l.pos}} +loop: + for l.e == nil { + s := l.save() + r := l.next() + switch { + case r == '-', r == '+', isNumeric(r): + continue + case isAlpha(r), r == '_': + switch tok.Type { + case Unknown: + tok.Type = Ident + case Float, Integer: + l.err(tok, "invalid number") + return + } + case r == '.': + switch tok.Type { + case Unknown: + tok.Type = Float + default: + l.restore(s) + break loop + } + default: + if tok.Type == Unknown { + tok.Type = Integer + } + l.restore(s) + break loop + } + } + tok.Range.End = l.pos + l.toks = append(l.toks, tok) +} + +// string processes the String token at the current position. +// The lexer *must* know the next token is a String before calling. +func (l *lexer) string() { + tok := &Token{Type: String, Range: Range{Start: l.pos, End: l.pos}} + if r := l.next(); r != '"' { + log.Fatalf("lexer expected '\"', got '%v'", r) + return + } + escape := false + for l.e == nil { + switch l.next() { + case '"': + if !escape { + tok.Range.End = l.pos + l.toks = append(l.toks, tok) + return + } + case '\\': + escape = !escape + default: + escape = false + } + } +} + +// operator processes the Operator token at the current position. +// The lexer *must* know the next token is a Operator before calling. +func (l *lexer) operator() { + tok := &Token{Type: Operator, Range: Range{Start: l.pos, End: l.pos}} + for l.e == nil { + switch l.next() { + case '=', '|': + tok.Range.End = l.pos + l.toks = append(l.toks, tok) + return + } + } +} + +// lineComment processes the Comment token at the current position. +// The lexer *must* know the next token is a Comment before calling. +func (l *lexer) lineComment() { + tok := &Token{Type: Comment, Range: Range{Start: l.pos, End: l.pos}} + if r := l.next(); r != ';' { + log.Fatalf("lexer expected ';', got '%v'", r) + return + } + for l.e == nil { + s := l.save() + switch l.next() { + case '\n': + l.restore(s) + tok.Range.End = l.pos + l.toks = append(l.toks, tok) + return + } + } +} + +// newline processes the Newline token at the current position. +// The lexer *must* know the next token is a Newline before calling. +func (l *lexer) newline() { + tok := &Token{Type: Newline, Range: Range{Start: l.pos, End: l.pos}} + if r := l.next(); r != '\n' { + log.Fatalf("lexer expected '\n', got '%v'", r) + return + } + tok.Range.End = l.pos + l.toks = append(l.toks, tok) +} + +// lex returns all the tokens and diagnostics after lexing source. +func lex(source string) ([]*Token, []Diagnostic, error) { + l := lexer{source: source, lexerState: lexerState{pos: Position{1, 1}}} + + lastPos := Position{} + for l.e == nil { + // Integrity check that the parser is making progress + if l.pos == lastPos { + log.Panicf("Parsing stuck at %v", l.pos) + } + lastPos = l.pos + + s := l.save() + r := l.next() + switch { + case r == '%': + l.restore(s) + l.pident() + case r == '+' || r == '-' || r == '_' || isAlphaNumeric(r): + l.restore(s) + l.numberOrIdent() + case r == '"': + l.restore(s) + l.string() + case r == '=', r == '|': + l.restore(s) + l.operator() + case r == ';': + l.restore(s) + l.lineComment() + case r == '\n': + l.restore(s) + l.newline() + } + } + if l.e != nil && l.e != io.EOF { + return nil, nil, l.e + } + return l.toks, l.diags, nil +} + +func isNumeric(r rune) bool { return unicode.IsDigit(r) } +func isAlpha(r rune) bool { return unicode.IsLetter(r) } +func isAlphaNumeric(r rune) bool { return isAlpha(r) || isNumeric(r) } + +type parser struct { + lines []string // all source lines + toks []*Token // all tokens + diags []Diagnostic // parser emitted diagnostics + idents map[string]*Identifier // identifiers by name + mappings map[*Token]interface{} // tokens to semantic map + extInstImports map[string]schema.OpcodeMap // extension imports by identifier + insts []*Instruction // all instructions +} + +func (p *parser) parse() error { + for i := 0; i < len(p.toks); { + if p.newline(i) || p.comment(i) { + i++ + continue + } + if n := p.instruction(i); n > 0 { + i += n + } else { + p.unexpected(i) + i++ + } + } + return nil +} + +// instruction parses the instruction starting at the i'th token. +func (p *parser) instruction(i int) (n int) { + inst := &Instruction{} + + switch { + case p.opcode(i) != nil: + inst.Opcode = p.opcode(i) + inst.Tokens = []*Token{p.tok(i)} + p.mappings[p.tok(i)] = inst + n++ + case p.opcode(i+2) != nil: // try '%id' '=' + inst.Result, inst.Opcode = p.pident(i), p.opcode(i+2) + if inst.Result == nil || p.operator(i+1) != "=" { + return 0 + } + n += 3 + inst.Tokens = []*Token{p.tok(i), p.tok(i + 1), p.tok(i + 2)} + p.mappings[p.tok(i+2)] = inst + default: + return + } + + expectsResult := len(inst.Opcode.Operands) > 0 && IsResult(inst.Opcode.Operands[0].Kind) + operands := inst.Opcode.Operands + switch { + case inst.Result != nil && !expectsResult: + p.err(inst.Result, "'%s' does not have a result", inst.Opcode.Opname) + return + case inst.Result == nil && expectsResult: + p.err(p.tok(i), "'%s' expects a result", inst.Opcode.Opname) + return + case inst.Result != nil && expectsResult: + // Check the result is of the correct type + o := inst.Opcode.Operands[0] + p.operand(o.Name, o.Kind, i, false) + operands = operands[1:] + p.addIdentDef(inst.Result.Text(p.lines), inst, p.tok(i)) + } + + processOperand := func(o schema.Operand) bool { + if p.newline(i + n) { + return false + } + + switch o.Quantifier { + case schema.Once: + if op, c := p.operand(o.Name, o.Kind, i+n, false); op != nil { + inst.Tokens = append(inst.Tokens, op.Tokens...) + n += c + } + case schema.ZeroOrOnce: + if op, c := p.operand(o.Name, o.Kind, i+n, true); op != nil { + inst.Tokens = append(inst.Tokens, op.Tokens...) + n += c + } + case schema.ZeroOrMany: + for !p.newline(i + n) { + if op, c := p.operand(o.Name, o.Kind, i+n, true); op != nil { + inst.Tokens = append(inst.Tokens, op.Tokens...) + n += c + } else { + return false + } + } + } + return true + } + + for _, o := range operands { + if !processOperand(o) { + break + } + + if inst.Opcode == schema.OpExtInst && n == 4 { + extImportTok, extNameTok := p.tok(i+n), p.tok(i+n+1) + extImport := extImportTok.Text(p.lines) + if extOpcodes, ok := p.extInstImports[extImport]; ok { + extName := extNameTok.Text(p.lines) + if extOpcode, ok := extOpcodes[extName]; ok { + n += 2 // skip ext import, ext name + for _, o := range extOpcode.Operands { + if !processOperand(o) { + break + } + } + } else { + p.err(extNameTok, "Unknown extension opcode '%s'", extName) + } + } else { + p.err(extImportTok, "Expected identifier to OpExtInstImport") + } + } + } + + for _, t := range inst.Tokens { + inst.Range.grow(t.Range) + } + + p.insts = append(p.insts, inst) + + if inst.Opcode == schema.OpExtInstImport && len(inst.Tokens) >= 4 { + // Instruction is a OpExtInstImport. Keep track of this. + extTok := inst.Tokens[3] + extName := strings.Trim(extTok.Text(p.lines), `"`) + extOpcodes, ok := schema.ExtOpcodes[extName] + if !ok { + p.err(extTok, "Unknown extension '%s'", extName) + } + extImport := inst.Result.Text(p.lines) + p.extInstImports[extImport] = extOpcodes + } + + return +} + +// operand parses the operand with the name n, kind k, starting at the i'th +// token. +func (p *parser) operand(n string, k *schema.OperandKind, i int, optional bool) (*Operand, int) { + tok := p.tok(i) + if tok == nil { + return nil, 0 + } + + op := &Operand{ + Name: n, + Kind: k, + Tokens: []*Token{tok}, + } + p.mappings[tok] = op + + switch k.Category { + case schema.OperandCategoryBitEnum, schema.OperandCategoryValueEnum: + s := tok.Text(p.lines) + for _, e := range k.Enumerants { + if e.Enumerant == s { + count := 1 + for _, param := range e.Parameters { + p, c := p.operand(param.Name, param.Kind, i+count, false) + if p != nil { + op.Tokens = append(op.Tokens, p.Tokens...) + op.Parameters = append(op.Parameters, p) + } + count += c + } + + // Handle bitfield '|' chains + if p.tok(i+count).Text(p.lines) == "|" { + count++ // '|' + p, c := p.operand(n, k, i+count, false) + if p != nil { + op.Tokens = append(op.Tokens, p.Tokens...) + op.Parameters = append(op.Parameters, p) + } + count += c + } + + return op, count + } + } + if !optional { + p.err(p.tok(i), "invalid operand value '%s'", s) + } + + return nil, 0 + + case schema.OperandCategoryID: + id := p.pident(i) + if id != nil { + p.addIdentRef(p.tok(i)) + return op, 1 + } + if !optional { + p.err(p.tok(i), "operand requires id, got '%s'", tok.Text(p.lines)) + } + return nil, 0 + + case schema.OperandCategoryLiteral: + switch tok.Type { + case String, Integer, Float, Ident: + return op, 1 + } + if !optional { + p.err(p.tok(i), "operand requires literal, got '%s'", tok.Text(p.lines)) + } + return nil, 0 + + case schema.OperandCategoryComposite: + n := 1 + for _, b := range k.Bases { + o, c := p.operand(b.Kind, b, i+n, optional) + if o != nil { + op.Tokens = append(op.Tokens, o.Tokens...) + } + n += c + } + return op, n + + default: + p.err(p.tok(i), "OperandKind '%s' has unexpected category '%s'", k.Kind, k.Category) + return nil, 0 + } +} + +// tok returns the i'th token, or nil if i is out of bounds. +func (p *parser) tok(i int) *Token { + if i < 0 || i >= len(p.toks) { + return nil + } + return p.toks[i] +} + +// opcode returns the schema.Opcode for the i'th token, or nil if the i'th token +// does not represent an opcode. +func (p *parser) opcode(i int) *schema.Opcode { + if tok := p.ident(i); tok != nil { + name := tok.Text(p.lines) + if inst, found := schema.Opcodes[name]; found { + return inst + } + } + return nil +} + +// operator returns the operator for the i'th token, or and empty string if the +// i'th token is not an operator. +func (p *parser) operator(i int) string { + if tok := p.tok(i); tok != nil && tok.Type == Operator { + return tok.Text(p.lines) + } + return "" +} + +// ident returns the i'th token if it is an Ident, otherwise nil. +func (p *parser) ident(i int) *Token { + if tok := p.tok(i); tok != nil && tok.Type == Ident { + return tok + } + return nil +} + +// pident returns the i'th token if it is an PIdent, otherwise nil. +func (p *parser) pident(i int) *Token { + if tok := p.tok(i); tok != nil && tok.Type == PIdent { + return tok + } + return nil +} + +// comment returns true if the i'th token is a Comment, otherwise false. +func (p *parser) comment(i int) bool { + if tok := p.tok(i); tok != nil && tok.Type == Comment { + return true + } + return false +} + +// newline returns true if the i'th token is a Newline, otherwise false. +func (p *parser) newline(i int) bool { + if tok := p.tok(i); tok != nil && tok.Type == Newline { + return true + } + return false +} + +// unexpected emits an 'unexpected token error' for the i'th token. +func (p *parser) unexpected(i int) { + p.err(p.toks[i], "syntax error: unexpected '%s'", p.toks[i].Text(p.lines)) +} + +// addIdentDef records the token definition for the instruction inst with the +// given id. +func (p *parser) addIdentDef(id string, inst *Instruction, def *Token) { + i, existing := p.idents[id] + if !existing { + i = &Identifier{} + p.idents[id] = i + } + if i.Definition == nil { + i.Definition = inst + } else { + p.err(def, "id '%v' redeclared", id) + } +} + +// addIdentRef adds a identifier reference for the token ref. +func (p *parser) addIdentRef(ref *Token) { + id := ref.Text(p.lines) + i, existing := p.idents[id] + if !existing { + i = &Identifier{} + p.idents[id] = i + } + i.References = append(i.References, ref) +} + +// err appends an fmt.Printf style error into l.diags for the given token. +func (p *parser) err(tok *Token, msg string, args ...interface{}) { + rng := Range{} + if tok != nil { + rng = tok.Range + } + p.diags = append(p.diags, Diagnostic{ + Range: rng, + Severity: SeverityError, + Message: fmt.Sprintf(msg, args...), + }) +} + +// Parse parses the SPIR-V assembly string source, returning the parse results. +func Parse(source string) (Results, error) { + toks, diags, err := lex(source) + if err != nil { + return Results{}, err + } + lines := strings.SplitAfter(source, "\n") + p := parser{ + lines: lines, + toks: toks, + idents: map[string]*Identifier{}, + mappings: map[*Token]interface{}{}, + extInstImports: map[string]schema.OpcodeMap{}, + } + if err := p.parse(); err != nil { + return Results{}, err + } + diags = append(diags, p.diags...) + return Results{ + Lines: lines, + Tokens: toks, + Diagnostics: p.diags, + Identifiers: p.idents, + Mappings: p.mappings, + }, nil +} + +// IsResult returns true if k is used to store the result of an instruction. +func IsResult(k *schema.OperandKind) bool { + switch k { + case schema.OperandKindIdResult, schema.OperandKindIdResultType: + return true + default: + return false + } +} + +// Results holds the output of Parse(). +type Results struct { + Lines []string + Tokens []*Token + Diagnostics []Diagnostic + Identifiers map[string]*Identifier // identifiers by name + Mappings map[*Token]interface{} // tokens to semantic map +} + +// Instruction describes a single instruction instance +type Instruction struct { + Tokens []*Token // all the tokens that make up the instruction + Result *Token // the token that represents the result of the instruction, or nil + Operands []*Operand // the operands of the instruction + Range Range // the textual range of the instruction + Opcode *schema.Opcode // the opcode for the instruction +} + +// Operand describes a single operand instance +type Operand struct { + Name string // name of the operand + Kind *schema.OperandKind // kind of the operand + Tokens []*Token // all the tokens that make up the operand + Parameters []*Operand // all the parameters for the operand +} + +// Identifier describes a single, unique SPIR-V identifier (i.e. %32) +type Identifier struct { + Definition *Instruction // where the identifier was defined + References []*Token // all the places the identifier was referenced +} + +// Severity is an enumerator of diagnostic severities +type Severity int + +// Severity levels +const ( + SeverityError Severity = iota + SeverityWarning + SeverityInformation + SeverityHint +) + +// Diagnostic holds a single diagnostic message that was generated while +// parsing. +type Diagnostic struct { + Range Range + Severity Severity + Message string +} diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/schema/schema.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/schema/schema.go new file mode 100644 index 000000000000..ed02de4e3a3d --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/schema/schema.go @@ -0,0 +1,25094 @@ +// Copyright (C) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Generated by gen-grammar.go --template=./src/schema/schema.go.tmpl --out=./src/schema/schema.go +// Do not modify this file directly. + +package schema + +// Opcode holds information about a specific SPIR-V opcode. +type Opcode struct { + Opname string + Class string + Opcode int + Operands []Operand +} + +// Operand contains information about a logical operand for an instruction. +type Operand struct { + Kind *OperandKind + Name string + Quantifier Quantifier +} + +// OperandKind contains information about a specific operand kind. +type OperandKind struct { + Category OperandCategory + Kind string + Enumerants []Enumerant + Bases []*OperandKind +} + +// Enumerant contains information about an enumerant in an enum. +type Enumerant struct { + Enumerant string + Value interface{} + Capabilities []string + Parameters []Parameter + Version string +} + +// Parameter contains information about a logical parameter for an enumerant. +type Parameter struct { + Kind *OperandKind + Name string +} + +// Quantifier indicates the number of times the quantified term may appear. +type Quantifier string + +const ( + // Once indicates the quantified term may appear exactly once. + Once Quantifier = "" + + // ZeroOrOnce indicates the quantified term may appear zero or one + // time; an optional term. + ZeroOrOnce Quantifier = "?" + + // ZeroOrMany indicates the quantified term may appear any number of + // times. + ZeroOrMany Quantifier = "*" +) + +// OperandCategory is an enumerator that groups operand kinds. +type OperandCategory string + +const ( + // OperandCategoryBitEnum describes an operand kind where its value is a + // mask, which is formed by combining the bits specified as enumerants in an + // enum. + OperandCategoryBitEnum = "BitEnum" + + // OperandCategoryValueEnum describes an operand kind where its value is an + // enumerant from an enum. + OperandCategoryValueEnum = "ValueEnum" + + // OperandCategoryID describes and operand kind where its value is an + // definition or reference. + OperandCategoryID = "Id" + + // OperandCategoryLiteral describes and operand kind where its value is an + // literal number or string. + OperandCategoryLiteral = "Literal" + + // OperandCategoryComposite describes and operand kind where its value is + // composed from operand values from the above categories. + OperandCategoryComposite = "Composite" +) + +// OpcodeMap is a map of opcode name to Opcode type. +type OpcodeMap map[string]*Opcode + +var ( + // Opcodes is a map of opcode name to Opcode description. + Opcodes = OpcodeMap { + "OpNop": OpNop, + "OpUndef": OpUndef, + "OpSourceContinued": OpSourceContinued, + "OpSource": OpSource, + "OpSourceExtension": OpSourceExtension, + "OpName": OpName, + "OpMemberName": OpMemberName, + "OpString": OpString, + "OpLine": OpLine, + "OpExtension": OpExtension, + "OpExtInstImport": OpExtInstImport, + "OpExtInst": OpExtInst, + "OpMemoryModel": OpMemoryModel, + "OpEntryPoint": OpEntryPoint, + "OpExecutionMode": OpExecutionMode, + "OpCapability": OpCapability, + "OpTypeVoid": OpTypeVoid, + "OpTypeBool": OpTypeBool, + "OpTypeInt": OpTypeInt, + "OpTypeFloat": OpTypeFloat, + "OpTypeVector": OpTypeVector, + "OpTypeMatrix": OpTypeMatrix, + "OpTypeImage": OpTypeImage, + "OpTypeSampler": OpTypeSampler, + "OpTypeSampledImage": OpTypeSampledImage, + "OpTypeArray": OpTypeArray, + "OpTypeRuntimeArray": OpTypeRuntimeArray, + "OpTypeStruct": OpTypeStruct, + "OpTypeOpaque": OpTypeOpaque, + "OpTypePointer": OpTypePointer, + "OpTypeFunction": OpTypeFunction, + "OpTypeEvent": OpTypeEvent, + "OpTypeDeviceEvent": OpTypeDeviceEvent, + "OpTypeReserveId": OpTypeReserveId, + "OpTypeQueue": OpTypeQueue, + "OpTypePipe": OpTypePipe, + "OpTypeForwardPointer": OpTypeForwardPointer, + "OpConstantTrue": OpConstantTrue, + "OpConstantFalse": OpConstantFalse, + "OpConstant": OpConstant, + "OpConstantComposite": OpConstantComposite, + "OpConstantSampler": OpConstantSampler, + "OpConstantNull": OpConstantNull, + "OpSpecConstantTrue": OpSpecConstantTrue, + "OpSpecConstantFalse": OpSpecConstantFalse, + "OpSpecConstant": OpSpecConstant, + "OpSpecConstantComposite": OpSpecConstantComposite, + "OpSpecConstantOp": OpSpecConstantOp, + "OpFunction": OpFunction, + "OpFunctionParameter": OpFunctionParameter, + "OpFunctionEnd": OpFunctionEnd, + "OpFunctionCall": OpFunctionCall, + "OpVariable": OpVariable, + "OpImageTexelPointer": OpImageTexelPointer, + "OpLoad": OpLoad, + "OpStore": OpStore, + "OpCopyMemory": OpCopyMemory, + "OpCopyMemorySized": OpCopyMemorySized, + "OpAccessChain": OpAccessChain, + "OpInBoundsAccessChain": OpInBoundsAccessChain, + "OpPtrAccessChain": OpPtrAccessChain, + "OpArrayLength": OpArrayLength, + "OpGenericPtrMemSemantics": OpGenericPtrMemSemantics, + "OpInBoundsPtrAccessChain": OpInBoundsPtrAccessChain, + "OpDecorate": OpDecorate, + "OpMemberDecorate": OpMemberDecorate, + "OpDecorationGroup": OpDecorationGroup, + "OpGroupDecorate": OpGroupDecorate, + "OpGroupMemberDecorate": OpGroupMemberDecorate, + "OpVectorExtractDynamic": OpVectorExtractDynamic, + "OpVectorInsertDynamic": OpVectorInsertDynamic, + "OpVectorShuffle": OpVectorShuffle, + "OpCompositeConstruct": OpCompositeConstruct, + "OpCompositeExtract": OpCompositeExtract, + "OpCompositeInsert": OpCompositeInsert, + "OpCopyObject": OpCopyObject, + "OpTranspose": OpTranspose, + "OpSampledImage": OpSampledImage, + "OpImageSampleImplicitLod": OpImageSampleImplicitLod, + "OpImageSampleExplicitLod": OpImageSampleExplicitLod, + "OpImageSampleDrefImplicitLod": OpImageSampleDrefImplicitLod, + "OpImageSampleDrefExplicitLod": OpImageSampleDrefExplicitLod, + "OpImageSampleProjImplicitLod": OpImageSampleProjImplicitLod, + "OpImageSampleProjExplicitLod": OpImageSampleProjExplicitLod, + "OpImageSampleProjDrefImplicitLod": OpImageSampleProjDrefImplicitLod, + "OpImageSampleProjDrefExplicitLod": OpImageSampleProjDrefExplicitLod, + "OpImageFetch": OpImageFetch, + "OpImageGather": OpImageGather, + "OpImageDrefGather": OpImageDrefGather, + "OpImageRead": OpImageRead, + "OpImageWrite": OpImageWrite, + "OpImage": OpImage, + "OpImageQueryFormat": OpImageQueryFormat, + "OpImageQueryOrder": OpImageQueryOrder, + "OpImageQuerySizeLod": OpImageQuerySizeLod, + "OpImageQuerySize": OpImageQuerySize, + "OpImageQueryLod": OpImageQueryLod, + "OpImageQueryLevels": OpImageQueryLevels, + "OpImageQuerySamples": OpImageQuerySamples, + "OpConvertFToU": OpConvertFToU, + "OpConvertFToS": OpConvertFToS, + "OpConvertSToF": OpConvertSToF, + "OpConvertUToF": OpConvertUToF, + "OpUConvert": OpUConvert, + "OpSConvert": OpSConvert, + "OpFConvert": OpFConvert, + "OpQuantizeToF16": OpQuantizeToF16, + "OpConvertPtrToU": OpConvertPtrToU, + "OpSatConvertSToU": OpSatConvertSToU, + "OpSatConvertUToS": OpSatConvertUToS, + "OpConvertUToPtr": OpConvertUToPtr, + "OpPtrCastToGeneric": OpPtrCastToGeneric, + "OpGenericCastToPtr": OpGenericCastToPtr, + "OpGenericCastToPtrExplicit": OpGenericCastToPtrExplicit, + "OpBitcast": OpBitcast, + "OpSNegate": OpSNegate, + "OpFNegate": OpFNegate, + "OpIAdd": OpIAdd, + "OpFAdd": OpFAdd, + "OpISub": OpISub, + "OpFSub": OpFSub, + "OpIMul": OpIMul, + "OpFMul": OpFMul, + "OpUDiv": OpUDiv, + "OpSDiv": OpSDiv, + "OpFDiv": OpFDiv, + "OpUMod": OpUMod, + "OpSRem": OpSRem, + "OpSMod": OpSMod, + "OpFRem": OpFRem, + "OpFMod": OpFMod, + "OpVectorTimesScalar": OpVectorTimesScalar, + "OpMatrixTimesScalar": OpMatrixTimesScalar, + "OpVectorTimesMatrix": OpVectorTimesMatrix, + "OpMatrixTimesVector": OpMatrixTimesVector, + "OpMatrixTimesMatrix": OpMatrixTimesMatrix, + "OpOuterProduct": OpOuterProduct, + "OpDot": OpDot, + "OpIAddCarry": OpIAddCarry, + "OpISubBorrow": OpISubBorrow, + "OpUMulExtended": OpUMulExtended, + "OpSMulExtended": OpSMulExtended, + "OpAny": OpAny, + "OpAll": OpAll, + "OpIsNan": OpIsNan, + "OpIsInf": OpIsInf, + "OpIsFinite": OpIsFinite, + "OpIsNormal": OpIsNormal, + "OpSignBitSet": OpSignBitSet, + "OpLessOrGreater": OpLessOrGreater, + "OpOrdered": OpOrdered, + "OpUnordered": OpUnordered, + "OpLogicalEqual": OpLogicalEqual, + "OpLogicalNotEqual": OpLogicalNotEqual, + "OpLogicalOr": OpLogicalOr, + "OpLogicalAnd": OpLogicalAnd, + "OpLogicalNot": OpLogicalNot, + "OpSelect": OpSelect, + "OpIEqual": OpIEqual, + "OpINotEqual": OpINotEqual, + "OpUGreaterThan": OpUGreaterThan, + "OpSGreaterThan": OpSGreaterThan, + "OpUGreaterThanEqual": OpUGreaterThanEqual, + "OpSGreaterThanEqual": OpSGreaterThanEqual, + "OpULessThan": OpULessThan, + "OpSLessThan": OpSLessThan, + "OpULessThanEqual": OpULessThanEqual, + "OpSLessThanEqual": OpSLessThanEqual, + "OpFOrdEqual": OpFOrdEqual, + "OpFUnordEqual": OpFUnordEqual, + "OpFOrdNotEqual": OpFOrdNotEqual, + "OpFUnordNotEqual": OpFUnordNotEqual, + "OpFOrdLessThan": OpFOrdLessThan, + "OpFUnordLessThan": OpFUnordLessThan, + "OpFOrdGreaterThan": OpFOrdGreaterThan, + "OpFUnordGreaterThan": OpFUnordGreaterThan, + "OpFOrdLessThanEqual": OpFOrdLessThanEqual, + "OpFUnordLessThanEqual": OpFUnordLessThanEqual, + "OpFOrdGreaterThanEqual": OpFOrdGreaterThanEqual, + "OpFUnordGreaterThanEqual": OpFUnordGreaterThanEqual, + "OpShiftRightLogical": OpShiftRightLogical, + "OpShiftRightArithmetic": OpShiftRightArithmetic, + "OpShiftLeftLogical": OpShiftLeftLogical, + "OpBitwiseOr": OpBitwiseOr, + "OpBitwiseXor": OpBitwiseXor, + "OpBitwiseAnd": OpBitwiseAnd, + "OpNot": OpNot, + "OpBitFieldInsert": OpBitFieldInsert, + "OpBitFieldSExtract": OpBitFieldSExtract, + "OpBitFieldUExtract": OpBitFieldUExtract, + "OpBitReverse": OpBitReverse, + "OpBitCount": OpBitCount, + "OpDPdx": OpDPdx, + "OpDPdy": OpDPdy, + "OpFwidth": OpFwidth, + "OpDPdxFine": OpDPdxFine, + "OpDPdyFine": OpDPdyFine, + "OpFwidthFine": OpFwidthFine, + "OpDPdxCoarse": OpDPdxCoarse, + "OpDPdyCoarse": OpDPdyCoarse, + "OpFwidthCoarse": OpFwidthCoarse, + "OpEmitVertex": OpEmitVertex, + "OpEndPrimitive": OpEndPrimitive, + "OpEmitStreamVertex": OpEmitStreamVertex, + "OpEndStreamPrimitive": OpEndStreamPrimitive, + "OpControlBarrier": OpControlBarrier, + "OpMemoryBarrier": OpMemoryBarrier, + "OpAtomicLoad": OpAtomicLoad, + "OpAtomicStore": OpAtomicStore, + "OpAtomicExchange": OpAtomicExchange, + "OpAtomicCompareExchange": OpAtomicCompareExchange, + "OpAtomicCompareExchangeWeak": OpAtomicCompareExchangeWeak, + "OpAtomicIIncrement": OpAtomicIIncrement, + "OpAtomicIDecrement": OpAtomicIDecrement, + "OpAtomicIAdd": OpAtomicIAdd, + "OpAtomicISub": OpAtomicISub, + "OpAtomicSMin": OpAtomicSMin, + "OpAtomicUMin": OpAtomicUMin, + "OpAtomicSMax": OpAtomicSMax, + "OpAtomicUMax": OpAtomicUMax, + "OpAtomicAnd": OpAtomicAnd, + "OpAtomicOr": OpAtomicOr, + "OpAtomicXor": OpAtomicXor, + "OpPhi": OpPhi, + "OpLoopMerge": OpLoopMerge, + "OpSelectionMerge": OpSelectionMerge, + "OpLabel": OpLabel, + "OpBranch": OpBranch, + "OpBranchConditional": OpBranchConditional, + "OpSwitch": OpSwitch, + "OpKill": OpKill, + "OpReturn": OpReturn, + "OpReturnValue": OpReturnValue, + "OpUnreachable": OpUnreachable, + "OpLifetimeStart": OpLifetimeStart, + "OpLifetimeStop": OpLifetimeStop, + "OpGroupAsyncCopy": OpGroupAsyncCopy, + "OpGroupWaitEvents": OpGroupWaitEvents, + "OpGroupAll": OpGroupAll, + "OpGroupAny": OpGroupAny, + "OpGroupBroadcast": OpGroupBroadcast, + "OpGroupIAdd": OpGroupIAdd, + "OpGroupFAdd": OpGroupFAdd, + "OpGroupFMin": OpGroupFMin, + "OpGroupUMin": OpGroupUMin, + "OpGroupSMin": OpGroupSMin, + "OpGroupFMax": OpGroupFMax, + "OpGroupUMax": OpGroupUMax, + "OpGroupSMax": OpGroupSMax, + "OpReadPipe": OpReadPipe, + "OpWritePipe": OpWritePipe, + "OpReservedReadPipe": OpReservedReadPipe, + "OpReservedWritePipe": OpReservedWritePipe, + "OpReserveReadPipePackets": OpReserveReadPipePackets, + "OpReserveWritePipePackets": OpReserveWritePipePackets, + "OpCommitReadPipe": OpCommitReadPipe, + "OpCommitWritePipe": OpCommitWritePipe, + "OpIsValidReserveId": OpIsValidReserveId, + "OpGetNumPipePackets": OpGetNumPipePackets, + "OpGetMaxPipePackets": OpGetMaxPipePackets, + "OpGroupReserveReadPipePackets": OpGroupReserveReadPipePackets, + "OpGroupReserveWritePipePackets": OpGroupReserveWritePipePackets, + "OpGroupCommitReadPipe": OpGroupCommitReadPipe, + "OpGroupCommitWritePipe": OpGroupCommitWritePipe, + "OpEnqueueMarker": OpEnqueueMarker, + "OpEnqueueKernel": OpEnqueueKernel, + "OpGetKernelNDrangeSubGroupCount": OpGetKernelNDrangeSubGroupCount, + "OpGetKernelNDrangeMaxSubGroupSize": OpGetKernelNDrangeMaxSubGroupSize, + "OpGetKernelWorkGroupSize": OpGetKernelWorkGroupSize, + "OpGetKernelPreferredWorkGroupSizeMultiple": OpGetKernelPreferredWorkGroupSizeMultiple, + "OpRetainEvent": OpRetainEvent, + "OpReleaseEvent": OpReleaseEvent, + "OpCreateUserEvent": OpCreateUserEvent, + "OpIsValidEvent": OpIsValidEvent, + "OpSetUserEventStatus": OpSetUserEventStatus, + "OpCaptureEventProfilingInfo": OpCaptureEventProfilingInfo, + "OpGetDefaultQueue": OpGetDefaultQueue, + "OpBuildNDRange": OpBuildNDRange, + "OpImageSparseSampleImplicitLod": OpImageSparseSampleImplicitLod, + "OpImageSparseSampleExplicitLod": OpImageSparseSampleExplicitLod, + "OpImageSparseSampleDrefImplicitLod": OpImageSparseSampleDrefImplicitLod, + "OpImageSparseSampleDrefExplicitLod": OpImageSparseSampleDrefExplicitLod, + "OpImageSparseSampleProjImplicitLod": OpImageSparseSampleProjImplicitLod, + "OpImageSparseSampleProjExplicitLod": OpImageSparseSampleProjExplicitLod, + "OpImageSparseSampleProjDrefImplicitLod": OpImageSparseSampleProjDrefImplicitLod, + "OpImageSparseSampleProjDrefExplicitLod": OpImageSparseSampleProjDrefExplicitLod, + "OpImageSparseFetch": OpImageSparseFetch, + "OpImageSparseGather": OpImageSparseGather, + "OpImageSparseDrefGather": OpImageSparseDrefGather, + "OpImageSparseTexelsResident": OpImageSparseTexelsResident, + "OpNoLine": OpNoLine, + "OpAtomicFlagTestAndSet": OpAtomicFlagTestAndSet, + "OpAtomicFlagClear": OpAtomicFlagClear, + "OpImageSparseRead": OpImageSparseRead, + "OpSizeOf": OpSizeOf, + "OpTypePipeStorage": OpTypePipeStorage, + "OpConstantPipeStorage": OpConstantPipeStorage, + "OpCreatePipeFromPipeStorage": OpCreatePipeFromPipeStorage, + "OpGetKernelLocalSizeForSubgroupCount": OpGetKernelLocalSizeForSubgroupCount, + "OpGetKernelMaxNumSubgroups": OpGetKernelMaxNumSubgroups, + "OpTypeNamedBarrier": OpTypeNamedBarrier, + "OpNamedBarrierInitialize": OpNamedBarrierInitialize, + "OpMemoryNamedBarrier": OpMemoryNamedBarrier, + "OpModuleProcessed": OpModuleProcessed, + "OpExecutionModeId": OpExecutionModeId, + "OpDecorateId": OpDecorateId, + "OpGroupNonUniformElect": OpGroupNonUniformElect, + "OpGroupNonUniformAll": OpGroupNonUniformAll, + "OpGroupNonUniformAny": OpGroupNonUniformAny, + "OpGroupNonUniformAllEqual": OpGroupNonUniformAllEqual, + "OpGroupNonUniformBroadcast": OpGroupNonUniformBroadcast, + "OpGroupNonUniformBroadcastFirst": OpGroupNonUniformBroadcastFirst, + "OpGroupNonUniformBallot": OpGroupNonUniformBallot, + "OpGroupNonUniformInverseBallot": OpGroupNonUniformInverseBallot, + "OpGroupNonUniformBallotBitExtract": OpGroupNonUniformBallotBitExtract, + "OpGroupNonUniformBallotBitCount": OpGroupNonUniformBallotBitCount, + "OpGroupNonUniformBallotFindLSB": OpGroupNonUniformBallotFindLSB, + "OpGroupNonUniformBallotFindMSB": OpGroupNonUniformBallotFindMSB, + "OpGroupNonUniformShuffle": OpGroupNonUniformShuffle, + "OpGroupNonUniformShuffleXor": OpGroupNonUniformShuffleXor, + "OpGroupNonUniformShuffleUp": OpGroupNonUniformShuffleUp, + "OpGroupNonUniformShuffleDown": OpGroupNonUniformShuffleDown, + "OpGroupNonUniformIAdd": OpGroupNonUniformIAdd, + "OpGroupNonUniformFAdd": OpGroupNonUniformFAdd, + "OpGroupNonUniformIMul": OpGroupNonUniformIMul, + "OpGroupNonUniformFMul": OpGroupNonUniformFMul, + "OpGroupNonUniformSMin": OpGroupNonUniformSMin, + "OpGroupNonUniformUMin": OpGroupNonUniformUMin, + "OpGroupNonUniformFMin": OpGroupNonUniformFMin, + "OpGroupNonUniformSMax": OpGroupNonUniformSMax, + "OpGroupNonUniformUMax": OpGroupNonUniformUMax, + "OpGroupNonUniformFMax": OpGroupNonUniformFMax, + "OpGroupNonUniformBitwiseAnd": OpGroupNonUniformBitwiseAnd, + "OpGroupNonUniformBitwiseOr": OpGroupNonUniformBitwiseOr, + "OpGroupNonUniformBitwiseXor": OpGroupNonUniformBitwiseXor, + "OpGroupNonUniformLogicalAnd": OpGroupNonUniformLogicalAnd, + "OpGroupNonUniformLogicalOr": OpGroupNonUniformLogicalOr, + "OpGroupNonUniformLogicalXor": OpGroupNonUniformLogicalXor, + "OpGroupNonUniformQuadBroadcast": OpGroupNonUniformQuadBroadcast, + "OpGroupNonUniformQuadSwap": OpGroupNonUniformQuadSwap, + "OpCopyLogical": OpCopyLogical, + "OpPtrEqual": OpPtrEqual, + "OpPtrNotEqual": OpPtrNotEqual, + "OpPtrDiff": OpPtrDiff, + "OpSubgroupBallotKHR": OpSubgroupBallotKHR, + "OpSubgroupFirstInvocationKHR": OpSubgroupFirstInvocationKHR, + "OpSubgroupAllKHR": OpSubgroupAllKHR, + "OpSubgroupAnyKHR": OpSubgroupAnyKHR, + "OpSubgroupAllEqualKHR": OpSubgroupAllEqualKHR, + "OpSubgroupReadInvocationKHR": OpSubgroupReadInvocationKHR, + "OpGroupIAddNonUniformAMD": OpGroupIAddNonUniformAMD, + "OpGroupFAddNonUniformAMD": OpGroupFAddNonUniformAMD, + "OpGroupFMinNonUniformAMD": OpGroupFMinNonUniformAMD, + "OpGroupUMinNonUniformAMD": OpGroupUMinNonUniformAMD, + "OpGroupSMinNonUniformAMD": OpGroupSMinNonUniformAMD, + "OpGroupFMaxNonUniformAMD": OpGroupFMaxNonUniformAMD, + "OpGroupUMaxNonUniformAMD": OpGroupUMaxNonUniformAMD, + "OpGroupSMaxNonUniformAMD": OpGroupSMaxNonUniformAMD, + "OpFragmentMaskFetchAMD": OpFragmentMaskFetchAMD, + "OpFragmentFetchAMD": OpFragmentFetchAMD, + "OpReadClockKHR": OpReadClockKHR, + "OpImageSampleFootprintNV": OpImageSampleFootprintNV, + "OpGroupNonUniformPartitionNV": OpGroupNonUniformPartitionNV, + "OpWritePackedPrimitiveIndices4x8NV": OpWritePackedPrimitiveIndices4x8NV, + "OpReportIntersectionNV": OpReportIntersectionNV, + "OpReportIntersectionKHR": OpReportIntersectionKHR, + "OpIgnoreIntersectionNV": OpIgnoreIntersectionNV, + "OpIgnoreIntersectionKHR": OpIgnoreIntersectionKHR, + "OpTerminateRayNV": OpTerminateRayNV, + "OpTerminateRayKHR": OpTerminateRayKHR, + "OpTraceNV": OpTraceNV, + "OpTraceRayKHR": OpTraceRayKHR, + "OpTypeAccelerationStructureNV": OpTypeAccelerationStructureNV, + "OpTypeAccelerationStructureKHR": OpTypeAccelerationStructureKHR, + "OpTypeRayQueryProvisionalKHR": OpTypeRayQueryProvisionalKHR, + "OpRayQueryInitializeKHR": OpRayQueryInitializeKHR, + "OpRayQueryTerminateKHR": OpRayQueryTerminateKHR, + "OpRayQueryGenerateIntersectionKHR": OpRayQueryGenerateIntersectionKHR, + "OpRayQueryConfirmIntersectionKHR": OpRayQueryConfirmIntersectionKHR, + "OpRayQueryProceedKHR": OpRayQueryProceedKHR, + "OpRayQueryGetIntersectionTypeKHR": OpRayQueryGetIntersectionTypeKHR, + "OpRayQueryGetRayTMinKHR": OpRayQueryGetRayTMinKHR, + "OpRayQueryGetRayFlagsKHR": OpRayQueryGetRayFlagsKHR, + "OpRayQueryGetIntersectionTKHR": OpRayQueryGetIntersectionTKHR, + "OpRayQueryGetIntersectionInstanceCustomIndexKHR": OpRayQueryGetIntersectionInstanceCustomIndexKHR, + "OpRayQueryGetIntersectionInstanceIdKHR": OpRayQueryGetIntersectionInstanceIdKHR, + "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR": OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, + "OpRayQueryGetIntersectionGeometryIndexKHR": OpRayQueryGetIntersectionGeometryIndexKHR, + "OpRayQueryGetIntersectionPrimitiveIndexKHR": OpRayQueryGetIntersectionPrimitiveIndexKHR, + "OpRayQueryGetIntersectionBarycentricsKHR": OpRayQueryGetIntersectionBarycentricsKHR, + "OpRayQueryGetIntersectionFrontFaceKHR": OpRayQueryGetIntersectionFrontFaceKHR, + "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR": OpRayQueryGetIntersectionCandidateAABBOpaqueKHR, + "OpRayQueryGetIntersectionObjectRayDirectionKHR": OpRayQueryGetIntersectionObjectRayDirectionKHR, + "OpRayQueryGetIntersectionObjectRayOriginKHR": OpRayQueryGetIntersectionObjectRayOriginKHR, + "OpRayQueryGetWorldRayDirectionKHR": OpRayQueryGetWorldRayDirectionKHR, + "OpRayQueryGetWorldRayOriginKHR": OpRayQueryGetWorldRayOriginKHR, + "OpRayQueryGetIntersectionObjectToWorldKHR": OpRayQueryGetIntersectionObjectToWorldKHR, + "OpRayQueryGetIntersectionWorldToObjectKHR": OpRayQueryGetIntersectionWorldToObjectKHR, + "OpExecuteCallableNV": OpExecuteCallableNV, + "OpExecuteCallableKHR": OpExecuteCallableKHR, + "OpTypeCooperativeMatrixNV": OpTypeCooperativeMatrixNV, + "OpCooperativeMatrixLoadNV": OpCooperativeMatrixLoadNV, + "OpCooperativeMatrixStoreNV": OpCooperativeMatrixStoreNV, + "OpCooperativeMatrixMulAddNV": OpCooperativeMatrixMulAddNV, + "OpCooperativeMatrixLengthNV": OpCooperativeMatrixLengthNV, + "OpBeginInvocationInterlockEXT": OpBeginInvocationInterlockEXT, + "OpEndInvocationInterlockEXT": OpEndInvocationInterlockEXT, + "OpDemoteToHelperInvocationEXT": OpDemoteToHelperInvocationEXT, + "OpIsHelperInvocationEXT": OpIsHelperInvocationEXT, + "OpSubgroupShuffleINTEL": OpSubgroupShuffleINTEL, + "OpSubgroupShuffleDownINTEL": OpSubgroupShuffleDownINTEL, + "OpSubgroupShuffleUpINTEL": OpSubgroupShuffleUpINTEL, + "OpSubgroupShuffleXorINTEL": OpSubgroupShuffleXorINTEL, + "OpSubgroupBlockReadINTEL": OpSubgroupBlockReadINTEL, + "OpSubgroupBlockWriteINTEL": OpSubgroupBlockWriteINTEL, + "OpSubgroupImageBlockReadINTEL": OpSubgroupImageBlockReadINTEL, + "OpSubgroupImageBlockWriteINTEL": OpSubgroupImageBlockWriteINTEL, + "OpSubgroupImageMediaBlockReadINTEL": OpSubgroupImageMediaBlockReadINTEL, + "OpSubgroupImageMediaBlockWriteINTEL": OpSubgroupImageMediaBlockWriteINTEL, + "OpUCountLeadingZerosINTEL": OpUCountLeadingZerosINTEL, + "OpUCountTrailingZerosINTEL": OpUCountTrailingZerosINTEL, + "OpAbsISubINTEL": OpAbsISubINTEL, + "OpAbsUSubINTEL": OpAbsUSubINTEL, + "OpIAddSatINTEL": OpIAddSatINTEL, + "OpUAddSatINTEL": OpUAddSatINTEL, + "OpIAverageINTEL": OpIAverageINTEL, + "OpUAverageINTEL": OpUAverageINTEL, + "OpIAverageRoundedINTEL": OpIAverageRoundedINTEL, + "OpUAverageRoundedINTEL": OpUAverageRoundedINTEL, + "OpISubSatINTEL": OpISubSatINTEL, + "OpUSubSatINTEL": OpUSubSatINTEL, + "OpIMul32x16INTEL": OpIMul32x16INTEL, + "OpUMul32x16INTEL": OpUMul32x16INTEL, + "OpDecorateString": OpDecorateString, + "OpDecorateStringGOOGLE": OpDecorateStringGOOGLE, + "OpMemberDecorateString": OpMemberDecorateString, + "OpMemberDecorateStringGOOGLE": OpMemberDecorateStringGOOGLE, + "OpVmeImageINTEL": OpVmeImageINTEL, + "OpTypeVmeImageINTEL": OpTypeVmeImageINTEL, + "OpTypeAvcImePayloadINTEL": OpTypeAvcImePayloadINTEL, + "OpTypeAvcRefPayloadINTEL": OpTypeAvcRefPayloadINTEL, + "OpTypeAvcSicPayloadINTEL": OpTypeAvcSicPayloadINTEL, + "OpTypeAvcMcePayloadINTEL": OpTypeAvcMcePayloadINTEL, + "OpTypeAvcMceResultINTEL": OpTypeAvcMceResultINTEL, + "OpTypeAvcImeResultINTEL": OpTypeAvcImeResultINTEL, + "OpTypeAvcImeResultSingleReferenceStreamoutINTEL": OpTypeAvcImeResultSingleReferenceStreamoutINTEL, + "OpTypeAvcImeResultDualReferenceStreamoutINTEL": OpTypeAvcImeResultDualReferenceStreamoutINTEL, + "OpTypeAvcImeSingleReferenceStreaminINTEL": OpTypeAvcImeSingleReferenceStreaminINTEL, + "OpTypeAvcImeDualReferenceStreaminINTEL": OpTypeAvcImeDualReferenceStreaminINTEL, + "OpTypeAvcRefResultINTEL": OpTypeAvcRefResultINTEL, + "OpTypeAvcSicResultINTEL": OpTypeAvcSicResultINTEL, + "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL": OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, + "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL": OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, + "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL": OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, + "OpSubgroupAvcMceSetInterShapePenaltyINTEL": OpSubgroupAvcMceSetInterShapePenaltyINTEL, + "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL": OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, + "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL": OpSubgroupAvcMceSetInterDirectionPenaltyINTEL, + "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL": OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, + "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL": OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, + "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL": OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL, + "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL": OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL, + "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL": OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL, + "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL": OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, + "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL": OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, + "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL": OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL, + "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL": OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL, + "OpSubgroupAvcMceSetAcOnlyHaarINTEL": OpSubgroupAvcMceSetAcOnlyHaarINTEL, + "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL": OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, + "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL": OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, + "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL": OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, + "OpSubgroupAvcMceConvertToImePayloadINTEL": OpSubgroupAvcMceConvertToImePayloadINTEL, + "OpSubgroupAvcMceConvertToImeResultINTEL": OpSubgroupAvcMceConvertToImeResultINTEL, + "OpSubgroupAvcMceConvertToRefPayloadINTEL": OpSubgroupAvcMceConvertToRefPayloadINTEL, + "OpSubgroupAvcMceConvertToRefResultINTEL": OpSubgroupAvcMceConvertToRefResultINTEL, + "OpSubgroupAvcMceConvertToSicPayloadINTEL": OpSubgroupAvcMceConvertToSicPayloadINTEL, + "OpSubgroupAvcMceConvertToSicResultINTEL": OpSubgroupAvcMceConvertToSicResultINTEL, + "OpSubgroupAvcMceGetMotionVectorsINTEL": OpSubgroupAvcMceGetMotionVectorsINTEL, + "OpSubgroupAvcMceGetInterDistortionsINTEL": OpSubgroupAvcMceGetInterDistortionsINTEL, + "OpSubgroupAvcMceGetBestInterDistortionsINTEL": OpSubgroupAvcMceGetBestInterDistortionsINTEL, + "OpSubgroupAvcMceGetInterMajorShapeINTEL": OpSubgroupAvcMceGetInterMajorShapeINTEL, + "OpSubgroupAvcMceGetInterMinorShapeINTEL": OpSubgroupAvcMceGetInterMinorShapeINTEL, + "OpSubgroupAvcMceGetInterDirectionsINTEL": OpSubgroupAvcMceGetInterDirectionsINTEL, + "OpSubgroupAvcMceGetInterMotionVectorCountINTEL": OpSubgroupAvcMceGetInterMotionVectorCountINTEL, + "OpSubgroupAvcMceGetInterReferenceIdsINTEL": OpSubgroupAvcMceGetInterReferenceIdsINTEL, + "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL": OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, + "OpSubgroupAvcImeInitializeINTEL": OpSubgroupAvcImeInitializeINTEL, + "OpSubgroupAvcImeSetSingleReferenceINTEL": OpSubgroupAvcImeSetSingleReferenceINTEL, + "OpSubgroupAvcImeSetDualReferenceINTEL": OpSubgroupAvcImeSetDualReferenceINTEL, + "OpSubgroupAvcImeRefWindowSizeINTEL": OpSubgroupAvcImeRefWindowSizeINTEL, + "OpSubgroupAvcImeAdjustRefOffsetINTEL": OpSubgroupAvcImeAdjustRefOffsetINTEL, + "OpSubgroupAvcImeConvertToMcePayloadINTEL": OpSubgroupAvcImeConvertToMcePayloadINTEL, + "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL": OpSubgroupAvcImeSetMaxMotionVectorCountINTEL, + "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL": OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, + "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL": OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, + "OpSubgroupAvcImeSetWeightedSadINTEL": OpSubgroupAvcImeSetWeightedSadINTEL, + "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL": OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, + "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL": OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL": OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL": OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL": OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL": OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL": OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL": OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, + "OpSubgroupAvcImeConvertToMceResultINTEL": OpSubgroupAvcImeConvertToMceResultINTEL, + "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL": OpSubgroupAvcImeGetSingleReferenceStreaminINTEL, + "OpSubgroupAvcImeGetDualReferenceStreaminINTEL": OpSubgroupAvcImeGetDualReferenceStreaminINTEL, + "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL": OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, + "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL": OpSubgroupAvcImeStripDualReferenceStreamoutINTEL, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL": OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL": OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL": OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL": OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL": OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL": OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, + "OpSubgroupAvcImeGetBorderReachedINTEL": OpSubgroupAvcImeGetBorderReachedINTEL, + "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL": OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, + "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL": OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, + "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL": OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, + "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL": OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, + "OpSubgroupAvcFmeInitializeINTEL": OpSubgroupAvcFmeInitializeINTEL, + "OpSubgroupAvcBmeInitializeINTEL": OpSubgroupAvcBmeInitializeINTEL, + "OpSubgroupAvcRefConvertToMcePayloadINTEL": OpSubgroupAvcRefConvertToMcePayloadINTEL, + "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL": OpSubgroupAvcRefSetBidirectionalMixDisableINTEL, + "OpSubgroupAvcRefSetBilinearFilterEnableINTEL": OpSubgroupAvcRefSetBilinearFilterEnableINTEL, + "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL": OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, + "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL": OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, + "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL": OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, + "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL": OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, + "OpSubgroupAvcRefConvertToMceResultINTEL": OpSubgroupAvcRefConvertToMceResultINTEL, + "OpSubgroupAvcSicInitializeINTEL": OpSubgroupAvcSicInitializeINTEL, + "OpSubgroupAvcSicConfigureSkcINTEL": OpSubgroupAvcSicConfigureSkcINTEL, + "OpSubgroupAvcSicConfigureIpeLumaINTEL": OpSubgroupAvcSicConfigureIpeLumaINTEL, + "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL": OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, + "OpSubgroupAvcSicGetMotionVectorMaskINTEL": OpSubgroupAvcSicGetMotionVectorMaskINTEL, + "OpSubgroupAvcSicConvertToMcePayloadINTEL": OpSubgroupAvcSicConvertToMcePayloadINTEL, + "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL": OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, + "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL": OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, + "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL": OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, + "OpSubgroupAvcSicSetBilinearFilterEnableINTEL": OpSubgroupAvcSicSetBilinearFilterEnableINTEL, + "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL": OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, + "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL": OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, + "OpSubgroupAvcSicEvaluateIpeINTEL": OpSubgroupAvcSicEvaluateIpeINTEL, + "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL": OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, + "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL": OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, + "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL": OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, + "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL": OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, + "OpSubgroupAvcSicConvertToMceResultINTEL": OpSubgroupAvcSicConvertToMceResultINTEL, + "OpSubgroupAvcSicGetIpeLumaShapeINTEL": OpSubgroupAvcSicGetIpeLumaShapeINTEL, + "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL": OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, + "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL": OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, + "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL": OpSubgroupAvcSicGetPackedIpeLumaModesINTEL, + "OpSubgroupAvcSicGetIpeChromaModeINTEL": OpSubgroupAvcSicGetIpeChromaModeINTEL, + "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL": OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, + "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL": OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, + "OpSubgroupAvcSicGetInterRawSadsINTEL": OpSubgroupAvcSicGetInterRawSadsINTEL, + } + + // ExtOpcodes is a map of extension name to Opcode description list. + ExtOpcodes = map[string]OpcodeMap { + "GLSL.std.450": { + "Round": GLSLStd450_Round, + "RoundEven": GLSLStd450_RoundEven, + "Trunc": GLSLStd450_Trunc, + "FAbs": GLSLStd450_FAbs, + "SAbs": GLSLStd450_SAbs, + "FSign": GLSLStd450_FSign, + "SSign": GLSLStd450_SSign, + "Floor": GLSLStd450_Floor, + "Ceil": GLSLStd450_Ceil, + "Fract": GLSLStd450_Fract, + "Radians": GLSLStd450_Radians, + "Degrees": GLSLStd450_Degrees, + "Sin": GLSLStd450_Sin, + "Cos": GLSLStd450_Cos, + "Tan": GLSLStd450_Tan, + "Asin": GLSLStd450_Asin, + "Acos": GLSLStd450_Acos, + "Atan": GLSLStd450_Atan, + "Sinh": GLSLStd450_Sinh, + "Cosh": GLSLStd450_Cosh, + "Tanh": GLSLStd450_Tanh, + "Asinh": GLSLStd450_Asinh, + "Acosh": GLSLStd450_Acosh, + "Atanh": GLSLStd450_Atanh, + "Atan2": GLSLStd450_Atan2, + "Pow": GLSLStd450_Pow, + "Exp": GLSLStd450_Exp, + "Log": GLSLStd450_Log, + "Exp2": GLSLStd450_Exp2, + "Log2": GLSLStd450_Log2, + "Sqrt": GLSLStd450_Sqrt, + "InverseSqrt": GLSLStd450_InverseSqrt, + "Determinant": GLSLStd450_Determinant, + "MatrixInverse": GLSLStd450_MatrixInverse, + "Modf": GLSLStd450_Modf, + "ModfStruct": GLSLStd450_ModfStruct, + "FMin": GLSLStd450_FMin, + "UMin": GLSLStd450_UMin, + "SMin": GLSLStd450_SMin, + "FMax": GLSLStd450_FMax, + "UMax": GLSLStd450_UMax, + "SMax": GLSLStd450_SMax, + "FClamp": GLSLStd450_FClamp, + "UClamp": GLSLStd450_UClamp, + "SClamp": GLSLStd450_SClamp, + "FMix": GLSLStd450_FMix, + "IMix": GLSLStd450_IMix, + "Step": GLSLStd450_Step, + "SmoothStep": GLSLStd450_SmoothStep, + "Fma": GLSLStd450_Fma, + "Frexp": GLSLStd450_Frexp, + "FrexpStruct": GLSLStd450_FrexpStruct, + "Ldexp": GLSLStd450_Ldexp, + "PackSnorm4x8": GLSLStd450_PackSnorm4x8, + "PackUnorm4x8": GLSLStd450_PackUnorm4x8, + "PackSnorm2x16": GLSLStd450_PackSnorm2x16, + "PackUnorm2x16": GLSLStd450_PackUnorm2x16, + "PackHalf2x16": GLSLStd450_PackHalf2x16, + "PackDouble2x32": GLSLStd450_PackDouble2x32, + "UnpackSnorm2x16": GLSLStd450_UnpackSnorm2x16, + "UnpackUnorm2x16": GLSLStd450_UnpackUnorm2x16, + "UnpackHalf2x16": GLSLStd450_UnpackHalf2x16, + "UnpackSnorm4x8": GLSLStd450_UnpackSnorm4x8, + "UnpackUnorm4x8": GLSLStd450_UnpackUnorm4x8, + "UnpackDouble2x32": GLSLStd450_UnpackDouble2x32, + "Length": GLSLStd450_Length, + "Distance": GLSLStd450_Distance, + "Cross": GLSLStd450_Cross, + "Normalize": GLSLStd450_Normalize, + "FaceForward": GLSLStd450_FaceForward, + "Reflect": GLSLStd450_Reflect, + "Refract": GLSLStd450_Refract, + "FindILsb": GLSLStd450_FindILsb, + "FindSMsb": GLSLStd450_FindSMsb, + "FindUMsb": GLSLStd450_FindUMsb, + "InterpolateAtCentroid": GLSLStd450_InterpolateAtCentroid, + "InterpolateAtSample": GLSLStd450_InterpolateAtSample, + "InterpolateAtOffset": GLSLStd450_InterpolateAtOffset, + "NMin": GLSLStd450_NMin, + "NMax": GLSLStd450_NMax, + "NClamp": GLSLStd450_NClamp, + }, + "OpenCL.std": { + "acos": OpenCLStd_acos, + "acosh": OpenCLStd_acosh, + "acospi": OpenCLStd_acospi, + "asin": OpenCLStd_asin, + "asinh": OpenCLStd_asinh, + "asinpi": OpenCLStd_asinpi, + "atan": OpenCLStd_atan, + "atan2": OpenCLStd_atan2, + "atanh": OpenCLStd_atanh, + "atanpi": OpenCLStd_atanpi, + "atan2pi": OpenCLStd_atan2pi, + "cbrt": OpenCLStd_cbrt, + "ceil": OpenCLStd_ceil, + "copysign": OpenCLStd_copysign, + "cos": OpenCLStd_cos, + "cosh": OpenCLStd_cosh, + "cospi": OpenCLStd_cospi, + "erfc": OpenCLStd_erfc, + "erf": OpenCLStd_erf, + "exp": OpenCLStd_exp, + "exp2": OpenCLStd_exp2, + "exp10": OpenCLStd_exp10, + "expm1": OpenCLStd_expm1, + "fabs": OpenCLStd_fabs, + "fdim": OpenCLStd_fdim, + "floor": OpenCLStd_floor, + "fma": OpenCLStd_fma, + "fmax": OpenCLStd_fmax, + "fmin": OpenCLStd_fmin, + "fmod": OpenCLStd_fmod, + "fract": OpenCLStd_fract, + "frexp": OpenCLStd_frexp, + "hypot": OpenCLStd_hypot, + "ilogb": OpenCLStd_ilogb, + "ldexp": OpenCLStd_ldexp, + "lgamma": OpenCLStd_lgamma, + "lgamma_r": OpenCLStd_lgamma_r, + "log": OpenCLStd_log, + "log2": OpenCLStd_log2, + "log10": OpenCLStd_log10, + "log1p": OpenCLStd_log1p, + "logb": OpenCLStd_logb, + "mad": OpenCLStd_mad, + "maxmag": OpenCLStd_maxmag, + "minmag": OpenCLStd_minmag, + "modf": OpenCLStd_modf, + "nan": OpenCLStd_nan, + "nextafter": OpenCLStd_nextafter, + "pow": OpenCLStd_pow, + "pown": OpenCLStd_pown, + "powr": OpenCLStd_powr, + "remainder": OpenCLStd_remainder, + "remquo": OpenCLStd_remquo, + "rint": OpenCLStd_rint, + "rootn": OpenCLStd_rootn, + "round": OpenCLStd_round, + "rsqrt": OpenCLStd_rsqrt, + "sin": OpenCLStd_sin, + "sincos": OpenCLStd_sincos, + "sinh": OpenCLStd_sinh, + "sinpi": OpenCLStd_sinpi, + "sqrt": OpenCLStd_sqrt, + "tan": OpenCLStd_tan, + "tanh": OpenCLStd_tanh, + "tanpi": OpenCLStd_tanpi, + "tgamma": OpenCLStd_tgamma, + "trunc": OpenCLStd_trunc, + "half_cos": OpenCLStd_half_cos, + "half_divide": OpenCLStd_half_divide, + "half_exp": OpenCLStd_half_exp, + "half_exp2": OpenCLStd_half_exp2, + "half_exp10": OpenCLStd_half_exp10, + "half_log": OpenCLStd_half_log, + "half_log2": OpenCLStd_half_log2, + "half_log10": OpenCLStd_half_log10, + "half_powr": OpenCLStd_half_powr, + "half_recip": OpenCLStd_half_recip, + "half_rsqrt": OpenCLStd_half_rsqrt, + "half_sin": OpenCLStd_half_sin, + "half_sqrt": OpenCLStd_half_sqrt, + "half_tan": OpenCLStd_half_tan, + "native_cos": OpenCLStd_native_cos, + "native_divide": OpenCLStd_native_divide, + "native_exp": OpenCLStd_native_exp, + "native_exp2": OpenCLStd_native_exp2, + "native_exp10": OpenCLStd_native_exp10, + "native_log": OpenCLStd_native_log, + "native_log2": OpenCLStd_native_log2, + "native_log10": OpenCLStd_native_log10, + "native_powr": OpenCLStd_native_powr, + "native_recip": OpenCLStd_native_recip, + "native_rsqrt": OpenCLStd_native_rsqrt, + "native_sin": OpenCLStd_native_sin, + "native_sqrt": OpenCLStd_native_sqrt, + "native_tan": OpenCLStd_native_tan, + "s_abs": OpenCLStd_s_abs, + "s_abs_diff": OpenCLStd_s_abs_diff, + "s_add_sat": OpenCLStd_s_add_sat, + "u_add_sat": OpenCLStd_u_add_sat, + "s_hadd": OpenCLStd_s_hadd, + "u_hadd": OpenCLStd_u_hadd, + "s_rhadd": OpenCLStd_s_rhadd, + "u_rhadd": OpenCLStd_u_rhadd, + "s_clamp": OpenCLStd_s_clamp, + "u_clamp": OpenCLStd_u_clamp, + "clz": OpenCLStd_clz, + "ctz": OpenCLStd_ctz, + "s_mad_hi": OpenCLStd_s_mad_hi, + "u_mad_sat": OpenCLStd_u_mad_sat, + "s_mad_sat": OpenCLStd_s_mad_sat, + "s_max": OpenCLStd_s_max, + "u_max": OpenCLStd_u_max, + "s_min": OpenCLStd_s_min, + "u_min": OpenCLStd_u_min, + "s_mul_hi": OpenCLStd_s_mul_hi, + "rotate": OpenCLStd_rotate, + "s_sub_sat": OpenCLStd_s_sub_sat, + "u_sub_sat": OpenCLStd_u_sub_sat, + "u_upsample": OpenCLStd_u_upsample, + "s_upsample": OpenCLStd_s_upsample, + "popcount": OpenCLStd_popcount, + "s_mad24": OpenCLStd_s_mad24, + "u_mad24": OpenCLStd_u_mad24, + "s_mul24": OpenCLStd_s_mul24, + "u_mul24": OpenCLStd_u_mul24, + "u_abs": OpenCLStd_u_abs, + "u_abs_diff": OpenCLStd_u_abs_diff, + "u_mul_hi": OpenCLStd_u_mul_hi, + "u_mad_hi": OpenCLStd_u_mad_hi, + "fclamp": OpenCLStd_fclamp, + "degrees": OpenCLStd_degrees, + "fmax_common": OpenCLStd_fmax_common, + "fmin_common": OpenCLStd_fmin_common, + "mix": OpenCLStd_mix, + "radians": OpenCLStd_radians, + "step": OpenCLStd_step, + "smoothstep": OpenCLStd_smoothstep, + "sign": OpenCLStd_sign, + "cross": OpenCLStd_cross, + "distance": OpenCLStd_distance, + "length": OpenCLStd_length, + "normalize": OpenCLStd_normalize, + "fast_distance": OpenCLStd_fast_distance, + "fast_length": OpenCLStd_fast_length, + "fast_normalize": OpenCLStd_fast_normalize, + "bitselect": OpenCLStd_bitselect, + "select": OpenCLStd_select, + "vloadn": OpenCLStd_vloadn, + "vstoren": OpenCLStd_vstoren, + "vload_half": OpenCLStd_vload_half, + "vload_halfn": OpenCLStd_vload_halfn, + "vstore_half": OpenCLStd_vstore_half, + "vstore_half_r": OpenCLStd_vstore_half_r, + "vstore_halfn": OpenCLStd_vstore_halfn, + "vstore_halfn_r": OpenCLStd_vstore_halfn_r, + "vloada_halfn": OpenCLStd_vloada_halfn, + "vstorea_halfn": OpenCLStd_vstorea_halfn, + "vstorea_halfn_r": OpenCLStd_vstorea_halfn_r, + "shuffle": OpenCLStd_shuffle, + "shuffle2": OpenCLStd_shuffle2, + "printf": OpenCLStd_printf, + "prefetch": OpenCLStd_prefetch, + }, + "OpenCL.DebugInfo.100": { + "DebugInfoNone": OpenCLDebugInfo100_DebugInfoNone, + "DebugCompilationUnit": OpenCLDebugInfo100_DebugCompilationUnit, + "DebugTypeBasic": OpenCLDebugInfo100_DebugTypeBasic, + "DebugTypePointer": OpenCLDebugInfo100_DebugTypePointer, + "DebugTypeQualifier": OpenCLDebugInfo100_DebugTypeQualifier, + "DebugTypeArray": OpenCLDebugInfo100_DebugTypeArray, + "DebugTypeVector": OpenCLDebugInfo100_DebugTypeVector, + "DebugTypedef": OpenCLDebugInfo100_DebugTypedef, + "DebugTypeFunction": OpenCLDebugInfo100_DebugTypeFunction, + "DebugTypeEnum": OpenCLDebugInfo100_DebugTypeEnum, + "DebugTypeComposite": OpenCLDebugInfo100_DebugTypeComposite, + "DebugTypeMember": OpenCLDebugInfo100_DebugTypeMember, + "DebugTypeInheritance": OpenCLDebugInfo100_DebugTypeInheritance, + "DebugTypePtrToMember": OpenCLDebugInfo100_DebugTypePtrToMember, + "DebugTypeTemplate": OpenCLDebugInfo100_DebugTypeTemplate, + "DebugTypeTemplateParameter": OpenCLDebugInfo100_DebugTypeTemplateParameter, + "DebugTypeTemplateTemplateParameter": OpenCLDebugInfo100_DebugTypeTemplateTemplateParameter, + "DebugTypeTemplateParameterPack": OpenCLDebugInfo100_DebugTypeTemplateParameterPack, + "DebugGlobalVariable": OpenCLDebugInfo100_DebugGlobalVariable, + "DebugFunctionDeclaration": OpenCLDebugInfo100_DebugFunctionDeclaration, + "DebugFunction": OpenCLDebugInfo100_DebugFunction, + "DebugLexicalBlock": OpenCLDebugInfo100_DebugLexicalBlock, + "DebugLexicalBlockDiscriminator": OpenCLDebugInfo100_DebugLexicalBlockDiscriminator, + "DebugScope": OpenCLDebugInfo100_DebugScope, + "DebugNoScope": OpenCLDebugInfo100_DebugNoScope, + "DebugInlinedAt": OpenCLDebugInfo100_DebugInlinedAt, + "DebugLocalVariable": OpenCLDebugInfo100_DebugLocalVariable, + "DebugInlinedVariable": OpenCLDebugInfo100_DebugInlinedVariable, + "DebugDeclare": OpenCLDebugInfo100_DebugDeclare, + "DebugValue": OpenCLDebugInfo100_DebugValue, + "DebugOperation": OpenCLDebugInfo100_DebugOperation, + "DebugExpression": OpenCLDebugInfo100_DebugExpression, + "DebugMacroDef": OpenCLDebugInfo100_DebugMacroDef, + "DebugMacroUndef": OpenCLDebugInfo100_DebugMacroUndef, + "DebugImportedEntity": OpenCLDebugInfo100_DebugImportedEntity, + "DebugSource": OpenCLDebugInfo100_DebugSource, + }, + } + + OpNop = &Opcode { + Opname: "OpNop", + Class: "Miscellaneous", + Opcode: 0, + Operands: []Operand { + }, + } + OpUndef = &Opcode { + Opname: "OpUndef", + Class: "Miscellaneous", + Opcode: 1, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSourceContinued = &Opcode { + Opname: "OpSourceContinued", + Class: "Debug", + Opcode: 2, + Operands: []Operand { + Operand { + Kind: OperandKindLiteralString, + Name: "'Continued Source'", + Quantifier: "", + }, + }, + } + OpSource = &Opcode { + Opname: "OpSource", + Class: "Debug", + Opcode: 3, + Operands: []Operand { + Operand { + Kind: OperandKindSourceLanguage, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Version'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'File'", + Quantifier: "?", + }, + Operand { + Kind: OperandKindLiteralString, + Name: "'Source'", + Quantifier: "?", + }, + }, + } + OpSourceExtension = &Opcode { + Opname: "OpSourceExtension", + Class: "Debug", + Opcode: 4, + Operands: []Operand { + Operand { + Kind: OperandKindLiteralString, + Name: "'Extension'", + Quantifier: "", + }, + }, + } + OpName = &Opcode { + Opname: "OpName", + Class: "Debug", + Opcode: 5, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralString, + Name: "'Name'", + Quantifier: "", + }, + }, + } + OpMemberName = &Opcode { + Opname: "OpMemberName", + Class: "Debug", + Opcode: 6, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Member'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralString, + Name: "'Name'", + Quantifier: "", + }, + }, + } + OpString = &Opcode { + Opname: "OpString", + Class: "Debug", + Opcode: 7, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralString, + Name: "'String'", + Quantifier: "", + }, + }, + } + OpLine = &Opcode { + Opname: "OpLine", + Class: "Debug", + Opcode: 8, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'File'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + }, + } + OpExtension = &Opcode { + Opname: "OpExtension", + Class: "Extension", + Opcode: 10, + Operands: []Operand { + Operand { + Kind: OperandKindLiteralString, + Name: "'Name'", + Quantifier: "", + }, + }, + } + OpExtInstImport = &Opcode { + Opname: "OpExtInstImport", + Class: "Extension", + Opcode: 11, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralString, + Name: "'Name'", + Quantifier: "", + }, + }, + } + OpExtInst = &Opcode { + Opname: "OpExtInst", + Class: "Extension", + Opcode: 12, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Set'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralExtInstInteger, + Name: "'Instruction'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1', + 'Operand 2', + ...", + Quantifier: "*", + }, + }, + } + OpMemoryModel = &Opcode { + Opname: "OpMemoryModel", + Class: "Mode-Setting", + Opcode: 14, + Operands: []Operand { + Operand { + Kind: OperandKindAddressingModel, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindMemoryModel, + Name: "", + Quantifier: "", + }, + }, + } + OpEntryPoint = &Opcode { + Opname: "OpEntryPoint", + Class: "Mode-Setting", + Opcode: 15, + Operands: []Operand { + Operand { + Kind: OperandKindExecutionModel, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Entry Point'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralString, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Interface'", + Quantifier: "*", + }, + }, + } + OpExecutionMode = &Opcode { + Opname: "OpExecutionMode", + Class: "Mode-Setting", + Opcode: 16, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Entry Point'", + Quantifier: "", + }, + Operand { + Kind: OperandKindExecutionMode, + Name: "'Mode'", + Quantifier: "", + }, + }, + } + OpCapability = &Opcode { + Opname: "OpCapability", + Class: "Mode-Setting", + Opcode: 17, + Operands: []Operand { + Operand { + Kind: OperandKindCapability, + Name: "'Capability'", + Quantifier: "", + }, + }, + } + OpTypeVoid = &Opcode { + Opname: "OpTypeVoid", + Class: "Type-Declaration", + Opcode: 19, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeBool = &Opcode { + Opname: "OpTypeBool", + Class: "Type-Declaration", + Opcode: 20, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeInt = &Opcode { + Opname: "OpTypeInt", + Class: "Type-Declaration", + Opcode: 21, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Width'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Signedness'", + Quantifier: "", + }, + }, + } + OpTypeFloat = &Opcode { + Opname: "OpTypeFloat", + Class: "Type-Declaration", + Opcode: 22, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Width'", + Quantifier: "", + }, + }, + } + OpTypeVector = &Opcode { + Opname: "OpTypeVector", + Class: "Type-Declaration", + Opcode: 23, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Component Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Component Count'", + Quantifier: "", + }, + }, + } + OpTypeMatrix = &Opcode { + Opname: "OpTypeMatrix", + Class: "Type-Declaration", + Opcode: 24, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Column Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column Count'", + Quantifier: "", + }, + }, + } + OpTypeImage = &Opcode { + Opname: "OpTypeImage", + Class: "Type-Declaration", + Opcode: 25, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDim, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Depth'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Arrayed'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'MS'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Sampled'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageFormat, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindAccessQualifier, + Name: "", + Quantifier: "?", + }, + }, + } + OpTypeSampler = &Opcode { + Opname: "OpTypeSampler", + Class: "Type-Declaration", + Opcode: 26, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeSampledImage = &Opcode { + Opname: "OpTypeSampledImage", + Class: "Type-Declaration", + Opcode: 27, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image Type'", + Quantifier: "", + }, + }, + } + OpTypeArray = &Opcode { + Opname: "OpTypeArray", + Class: "Type-Declaration", + Opcode: 28, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Element Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Length'", + Quantifier: "", + }, + }, + } + OpTypeRuntimeArray = &Opcode { + Opname: "OpTypeRuntimeArray", + Class: "Type-Declaration", + Opcode: 29, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Element Type'", + Quantifier: "", + }, + }, + } + OpTypeStruct = &Opcode { + Opname: "OpTypeStruct", + Class: "Type-Declaration", + Opcode: 30, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Member 0 type', + 'member 1 type', + ...", + Quantifier: "*", + }, + }, + } + OpTypeOpaque = &Opcode { + Opname: "OpTypeOpaque", + Class: "Type-Declaration", + Opcode: 31, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralString, + Name: "The name of the opaque type.", + Quantifier: "", + }, + }, + } + OpTypePointer = &Opcode { + Opname: "OpTypePointer", + Class: "Type-Declaration", + Opcode: 32, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindStorageClass, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Type'", + Quantifier: "", + }, + }, + } + OpTypeFunction = &Opcode { + Opname: "OpTypeFunction", + Class: "Type-Declaration", + Opcode: 33, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Return Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parameter 0 Type', + 'Parameter 1 Type', + ...", + Quantifier: "*", + }, + }, + } + OpTypeEvent = &Opcode { + Opname: "OpTypeEvent", + Class: "Type-Declaration", + Opcode: 34, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeDeviceEvent = &Opcode { + Opname: "OpTypeDeviceEvent", + Class: "Type-Declaration", + Opcode: 35, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeReserveId = &Opcode { + Opname: "OpTypeReserveId", + Class: "Type-Declaration", + Opcode: 36, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeQueue = &Opcode { + Opname: "OpTypeQueue", + Class: "Type-Declaration", + Opcode: 37, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypePipe = &Opcode { + Opname: "OpTypePipe", + Class: "Type-Declaration", + Opcode: 38, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindAccessQualifier, + Name: "'Qualifier'", + Quantifier: "", + }, + }, + } + OpTypeForwardPointer = &Opcode { + Opname: "OpTypeForwardPointer", + Class: "Type-Declaration", + Opcode: 39, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindStorageClass, + Name: "", + Quantifier: "", + }, + }, + } + OpConstantTrue = &Opcode { + Opname: "OpConstantTrue", + Class: "Constant-Creation", + Opcode: 41, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpConstantFalse = &Opcode { + Opname: "OpConstantFalse", + Class: "Constant-Creation", + Opcode: 42, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpConstant = &Opcode { + Opname: "OpConstant", + Class: "Constant-Creation", + Opcode: 43, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralContextDependentNumber, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpConstantComposite = &Opcode { + Opname: "OpConstantComposite", + Class: "Constant-Creation", + Opcode: 44, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Constituents'", + Quantifier: "*", + }, + }, + } + OpConstantSampler = &Opcode { + Opname: "OpConstantSampler", + Class: "Constant-Creation", + Opcode: 45, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindSamplerAddressingMode, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Param'", + Quantifier: "", + }, + Operand { + Kind: OperandKindSamplerFilterMode, + Name: "", + Quantifier: "", + }, + }, + } + OpConstantNull = &Opcode { + Opname: "OpConstantNull", + Class: "Constant-Creation", + Opcode: 46, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSpecConstantTrue = &Opcode { + Opname: "OpSpecConstantTrue", + Class: "Constant-Creation", + Opcode: 48, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSpecConstantFalse = &Opcode { + Opname: "OpSpecConstantFalse", + Class: "Constant-Creation", + Opcode: 49, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSpecConstant = &Opcode { + Opname: "OpSpecConstant", + Class: "Constant-Creation", + Opcode: 50, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralContextDependentNumber, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpSpecConstantComposite = &Opcode { + Opname: "OpSpecConstantComposite", + Class: "Constant-Creation", + Opcode: 51, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Constituents'", + Quantifier: "*", + }, + }, + } + OpSpecConstantOp = &Opcode { + Opname: "OpSpecConstantOp", + Class: "Constant-Creation", + Opcode: 52, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralSpecConstantOpInteger, + Name: "'Opcode'", + Quantifier: "", + }, + }, + } + OpFunction = &Opcode { + Opname: "OpFunction", + Class: "Function", + Opcode: 54, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindFunctionControl, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Function Type'", + Quantifier: "", + }, + }, + } + OpFunctionParameter = &Opcode { + Opname: "OpFunctionParameter", + Class: "Function", + Opcode: 55, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpFunctionEnd = &Opcode { + Opname: "OpFunctionEnd", + Class: "Function", + Opcode: 56, + Operands: []Operand { + }, + } + OpFunctionCall = &Opcode { + Opname: "OpFunctionCall", + Class: "Function", + Opcode: 57, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Function'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Argument 0', + 'Argument 1', + ...", + Quantifier: "*", + }, + }, + } + OpVariable = &Opcode { + Opname: "OpVariable", + Class: "Memory", + Opcode: 59, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindStorageClass, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Initializer'", + Quantifier: "?", + }, + }, + } + OpImageTexelPointer = &Opcode { + Opname: "OpImageTexelPointer", + Class: "Memory", + Opcode: 60, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sample'", + Quantifier: "", + }, + }, + } + OpLoad = &Opcode { + Opname: "OpLoad", + Class: "Memory", + Opcode: 61, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindMemoryAccess, + Name: "", + Quantifier: "?", + }, + }, + } + OpStore = &Opcode { + Opname: "OpStore", + Class: "Memory", + Opcode: 62, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Object'", + Quantifier: "", + }, + Operand { + Kind: OperandKindMemoryAccess, + Name: "", + Quantifier: "?", + }, + }, + } + OpCopyMemory = &Opcode { + Opname: "OpCopyMemory", + Class: "Memory", + Opcode: 63, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindMemoryAccess, + Name: "", + Quantifier: "?", + }, + Operand { + Kind: OperandKindMemoryAccess, + Name: "", + Quantifier: "?", + }, + }, + } + OpCopyMemorySized = &Opcode { + Opname: "OpCopyMemorySized", + Class: "Memory", + Opcode: 64, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindMemoryAccess, + Name: "", + Quantifier: "?", + }, + Operand { + Kind: OperandKindMemoryAccess, + Name: "", + Quantifier: "?", + }, + }, + } + OpAccessChain = &Opcode { + Opname: "OpAccessChain", + Class: "Memory", + Opcode: 65, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Indexes'", + Quantifier: "*", + }, + }, + } + OpInBoundsAccessChain = &Opcode { + Opname: "OpInBoundsAccessChain", + Class: "Memory", + Opcode: 66, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Indexes'", + Quantifier: "*", + }, + }, + } + OpPtrAccessChain = &Opcode { + Opname: "OpPtrAccessChain", + Class: "Memory", + Opcode: 67, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Element'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Indexes'", + Quantifier: "*", + }, + }, + } + OpArrayLength = &Opcode { + Opname: "OpArrayLength", + Class: "Memory", + Opcode: 68, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Structure'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Array member'", + Quantifier: "", + }, + }, + } + OpGenericPtrMemSemantics = &Opcode { + Opname: "OpGenericPtrMemSemantics", + Class: "Memory", + Opcode: 69, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + }, + } + OpInBoundsPtrAccessChain = &Opcode { + Opname: "OpInBoundsPtrAccessChain", + Class: "Memory", + Opcode: 70, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Element'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Indexes'", + Quantifier: "*", + }, + }, + } + OpDecorate = &Opcode { + Opname: "OpDecorate", + Class: "Annotation", + Opcode: 71, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDecoration, + Name: "", + Quantifier: "", + }, + }, + } + OpMemberDecorate = &Opcode { + Opname: "OpMemberDecorate", + Class: "Annotation", + Opcode: 72, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Structure Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Member'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDecoration, + Name: "", + Quantifier: "", + }, + }, + } + OpDecorationGroup = &Opcode { + Opname: "OpDecorationGroup", + Class: "Annotation", + Opcode: 73, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpGroupDecorate = &Opcode { + Opname: "OpGroupDecorate", + Class: "Annotation", + Opcode: 74, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Decoration Group'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Targets'", + Quantifier: "*", + }, + }, + } + OpGroupMemberDecorate = &Opcode { + Opname: "OpGroupMemberDecorate", + Class: "Annotation", + Opcode: 75, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Decoration Group'", + Quantifier: "", + }, + Operand { + Kind: OperandKindPairIdRefLiteralInteger, + Name: "'Targets'", + Quantifier: "*", + }, + }, + } + OpVectorExtractDynamic = &Opcode { + Opname: "OpVectorExtractDynamic", + Class: "Composite", + Opcode: 77, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Index'", + Quantifier: "", + }, + }, + } + OpVectorInsertDynamic = &Opcode { + Opname: "OpVectorInsertDynamic", + Class: "Composite", + Opcode: 78, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Component'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Index'", + Quantifier: "", + }, + }, + } + OpVectorShuffle = &Opcode { + Opname: "OpVectorShuffle", + Class: "Composite", + Opcode: 79, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector 2'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Components'", + Quantifier: "*", + }, + }, + } + OpCompositeConstruct = &Opcode { + Opname: "OpCompositeConstruct", + Class: "Composite", + Opcode: 80, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Constituents'", + Quantifier: "*", + }, + }, + } + OpCompositeExtract = &Opcode { + Opname: "OpCompositeExtract", + Class: "Composite", + Opcode: 81, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Composite'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Indexes'", + Quantifier: "*", + }, + }, + } + OpCompositeInsert = &Opcode { + Opname: "OpCompositeInsert", + Class: "Composite", + Opcode: 82, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Object'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Composite'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Indexes'", + Quantifier: "*", + }, + }, + } + OpCopyObject = &Opcode { + Opname: "OpCopyObject", + Class: "Composite", + Opcode: 83, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpTranspose = &Opcode { + Opname: "OpTranspose", + Class: "Composite", + Opcode: 84, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Matrix'", + Quantifier: "", + }, + }, + } + OpSampledImage = &Opcode { + Opname: "OpSampledImage", + Class: "Image", + Opcode: 86, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampler'", + Quantifier: "", + }, + }, + } + OpImageSampleImplicitLod = &Opcode { + Opname: "OpImageSampleImplicitLod", + Class: "Image", + Opcode: 87, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSampleExplicitLod = &Opcode { + Opname: "OpImageSampleExplicitLod", + Class: "Image", + Opcode: 88, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "", + }, + }, + } + OpImageSampleDrefImplicitLod = &Opcode { + Opname: "OpImageSampleDrefImplicitLod", + Class: "Image", + Opcode: 89, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSampleDrefExplicitLod = &Opcode { + Opname: "OpImageSampleDrefExplicitLod", + Class: "Image", + Opcode: 90, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "", + }, + }, + } + OpImageSampleProjImplicitLod = &Opcode { + Opname: "OpImageSampleProjImplicitLod", + Class: "Image", + Opcode: 91, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSampleProjExplicitLod = &Opcode { + Opname: "OpImageSampleProjExplicitLod", + Class: "Image", + Opcode: 92, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "", + }, + }, + } + OpImageSampleProjDrefImplicitLod = &Opcode { + Opname: "OpImageSampleProjDrefImplicitLod", + Class: "Image", + Opcode: 93, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSampleProjDrefExplicitLod = &Opcode { + Opname: "OpImageSampleProjDrefExplicitLod", + Class: "Image", + Opcode: 94, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "", + }, + }, + } + OpImageFetch = &Opcode { + Opname: "OpImageFetch", + Class: "Image", + Opcode: 95, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageGather = &Opcode { + Opname: "OpImageGather", + Class: "Image", + Opcode: 96, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Component'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageDrefGather = &Opcode { + Opname: "OpImageDrefGather", + Class: "Image", + Opcode: 97, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageRead = &Opcode { + Opname: "OpImageRead", + Class: "Image", + Opcode: 98, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageWrite = &Opcode { + Opname: "OpImageWrite", + Class: "Image", + Opcode: 99, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Texel'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImage = &Opcode { + Opname: "OpImage", + Class: "Image", + Opcode: 100, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + }, + } + OpImageQueryFormat = &Opcode { + Opname: "OpImageQueryFormat", + Class: "Image", + Opcode: 101, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + }, + } + OpImageQueryOrder = &Opcode { + Opname: "OpImageQueryOrder", + Class: "Image", + Opcode: 102, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + }, + } + OpImageQuerySizeLod = &Opcode { + Opname: "OpImageQuerySizeLod", + Class: "Image", + Opcode: 103, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Level of Detail'", + Quantifier: "", + }, + }, + } + OpImageQuerySize = &Opcode { + Opname: "OpImageQuerySize", + Class: "Image", + Opcode: 104, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + }, + } + OpImageQueryLod = &Opcode { + Opname: "OpImageQueryLod", + Class: "Image", + Opcode: 105, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + }, + } + OpImageQueryLevels = &Opcode { + Opname: "OpImageQueryLevels", + Class: "Image", + Opcode: 106, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + }, + } + OpImageQuerySamples = &Opcode { + Opname: "OpImageQuerySamples", + Class: "Image", + Opcode: 107, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + }, + } + OpConvertFToU = &Opcode { + Opname: "OpConvertFToU", + Class: "Conversion", + Opcode: 109, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Float Value'", + Quantifier: "", + }, + }, + } + OpConvertFToS = &Opcode { + Opname: "OpConvertFToS", + Class: "Conversion", + Opcode: 110, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Float Value'", + Quantifier: "", + }, + }, + } + OpConvertSToF = &Opcode { + Opname: "OpConvertSToF", + Class: "Conversion", + Opcode: 111, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Signed Value'", + Quantifier: "", + }, + }, + } + OpConvertUToF = &Opcode { + Opname: "OpConvertUToF", + Class: "Conversion", + Opcode: 112, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Unsigned Value'", + Quantifier: "", + }, + }, + } + OpUConvert = &Opcode { + Opname: "OpUConvert", + Class: "Conversion", + Opcode: 113, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Unsigned Value'", + Quantifier: "", + }, + }, + } + OpSConvert = &Opcode { + Opname: "OpSConvert", + Class: "Conversion", + Opcode: 114, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Signed Value'", + Quantifier: "", + }, + }, + } + OpFConvert = &Opcode { + Opname: "OpFConvert", + Class: "Conversion", + Opcode: 115, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Float Value'", + Quantifier: "", + }, + }, + } + OpQuantizeToF16 = &Opcode { + Opname: "OpQuantizeToF16", + Class: "Conversion", + Opcode: 116, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpConvertPtrToU = &Opcode { + Opname: "OpConvertPtrToU", + Class: "Conversion", + Opcode: 117, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + }, + } + OpSatConvertSToU = &Opcode { + Opname: "OpSatConvertSToU", + Class: "Conversion", + Opcode: 118, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Signed Value'", + Quantifier: "", + }, + }, + } + OpSatConvertUToS = &Opcode { + Opname: "OpSatConvertUToS", + Class: "Conversion", + Opcode: 119, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Unsigned Value'", + Quantifier: "", + }, + }, + } + OpConvertUToPtr = &Opcode { + Opname: "OpConvertUToPtr", + Class: "Conversion", + Opcode: 120, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Integer Value'", + Quantifier: "", + }, + }, + } + OpPtrCastToGeneric = &Opcode { + Opname: "OpPtrCastToGeneric", + Class: "Conversion", + Opcode: 121, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + }, + } + OpGenericCastToPtr = &Opcode { + Opname: "OpGenericCastToPtr", + Class: "Conversion", + Opcode: 122, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + }, + } + OpGenericCastToPtrExplicit = &Opcode { + Opname: "OpGenericCastToPtrExplicit", + Class: "Conversion", + Opcode: 123, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindStorageClass, + Name: "'Storage'", + Quantifier: "", + }, + }, + } + OpBitcast = &Opcode { + Opname: "OpBitcast", + Class: "Conversion", + Opcode: 124, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpSNegate = &Opcode { + Opname: "OpSNegate", + Class: "Arithmetic", + Opcode: 126, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpFNegate = &Opcode { + Opname: "OpFNegate", + Class: "Arithmetic", + Opcode: 127, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpIAdd = &Opcode { + Opname: "OpIAdd", + Class: "Arithmetic", + Opcode: 128, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFAdd = &Opcode { + Opname: "OpFAdd", + Class: "Arithmetic", + Opcode: 129, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpISub = &Opcode { + Opname: "OpISub", + Class: "Arithmetic", + Opcode: 130, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFSub = &Opcode { + Opname: "OpFSub", + Class: "Arithmetic", + Opcode: 131, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpIMul = &Opcode { + Opname: "OpIMul", + Class: "Arithmetic", + Opcode: 132, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFMul = &Opcode { + Opname: "OpFMul", + Class: "Arithmetic", + Opcode: 133, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUDiv = &Opcode { + Opname: "OpUDiv", + Class: "Arithmetic", + Opcode: 134, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSDiv = &Opcode { + Opname: "OpSDiv", + Class: "Arithmetic", + Opcode: 135, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFDiv = &Opcode { + Opname: "OpFDiv", + Class: "Arithmetic", + Opcode: 136, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUMod = &Opcode { + Opname: "OpUMod", + Class: "Arithmetic", + Opcode: 137, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSRem = &Opcode { + Opname: "OpSRem", + Class: "Arithmetic", + Opcode: 138, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSMod = &Opcode { + Opname: "OpSMod", + Class: "Arithmetic", + Opcode: 139, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFRem = &Opcode { + Opname: "OpFRem", + Class: "Arithmetic", + Opcode: 140, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFMod = &Opcode { + Opname: "OpFMod", + Class: "Arithmetic", + Opcode: 141, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpVectorTimesScalar = &Opcode { + Opname: "OpVectorTimesScalar", + Class: "Arithmetic", + Opcode: 142, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Scalar'", + Quantifier: "", + }, + }, + } + OpMatrixTimesScalar = &Opcode { + Opname: "OpMatrixTimesScalar", + Class: "Arithmetic", + Opcode: 143, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Matrix'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Scalar'", + Quantifier: "", + }, + }, + } + OpVectorTimesMatrix = &Opcode { + Opname: "OpVectorTimesMatrix", + Class: "Arithmetic", + Opcode: 144, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Matrix'", + Quantifier: "", + }, + }, + } + OpMatrixTimesVector = &Opcode { + Opname: "OpMatrixTimesVector", + Class: "Arithmetic", + Opcode: 145, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Matrix'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector'", + Quantifier: "", + }, + }, + } + OpMatrixTimesMatrix = &Opcode { + Opname: "OpMatrixTimesMatrix", + Class: "Arithmetic", + Opcode: 146, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'LeftMatrix'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RightMatrix'", + Quantifier: "", + }, + }, + } + OpOuterProduct = &Opcode { + Opname: "OpOuterProduct", + Class: "Arithmetic", + Opcode: 147, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector 2'", + Quantifier: "", + }, + }, + } + OpDot = &Opcode { + Opname: "OpDot", + Class: "Arithmetic", + Opcode: 148, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector 2'", + Quantifier: "", + }, + }, + } + OpIAddCarry = &Opcode { + Opname: "OpIAddCarry", + Class: "Arithmetic", + Opcode: 149, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpISubBorrow = &Opcode { + Opname: "OpISubBorrow", + Class: "Arithmetic", + Opcode: 150, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUMulExtended = &Opcode { + Opname: "OpUMulExtended", + Class: "Arithmetic", + Opcode: 151, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSMulExtended = &Opcode { + Opname: "OpSMulExtended", + Class: "Arithmetic", + Opcode: 152, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpAny = &Opcode { + Opname: "OpAny", + Class: "Relational_and_Logical", + Opcode: 154, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector'", + Quantifier: "", + }, + }, + } + OpAll = &Opcode { + Opname: "OpAll", + Class: "Relational_and_Logical", + Opcode: 155, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Vector'", + Quantifier: "", + }, + }, + } + OpIsNan = &Opcode { + Opname: "OpIsNan", + Class: "Relational_and_Logical", + Opcode: 156, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpIsInf = &Opcode { + Opname: "OpIsInf", + Class: "Relational_and_Logical", + Opcode: 157, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpIsFinite = &Opcode { + Opname: "OpIsFinite", + Class: "Relational_and_Logical", + Opcode: 158, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpIsNormal = &Opcode { + Opname: "OpIsNormal", + Class: "Relational_and_Logical", + Opcode: 159, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpSignBitSet = &Opcode { + Opname: "OpSignBitSet", + Class: "Relational_and_Logical", + Opcode: 160, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpLessOrGreater = &Opcode { + Opname: "OpLessOrGreater", + Class: "Relational_and_Logical", + Opcode: 161, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpOrdered = &Opcode { + Opname: "OpOrdered", + Class: "Relational_and_Logical", + Opcode: 162, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpUnordered = &Opcode { + Opname: "OpUnordered", + Class: "Relational_and_Logical", + Opcode: 163, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpLogicalEqual = &Opcode { + Opname: "OpLogicalEqual", + Class: "Relational_and_Logical", + Opcode: 164, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpLogicalNotEqual = &Opcode { + Opname: "OpLogicalNotEqual", + Class: "Relational_and_Logical", + Opcode: 165, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpLogicalOr = &Opcode { + Opname: "OpLogicalOr", + Class: "Relational_and_Logical", + Opcode: 166, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpLogicalAnd = &Opcode { + Opname: "OpLogicalAnd", + Class: "Relational_and_Logical", + Opcode: 167, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpLogicalNot = &Opcode { + Opname: "OpLogicalNot", + Class: "Relational_and_Logical", + Opcode: 168, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpSelect = &Opcode { + Opname: "OpSelect", + Class: "Relational_and_Logical", + Opcode: 169, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Condition'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Object 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Object 2'", + Quantifier: "", + }, + }, + } + OpIEqual = &Opcode { + Opname: "OpIEqual", + Class: "Relational_and_Logical", + Opcode: 170, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpINotEqual = &Opcode { + Opname: "OpINotEqual", + Class: "Relational_and_Logical", + Opcode: 171, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUGreaterThan = &Opcode { + Opname: "OpUGreaterThan", + Class: "Relational_and_Logical", + Opcode: 172, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSGreaterThan = &Opcode { + Opname: "OpSGreaterThan", + Class: "Relational_and_Logical", + Opcode: 173, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUGreaterThanEqual = &Opcode { + Opname: "OpUGreaterThanEqual", + Class: "Relational_and_Logical", + Opcode: 174, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSGreaterThanEqual = &Opcode { + Opname: "OpSGreaterThanEqual", + Class: "Relational_and_Logical", + Opcode: 175, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpULessThan = &Opcode { + Opname: "OpULessThan", + Class: "Relational_and_Logical", + Opcode: 176, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSLessThan = &Opcode { + Opname: "OpSLessThan", + Class: "Relational_and_Logical", + Opcode: 177, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpULessThanEqual = &Opcode { + Opname: "OpULessThanEqual", + Class: "Relational_and_Logical", + Opcode: 178, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSLessThanEqual = &Opcode { + Opname: "OpSLessThanEqual", + Class: "Relational_and_Logical", + Opcode: 179, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFOrdEqual = &Opcode { + Opname: "OpFOrdEqual", + Class: "Relational_and_Logical", + Opcode: 180, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFUnordEqual = &Opcode { + Opname: "OpFUnordEqual", + Class: "Relational_and_Logical", + Opcode: 181, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFOrdNotEqual = &Opcode { + Opname: "OpFOrdNotEqual", + Class: "Relational_and_Logical", + Opcode: 182, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFUnordNotEqual = &Opcode { + Opname: "OpFUnordNotEqual", + Class: "Relational_and_Logical", + Opcode: 183, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFOrdLessThan = &Opcode { + Opname: "OpFOrdLessThan", + Class: "Relational_and_Logical", + Opcode: 184, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFUnordLessThan = &Opcode { + Opname: "OpFUnordLessThan", + Class: "Relational_and_Logical", + Opcode: 185, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFOrdGreaterThan = &Opcode { + Opname: "OpFOrdGreaterThan", + Class: "Relational_and_Logical", + Opcode: 186, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFUnordGreaterThan = &Opcode { + Opname: "OpFUnordGreaterThan", + Class: "Relational_and_Logical", + Opcode: 187, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFOrdLessThanEqual = &Opcode { + Opname: "OpFOrdLessThanEqual", + Class: "Relational_and_Logical", + Opcode: 188, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFUnordLessThanEqual = &Opcode { + Opname: "OpFUnordLessThanEqual", + Class: "Relational_and_Logical", + Opcode: 189, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFOrdGreaterThanEqual = &Opcode { + Opname: "OpFOrdGreaterThanEqual", + Class: "Relational_and_Logical", + Opcode: 190, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpFUnordGreaterThanEqual = &Opcode { + Opname: "OpFUnordGreaterThanEqual", + Class: "Relational_and_Logical", + Opcode: 191, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpShiftRightLogical = &Opcode { + Opname: "OpShiftRightLogical", + Class: "Bit", + Opcode: 194, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Shift'", + Quantifier: "", + }, + }, + } + OpShiftRightArithmetic = &Opcode { + Opname: "OpShiftRightArithmetic", + Class: "Bit", + Opcode: 195, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Shift'", + Quantifier: "", + }, + }, + } + OpShiftLeftLogical = &Opcode { + Opname: "OpShiftLeftLogical", + Class: "Bit", + Opcode: 196, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Shift'", + Quantifier: "", + }, + }, + } + OpBitwiseOr = &Opcode { + Opname: "OpBitwiseOr", + Class: "Bit", + Opcode: 197, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpBitwiseXor = &Opcode { + Opname: "OpBitwiseXor", + Class: "Bit", + Opcode: 198, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpBitwiseAnd = &Opcode { + Opname: "OpBitwiseAnd", + Class: "Bit", + Opcode: 199, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpNot = &Opcode { + Opname: "OpNot", + Class: "Bit", + Opcode: 200, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpBitFieldInsert = &Opcode { + Opname: "OpBitFieldInsert", + Class: "Bit", + Opcode: 201, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Insert'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Count'", + Quantifier: "", + }, + }, + } + OpBitFieldSExtract = &Opcode { + Opname: "OpBitFieldSExtract", + Class: "Bit", + Opcode: 202, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Count'", + Quantifier: "", + }, + }, + } + OpBitFieldUExtract = &Opcode { + Opname: "OpBitFieldUExtract", + Class: "Bit", + Opcode: 203, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Count'", + Quantifier: "", + }, + }, + } + OpBitReverse = &Opcode { + Opname: "OpBitReverse", + Class: "Bit", + Opcode: 204, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + }, + } + OpBitCount = &Opcode { + Opname: "OpBitCount", + Class: "Bit", + Opcode: 205, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base'", + Quantifier: "", + }, + }, + } + OpDPdx = &Opcode { + Opname: "OpDPdx", + Class: "Derivative", + Opcode: 207, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpDPdy = &Opcode { + Opname: "OpDPdy", + Class: "Derivative", + Opcode: 208, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpFwidth = &Opcode { + Opname: "OpFwidth", + Class: "Derivative", + Opcode: 209, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpDPdxFine = &Opcode { + Opname: "OpDPdxFine", + Class: "Derivative", + Opcode: 210, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpDPdyFine = &Opcode { + Opname: "OpDPdyFine", + Class: "Derivative", + Opcode: 211, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpFwidthFine = &Opcode { + Opname: "OpFwidthFine", + Class: "Derivative", + Opcode: 212, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpDPdxCoarse = &Opcode { + Opname: "OpDPdxCoarse", + Class: "Derivative", + Opcode: 213, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpDPdyCoarse = &Opcode { + Opname: "OpDPdyCoarse", + Class: "Derivative", + Opcode: 214, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpFwidthCoarse = &Opcode { + Opname: "OpFwidthCoarse", + Class: "Derivative", + Opcode: 215, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'P'", + Quantifier: "", + }, + }, + } + OpEmitVertex = &Opcode { + Opname: "OpEmitVertex", + Class: "Primitive", + Opcode: 218, + Operands: []Operand { + }, + } + OpEndPrimitive = &Opcode { + Opname: "OpEndPrimitive", + Class: "Primitive", + Opcode: 219, + Operands: []Operand { + }, + } + OpEmitStreamVertex = &Opcode { + Opname: "OpEmitStreamVertex", + Class: "Primitive", + Opcode: 220, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Stream'", + Quantifier: "", + }, + }, + } + OpEndStreamPrimitive = &Opcode { + Opname: "OpEndStreamPrimitive", + Class: "Primitive", + Opcode: 221, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Stream'", + Quantifier: "", + }, + }, + } + OpControlBarrier = &Opcode { + Opname: "OpControlBarrier", + Class: "Barrier", + Opcode: 224, + Operands: []Operand { + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + }, + } + OpMemoryBarrier = &Opcode { + Opname: "OpMemoryBarrier", + Class: "Barrier", + Opcode: 225, + Operands: []Operand { + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + }, + } + OpAtomicLoad = &Opcode { + Opname: "OpAtomicLoad", + Class: "Atomic", + Opcode: 227, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + }, + } + OpAtomicStore = &Opcode { + Opname: "OpAtomicStore", + Class: "Atomic", + Opcode: 228, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicExchange = &Opcode { + Opname: "OpAtomicExchange", + Class: "Atomic", + Opcode: 229, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicCompareExchange = &Opcode { + Opname: "OpAtomicCompareExchange", + Class: "Atomic", + Opcode: 230, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Equal'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Unequal'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Comparator'", + Quantifier: "", + }, + }, + } + OpAtomicCompareExchangeWeak = &Opcode { + Opname: "OpAtomicCompareExchangeWeak", + Class: "Atomic", + Opcode: 231, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Equal'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Unequal'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Comparator'", + Quantifier: "", + }, + }, + } + OpAtomicIIncrement = &Opcode { + Opname: "OpAtomicIIncrement", + Class: "Atomic", + Opcode: 232, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + }, + } + OpAtomicIDecrement = &Opcode { + Opname: "OpAtomicIDecrement", + Class: "Atomic", + Opcode: 233, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + }, + } + OpAtomicIAdd = &Opcode { + Opname: "OpAtomicIAdd", + Class: "Atomic", + Opcode: 234, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicISub = &Opcode { + Opname: "OpAtomicISub", + Class: "Atomic", + Opcode: 235, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicSMin = &Opcode { + Opname: "OpAtomicSMin", + Class: "Atomic", + Opcode: 236, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicUMin = &Opcode { + Opname: "OpAtomicUMin", + Class: "Atomic", + Opcode: 237, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicSMax = &Opcode { + Opname: "OpAtomicSMax", + Class: "Atomic", + Opcode: 238, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicUMax = &Opcode { + Opname: "OpAtomicUMax", + Class: "Atomic", + Opcode: 239, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicAnd = &Opcode { + Opname: "OpAtomicAnd", + Class: "Atomic", + Opcode: 240, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicOr = &Opcode { + Opname: "OpAtomicOr", + Class: "Atomic", + Opcode: 241, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpAtomicXor = &Opcode { + Opname: "OpAtomicXor", + Class: "Atomic", + Opcode: 242, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpPhi = &Opcode { + Opname: "OpPhi", + Class: "Control-Flow", + Opcode: 245, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindPairIdRefIdRef, + Name: "'Variable, Parent, ...'", + Quantifier: "*", + }, + }, + } + OpLoopMerge = &Opcode { + Opname: "OpLoopMerge", + Class: "Control-Flow", + Opcode: 246, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Merge Block'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Continue Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLoopControl, + Name: "", + Quantifier: "", + }, + }, + } + OpSelectionMerge = &Opcode { + Opname: "OpSelectionMerge", + Class: "Control-Flow", + Opcode: 247, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Merge Block'", + Quantifier: "", + }, + Operand { + Kind: OperandKindSelectionControl, + Name: "", + Quantifier: "", + }, + }, + } + OpLabel = &Opcode { + Opname: "OpLabel", + Class: "Control-Flow", + Opcode: 248, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpBranch = &Opcode { + Opname: "OpBranch", + Class: "Control-Flow", + Opcode: 249, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target Label'", + Quantifier: "", + }, + }, + } + OpBranchConditional = &Opcode { + Opname: "OpBranchConditional", + Class: "Control-Flow", + Opcode: 250, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Condition'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'True Label'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'False Label'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Branch weights'", + Quantifier: "*", + }, + }, + } + OpSwitch = &Opcode { + Opname: "OpSwitch", + Class: "Control-Flow", + Opcode: 251, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Selector'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Default'", + Quantifier: "", + }, + Operand { + Kind: OperandKindPairLiteralIntegerIdRef, + Name: "'Target'", + Quantifier: "*", + }, + }, + } + OpKill = &Opcode { + Opname: "OpKill", + Class: "Control-Flow", + Opcode: 252, + Operands: []Operand { + }, + } + OpReturn = &Opcode { + Opname: "OpReturn", + Class: "Control-Flow", + Opcode: 253, + Operands: []Operand { + }, + } + OpReturnValue = &Opcode { + Opname: "OpReturnValue", + Class: "Control-Flow", + Opcode: 254, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpUnreachable = &Opcode { + Opname: "OpUnreachable", + Class: "Control-Flow", + Opcode: 255, + Operands: []Operand { + }, + } + OpLifetimeStart = &Opcode { + Opname: "OpLifetimeStart", + Class: "Control-Flow", + Opcode: 256, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Size'", + Quantifier: "", + }, + }, + } + OpLifetimeStop = &Opcode { + Opname: "OpLifetimeStop", + Class: "Control-Flow", + Opcode: 257, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Size'", + Quantifier: "", + }, + }, + } + OpGroupAsyncCopy = &Opcode { + Opname: "OpGroupAsyncCopy", + Class: "Group", + Opcode: 259, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Destination'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Num Elements'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Stride'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Event'", + Quantifier: "", + }, + }, + } + OpGroupWaitEvents = &Opcode { + Opname: "OpGroupWaitEvents", + Class: "Group", + Opcode: 260, + Operands: []Operand { + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Num Events'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Events List'", + Quantifier: "", + }, + }, + } + OpGroupAll = &Opcode { + Opname: "OpGroupAll", + Class: "Group", + Opcode: 261, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpGroupAny = &Opcode { + Opname: "OpGroupAny", + Class: "Group", + Opcode: 262, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpGroupBroadcast = &Opcode { + Opname: "OpGroupBroadcast", + Class: "Group", + Opcode: 263, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'LocalId'", + Quantifier: "", + }, + }, + } + OpGroupIAdd = &Opcode { + Opname: "OpGroupIAdd", + Class: "Group", + Opcode: 264, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupFAdd = &Opcode { + Opname: "OpGroupFAdd", + Class: "Group", + Opcode: 265, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupFMin = &Opcode { + Opname: "OpGroupFMin", + Class: "Group", + Opcode: 266, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupUMin = &Opcode { + Opname: "OpGroupUMin", + Class: "Group", + Opcode: 267, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupSMin = &Opcode { + Opname: "OpGroupSMin", + Class: "Group", + Opcode: 268, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupFMax = &Opcode { + Opname: "OpGroupFMax", + Class: "Group", + Opcode: 269, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupUMax = &Opcode { + Opname: "OpGroupUMax", + Class: "Group", + Opcode: 270, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupSMax = &Opcode { + Opname: "OpGroupSMax", + Class: "Group", + Opcode: 271, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpReadPipe = &Opcode { + Opname: "OpReadPipe", + Class: "Pipe", + Opcode: 274, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpWritePipe = &Opcode { + Opname: "OpWritePipe", + Class: "Pipe", + Opcode: 275, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpReservedReadPipe = &Opcode { + Opname: "OpReservedReadPipe", + Class: "Pipe", + Opcode: 276, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reserve Id'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Index'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpReservedWritePipe = &Opcode { + Opname: "OpReservedWritePipe", + Class: "Pipe", + Opcode: 277, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reserve Id'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Index'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpReserveReadPipePackets = &Opcode { + Opname: "OpReserveReadPipePackets", + Class: "Pipe", + Opcode: 278, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Num Packets'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpReserveWritePipePackets = &Opcode { + Opname: "OpReserveWritePipePackets", + Class: "Pipe", + Opcode: 279, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Num Packets'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpCommitReadPipe = &Opcode { + Opname: "OpCommitReadPipe", + Class: "Pipe", + Opcode: 280, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reserve Id'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpCommitWritePipe = &Opcode { + Opname: "OpCommitWritePipe", + Class: "Pipe", + Opcode: 281, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reserve Id'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpIsValidReserveId = &Opcode { + Opname: "OpIsValidReserveId", + Class: "Pipe", + Opcode: 282, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reserve Id'", + Quantifier: "", + }, + }, + } + OpGetNumPipePackets = &Opcode { + Opname: "OpGetNumPipePackets", + Class: "Pipe", + Opcode: 283, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpGetMaxPipePackets = &Opcode { + Opname: "OpGetMaxPipePackets", + Class: "Pipe", + Opcode: 284, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpGroupReserveReadPipePackets = &Opcode { + Opname: "OpGroupReserveReadPipePackets", + Class: "Pipe", + Opcode: 285, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Num Packets'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpGroupReserveWritePipePackets = &Opcode { + Opname: "OpGroupReserveWritePipePackets", + Class: "Pipe", + Opcode: 286, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Num Packets'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpGroupCommitReadPipe = &Opcode { + Opname: "OpGroupCommitReadPipe", + Class: "Pipe", + Opcode: 287, + Operands: []Operand { + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reserve Id'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpGroupCommitWritePipe = &Opcode { + Opname: "OpGroupCommitWritePipe", + Class: "Pipe", + Opcode: 288, + Operands: []Operand { + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reserve Id'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packet Alignment'", + Quantifier: "", + }, + }, + } + OpEnqueueMarker = &Opcode { + Opname: "OpEnqueueMarker", + Class: "Device-Side_Enqueue", + Opcode: 291, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Queue'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Num Events'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Wait Events'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ret Event'", + Quantifier: "", + }, + }, + } + OpEnqueueKernel = &Opcode { + Opname: "OpEnqueueKernel", + Class: "Device-Side_Enqueue", + Opcode: 292, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Queue'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ND Range'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Num Events'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Wait Events'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ret Event'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Invoke'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Align'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Local Size'", + Quantifier: "*", + }, + }, + } + OpGetKernelNDrangeSubGroupCount = &Opcode { + Opname: "OpGetKernelNDrangeSubGroupCount", + Class: "Device-Side_Enqueue", + Opcode: 293, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ND Range'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Invoke'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Align'", + Quantifier: "", + }, + }, + } + OpGetKernelNDrangeMaxSubGroupSize = &Opcode { + Opname: "OpGetKernelNDrangeMaxSubGroupSize", + Class: "Device-Side_Enqueue", + Opcode: 294, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ND Range'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Invoke'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Align'", + Quantifier: "", + }, + }, + } + OpGetKernelWorkGroupSize = &Opcode { + Opname: "OpGetKernelWorkGroupSize", + Class: "Device-Side_Enqueue", + Opcode: 295, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Invoke'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Align'", + Quantifier: "", + }, + }, + } + OpGetKernelPreferredWorkGroupSizeMultiple = &Opcode { + Opname: "OpGetKernelPreferredWorkGroupSizeMultiple", + Class: "Device-Side_Enqueue", + Opcode: 296, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Invoke'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Align'", + Quantifier: "", + }, + }, + } + OpRetainEvent = &Opcode { + Opname: "OpRetainEvent", + Class: "Device-Side_Enqueue", + Opcode: 297, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Event'", + Quantifier: "", + }, + }, + } + OpReleaseEvent = &Opcode { + Opname: "OpReleaseEvent", + Class: "Device-Side_Enqueue", + Opcode: 298, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Event'", + Quantifier: "", + }, + }, + } + OpCreateUserEvent = &Opcode { + Opname: "OpCreateUserEvent", + Class: "Device-Side_Enqueue", + Opcode: 299, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpIsValidEvent = &Opcode { + Opname: "OpIsValidEvent", + Class: "Device-Side_Enqueue", + Opcode: 300, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Event'", + Quantifier: "", + }, + }, + } + OpSetUserEventStatus = &Opcode { + Opname: "OpSetUserEventStatus", + Class: "Device-Side_Enqueue", + Opcode: 301, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Event'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Status'", + Quantifier: "", + }, + }, + } + OpCaptureEventProfilingInfo = &Opcode { + Opname: "OpCaptureEventProfilingInfo", + Class: "Device-Side_Enqueue", + Opcode: 302, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Event'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Profiling Info'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpGetDefaultQueue = &Opcode { + Opname: "OpGetDefaultQueue", + Class: "Device-Side_Enqueue", + Opcode: 303, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpBuildNDRange = &Opcode { + Opname: "OpBuildNDRange", + Class: "Device-Side_Enqueue", + Opcode: 304, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'GlobalWorkSize'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'LocalWorkSize'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'GlobalWorkOffset'", + Quantifier: "", + }, + }, + } + OpImageSparseSampleImplicitLod = &Opcode { + Opname: "OpImageSparseSampleImplicitLod", + Class: "Image", + Opcode: 305, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSparseSampleExplicitLod = &Opcode { + Opname: "OpImageSparseSampleExplicitLod", + Class: "Image", + Opcode: 306, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "", + }, + }, + } + OpImageSparseSampleDrefImplicitLod = &Opcode { + Opname: "OpImageSparseSampleDrefImplicitLod", + Class: "Image", + Opcode: 307, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSparseSampleDrefExplicitLod = &Opcode { + Opname: "OpImageSparseSampleDrefExplicitLod", + Class: "Image", + Opcode: 308, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "", + }, + }, + } + OpImageSparseSampleProjImplicitLod = &Opcode { + Opname: "OpImageSparseSampleProjImplicitLod", + Class: "Image", + Opcode: 309, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSparseSampleProjExplicitLod = &Opcode { + Opname: "OpImageSparseSampleProjExplicitLod", + Class: "Image", + Opcode: 310, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "", + }, + }, + } + OpImageSparseSampleProjDrefImplicitLod = &Opcode { + Opname: "OpImageSparseSampleProjDrefImplicitLod", + Class: "Image", + Opcode: 311, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSparseSampleProjDrefExplicitLod = &Opcode { + Opname: "OpImageSparseSampleProjDrefExplicitLod", + Class: "Image", + Opcode: 312, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "", + }, + }, + } + OpImageSparseFetch = &Opcode { + Opname: "OpImageSparseFetch", + Class: "Image", + Opcode: 313, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSparseGather = &Opcode { + Opname: "OpImageSparseGather", + Class: "Image", + Opcode: 314, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Component'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSparseDrefGather = &Opcode { + Opname: "OpImageSparseDrefGather", + Class: "Image", + Opcode: 315, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'D~ref~'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpImageSparseTexelsResident = &Opcode { + Opname: "OpImageSparseTexelsResident", + Class: "Image", + Opcode: 316, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Resident Code'", + Quantifier: "", + }, + }, + } + OpNoLine = &Opcode { + Opname: "OpNoLine", + Class: "Debug", + Opcode: 317, + Operands: []Operand { + }, + } + OpAtomicFlagTestAndSet = &Opcode { + Opname: "OpAtomicFlagTestAndSet", + Class: "Atomic", + Opcode: 318, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + }, + } + OpAtomicFlagClear = &Opcode { + Opname: "OpAtomicFlagClear", + Class: "Atomic", + Opcode: 319, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + }, + } + OpImageSparseRead = &Opcode { + Opname: "OpImageSparseRead", + Class: "Image", + Opcode: 320, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpSizeOf = &Opcode { + Opname: "OpSizeOf", + Class: "Miscellaneous", + Opcode: 321, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + }, + } + OpTypePipeStorage = &Opcode { + Opname: "OpTypePipeStorage", + Class: "Type-Declaration", + Opcode: 322, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpConstantPipeStorage = &Opcode { + Opname: "OpConstantPipeStorage", + Class: "Pipe", + Opcode: 323, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Packet Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Packet Alignment'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Capacity'", + Quantifier: "", + }, + }, + } + OpCreatePipeFromPipeStorage = &Opcode { + Opname: "OpCreatePipeFromPipeStorage", + Class: "Pipe", + Opcode: 324, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pipe Storage'", + Quantifier: "", + }, + }, + } + OpGetKernelLocalSizeForSubgroupCount = &Opcode { + Opname: "OpGetKernelLocalSizeForSubgroupCount", + Class: "Device-Side_Enqueue", + Opcode: 325, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Subgroup Count'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Invoke'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Align'", + Quantifier: "", + }, + }, + } + OpGetKernelMaxNumSubgroups = &Opcode { + Opname: "OpGetKernelMaxNumSubgroups", + Class: "Device-Side_Enqueue", + Opcode: 326, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Invoke'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Param Align'", + Quantifier: "", + }, + }, + } + OpTypeNamedBarrier = &Opcode { + Opname: "OpTypeNamedBarrier", + Class: "Type-Declaration", + Opcode: 327, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpNamedBarrierInitialize = &Opcode { + Opname: "OpNamedBarrierInitialize", + Class: "Barrier", + Opcode: 328, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Subgroup Count'", + Quantifier: "", + }, + }, + } + OpMemoryNamedBarrier = &Opcode { + Opname: "OpMemoryNamedBarrier", + Class: "Barrier", + Opcode: 329, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Named Barrier'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Memory'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdMemorySemantics, + Name: "'Semantics'", + Quantifier: "", + }, + }, + } + OpModuleProcessed = &Opcode { + Opname: "OpModuleProcessed", + Class: "Debug", + Opcode: 330, + Operands: []Operand { + Operand { + Kind: OperandKindLiteralString, + Name: "'Process'", + Quantifier: "", + }, + }, + } + OpExecutionModeId = &Opcode { + Opname: "OpExecutionModeId", + Class: "Mode-Setting", + Opcode: 331, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Entry Point'", + Quantifier: "", + }, + Operand { + Kind: OperandKindExecutionMode, + Name: "'Mode'", + Quantifier: "", + }, + }, + } + OpDecorateId = &Opcode { + Opname: "OpDecorateId", + Class: "Annotation", + Opcode: 332, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDecoration, + Name: "", + Quantifier: "", + }, + }, + } + OpGroupNonUniformElect = &Opcode { + Opname: "OpGroupNonUniformElect", + Class: "Non-Uniform", + Opcode: 333, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformAll = &Opcode { + Opname: "OpGroupNonUniformAll", + Class: "Non-Uniform", + Opcode: 334, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformAny = &Opcode { + Opname: "OpGroupNonUniformAny", + Class: "Non-Uniform", + Opcode: 335, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformAllEqual = &Opcode { + Opname: "OpGroupNonUniformAllEqual", + Class: "Non-Uniform", + Opcode: 336, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformBroadcast = &Opcode { + Opname: "OpGroupNonUniformBroadcast", + Class: "Non-Uniform", + Opcode: 337, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Id'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformBroadcastFirst = &Opcode { + Opname: "OpGroupNonUniformBroadcastFirst", + Class: "Non-Uniform", + Opcode: 338, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformBallot = &Opcode { + Opname: "OpGroupNonUniformBallot", + Class: "Non-Uniform", + Opcode: 339, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformInverseBallot = &Opcode { + Opname: "OpGroupNonUniformInverseBallot", + Class: "Non-Uniform", + Opcode: 340, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformBallotBitExtract = &Opcode { + Opname: "OpGroupNonUniformBallotBitExtract", + Class: "Non-Uniform", + Opcode: 341, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Index'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformBallotBitCount = &Opcode { + Opname: "OpGroupNonUniformBallotBitCount", + Class: "Non-Uniform", + Opcode: 342, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformBallotFindLSB = &Opcode { + Opname: "OpGroupNonUniformBallotFindLSB", + Class: "Non-Uniform", + Opcode: 343, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformBallotFindMSB = &Opcode { + Opname: "OpGroupNonUniformBallotFindMSB", + Class: "Non-Uniform", + Opcode: 344, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformShuffle = &Opcode { + Opname: "OpGroupNonUniformShuffle", + Class: "Non-Uniform", + Opcode: 345, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Id'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformShuffleXor = &Opcode { + Opname: "OpGroupNonUniformShuffleXor", + Class: "Non-Uniform", + Opcode: 346, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Mask'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformShuffleUp = &Opcode { + Opname: "OpGroupNonUniformShuffleUp", + Class: "Non-Uniform", + Opcode: 347, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Delta'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformShuffleDown = &Opcode { + Opname: "OpGroupNonUniformShuffleDown", + Class: "Non-Uniform", + Opcode: 348, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Delta'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformIAdd = &Opcode { + Opname: "OpGroupNonUniformIAdd", + Class: "Non-Uniform", + Opcode: 349, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformFAdd = &Opcode { + Opname: "OpGroupNonUniformFAdd", + Class: "Non-Uniform", + Opcode: 350, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformIMul = &Opcode { + Opname: "OpGroupNonUniformIMul", + Class: "Non-Uniform", + Opcode: 351, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformFMul = &Opcode { + Opname: "OpGroupNonUniformFMul", + Class: "Non-Uniform", + Opcode: 352, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformSMin = &Opcode { + Opname: "OpGroupNonUniformSMin", + Class: "Non-Uniform", + Opcode: 353, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformUMin = &Opcode { + Opname: "OpGroupNonUniformUMin", + Class: "Non-Uniform", + Opcode: 354, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformFMin = &Opcode { + Opname: "OpGroupNonUniformFMin", + Class: "Non-Uniform", + Opcode: 355, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformSMax = &Opcode { + Opname: "OpGroupNonUniformSMax", + Class: "Non-Uniform", + Opcode: 356, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformUMax = &Opcode { + Opname: "OpGroupNonUniformUMax", + Class: "Non-Uniform", + Opcode: 357, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformFMax = &Opcode { + Opname: "OpGroupNonUniformFMax", + Class: "Non-Uniform", + Opcode: 358, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformBitwiseAnd = &Opcode { + Opname: "OpGroupNonUniformBitwiseAnd", + Class: "Non-Uniform", + Opcode: 359, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformBitwiseOr = &Opcode { + Opname: "OpGroupNonUniformBitwiseOr", + Class: "Non-Uniform", + Opcode: 360, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformBitwiseXor = &Opcode { + Opname: "OpGroupNonUniformBitwiseXor", + Class: "Non-Uniform", + Opcode: 361, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformLogicalAnd = &Opcode { + Opname: "OpGroupNonUniformLogicalAnd", + Class: "Non-Uniform", + Opcode: 362, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformLogicalOr = &Opcode { + Opname: "OpGroupNonUniformLogicalOr", + Class: "Non-Uniform", + Opcode: 363, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformLogicalXor = &Opcode { + Opname: "OpGroupNonUniformLogicalXor", + Class: "Non-Uniform", + Opcode: 364, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ClusterSize'", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformQuadBroadcast = &Opcode { + Opname: "OpGroupNonUniformQuadBroadcast", + Class: "Non-Uniform", + Opcode: 365, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Index'", + Quantifier: "", + }, + }, + } + OpGroupNonUniformQuadSwap = &Opcode { + Opname: "OpGroupNonUniformQuadSwap", + Class: "Non-Uniform", + Opcode: 366, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Direction'", + Quantifier: "", + }, + }, + } + OpCopyLogical = &Opcode { + Opname: "OpCopyLogical", + Class: "Composite", + Opcode: 400, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpPtrEqual = &Opcode { + Opname: "OpPtrEqual", + Class: "Memory", + Opcode: 401, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpPtrNotEqual = &Opcode { + Opname: "OpPtrNotEqual", + Class: "Memory", + Opcode: 402, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpPtrDiff = &Opcode { + Opname: "OpPtrDiff", + Class: "Memory", + Opcode: 403, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpSubgroupBallotKHR = &Opcode { + Opname: "OpSubgroupBallotKHR", + Class: "Group", + Opcode: 4421, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpSubgroupFirstInvocationKHR = &Opcode { + Opname: "OpSubgroupFirstInvocationKHR", + Class: "Group", + Opcode: 4422, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpSubgroupAllKHR = &Opcode { + Opname: "OpSubgroupAllKHR", + Class: "Group", + Opcode: 4428, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpSubgroupAnyKHR = &Opcode { + Opname: "OpSubgroupAnyKHR", + Class: "Group", + Opcode: 4429, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpSubgroupAllEqualKHR = &Opcode { + Opname: "OpSubgroupAllEqualKHR", + Class: "Group", + Opcode: 4430, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Predicate'", + Quantifier: "", + }, + }, + } + OpSubgroupReadInvocationKHR = &Opcode { + Opname: "OpSubgroupReadInvocationKHR", + Class: "Group", + Opcode: 4432, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Index'", + Quantifier: "", + }, + }, + } + OpGroupIAddNonUniformAMD = &Opcode { + Opname: "OpGroupIAddNonUniformAMD", + Class: "Group", + Opcode: 5000, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupFAddNonUniformAMD = &Opcode { + Opname: "OpGroupFAddNonUniformAMD", + Class: "Group", + Opcode: 5001, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupFMinNonUniformAMD = &Opcode { + Opname: "OpGroupFMinNonUniformAMD", + Class: "Group", + Opcode: 5002, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupUMinNonUniformAMD = &Opcode { + Opname: "OpGroupUMinNonUniformAMD", + Class: "Group", + Opcode: 5003, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupSMinNonUniformAMD = &Opcode { + Opname: "OpGroupSMinNonUniformAMD", + Class: "Group", + Opcode: 5004, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupFMaxNonUniformAMD = &Opcode { + Opname: "OpGroupFMaxNonUniformAMD", + Class: "Group", + Opcode: 5005, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupUMaxNonUniformAMD = &Opcode { + Opname: "OpGroupUMaxNonUniformAMD", + Class: "Group", + Opcode: 5006, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpGroupSMaxNonUniformAMD = &Opcode { + Opname: "OpGroupSMaxNonUniformAMD", + Class: "Group", + Opcode: 5007, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindGroupOperation, + Name: "'Operation'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'X'", + Quantifier: "", + }, + }, + } + OpFragmentMaskFetchAMD = &Opcode { + Opname: "OpFragmentMaskFetchAMD", + Class: "Reserved", + Opcode: 5011, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + }, + } + OpFragmentFetchAMD = &Opcode { + Opname: "OpFragmentFetchAMD", + Class: "Reserved", + Opcode: 5012, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Fragment Index'", + Quantifier: "", + }, + }, + } + OpReadClockKHR = &Opcode { + Opname: "OpReadClockKHR", + Class: "Reserved", + Opcode: 5056, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + }, + } + OpImageSampleFootprintNV = &Opcode { + Opname: "OpImageSampleFootprintNV", + Class: "Image", + Opcode: 5283, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampled Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Granularity'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coarse'", + Quantifier: "", + }, + Operand { + Kind: OperandKindImageOperands, + Name: "", + Quantifier: "?", + }, + }, + } + OpGroupNonUniformPartitionNV = &Opcode { + Opname: "OpGroupNonUniformPartitionNV", + Class: "Non-Uniform", + Opcode: 5296, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpWritePackedPrimitiveIndices4x8NV = &Opcode { + Opname: "OpWritePackedPrimitiveIndices4x8NV", + Class: "Reserved", + Opcode: 5299, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Index Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Indices'", + Quantifier: "", + }, + }, + } + OpReportIntersectionNV = &Opcode { + Opname: "OpReportIntersectionNV", + Class: "Reserved", + Opcode: 5334, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Hit'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'HitKind'", + Quantifier: "", + }, + }, + } + OpReportIntersectionKHR = &Opcode { + Opname: "OpReportIntersectionKHR", + Class: "Reserved", + Opcode: 5334, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Hit'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'HitKind'", + Quantifier: "", + }, + }, + } + OpIgnoreIntersectionNV = &Opcode { + Opname: "OpIgnoreIntersectionNV", + Class: "Reserved", + Opcode: 5335, + Operands: []Operand { + }, + } + OpIgnoreIntersectionKHR = &Opcode { + Opname: "OpIgnoreIntersectionKHR", + Class: "Reserved", + Opcode: 5335, + Operands: []Operand { + }, + } + OpTerminateRayNV = &Opcode { + Opname: "OpTerminateRayNV", + Class: "Reserved", + Opcode: 5336, + Operands: []Operand { + }, + } + OpTerminateRayKHR = &Opcode { + Opname: "OpTerminateRayKHR", + Class: "Reserved", + Opcode: 5336, + Operands: []Operand { + }, + } + OpTraceNV = &Opcode { + Opname: "OpTraceNV", + Class: "Reserved", + Opcode: 5337, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Accel'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Cull Mask'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'SBT Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'SBT Stride'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Miss Index'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Origin'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Tmin'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Direction'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Tmax'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'PayloadId'", + Quantifier: "", + }, + }, + } + OpTraceRayKHR = &Opcode { + Opname: "OpTraceRayKHR", + Class: "Reserved", + Opcode: 5337, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Accel'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Cull Mask'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'SBT Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'SBT Stride'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Miss Index'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Origin'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Tmin'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Direction'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ray Tmax'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'PayloadId'", + Quantifier: "", + }, + }, + } + OpTypeAccelerationStructureNV = &Opcode { + Opname: "OpTypeAccelerationStructureNV", + Class: "Reserved", + Opcode: 5341, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAccelerationStructureKHR = &Opcode { + Opname: "OpTypeAccelerationStructureKHR", + Class: "Reserved", + Opcode: 5341, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeRayQueryProvisionalKHR = &Opcode { + Opname: "OpTypeRayQueryProvisionalKHR", + Class: "Reserved", + Opcode: 4472, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpRayQueryInitializeKHR = &Opcode { + Opname: "OpRayQueryInitializeKHR", + Class: "Reserved", + Opcode: 4473, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Accel'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayFlags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'CullMask'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayOrigin'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayTMin'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayDirection'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayTMax'", + Quantifier: "", + }, + }, + } + OpRayQueryTerminateKHR = &Opcode { + Opname: "OpRayQueryTerminateKHR", + Class: "Reserved", + Opcode: 4474, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + }, + } + OpRayQueryGenerateIntersectionKHR = &Opcode { + Opname: "OpRayQueryGenerateIntersectionKHR", + Class: "Reserved", + Opcode: 4475, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'HitT'", + Quantifier: "", + }, + }, + } + OpRayQueryConfirmIntersectionKHR = &Opcode { + Opname: "OpRayQueryConfirmIntersectionKHR", + Class: "Reserved", + Opcode: 4476, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + }, + } + OpRayQueryProceedKHR = &Opcode { + Opname: "OpRayQueryProceedKHR", + Class: "Reserved", + Opcode: 4477, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionTypeKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionTypeKHR", + Class: "Reserved", + Opcode: 4479, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetRayTMinKHR = &Opcode { + Opname: "OpRayQueryGetRayTMinKHR", + Class: "Reserved", + Opcode: 6016, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + }, + } + OpRayQueryGetRayFlagsKHR = &Opcode { + Opname: "OpRayQueryGetRayFlagsKHR", + Class: "Reserved", + Opcode: 6017, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionTKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionTKHR", + Class: "Reserved", + Opcode: 6018, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionInstanceCustomIndexKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionInstanceCustomIndexKHR", + Class: "Reserved", + Opcode: 6019, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionInstanceIdKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionInstanceIdKHR", + Class: "Reserved", + Opcode: 6020, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR", + Class: "Reserved", + Opcode: 6021, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionGeometryIndexKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionGeometryIndexKHR", + Class: "Reserved", + Opcode: 6022, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionPrimitiveIndexKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionPrimitiveIndexKHR", + Class: "Reserved", + Opcode: 6023, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionBarycentricsKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionBarycentricsKHR", + Class: "Reserved", + Opcode: 6024, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionFrontFaceKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionFrontFaceKHR", + Class: "Reserved", + Opcode: 6025, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR", + Class: "Reserved", + Opcode: 6026, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionObjectRayDirectionKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionObjectRayDirectionKHR", + Class: "Reserved", + Opcode: 6027, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionObjectRayOriginKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionObjectRayOriginKHR", + Class: "Reserved", + Opcode: 6028, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetWorldRayDirectionKHR = &Opcode { + Opname: "OpRayQueryGetWorldRayDirectionKHR", + Class: "Reserved", + Opcode: 6029, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + }, + } + OpRayQueryGetWorldRayOriginKHR = &Opcode { + Opname: "OpRayQueryGetWorldRayOriginKHR", + Class: "Reserved", + Opcode: 6030, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionObjectToWorldKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionObjectToWorldKHR", + Class: "Reserved", + Opcode: 6031, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpRayQueryGetIntersectionWorldToObjectKHR = &Opcode { + Opname: "OpRayQueryGetIntersectionWorldToObjectKHR", + Class: "Reserved", + Opcode: 6032, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'RayQuery'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intersection'", + Quantifier: "", + }, + }, + } + OpExecuteCallableNV = &Opcode { + Opname: "OpExecuteCallableNV", + Class: "Reserved", + Opcode: 5344, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'SBT Index'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Callable DataId'", + Quantifier: "", + }, + }, + } + OpExecuteCallableKHR = &Opcode { + Opname: "OpExecuteCallableKHR", + Class: "Reserved", + Opcode: 5344, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'SBT Index'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Callable DataId'", + Quantifier: "", + }, + }, + } + OpTypeCooperativeMatrixNV = &Opcode { + Opname: "OpTypeCooperativeMatrixNV", + Class: "Reserved", + Opcode: 5358, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Component Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdScope, + Name: "'Execution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Rows'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Columns'", + Quantifier: "", + }, + }, + } + OpCooperativeMatrixLoadNV = &Opcode { + Opname: "OpCooperativeMatrixLoadNV", + Class: "Reserved", + Opcode: 5359, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Stride'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Column Major'", + Quantifier: "", + }, + Operand { + Kind: OperandKindMemoryAccess, + Name: "", + Quantifier: "?", + }, + }, + } + OpCooperativeMatrixStoreNV = &Opcode { + Opname: "OpCooperativeMatrixStoreNV", + Class: "Reserved", + Opcode: 5360, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Pointer'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Object'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Stride'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Column Major'", + Quantifier: "", + }, + Operand { + Kind: OperandKindMemoryAccess, + Name: "", + Quantifier: "?", + }, + }, + } + OpCooperativeMatrixMulAddNV = &Opcode { + Opname: "OpCooperativeMatrixMulAddNV", + Class: "Reserved", + Opcode: 5361, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'A'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'B'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'C'", + Quantifier: "", + }, + }, + } + OpCooperativeMatrixLengthNV = &Opcode { + Opname: "OpCooperativeMatrixLengthNV", + Class: "Reserved", + Opcode: 5362, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Type'", + Quantifier: "", + }, + }, + } + OpBeginInvocationInterlockEXT = &Opcode { + Opname: "OpBeginInvocationInterlockEXT", + Class: "Reserved", + Opcode: 5364, + Operands: []Operand { + }, + } + OpEndInvocationInterlockEXT = &Opcode { + Opname: "OpEndInvocationInterlockEXT", + Class: "Reserved", + Opcode: 5365, + Operands: []Operand { + }, + } + OpDemoteToHelperInvocationEXT = &Opcode { + Opname: "OpDemoteToHelperInvocationEXT", + Class: "Reserved", + Opcode: 5380, + Operands: []Operand { + }, + } + OpIsHelperInvocationEXT = &Opcode { + Opname: "OpIsHelperInvocationEXT", + Class: "Reserved", + Opcode: 5381, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSubgroupShuffleINTEL = &Opcode { + Opname: "OpSubgroupShuffleINTEL", + Class: "Group", + Opcode: 5571, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'InvocationId'", + Quantifier: "", + }, + }, + } + OpSubgroupShuffleDownINTEL = &Opcode { + Opname: "OpSubgroupShuffleDownINTEL", + Class: "Group", + Opcode: 5572, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Current'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Next'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Delta'", + Quantifier: "", + }, + }, + } + OpSubgroupShuffleUpINTEL = &Opcode { + Opname: "OpSubgroupShuffleUpINTEL", + Class: "Group", + Opcode: 5573, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Previous'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Current'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Delta'", + Quantifier: "", + }, + }, + } + OpSubgroupShuffleXorINTEL = &Opcode { + Opname: "OpSubgroupShuffleXorINTEL", + Class: "Group", + Opcode: 5574, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + OpSubgroupBlockReadINTEL = &Opcode { + Opname: "OpSubgroupBlockReadINTEL", + Class: "Group", + Opcode: 5575, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ptr'", + Quantifier: "", + }, + }, + } + OpSubgroupBlockWriteINTEL = &Opcode { + Opname: "OpSubgroupBlockWriteINTEL", + Class: "Group", + Opcode: 5576, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Ptr'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Data'", + Quantifier: "", + }, + }, + } + OpSubgroupImageBlockReadINTEL = &Opcode { + Opname: "OpSubgroupImageBlockReadINTEL", + Class: "Group", + Opcode: 5577, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + }, + } + OpSubgroupImageBlockWriteINTEL = &Opcode { + Opname: "OpSubgroupImageBlockWriteINTEL", + Class: "Group", + Opcode: 5578, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Data'", + Quantifier: "", + }, + }, + } + OpSubgroupImageMediaBlockReadINTEL = &Opcode { + Opname: "OpSubgroupImageMediaBlockReadINTEL", + Class: "Group", + Opcode: 5580, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Width'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Height'", + Quantifier: "", + }, + }, + } + OpSubgroupImageMediaBlockWriteINTEL = &Opcode { + Opname: "OpSubgroupImageMediaBlockWriteINTEL", + Class: "Group", + Opcode: 5581, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Coordinate'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Width'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Height'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Data'", + Quantifier: "", + }, + }, + } + OpUCountLeadingZerosINTEL = &Opcode { + Opname: "OpUCountLeadingZerosINTEL", + Class: "Reserved", + Opcode: 5585, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpUCountTrailingZerosINTEL = &Opcode { + Opname: "OpUCountTrailingZerosINTEL", + Class: "Reserved", + Opcode: 5586, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand'", + Quantifier: "", + }, + }, + } + OpAbsISubINTEL = &Opcode { + Opname: "OpAbsISubINTEL", + Class: "Reserved", + Opcode: 5587, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpAbsUSubINTEL = &Opcode { + Opname: "OpAbsUSubINTEL", + Class: "Reserved", + Opcode: 5588, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpIAddSatINTEL = &Opcode { + Opname: "OpIAddSatINTEL", + Class: "Reserved", + Opcode: 5589, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUAddSatINTEL = &Opcode { + Opname: "OpUAddSatINTEL", + Class: "Reserved", + Opcode: 5590, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpIAverageINTEL = &Opcode { + Opname: "OpIAverageINTEL", + Class: "Reserved", + Opcode: 5591, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUAverageINTEL = &Opcode { + Opname: "OpUAverageINTEL", + Class: "Reserved", + Opcode: 5592, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpIAverageRoundedINTEL = &Opcode { + Opname: "OpIAverageRoundedINTEL", + Class: "Reserved", + Opcode: 5593, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUAverageRoundedINTEL = &Opcode { + Opname: "OpUAverageRoundedINTEL", + Class: "Reserved", + Opcode: 5594, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpISubSatINTEL = &Opcode { + Opname: "OpISubSatINTEL", + Class: "Reserved", + Opcode: 5595, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUSubSatINTEL = &Opcode { + Opname: "OpUSubSatINTEL", + Class: "Reserved", + Opcode: 5596, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpIMul32x16INTEL = &Opcode { + Opname: "OpIMul32x16INTEL", + Class: "Reserved", + Opcode: 5597, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpUMul32x16INTEL = &Opcode { + Opname: "OpUMul32x16INTEL", + Class: "Reserved", + Opcode: 5598, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Operand 2'", + Quantifier: "", + }, + }, + } + OpDecorateString = &Opcode { + Opname: "OpDecorateString", + Class: "Annotation", + Opcode: 5632, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDecoration, + Name: "", + Quantifier: "", + }, + }, + } + OpDecorateStringGOOGLE = &Opcode { + Opname: "OpDecorateStringGOOGLE", + Class: "Annotation", + Opcode: 5632, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDecoration, + Name: "", + Quantifier: "", + }, + }, + } + OpMemberDecorateString = &Opcode { + Opname: "OpMemberDecorateString", + Class: "Annotation", + Opcode: 5633, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Struct Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Member'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDecoration, + Name: "", + Quantifier: "", + }, + }, + } + OpMemberDecorateStringGOOGLE = &Opcode { + Opname: "OpMemberDecorateStringGOOGLE", + Class: "Annotation", + Opcode: 5633, + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Struct Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Member'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDecoration, + Name: "", + Quantifier: "", + }, + }, + } + OpVmeImageINTEL = &Opcode { + Opname: "OpVmeImageINTEL", + Class: "@exclude", + Opcode: 5699, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sampler'", + Quantifier: "", + }, + }, + } + OpTypeVmeImageINTEL = &Opcode { + Opname: "OpTypeVmeImageINTEL", + Class: "@exclude", + Opcode: 5700, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image Type'", + Quantifier: "", + }, + }, + } + OpTypeAvcImePayloadINTEL = &Opcode { + Opname: "OpTypeAvcImePayloadINTEL", + Class: "@exclude", + Opcode: 5701, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcRefPayloadINTEL = &Opcode { + Opname: "OpTypeAvcRefPayloadINTEL", + Class: "@exclude", + Opcode: 5702, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcSicPayloadINTEL = &Opcode { + Opname: "OpTypeAvcSicPayloadINTEL", + Class: "@exclude", + Opcode: 5703, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcMcePayloadINTEL = &Opcode { + Opname: "OpTypeAvcMcePayloadINTEL", + Class: "@exclude", + Opcode: 5704, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcMceResultINTEL = &Opcode { + Opname: "OpTypeAvcMceResultINTEL", + Class: "@exclude", + Opcode: 5705, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcImeResultINTEL = &Opcode { + Opname: "OpTypeAvcImeResultINTEL", + Class: "@exclude", + Opcode: 5706, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = &Opcode { + Opname: "OpTypeAvcImeResultSingleReferenceStreamoutINTEL", + Class: "@exclude", + Opcode: 5707, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcImeResultDualReferenceStreamoutINTEL = &Opcode { + Opname: "OpTypeAvcImeResultDualReferenceStreamoutINTEL", + Class: "@exclude", + Opcode: 5708, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcImeSingleReferenceStreaminINTEL = &Opcode { + Opname: "OpTypeAvcImeSingleReferenceStreaminINTEL", + Class: "@exclude", + Opcode: 5709, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcImeDualReferenceStreaminINTEL = &Opcode { + Opname: "OpTypeAvcImeDualReferenceStreaminINTEL", + Class: "@exclude", + Opcode: 5710, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcRefResultINTEL = &Opcode { + Opname: "OpTypeAvcRefResultINTEL", + Class: "@exclude", + Opcode: 5711, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpTypeAvcSicResultINTEL = &Opcode { + Opname: "OpTypeAvcSicResultINTEL", + Class: "@exclude", + Opcode: 5712, + Operands: []Operand { + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL", + Class: "@exclude", + Opcode: 5713, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Slice Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Qp'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL", + Class: "@exclude", + Opcode: 5714, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reference Base Penalty'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL", + Class: "@exclude", + Opcode: 5715, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Slice Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Qp'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceSetInterShapePenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceSetInterShapePenaltyINTEL", + Class: "@exclude", + Opcode: 5716, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Shape Penalty'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL", + Class: "@exclude", + Opcode: 5717, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Slice Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Qp'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL", + Class: "@exclude", + Opcode: 5718, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Direction Cost'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL", + Class: "@exclude", + Opcode: 5719, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Slice Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Qp'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL", + Class: "@exclude", + Opcode: 5720, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Slice Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Qp'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL", + Class: "@exclude", + Opcode: 5721, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL", + Class: "@exclude", + Opcode: 5722, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL", + Class: "@exclude", + Opcode: 5723, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = &Opcode { + Opname: "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL", + Class: "@exclude", + Opcode: 5724, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Cost Center Delta'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Cost Table'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Cost Precision'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL", + Class: "@exclude", + Opcode: 5725, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Slice Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Qp'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL", + Class: "@exclude", + Opcode: 5726, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL", + Class: "@exclude", + Opcode: 5727, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceSetAcOnlyHaarINTEL = &Opcode { + Opname: "OpSubgroupAvcMceSetAcOnlyHaarINTEL", + Class: "@exclude", + Opcode: 5728, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = &Opcode { + Opname: "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL", + Class: "@exclude", + Opcode: 5729, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source Field Polarity'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = &Opcode { + Opname: "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL", + Class: "@exclude", + Opcode: 5730, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Reference Field Polarity'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = &Opcode { + Opname: "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL", + Class: "@exclude", + Opcode: 5731, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Forward Reference Field Polarity'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Backward Reference Field Polarity'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceConvertToImePayloadINTEL = &Opcode { + Opname: "OpSubgroupAvcMceConvertToImePayloadINTEL", + Class: "@exclude", + Opcode: 5732, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceConvertToImeResultINTEL = &Opcode { + Opname: "OpSubgroupAvcMceConvertToImeResultINTEL", + Class: "@exclude", + Opcode: 5733, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceConvertToRefPayloadINTEL = &Opcode { + Opname: "OpSubgroupAvcMceConvertToRefPayloadINTEL", + Class: "@exclude", + Opcode: 5734, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceConvertToRefResultINTEL = &Opcode { + Opname: "OpSubgroupAvcMceConvertToRefResultINTEL", + Class: "@exclude", + Opcode: 5735, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceConvertToSicPayloadINTEL = &Opcode { + Opname: "OpSubgroupAvcMceConvertToSicPayloadINTEL", + Class: "@exclude", + Opcode: 5736, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceConvertToSicResultINTEL = &Opcode { + Opname: "OpSubgroupAvcMceConvertToSicResultINTEL", + Class: "@exclude", + Opcode: 5737, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetMotionVectorsINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetMotionVectorsINTEL", + Class: "@exclude", + Opcode: 5738, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetInterDistortionsINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetInterDistortionsINTEL", + Class: "@exclude", + Opcode: 5739, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetBestInterDistortionsINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetBestInterDistortionsINTEL", + Class: "@exclude", + Opcode: 5740, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetInterMajorShapeINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetInterMajorShapeINTEL", + Class: "@exclude", + Opcode: 5741, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetInterMinorShapeINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetInterMinorShapeINTEL", + Class: "@exclude", + Opcode: 5742, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetInterDirectionsINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetInterDirectionsINTEL", + Class: "@exclude", + Opcode: 5743, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetInterMotionVectorCountINTEL", + Class: "@exclude", + Opcode: 5744, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetInterReferenceIdsINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetInterReferenceIdsINTEL", + Class: "@exclude", + Opcode: 5745, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = &Opcode { + Opname: "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL", + Class: "@exclude", + Opcode: 5746, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Reference Ids'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Reference Parameter Field Polarities'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeInitializeINTEL = &Opcode { + Opname: "OpSubgroupAvcImeInitializeINTEL", + Class: "@exclude", + Opcode: 5747, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Coord'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Partition Mask'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'SAD Adjustment'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeSetSingleReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcImeSetSingleReferenceINTEL", + Class: "@exclude", + Opcode: 5748, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Search Window Config'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeSetDualReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcImeSetDualReferenceINTEL", + Class: "@exclude", + Opcode: 5749, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Fwd Ref Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bwd Ref Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'id> Search Window Config'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeRefWindowSizeINTEL = &Opcode { + Opname: "OpSubgroupAvcImeRefWindowSizeINTEL", + Class: "@exclude", + Opcode: 5750, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Search Window Config'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Dual Ref'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeAdjustRefOffsetINTEL = &Opcode { + Opname: "OpSubgroupAvcImeAdjustRefOffsetINTEL", + Class: "@exclude", + Opcode: 5751, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Coord'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Window Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image Size'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeConvertToMcePayloadINTEL = &Opcode { + Opname: "OpSubgroupAvcImeConvertToMcePayloadINTEL", + Class: "@exclude", + Opcode: 5752, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = &Opcode { + Opname: "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL", + Class: "@exclude", + Opcode: 5753, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Max Motion Vector Count'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = &Opcode { + Opname: "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL", + Class: "@exclude", + Opcode: 5754, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = &Opcode { + Opname: "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL", + Class: "@exclude", + Opcode: 5755, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Threshold'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeSetWeightedSadINTEL = &Opcode { + Opname: "OpSubgroupAvcImeSetWeightedSadINTEL", + Class: "@exclude", + Opcode: 5756, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Sad Weights'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL", + Class: "@exclude", + Opcode: 5757, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL", + Class: "@exclude", + Opcode: 5758, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Fwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = &Opcode { + Opname: "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL", + Class: "@exclude", + Opcode: 5759, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Streamin Components'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = &Opcode { + Opname: "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL", + Class: "@exclude", + Opcode: 5760, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Fwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Streamin Components'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = &Opcode { + Opname: "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL", + Class: "@exclude", + Opcode: 5761, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = &Opcode { + Opname: "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL", + Class: "@exclude", + Opcode: 5762, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Fwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = &Opcode { + Opname: "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL", + Class: "@exclude", + Opcode: 5763, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Streamin Components'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = &Opcode { + Opname: "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL", + Class: "@exclude", + Opcode: 5764, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Fwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Streamin Components'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeConvertToMceResultINTEL = &Opcode { + Opname: "OpSubgroupAvcImeConvertToMceResultINTEL", + Class: "@exclude", + Opcode: 5765, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL", + Class: "@exclude", + Opcode: 5766, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetDualReferenceStreaminINTEL", + Class: "@exclude", + Opcode: 5767, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = &Opcode { + Opname: "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL", + Class: "@exclude", + Opcode: 5768, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = &Opcode { + Opname: "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL", + Class: "@exclude", + Opcode: 5769, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL", + Class: "@exclude", + Opcode: 5770, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Major Shape'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL", + Class: "@exclude", + Opcode: 5771, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Major Shape'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL", + Class: "@exclude", + Opcode: 5772, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Major Shape'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL", + Class: "@exclude", + Opcode: 5773, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Major Shape'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Direction'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL", + Class: "@exclude", + Opcode: 5774, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Major Shape'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Direction'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL", + Class: "@exclude", + Opcode: 5775, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Major Shape'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Direction'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetBorderReachedINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetBorderReachedINTEL", + Class: "@exclude", + Opcode: 5776, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Image Select'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL", + Class: "@exclude", + Opcode: 5777, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL", + Class: "@exclude", + Opcode: 5778, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL", + Class: "@exclude", + Opcode: 5779, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = &Opcode { + Opname: "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL", + Class: "@exclude", + Opcode: 5780, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcFmeInitializeINTEL = &Opcode { + Opname: "OpSubgroupAvcFmeInitializeINTEL", + Class: "@exclude", + Opcode: 5781, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Coord'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Motion Vectors'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Major Shapes'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Minor Shapes'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Direction'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pixel Resolution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sad Adjustment'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcBmeInitializeINTEL = &Opcode { + Opname: "OpSubgroupAvcBmeInitializeINTEL", + Class: "@exclude", + Opcode: 5782, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Coord'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Motion Vectors'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Major Shapes'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Minor Shapes'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Direction'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Pixel Resolution'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bidirectional Weight'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sad Adjustment'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcRefConvertToMcePayloadINTEL = &Opcode { + Opname: "OpSubgroupAvcRefConvertToMcePayloadINTEL", + Class: "@exclude", + Opcode: 5783, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = &Opcode { + Opname: "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL", + Class: "@exclude", + Opcode: 5784, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = &Opcode { + Opname: "OpSubgroupAvcRefSetBilinearFilterEnableINTEL", + Class: "@exclude", + Opcode: 5785, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL", + Class: "@exclude", + Opcode: 5786, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL", + Class: "@exclude", + Opcode: 5787, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Fwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL", + Class: "@exclude", + Opcode: 5788, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Reference Ids'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = &Opcode { + Opname: "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL", + Class: "@exclude", + Opcode: 5789, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Reference Ids'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Reference Field Polarities'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcRefConvertToMceResultINTEL = &Opcode { + Opname: "OpSubgroupAvcRefConvertToMceResultINTEL", + Class: "@exclude", + Opcode: 5790, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicInitializeINTEL = &Opcode { + Opname: "OpSubgroupAvcSicInitializeINTEL", + Class: "@exclude", + Opcode: 5791, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Coord'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicConfigureSkcINTEL = &Opcode { + Opname: "OpSubgroupAvcSicConfigureSkcINTEL", + Class: "@exclude", + Opcode: 5792, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Skip Block Partition Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Skip Motion Vector Mask'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Motion Vectors'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bidirectional Weight'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sad Adjustment'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicConfigureIpeLumaINTEL = &Opcode { + Opname: "OpSubgroupAvcSicConfigureIpeLumaINTEL", + Class: "@exclude", + Opcode: 5793, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Luma Intra Partition Mask'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intra Neighbour Availabilty'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Left Edge Luma Pixels'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Upper Left Corner Luma Pixel'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Upper Edge Luma Pixels'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Upper Right Edge Luma Pixels'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sad Adjustment'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = &Opcode { + Opname: "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL", + Class: "@exclude", + Opcode: 5794, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Luma Intra Partition Mask'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Intra Neighbour Availabilty'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Left Edge Luma Pixels'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Upper Left Corner Luma Pixel'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Upper Edge Luma Pixels'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Upper Right Edge Luma Pixels'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Left Edge Chroma Pixels'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Upper Left Corner Chroma Pixel'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Upper Edge Chroma Pixels'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Sad Adjustment'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetMotionVectorMaskINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetMotionVectorMaskINTEL", + Class: "@exclude", + Opcode: 5795, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Skip Block Partition Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Direction'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicConvertToMcePayloadINTEL = &Opcode { + Opname: "OpSubgroupAvcSicConvertToMcePayloadINTEL", + Class: "@exclude", + Opcode: 5796, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = &Opcode { + Opname: "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL", + Class: "@exclude", + Opcode: 5797, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Shape Penalty'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = &Opcode { + Opname: "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL", + Class: "@exclude", + Opcode: 5798, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Luma Mode Penalty'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Luma Packed Neighbor Modes'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Luma Packed Non Dc Penalty'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = &Opcode { + Opname: "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL", + Class: "@exclude", + Opcode: 5799, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Chroma Mode Base Penalty'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = &Opcode { + Opname: "OpSubgroupAvcSicSetBilinearFilterEnableINTEL", + Class: "@exclude", + Opcode: 5800, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = &Opcode { + Opname: "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL", + Class: "@exclude", + Opcode: 5801, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Sad Coefficients'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = &Opcode { + Opname: "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL", + Class: "@exclude", + Opcode: 5802, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Block Based Skip Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicEvaluateIpeINTEL = &Opcode { + Opname: "OpSubgroupAvcSicEvaluateIpeINTEL", + Class: "@exclude", + Opcode: 5803, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL", + Class: "@exclude", + Opcode: 5804, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL", + Class: "@exclude", + Opcode: 5805, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Fwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Bwd Ref Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = &Opcode { + Opname: "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL", + Class: "@exclude", + Opcode: 5806, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Reference Ids'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = &Opcode { + Opname: "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL", + Class: "@exclude", + Opcode: 5807, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Src Image'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Reference Ids'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Packed Reference Field Polarities'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicConvertToMceResultINTEL = &Opcode { + Opname: "OpSubgroupAvcSicConvertToMceResultINTEL", + Class: "@exclude", + Opcode: 5808, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetIpeLumaShapeINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetIpeLumaShapeINTEL", + Class: "@exclude", + Opcode: 5809, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL", + Class: "@exclude", + Opcode: 5810, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL", + Class: "@exclude", + Opcode: 5811, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL", + Class: "@exclude", + Opcode: 5812, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetIpeChromaModeINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetIpeChromaModeINTEL", + Class: "@exclude", + Opcode: 5813, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", + Class: "@exclude", + Opcode: 5814, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", + Class: "@exclude", + Opcode: 5815, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + OpSubgroupAvcSicGetInterRawSadsINTEL = &Opcode { + Opname: "OpSubgroupAvcSicGetInterRawSadsINTEL", + Class: "@exclude", + Opcode: 5816, + Operands: []Operand { + Operand { + Kind: OperandKindIdResultType, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdResult, + Name: "", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Payload'", + Quantifier: "", + }, + }, + } + + GLSLStd450_Round = &Opcode { + Opname: "Round", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_RoundEven = &Opcode { + Opname: "RoundEven", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Trunc = &Opcode { + Opname: "Trunc", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_FAbs = &Opcode { + Opname: "FAbs", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_SAbs = &Opcode { + Opname: "SAbs", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_FSign = &Opcode { + Opname: "FSign", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_SSign = &Opcode { + Opname: "SSign", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Floor = &Opcode { + Opname: "Floor", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Ceil = &Opcode { + Opname: "Ceil", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Fract = &Opcode { + Opname: "Fract", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Radians = &Opcode { + Opname: "Radians", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'degrees'", + Quantifier: "", + }, + }, + } + GLSLStd450_Degrees = &Opcode { + Opname: "Degrees", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'radians'", + Quantifier: "", + }, + }, + } + GLSLStd450_Sin = &Opcode { + Opname: "Sin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Cos = &Opcode { + Opname: "Cos", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Tan = &Opcode { + Opname: "Tan", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Asin = &Opcode { + Opname: "Asin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Acos = &Opcode { + Opname: "Acos", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Atan = &Opcode { + Opname: "Atan", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'y_over_x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Sinh = &Opcode { + Opname: "Sinh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Cosh = &Opcode { + Opname: "Cosh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Tanh = &Opcode { + Opname: "Tanh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Asinh = &Opcode { + Opname: "Asinh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Acosh = &Opcode { + Opname: "Acosh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Atanh = &Opcode { + Opname: "Atanh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Atan2 = &Opcode { + Opname: "Atan2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Pow = &Opcode { + Opname: "Pow", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_Exp = &Opcode { + Opname: "Exp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Log = &Opcode { + Opname: "Log", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Exp2 = &Opcode { + Opname: "Exp2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Log2 = &Opcode { + Opname: "Log2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Sqrt = &Opcode { + Opname: "Sqrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_InverseSqrt = &Opcode { + Opname: "InverseSqrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Determinant = &Opcode { + Opname: "Determinant", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_MatrixInverse = &Opcode { + Opname: "MatrixInverse", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Modf = &Opcode { + Opname: "Modf", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'i'", + Quantifier: "", + }, + }, + } + GLSLStd450_ModfStruct = &Opcode { + Opname: "ModfStruct", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_FMin = &Opcode { + Opname: "FMin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_UMin = &Opcode { + Opname: "UMin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_SMin = &Opcode { + Opname: "SMin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_FMax = &Opcode { + Opname: "FMax", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_UMax = &Opcode { + Opname: "UMax", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_SMax = &Opcode { + Opname: "SMax", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_FClamp = &Opcode { + Opname: "FClamp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'minVal'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'maxVal'", + Quantifier: "", + }, + }, + } + GLSLStd450_UClamp = &Opcode { + Opname: "UClamp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'minVal'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'maxVal'", + Quantifier: "", + }, + }, + } + GLSLStd450_SClamp = &Opcode { + Opname: "SClamp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'minVal'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'maxVal'", + Quantifier: "", + }, + }, + } + GLSLStd450_FMix = &Opcode { + Opname: "FMix", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + }, + } + GLSLStd450_IMix = &Opcode { + Opname: "IMix", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + }, + } + GLSLStd450_Step = &Opcode { + Opname: "Step", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'edge'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_SmoothStep = &Opcode { + Opname: "SmoothStep", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'edge0'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'edge1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Fma = &Opcode { + Opname: "Fma", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'b'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'c'", + Quantifier: "", + }, + }, + } + GLSLStd450_Frexp = &Opcode { + Opname: "Frexp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'exp'", + Quantifier: "", + }, + }, + } + GLSLStd450_FrexpStruct = &Opcode { + Opname: "FrexpStruct", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Ldexp = &Opcode { + Opname: "Ldexp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'exp'", + Quantifier: "", + }, + }, + } + GLSLStd450_PackSnorm4x8 = &Opcode { + Opname: "PackSnorm4x8", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + }, + } + GLSLStd450_PackUnorm4x8 = &Opcode { + Opname: "PackUnorm4x8", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + }, + } + GLSLStd450_PackSnorm2x16 = &Opcode { + Opname: "PackSnorm2x16", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + }, + } + GLSLStd450_PackUnorm2x16 = &Opcode { + Opname: "PackUnorm2x16", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + }, + } + GLSLStd450_PackHalf2x16 = &Opcode { + Opname: "PackHalf2x16", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + }, + } + GLSLStd450_PackDouble2x32 = &Opcode { + Opname: "PackDouble2x32", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + }, + } + GLSLStd450_UnpackSnorm2x16 = &Opcode { + Opname: "UnpackSnorm2x16", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + GLSLStd450_UnpackUnorm2x16 = &Opcode { + Opname: "UnpackUnorm2x16", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + GLSLStd450_UnpackHalf2x16 = &Opcode { + Opname: "UnpackHalf2x16", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + }, + } + GLSLStd450_UnpackSnorm4x8 = &Opcode { + Opname: "UnpackSnorm4x8", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + GLSLStd450_UnpackUnorm4x8 = &Opcode { + Opname: "UnpackUnorm4x8", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + GLSLStd450_UnpackDouble2x32 = &Opcode { + Opname: "UnpackDouble2x32", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + }, + } + GLSLStd450_Length = &Opcode { + Opname: "Length", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_Distance = &Opcode { + Opname: "Distance", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p0'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p1'", + Quantifier: "", + }, + }, + } + GLSLStd450_Cross = &Opcode { + Opname: "Cross", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_Normalize = &Opcode { + Opname: "Normalize", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + GLSLStd450_FaceForward = &Opcode { + Opname: "FaceForward", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'N'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'I'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Nref'", + Quantifier: "", + }, + }, + } + GLSLStd450_Reflect = &Opcode { + Opname: "Reflect", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'I'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'N'", + Quantifier: "", + }, + }, + } + GLSLStd450_Refract = &Opcode { + Opname: "Refract", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'I'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'N'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'eta'", + Quantifier: "", + }, + }, + } + GLSLStd450_FindILsb = &Opcode { + Opname: "FindILsb", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + GLSLStd450_FindSMsb = &Opcode { + Opname: "FindSMsb", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + GLSLStd450_FindUMsb = &Opcode { + Opname: "FindUMsb", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + }, + } + GLSLStd450_InterpolateAtCentroid = &Opcode { + Opname: "InterpolateAtCentroid", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'interpolant'", + Quantifier: "", + }, + }, + } + GLSLStd450_InterpolateAtSample = &Opcode { + Opname: "InterpolateAtSample", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'interpolant'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'sample'", + Quantifier: "", + }, + }, + } + GLSLStd450_InterpolateAtOffset = &Opcode { + Opname: "InterpolateAtOffset", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'interpolant'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + }, + } + GLSLStd450_NMin = &Opcode { + Opname: "NMin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_NMax = &Opcode { + Opname: "NMax", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + GLSLStd450_NClamp = &Opcode { + Opname: "NClamp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'minVal'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'maxVal'", + Quantifier: "", + }, + }, + } + OpenCLStd_acos = &Opcode { + Opname: "acos", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_acosh = &Opcode { + Opname: "acosh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_acospi = &Opcode { + Opname: "acospi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_asin = &Opcode { + Opname: "asin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_asinh = &Opcode { + Opname: "asinh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_asinpi = &Opcode { + Opname: "asinpi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_atan = &Opcode { + Opname: "atan", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_atan2 = &Opcode { + Opname: "atan2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_atanh = &Opcode { + Opname: "atanh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_atanpi = &Opcode { + Opname: "atanpi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_atan2pi = &Opcode { + Opname: "atan2pi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_cbrt = &Opcode { + Opname: "cbrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_ceil = &Opcode { + Opname: "ceil", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_copysign = &Opcode { + Opname: "copysign", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_cos = &Opcode { + Opname: "cos", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_cosh = &Opcode { + Opname: "cosh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_cospi = &Opcode { + Opname: "cospi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_erfc = &Opcode { + Opname: "erfc", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_erf = &Opcode { + Opname: "erf", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_exp = &Opcode { + Opname: "exp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_exp2 = &Opcode { + Opname: "exp2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_exp10 = &Opcode { + Opname: "exp10", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_expm1 = &Opcode { + Opname: "expm1", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_fabs = &Opcode { + Opname: "fabs", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_fdim = &Opcode { + Opname: "fdim", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_floor = &Opcode { + Opname: "floor", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_fma = &Opcode { + Opname: "fma", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'b'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'c'", + Quantifier: "", + }, + }, + } + OpenCLStd_fmax = &Opcode { + Opname: "fmax", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_fmin = &Opcode { + Opname: "fmin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_fmod = &Opcode { + Opname: "fmod", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_fract = &Opcode { + Opname: "fract", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'ptr'", + Quantifier: "", + }, + }, + } + OpenCLStd_frexp = &Opcode { + Opname: "frexp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'exp'", + Quantifier: "", + }, + }, + } + OpenCLStd_hypot = &Opcode { + Opname: "hypot", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_ilogb = &Opcode { + Opname: "ilogb", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_ldexp = &Opcode { + Opname: "ldexp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'k'", + Quantifier: "", + }, + }, + } + OpenCLStd_lgamma = &Opcode { + Opname: "lgamma", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_lgamma_r = &Opcode { + Opname: "lgamma_r", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'signp'", + Quantifier: "", + }, + }, + } + OpenCLStd_log = &Opcode { + Opname: "log", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_log2 = &Opcode { + Opname: "log2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_log10 = &Opcode { + Opname: "log10", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_log1p = &Opcode { + Opname: "log1p", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_logb = &Opcode { + Opname: "logb", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_mad = &Opcode { + Opname: "mad", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'b'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'c'", + Quantifier: "", + }, + }, + } + OpenCLStd_maxmag = &Opcode { + Opname: "maxmag", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_minmag = &Opcode { + Opname: "minmag", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_modf = &Opcode { + Opname: "modf", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'iptr'", + Quantifier: "", + }, + }, + } + OpenCLStd_nan = &Opcode { + Opname: "nan", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'nancode'", + Quantifier: "", + }, + }, + } + OpenCLStd_nextafter = &Opcode { + Opname: "nextafter", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_pow = &Opcode { + Opname: "pow", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y", + Quantifier: "", + }, + }, + } + OpenCLStd_pown = &Opcode { + Opname: "pown", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_powr = &Opcode { + Opname: "powr", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_remainder = &Opcode { + Opname: "remainder", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_remquo = &Opcode { + Opname: "remquo", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'quo'", + Quantifier: "", + }, + }, + } + OpenCLStd_rint = &Opcode { + Opname: "rint", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_rootn = &Opcode { + Opname: "rootn", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_round = &Opcode { + Opname: "round", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_rsqrt = &Opcode { + Opname: "rsqrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_sin = &Opcode { + Opname: "sin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_sincos = &Opcode { + Opname: "sincos", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'cosval'", + Quantifier: "", + }, + }, + } + OpenCLStd_sinh = &Opcode { + Opname: "sinh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_sinpi = &Opcode { + Opname: "sinpi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_sqrt = &Opcode { + Opname: "sqrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_tan = &Opcode { + Opname: "tan", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_tanh = &Opcode { + Opname: "tanh", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_tanpi = &Opcode { + Opname: "tanpi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_tgamma = &Opcode { + Opname: "tgamma", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_trunc = &Opcode { + Opname: "trunc", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_cos = &Opcode { + Opname: "half_cos", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_divide = &Opcode { + Opname: "half_divide", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_exp = &Opcode { + Opname: "half_exp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_exp2 = &Opcode { + Opname: "half_exp2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_exp10 = &Opcode { + Opname: "half_exp10", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_log = &Opcode { + Opname: "half_log", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_log2 = &Opcode { + Opname: "half_log2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_log10 = &Opcode { + Opname: "half_log10", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_powr = &Opcode { + Opname: "half_powr", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_recip = &Opcode { + Opname: "half_recip", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_rsqrt = &Opcode { + Opname: "half_rsqrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_sin = &Opcode { + Opname: "half_sin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_sqrt = &Opcode { + Opname: "half_sqrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_half_tan = &Opcode { + Opname: "half_tan", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_cos = &Opcode { + Opname: "native_cos", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_divide = &Opcode { + Opname: "native_divide", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_exp = &Opcode { + Opname: "native_exp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_exp2 = &Opcode { + Opname: "native_exp2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_exp10 = &Opcode { + Opname: "native_exp10", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_log = &Opcode { + Opname: "native_log", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_log2 = &Opcode { + Opname: "native_log2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_log10 = &Opcode { + Opname: "native_log10", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_powr = &Opcode { + Opname: "native_powr", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_recip = &Opcode { + Opname: "native_recip", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_rsqrt = &Opcode { + Opname: "native_rsqrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_sin = &Opcode { + Opname: "native_sin", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_sqrt = &Opcode { + Opname: "native_sqrt", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_native_tan = &Opcode { + Opname: "native_tan", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_abs = &Opcode { + Opname: "s_abs", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_abs_diff = &Opcode { + Opname: "s_abs_diff", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_add_sat = &Opcode { + Opname: "s_add_sat", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_add_sat = &Opcode { + Opname: "u_add_sat", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_hadd = &Opcode { + Opname: "s_hadd", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_hadd = &Opcode { + Opname: "u_hadd", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_rhadd = &Opcode { + Opname: "s_rhadd", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_rhadd = &Opcode { + Opname: "u_rhadd", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_clamp = &Opcode { + Opname: "s_clamp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'minval'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'maxval'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_clamp = &Opcode { + Opname: "u_clamp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'minval'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'maxval'", + Quantifier: "", + }, + }, + } + OpenCLStd_clz = &Opcode { + Opname: "clz", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_ctz = &Opcode { + Opname: "ctz", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_mad_hi = &Opcode { + Opname: "s_mad_hi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'b'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'c'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_mad_sat = &Opcode { + Opname: "u_mad_sat", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'z'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_mad_sat = &Opcode { + Opname: "s_mad_sat", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'z'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_max = &Opcode { + Opname: "s_max", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_max = &Opcode { + Opname: "u_max", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_min = &Opcode { + Opname: "s_min", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_min = &Opcode { + Opname: "u_min", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_mul_hi = &Opcode { + Opname: "s_mul_hi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_rotate = &Opcode { + Opname: "rotate", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'v'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'i'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_sub_sat = &Opcode { + Opname: "s_sub_sat", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_sub_sat = &Opcode { + Opname: "u_sub_sat", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_upsample = &Opcode { + Opname: "u_upsample", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'hi'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'lo'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_upsample = &Opcode { + Opname: "s_upsample", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'hi'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'lo'", + Quantifier: "", + }, + }, + } + OpenCLStd_popcount = &Opcode { + Opname: "popcount", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_mad24 = &Opcode { + Opname: "s_mad24", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'z'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_mad24 = &Opcode { + Opname: "u_mad24", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'z'", + Quantifier: "", + }, + }, + } + OpenCLStd_s_mul24 = &Opcode { + Opname: "s_mul24", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_mul24 = &Opcode { + Opname: "u_mul24", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_abs = &Opcode { + Opname: "u_abs", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_abs_diff = &Opcode { + Opname: "u_abs_diff", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_mul_hi = &Opcode { + Opname: "u_mul_hi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_u_mad_hi = &Opcode { + Opname: "u_mad_hi", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'b'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'c'", + Quantifier: "", + }, + }, + } + OpenCLStd_fclamp = &Opcode { + Opname: "fclamp", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'minval'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'maxval'", + Quantifier: "", + }, + }, + } + OpenCLStd_degrees = &Opcode { + Opname: "degrees", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'radians'", + Quantifier: "", + }, + }, + } + OpenCLStd_fmax_common = &Opcode { + Opname: "fmax_common", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_fmin_common = &Opcode { + Opname: "fmin_common", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + }, + } + OpenCLStd_mix = &Opcode { + Opname: "mix", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + }, + } + OpenCLStd_radians = &Opcode { + Opname: "radians", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'degrees'", + Quantifier: "", + }, + }, + } + OpenCLStd_step = &Opcode { + Opname: "step", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'edge'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_smoothstep = &Opcode { + Opname: "smoothstep", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'edge0'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'edge1'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_sign = &Opcode { + Opname: "sign", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + }, + } + OpenCLStd_cross = &Opcode { + Opname: "cross", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p0'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p1'", + Quantifier: "", + }, + }, + } + OpenCLStd_distance = &Opcode { + Opname: "distance", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p0'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p1'", + Quantifier: "", + }, + }, + } + OpenCLStd_length = &Opcode { + Opname: "length", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_normalize = &Opcode { + Opname: "normalize", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_fast_distance = &Opcode { + Opname: "fast_distance", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p0'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p1'", + Quantifier: "", + }, + }, + } + OpenCLStd_fast_length = &Opcode { + Opname: "fast_length", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_fast_normalize = &Opcode { + Opname: "fast_normalize", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_bitselect = &Opcode { + Opname: "bitselect", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'b'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'c'", + Quantifier: "", + }, + }, + } + OpenCLStd_select = &Opcode { + Opname: "select", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'a'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'b'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'c'", + Quantifier: "", + }, + }, + } + OpenCLStd_vloadn = &Opcode { + Opname: "vloadn", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'n'", + Quantifier: "", + }, + }, + } + OpenCLStd_vstoren = &Opcode { + Opname: "vstoren", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_vload_half = &Opcode { + Opname: "vload_half", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_vload_halfn = &Opcode { + Opname: "vload_halfn", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'n'", + Quantifier: "", + }, + }, + } + OpenCLStd_vstore_half = &Opcode { + Opname: "vstore_half", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_vstore_half_r = &Opcode { + Opname: "vstore_half_r", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + Operand { + Kind: OperandKindFPRoundingMode, + Name: "'mode'", + Quantifier: "", + }, + }, + } + OpenCLStd_vstore_halfn = &Opcode { + Opname: "vstore_halfn", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_vstore_halfn_r = &Opcode { + Opname: "vstore_halfn_r", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + Operand { + Kind: OperandKindFPRoundingMode, + Name: "'mode'", + Quantifier: "", + }, + }, + } + OpenCLStd_vloada_halfn = &Opcode { + Opname: "vloada_halfn", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'n'", + Quantifier: "", + }, + }, + } + OpenCLStd_vstorea_halfn = &Opcode { + Opname: "vstorea_halfn", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + }, + } + OpenCLStd_vstorea_halfn_r = &Opcode { + Opname: "vstorea_halfn_r", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'data'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'p'", + Quantifier: "", + }, + Operand { + Kind: OperandKindFPRoundingMode, + Name: "'mode'", + Quantifier: "", + }, + }, + } + OpenCLStd_shuffle = &Opcode { + Opname: "shuffle", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'shuffle mask'", + Quantifier: "", + }, + }, + } + OpenCLStd_shuffle2 = &Opcode { + Opname: "shuffle2", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'x'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'y'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'shuffle mask'", + Quantifier: "", + }, + }, + } + OpenCLStd_printf = &Opcode { + Opname: "printf", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'format'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'additional arguments'", + Quantifier: "*", + }, + }, + } + OpenCLStd_prefetch = &Opcode { + Opname: "prefetch", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'ptr'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'num elements'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugInfoNone = &Opcode { + Opname: "DebugInfoNone", + Operands: []Operand { + }, + } + OpenCLDebugInfo100_DebugCompilationUnit = &Opcode { + Opname: "DebugCompilationUnit", + Operands: []Operand { + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Version'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'DWARF Version'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindSourceLanguage, + Name: "'Language'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypeBasic = &Opcode { + Opname: "DebugTypeBasic", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugBaseTypeAttributeEncoding, + Name: "'Encoding'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypePointer = &Opcode { + Opname: "DebugTypePointer", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Base Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindStorageClass, + Name: "'Storage Class'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypeQualifier = &Opcode { + Opname: "DebugTypeQualifier", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Base Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugTypeQualifier, + Name: "'Type Qualifier'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypeArray = &Opcode { + Opname: "DebugTypeArray", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Base Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Component Counts'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugTypeVector = &Opcode { + Opname: "DebugTypeVector", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Base Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Component Count'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypedef = &Opcode { + Opname: "DebugTypedef", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Base Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypeFunction = &Opcode { + Opname: "DebugTypeFunction", + Operands: []Operand { + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Return Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parameter Types'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugTypeEnum = &Opcode { + Opname: "DebugTypeEnum", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Underlying Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindPairIdRefIdRef, + Name: "'Value, Name, Value, Name, ...'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugTypeComposite = &Opcode { + Opname: "DebugTypeComposite", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugCompositeType, + Name: "'Tag'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Linkage Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Members'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugTypeMember = &Opcode { + Opname: "DebugTypeMember", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "?", + }, + }, + } + OpenCLDebugInfo100_DebugTypeInheritance = &Opcode { + Opname: "DebugTypeInheritance", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Child'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Offset'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Size'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypePtrToMember = &Opcode { + Opname: "DebugTypePtrToMember", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Member Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypeTemplate = &Opcode { + Opname: "DebugTypeTemplate", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Target'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parameters'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugTypeTemplateParameter = &Opcode { + Opname: "DebugTypeTemplateParameter", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Actual Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypeTemplateTemplateParameter = &Opcode { + Opname: "DebugTypeTemplateTemplateParameter", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Template Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugTypeTemplateParameterPack = &Opcode { + Opname: "DebugTypeTemplateParameterPack", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Template Parameters'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugGlobalVariable = &Opcode { + Opname: "DebugGlobalVariable", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Linkage Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Variable'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Static Member Declaration'", + Quantifier: "?", + }, + }, + } + OpenCLDebugInfo100_DebugFunctionDeclaration = &Opcode { + Opname: "DebugFunctionDeclaration", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Linkage Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugFunction = &Opcode { + Opname: "DebugFunction", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Linkage Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Scope Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Function'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Declaration'", + Quantifier: "?", + }, + }, + } + OpenCLDebugInfo100_DebugLexicalBlock = &Opcode { + Opname: "DebugLexicalBlock", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "?", + }, + }, + } + OpenCLDebugInfo100_DebugLexicalBlockDiscriminator = &Opcode { + Opname: "DebugLexicalBlockDiscriminator", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Discriminator'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugScope = &Opcode { + Opname: "DebugScope", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Scope'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Inlined At'", + Quantifier: "?", + }, + }, + } + OpenCLDebugInfo100_DebugNoScope = &Opcode { + Opname: "DebugNoScope", + Operands: []Operand { + }, + } + OpenCLDebugInfo100_DebugInlinedAt = &Opcode { + Opname: "DebugInlinedAt", + Operands: []Operand { + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Scope'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Inlined'", + Quantifier: "?", + }, + }, + } + OpenCLDebugInfo100_DebugLocalVariable = &Opcode { + Opname: "DebugLocalVariable", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Type'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugInfoFlags, + Name: "'Flags'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Arg Number'", + Quantifier: "?", + }, + }, + } + OpenCLDebugInfo100_DebugInlinedVariable = &Opcode { + Opname: "DebugInlinedVariable", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Variable'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Inlined'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugDeclare = &Opcode { + Opname: "DebugDeclare", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Local Variable'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Variable'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Expression'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugValue = &Opcode { + Opname: "DebugValue", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Local Variable'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Expression'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Indexes'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugOperation = &Opcode { + Opname: "DebugOperation", + Operands: []Operand { + Operand { + Kind: OperandKindDebugOperation, + Name: "'OpCode'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Operands ...'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugExpression = &Opcode { + Opname: "DebugExpression", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Operands ...'", + Quantifier: "*", + }, + }, + } + OpenCLDebugInfo100_DebugMacroDef = &Opcode { + Opname: "DebugMacroDef", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Value'", + Quantifier: "?", + }, + }, + } + OpenCLDebugInfo100_DebugMacroUndef = &Opcode { + Opname: "DebugMacroUndef", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Macro'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugImportedEntity = &Opcode { + Opname: "DebugImportedEntity", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'Name'", + Quantifier: "", + }, + Operand { + Kind: OperandKindDebugImportedEntity, + Name: "'Tag'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Source'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Entity'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Line'", + Quantifier: "", + }, + Operand { + Kind: OperandKindLiteralInteger, + Name: "'Column'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Parent'", + Quantifier: "", + }, + }, + } + OpenCLDebugInfo100_DebugSource = &Opcode { + Opname: "DebugSource", + Operands: []Operand { + Operand { + Kind: OperandKindIdRef, + Name: "'File'", + Quantifier: "", + }, + Operand { + Kind: OperandKindIdRef, + Name: "'Text'", + Quantifier: "?", + }, + }, + } + + + OperandKindImageOperands = &OperandKind { + Kind: "ImageOperands", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "None", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Bias", + Value: 0x0001, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindIdRef, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "Lod", + Value: 0x0002, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindIdRef, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "Grad", + Value: 0x0004, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindIdRef, ""},{OperandKindIdRef, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "ConstOffset", + Value: 0x0008, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindIdRef, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "Offset", + Value: 0x0010, + Capabilities: []string{"ImageGatherExtended",}, + Parameters: []Parameter{{OperandKindIdRef, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "ConstOffsets", + Value: 0x0020, + Capabilities: []string{"ImageGatherExtended",}, + Parameters: []Parameter{{OperandKindIdRef, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "Sample", + Value: 0x0040, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindIdRef, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "MinLod", + Value: 0x0080, + Capabilities: []string{"MinLod",}, + Parameters: []Parameter{{OperandKindIdRef, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "MakeTexelAvailable", + Value: 0x0100, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{{OperandKindIdScope, ""},}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakeTexelAvailableKHR", + Value: 0x0100, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{{OperandKindIdScope, ""},}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakeTexelVisible", + Value: 0x0200, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{{OperandKindIdScope, ""},}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakeTexelVisibleKHR", + Value: 0x0200, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{{OperandKindIdScope, ""},}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "NonPrivateTexel", + Value: 0x0400, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "NonPrivateTexelKHR", + Value: 0x0400, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "VolatileTexel", + Value: 0x0800, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "VolatileTexelKHR", + Value: 0x0800, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "SignExtend", + Value: 0x1000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "ZeroExtend", + Value: 0x2000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindFPFastMathMode = &OperandKind { + Kind: "FPFastMathMode", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "None", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NotNaN", + Value: 0x0001, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NotInf", + Value: 0x0002, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NSZ", + Value: 0x0004, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "AllowRecip", + Value: 0x0008, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Fast", + Value: 0x0010, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindSelectionControl = &OperandKind { + Kind: "SelectionControl", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "None", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Flatten", + Value: 0x0001, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DontFlatten", + Value: 0x0002, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindLoopControl = &OperandKind { + Kind: "LoopControl", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "None", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Unroll", + Value: 0x0001, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DontUnroll", + Value: 0x0002, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DependencyInfinite", + Value: 0x0004, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "DependencyLength", + Value: 0x0008, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "MinIterations", + Value: 0x0010, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "MaxIterations", + Value: 0x0020, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "IterationMultiple", + Value: 0x0040, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "PeelCount", + Value: 0x0080, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "PartialCount", + Value: 0x0100, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "1.4", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindFunctionControl = &OperandKind { + Kind: "FunctionControl", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "None", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Inline", + Value: 0x0001, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DontInline", + Value: 0x0002, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Pure", + Value: 0x0004, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Const", + Value: 0x0008, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindMemorySemantics = &OperandKind { + Kind: "MemorySemantics", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Relaxed", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "None", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Acquire", + Value: 0x0002, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Release", + Value: 0x0004, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "AcquireRelease", + Value: 0x0008, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SequentiallyConsistent", + Value: 0x0010, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UniformMemory", + Value: 0x0040, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SubgroupMemory", + Value: 0x0080, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "WorkgroupMemory", + Value: 0x0100, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CrossWorkgroupMemory", + Value: 0x0200, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "AtomicCounterMemory", + Value: 0x0400, + Capabilities: []string{"AtomicStorage",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageMemory", + Value: 0x0800, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OutputMemory", + Value: 0x1000, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "OutputMemoryKHR", + Value: 0x1000, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakeAvailable", + Value: 0x2000, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakeAvailableKHR", + Value: 0x2000, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakeVisible", + Value: 0x4000, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakeVisibleKHR", + Value: 0x4000, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "Volatile", + Value: 0x8000, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindMemoryAccess = &OperandKind { + Kind: "MemoryAccess", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "None", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Volatile", + Value: 0x0001, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Aligned", + Value: 0x0002, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "Nontemporal", + Value: 0x0004, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "MakePointerAvailable", + Value: 0x0008, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{{OperandKindIdScope, ""},}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakePointerAvailableKHR", + Value: 0x0008, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{{OperandKindIdScope, ""},}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakePointerVisible", + Value: 0x0010, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{{OperandKindIdScope, ""},}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "MakePointerVisibleKHR", + Value: 0x0010, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{{OperandKindIdScope, ""},}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "NonPrivatePointer", + Value: 0x0020, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "NonPrivatePointerKHR", + Value: 0x0020, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindKernelProfilingInfo = &OperandKind { + Kind: "KernelProfilingInfo", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "None", + Value: 0x0000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CmdExecTime", + Value: 0x0001, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindRayFlags = &OperandKind { + Kind: "RayFlags", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "NoneKHR", + Value: 0x0000, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OpaqueKHR", + Value: 0x0001, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NoOpaqueKHR", + Value: 0x0002, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TerminateOnFirstHitKHR", + Value: 0x0004, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SkipClosestHitShaderKHR", + Value: 0x0008, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CullBackFacingTrianglesKHR", + Value: 0x0010, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CullFrontFacingTrianglesKHR", + Value: 0x0020, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CullOpaqueKHR", + Value: 0x0040, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CullNoOpaqueKHR", + Value: 0x0080, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SkipTrianglesKHR", + Value: 0x0100, + Capabilities: []string{"RayTraversalPrimitiveCullingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SkipAABBsKHR", + Value: 0x0200, + Capabilities: []string{"RayTraversalPrimitiveCullingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindSourceLanguage = &OperandKind { + Kind: "SourceLanguage", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Unknown", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ESSL", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GLSL", + Value: 2, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OpenCL_C", + Value: 3, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OpenCL_CPP", + Value: 4, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "HLSL", + Value: 5, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindExecutionModel = &OperandKind { + Kind: "ExecutionModel", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Vertex", + Value: 0, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TessellationControl", + Value: 1, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TessellationEvaluation", + Value: 2, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Geometry", + Value: 3, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Fragment", + Value: 4, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GLCompute", + Value: 5, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Kernel", + Value: 6, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TaskNV", + Value: 5267, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "MeshNV", + Value: 5268, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayGenerationNV", + Value: 5313, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayGenerationKHR", + Value: 5313, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IntersectionNV", + Value: 5314, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IntersectionKHR", + Value: 5314, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "AnyHitNV", + Value: 5315, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "AnyHitKHR", + Value: 5315, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ClosestHitNV", + Value: 5316, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ClosestHitKHR", + Value: 5316, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "MissNV", + Value: 5317, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "MissKHR", + Value: 5317, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "CallableNV", + Value: 5318, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "CallableKHR", + Value: 5318, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindAddressingModel = &OperandKind { + Kind: "AddressingModel", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Logical", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Physical32", + Value: 1, + Capabilities: []string{"Addresses",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Physical64", + Value: 2, + Capabilities: []string{"Addresses",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PhysicalStorageBuffer64", + Value: 5348, + Capabilities: []string{"PhysicalStorageBufferAddresses",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "PhysicalStorageBuffer64EXT", + Value: 5348, + Capabilities: []string{"PhysicalStorageBufferAddresses",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindMemoryModel = &OperandKind { + Kind: "MemoryModel", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Simple", + Value: 0, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GLSL450", + Value: 1, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OpenCL", + Value: 2, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Vulkan", + Value: 3, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "VulkanKHR", + Value: 3, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindExecutionMode = &OperandKind { + Kind: "ExecutionMode", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Invocations", + Value: 0, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Number of <>'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "SpacingEqual", + Value: 1, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SpacingFractionalEven", + Value: 2, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SpacingFractionalOdd", + Value: 3, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "VertexOrderCw", + Value: 4, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "VertexOrderCcw", + Value: 5, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PixelCenterInteger", + Value: 6, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OriginUpperLeft", + Value: 7, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OriginLowerLeft", + Value: 8, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "EarlyFragmentTests", + Value: 9, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PointMode", + Value: 10, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Xfb", + Value: 11, + Capabilities: []string{"TransformFeedback",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DepthReplacing", + Value: 12, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DepthGreater", + Value: 14, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DepthLess", + Value: 15, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DepthUnchanged", + Value: 16, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "LocalSize", + Value: 17, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'x size'"},{OperandKindLiteralInteger, "'y size'"},{OperandKindLiteralInteger, "'z size'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "LocalSizeHint", + Value: 18, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'x size'"},{OperandKindLiteralInteger, "'y size'"},{OperandKindLiteralInteger, "'z size'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "InputPoints", + Value: 19, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InputLines", + Value: 20, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InputLinesAdjacency", + Value: 21, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Triangles", + Value: 22, + Capabilities: []string{"Geometry","Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InputTrianglesAdjacency", + Value: 23, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Quads", + Value: 24, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Isolines", + Value: 25, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OutputVertices", + Value: 26, + Capabilities: []string{"Geometry","Tessellation","MeshShadingNV",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Vertex count'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "OutputPoints", + Value: 27, + Capabilities: []string{"Geometry","MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OutputLineStrip", + Value: 28, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "OutputTriangleStrip", + Value: 29, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "VecTypeHint", + Value: 30, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Vector type'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "ContractionOff", + Value: 31, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Initializer", + Value: 33, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "Finalizer", + Value: 34, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "SubgroupSize", + Value: 35, + Capabilities: []string{"SubgroupDispatch",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Subgroup Size'"},}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "SubgroupsPerWorkgroup", + Value: 36, + Capabilities: []string{"SubgroupDispatch",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Subgroups Per Workgroup'"},}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "SubgroupsPerWorkgroupId", + Value: 37, + Capabilities: []string{"SubgroupDispatch",}, + Parameters: []Parameter{{OperandKindIdRef, "'Subgroups Per Workgroup'"},}, + Version: "1.2", + }, + Enumerant{ + Enumerant: "LocalSizeId", + Value: 38, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindIdRef, "'x size'"},{OperandKindIdRef, "'y size'"},{OperandKindIdRef, "'z size'"},}, + Version: "1.2", + }, + Enumerant{ + Enumerant: "LocalSizeHintId", + Value: 39, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{{OperandKindIdRef, "'Local Size Hint'"},}, + Version: "1.2", + }, + Enumerant{ + Enumerant: "PostDepthCoverage", + Value: 4446, + Capabilities: []string{"SampleMaskPostDepthCoverage",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "DenormPreserve", + Value: 4459, + Capabilities: []string{"DenormPreserve",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Target Width'"},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "DenormFlushToZero", + Value: 4460, + Capabilities: []string{"DenormFlushToZero",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Target Width'"},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "SignedZeroInfNanPreserve", + Value: 4461, + Capabilities: []string{"SignedZeroInfNanPreserve",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Target Width'"},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "RoundingModeRTE", + Value: 4462, + Capabilities: []string{"RoundingModeRTE",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Target Width'"},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "RoundingModeRTZ", + Value: 4463, + Capabilities: []string{"RoundingModeRTZ",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Target Width'"},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "StencilRefReplacingEXT", + Value: 5027, + Capabilities: []string{"StencilExportEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "OutputLinesNV", + Value: 5269, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "OutputPrimitivesNV", + Value: 5270, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Primitive count'"},}, + Version: "None", + }, + Enumerant{ + Enumerant: "DerivativeGroupQuadsNV", + Value: 5289, + Capabilities: []string{"ComputeDerivativeGroupQuadsNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "DerivativeGroupLinearNV", + Value: 5290, + Capabilities: []string{"ComputeDerivativeGroupLinearNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "OutputTrianglesNV", + Value: 5298, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PixelInterlockOrderedEXT", + Value: 5366, + Capabilities: []string{"FragmentShaderPixelInterlockEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PixelInterlockUnorderedEXT", + Value: 5367, + Capabilities: []string{"FragmentShaderPixelInterlockEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SampleInterlockOrderedEXT", + Value: 5368, + Capabilities: []string{"FragmentShaderSampleInterlockEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SampleInterlockUnorderedEXT", + Value: 5369, + Capabilities: []string{"FragmentShaderSampleInterlockEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShadingRateInterlockOrderedEXT", + Value: 5370, + Capabilities: []string{"FragmentShaderShadingRateInterlockEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShadingRateInterlockUnorderedEXT", + Value: 5371, + Capabilities: []string{"FragmentShaderShadingRateInterlockEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindStorageClass = &OperandKind { + Kind: "StorageClass", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "UniformConstant", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Input", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Uniform", + Value: 2, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Output", + Value: 3, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Workgroup", + Value: 4, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CrossWorkgroup", + Value: 5, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Private", + Value: 6, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Function", + Value: 7, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Generic", + Value: 8, + Capabilities: []string{"GenericPointer",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PushConstant", + Value: 9, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "AtomicCounter", + Value: 10, + Capabilities: []string{"AtomicStorage",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Image", + Value: 11, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "StorageBuffer", + Value: 12, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "CallableDataNV", + Value: 5328, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "CallableDataKHR", + Value: 5328, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IncomingCallableDataNV", + Value: 5329, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IncomingCallableDataKHR", + Value: 5329, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayPayloadNV", + Value: 5338, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayPayloadKHR", + Value: 5338, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "HitAttributeNV", + Value: 5339, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "HitAttributeKHR", + Value: 5339, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IncomingRayPayloadNV", + Value: 5342, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IncomingRayPayloadKHR", + Value: 5342, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderRecordBufferNV", + Value: 5343, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderRecordBufferKHR", + Value: 5343, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PhysicalStorageBuffer", + Value: 5349, + Capabilities: []string{"PhysicalStorageBufferAddresses",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "PhysicalStorageBufferEXT", + Value: 5349, + Capabilities: []string{"PhysicalStorageBufferAddresses",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindDim = &OperandKind { + Kind: "Dim", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "1D", + Value: 0, + Capabilities: []string{"Sampled1D","Image1D",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "2D", + Value: 1, + Capabilities: []string{"Shader","Kernel","ImageMSArray",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "3D", + Value: 2, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Cube", + Value: 3, + Capabilities: []string{"Shader","ImageCubeArray",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rect", + Value: 4, + Capabilities: []string{"SampledRect","ImageRect",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Buffer", + Value: 5, + Capabilities: []string{"SampledBuffer","ImageBuffer",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SubpassData", + Value: 6, + Capabilities: []string{"InputAttachment",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindSamplerAddressingMode = &OperandKind { + Kind: "SamplerAddressingMode", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "None", + Value: 0, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ClampToEdge", + Value: 1, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Clamp", + Value: 2, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Repeat", + Value: 3, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RepeatMirrored", + Value: 4, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindSamplerFilterMode = &OperandKind { + Kind: "SamplerFilterMode", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Nearest", + Value: 0, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Linear", + Value: 1, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindImageFormat = &OperandKind { + Kind: "ImageFormat", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Unknown", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba32f", + Value: 1, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba16f", + Value: 2, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R32f", + Value: 3, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba8", + Value: 4, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba8Snorm", + Value: 5, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg32f", + Value: 6, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg16f", + Value: 7, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R11fG11fB10f", + Value: 8, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R16f", + Value: 9, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba16", + Value: 10, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgb10A2", + Value: 11, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg16", + Value: 12, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg8", + Value: 13, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R16", + Value: 14, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R8", + Value: 15, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba16Snorm", + Value: 16, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg16Snorm", + Value: 17, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg8Snorm", + Value: 18, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R16Snorm", + Value: 19, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R8Snorm", + Value: 20, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba32i", + Value: 21, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba16i", + Value: 22, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba8i", + Value: 23, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R32i", + Value: 24, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg32i", + Value: 25, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg16i", + Value: 26, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg8i", + Value: 27, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R16i", + Value: 28, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R8i", + Value: 29, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba32ui", + Value: 30, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba16ui", + Value: 31, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgba8ui", + Value: 32, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R32ui", + Value: 33, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rgb10a2ui", + Value: 34, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg32ui", + Value: 35, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg16ui", + Value: 36, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rg8ui", + Value: 37, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R16ui", + Value: 38, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "R8ui", + Value: 39, + Capabilities: []string{"StorageImageExtendedFormats",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindImageChannelOrder = &OperandKind { + Kind: "ImageChannelOrder", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "R", + Value: 0, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "A", + Value: 1, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RG", + Value: 2, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RA", + Value: 3, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RGB", + Value: 4, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RGBA", + Value: 5, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "BGRA", + Value: 6, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ARGB", + Value: 7, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Intensity", + Value: 8, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Luminance", + Value: 9, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Rx", + Value: 10, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RGx", + Value: 11, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RGBx", + Value: 12, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Depth", + Value: 13, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DepthStencil", + Value: 14, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "sRGB", + Value: 15, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "sRGBx", + Value: 16, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "sRGBA", + Value: 17, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "sBGRA", + Value: 18, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ABGR", + Value: 19, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindImageChannelDataType = &OperandKind { + Kind: "ImageChannelDataType", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "SnormInt8", + Value: 0, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SnormInt16", + Value: 1, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnormInt8", + Value: 2, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnormInt16", + Value: 3, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnormShort565", + Value: 4, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnormShort555", + Value: 5, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnormInt101010", + Value: 6, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SignedInt8", + Value: 7, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SignedInt16", + Value: 8, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SignedInt32", + Value: 9, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnsignedInt8", + Value: 10, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnsignedInt16", + Value: 11, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnsignedInt32", + Value: 12, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "HalfFloat", + Value: 13, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Float", + Value: 14, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnormInt24", + Value: 15, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnormInt101010_2", + Value: 16, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindFPRoundingMode = &OperandKind { + Kind: "FPRoundingMode", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "RTE", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RTZ", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RTP", + Value: 2, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RTN", + Value: 3, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindLinkageType = &OperandKind { + Kind: "LinkageType", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Export", + Value: 0, + Capabilities: []string{"Linkage",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Import", + Value: 1, + Capabilities: []string{"Linkage",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindAccessQualifier = &OperandKind { + Kind: "AccessQualifier", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "ReadOnly", + Value: 0, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "WriteOnly", + Value: 1, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ReadWrite", + Value: 2, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindFunctionParameterAttribute = &OperandKind { + Kind: "FunctionParameterAttribute", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Zext", + Value: 0, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Sext", + Value: 1, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ByVal", + Value: 2, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Sret", + Value: 3, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NoAlias", + Value: 4, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NoCapture", + Value: 5, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NoWrite", + Value: 6, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NoReadWrite", + Value: 7, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindDecoration = &OperandKind { + Kind: "Decoration", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "RelaxedPrecision", + Value: 0, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SpecId", + Value: 1, + Capabilities: []string{"Shader","Kernel",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Specialization Constant ID'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "Block", + Value: 2, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "BufferBlock", + Value: 3, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RowMajor", + Value: 4, + Capabilities: []string{"Matrix",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ColMajor", + Value: 5, + Capabilities: []string{"Matrix",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ArrayStride", + Value: 6, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Array Stride'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "MatrixStride", + Value: 7, + Capabilities: []string{"Matrix",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Matrix Stride'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "GLSLShared", + Value: 8, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GLSLPacked", + Value: 9, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CPacked", + Value: 10, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "BuiltIn", + Value: 11, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindBuiltIn, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "NoPerspective", + Value: 13, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Flat", + Value: 14, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Patch", + Value: 15, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Centroid", + Value: 16, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Sample", + Value: 17, + Capabilities: []string{"SampleRateShading",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Invariant", + Value: 18, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Restrict", + Value: 19, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Aliased", + Value: 20, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Volatile", + Value: 21, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Constant", + Value: 22, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Coherent", + Value: 23, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NonWritable", + Value: 24, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NonReadable", + Value: 25, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Uniform", + Value: 26, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UniformId", + Value: 27, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindIdScope, "'Execution'"},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "SaturatedConversion", + Value: 28, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Stream", + Value: 29, + Capabilities: []string{"GeometryStreams",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Stream Number'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "Location", + Value: 30, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Location'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "Component", + Value: 31, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Component'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "Index", + Value: 32, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Index'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "Binding", + Value: 33, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Binding Point'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "DescriptorSet", + Value: 34, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Descriptor Set'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "Offset", + Value: 35, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Byte Offset'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "XfbBuffer", + Value: 36, + Capabilities: []string{"TransformFeedback",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'XFB Buffer Number'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "XfbStride", + Value: 37, + Capabilities: []string{"TransformFeedback",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'XFB Stride'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "FuncParamAttr", + Value: 38, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{{OperandKindFunctionParameterAttribute, "'Function Parameter Attribute'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "FPRoundingMode", + Value: 39, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindFPRoundingMode, "'Floating-Point Rounding Mode'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "FPFastMathMode", + Value: 40, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{{OperandKindFPFastMathMode, "'Fast-Math Mode'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "LinkageAttributes", + Value: 41, + Capabilities: []string{"Linkage",}, + Parameters: []Parameter{{OperandKindLiteralString, "'Name'"},{OperandKindLinkageType, "'Linkage Type'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "NoContraction", + Value: 42, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InputAttachmentIndex", + Value: 43, + Capabilities: []string{"InputAttachment",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Attachment Index'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "Alignment", + Value: 44, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Alignment'"},}, + Version: "", + }, + Enumerant{ + Enumerant: "MaxByteOffset", + Value: 45, + Capabilities: []string{"Addresses",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Max Byte Offset'"},}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "AlignmentId", + Value: 46, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{{OperandKindIdRef, "'Alignment'"},}, + Version: "1.2", + }, + Enumerant{ + Enumerant: "MaxByteOffsetId", + Value: 47, + Capabilities: []string{"Addresses",}, + Parameters: []Parameter{{OperandKindIdRef, "'Max Byte Offset'"},}, + Version: "1.2", + }, + Enumerant{ + Enumerant: "NoSignedWrap", + Value: 4469, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "NoUnsignedWrap", + Value: 4470, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "ExplicitInterpAMD", + Value: 4999, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "OverrideCoverageNV", + Value: 5248, + Capabilities: []string{"SampleMaskOverrideCoverageNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PassthroughNV", + Value: 5250, + Capabilities: []string{"GeometryShaderPassthroughNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ViewportRelativeNV", + Value: 5252, + Capabilities: []string{"ShaderViewportMaskNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SecondaryViewportRelativeNV", + Value: 5256, + Capabilities: []string{"ShaderStereoViewNV",}, + Parameters: []Parameter{{OperandKindLiteralInteger, "'Offset'"},}, + Version: "None", + }, + Enumerant{ + Enumerant: "PerPrimitiveNV", + Value: 5271, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PerViewNV", + Value: 5272, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PerTaskNV", + Value: 5273, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PerVertexNV", + Value: 5285, + Capabilities: []string{"FragmentBarycentricNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "NonUniform", + Value: 5300, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "NonUniformEXT", + Value: 5300, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "RestrictPointer", + Value: 5355, + Capabilities: []string{"PhysicalStorageBufferAddresses",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "RestrictPointerEXT", + Value: 5355, + Capabilities: []string{"PhysicalStorageBufferAddresses",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "AliasedPointer", + Value: 5356, + Capabilities: []string{"PhysicalStorageBufferAddresses",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "AliasedPointerEXT", + Value: 5356, + Capabilities: []string{"PhysicalStorageBufferAddresses",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "CounterBuffer", + Value: 5634, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindIdRef, "'Counter Buffer'"},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "HlslCounterBufferGOOGLE", + Value: 5634, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindIdRef, "'Counter Buffer'"},}, + Version: "None", + }, + Enumerant{ + Enumerant: "UserSemantic", + Value: 5635, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralString, "'Semantic'"},}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "HlslSemanticGOOGLE", + Value: 5635, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralString, "'Semantic'"},}, + Version: "None", + }, + Enumerant{ + Enumerant: "UserTypeGOOGLE", + Value: 5636, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralString, "'User Type'"},}, + Version: "None", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindBuiltIn = &OperandKind { + Kind: "BuiltIn", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Position", + Value: 0, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PointSize", + Value: 1, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ClipDistance", + Value: 3, + Capabilities: []string{"ClipDistance",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CullDistance", + Value: 4, + Capabilities: []string{"CullDistance",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "VertexId", + Value: 5, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InstanceId", + Value: 6, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PrimitiveId", + Value: 7, + Capabilities: []string{"Geometry","Tessellation","RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InvocationId", + Value: 8, + Capabilities: []string{"Geometry","Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Layer", + Value: 9, + Capabilities: []string{"Geometry","ShaderLayer","ShaderViewportIndexLayerEXT",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ViewportIndex", + Value: 10, + Capabilities: []string{"MultiViewport","ShaderViewportIndex","ShaderViewportIndexLayerEXT",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TessLevelOuter", + Value: 11, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TessLevelInner", + Value: 12, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TessCoord", + Value: 13, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PatchVertices", + Value: 14, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FragCoord", + Value: 15, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PointCoord", + Value: 16, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FrontFacing", + Value: 17, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SampleId", + Value: 18, + Capabilities: []string{"SampleRateShading",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SamplePosition", + Value: 19, + Capabilities: []string{"SampleRateShading",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SampleMask", + Value: 20, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FragDepth", + Value: 22, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "HelperInvocation", + Value: 23, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NumWorkgroups", + Value: 24, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "WorkgroupSize", + Value: 25, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "WorkgroupId", + Value: 26, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "LocalInvocationId", + Value: 27, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GlobalInvocationId", + Value: 28, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "LocalInvocationIndex", + Value: 29, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "WorkDim", + Value: 30, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GlobalSize", + Value: 31, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "EnqueuedWorkgroupSize", + Value: 32, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GlobalOffset", + Value: 33, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GlobalLinearId", + Value: 34, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SubgroupSize", + Value: 36, + Capabilities: []string{"Kernel","GroupNonUniform","SubgroupBallotKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SubgroupMaxSize", + Value: 37, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NumSubgroups", + Value: 38, + Capabilities: []string{"Kernel","GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "NumEnqueuedSubgroups", + Value: 39, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SubgroupId", + Value: 40, + Capabilities: []string{"Kernel","GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SubgroupLocalInvocationId", + Value: 41, + Capabilities: []string{"Kernel","GroupNonUniform","SubgroupBallotKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "VertexIndex", + Value: 42, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InstanceIndex", + Value: 43, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SubgroupEqMask", + Value: 4416, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupGeMask", + Value: 4417, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupGtMask", + Value: 4418, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupLeMask", + Value: 4419, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupLtMask", + Value: 4420, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupEqMaskKHR", + Value: 4416, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupGeMaskKHR", + Value: 4417, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupGtMaskKHR", + Value: 4418, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupLeMaskKHR", + Value: 4419, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupLtMaskKHR", + Value: 4420, + Capabilities: []string{"SubgroupBallotKHR","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "BaseVertex", + Value: 4424, + Capabilities: []string{"DrawParameters",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "BaseInstance", + Value: 4425, + Capabilities: []string{"DrawParameters",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "DrawIndex", + Value: 4426, + Capabilities: []string{"DrawParameters","MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "DeviceIndex", + Value: 4438, + Capabilities: []string{"DeviceGroup",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "ViewIndex", + Value: 4440, + Capabilities: []string{"MultiView",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "BaryCoordNoPerspAMD", + Value: 4992, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "BaryCoordNoPerspCentroidAMD", + Value: 4993, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "BaryCoordNoPerspSampleAMD", + Value: 4994, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "BaryCoordSmoothAMD", + Value: 4995, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "BaryCoordSmoothCentroidAMD", + Value: 4996, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "BaryCoordSmoothSampleAMD", + Value: 4997, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "BaryCoordPullModelAMD", + Value: 4998, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragStencilRefEXT", + Value: 5014, + Capabilities: []string{"StencilExportEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ViewportMaskNV", + Value: 5253, + Capabilities: []string{"ShaderViewportMaskNV","MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SecondaryPositionNV", + Value: 5257, + Capabilities: []string{"ShaderStereoViewNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SecondaryViewportMaskNV", + Value: 5258, + Capabilities: []string{"ShaderStereoViewNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PositionPerViewNV", + Value: 5261, + Capabilities: []string{"PerViewAttributesNV","MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ViewportMaskPerViewNV", + Value: 5262, + Capabilities: []string{"PerViewAttributesNV","MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FullyCoveredEXT", + Value: 5264, + Capabilities: []string{"FragmentFullyCoveredEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "TaskCountNV", + Value: 5274, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PrimitiveCountNV", + Value: 5275, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PrimitiveIndicesNV", + Value: 5276, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ClipDistancePerViewNV", + Value: 5277, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "CullDistancePerViewNV", + Value: 5278, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "LayerPerViewNV", + Value: 5279, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "MeshViewCountNV", + Value: 5280, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "MeshViewIndicesNV", + Value: 5281, + Capabilities: []string{"MeshShadingNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "BaryCoordNV", + Value: 5286, + Capabilities: []string{"FragmentBarycentricNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "BaryCoordNoPerspNV", + Value: 5287, + Capabilities: []string{"FragmentBarycentricNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragSizeEXT", + Value: 5292, + Capabilities: []string{"FragmentDensityEXT","ShadingRateNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragmentSizeNV", + Value: 5292, + Capabilities: []string{"ShadingRateNV","FragmentDensityEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragInvocationCountEXT", + Value: 5293, + Capabilities: []string{"FragmentDensityEXT","ShadingRateNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "InvocationsPerPixelNV", + Value: 5293, + Capabilities: []string{"ShadingRateNV","FragmentDensityEXT",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "LaunchIdNV", + Value: 5319, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "LaunchIdKHR", + Value: 5319, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "LaunchSizeNV", + Value: 5320, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "LaunchSizeKHR", + Value: 5320, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "WorldRayOriginNV", + Value: 5321, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "WorldRayOriginKHR", + Value: 5321, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "WorldRayDirectionNV", + Value: 5322, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "WorldRayDirectionKHR", + Value: 5322, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ObjectRayOriginNV", + Value: 5323, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ObjectRayOriginKHR", + Value: 5323, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ObjectRayDirectionNV", + Value: 5324, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ObjectRayDirectionKHR", + Value: 5324, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayTminNV", + Value: 5325, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayTminKHR", + Value: 5325, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayTmaxNV", + Value: 5326, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayTmaxKHR", + Value: 5326, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "InstanceCustomIndexNV", + Value: 5327, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "InstanceCustomIndexKHR", + Value: 5327, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ObjectToWorldNV", + Value: 5330, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ObjectToWorldKHR", + Value: 5330, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "WorldToObjectNV", + Value: 5331, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "WorldToObjectKHR", + Value: 5331, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "HitTNV", + Value: 5332, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "HitTKHR", + Value: 5332, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "HitKindNV", + Value: 5333, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "HitKindKHR", + Value: 5333, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IncomingRayFlagsNV", + Value: 5351, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IncomingRayFlagsKHR", + Value: 5351, + Capabilities: []string{"RayTracingNV","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayGeometryIndexKHR", + Value: 5352, + Capabilities: []string{"RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "WarpsPerSMNV", + Value: 5374, + Capabilities: []string{"ShaderSMBuiltinsNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SMCountNV", + Value: 5375, + Capabilities: []string{"ShaderSMBuiltinsNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "WarpIDNV", + Value: 5376, + Capabilities: []string{"ShaderSMBuiltinsNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SMIDNV", + Value: 5377, + Capabilities: []string{"ShaderSMBuiltinsNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindScope = &OperandKind { + Kind: "Scope", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "CrossDevice", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Device", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Workgroup", + Value: 2, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Subgroup", + Value: 3, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Invocation", + Value: 4, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "QueueFamily", + Value: 5, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "QueueFamilyKHR", + Value: 5, + Capabilities: []string{"VulkanMemoryModel",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "ShaderCallKHR", + Value: 6, + Capabilities: []string{"RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindGroupOperation = &OperandKind { + Kind: "GroupOperation", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Reduce", + Value: 0, + Capabilities: []string{"Kernel","GroupNonUniformArithmetic","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InclusiveScan", + Value: 1, + Capabilities: []string{"Kernel","GroupNonUniformArithmetic","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ExclusiveScan", + Value: 2, + Capabilities: []string{"Kernel","GroupNonUniformArithmetic","GroupNonUniformBallot",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ClusteredReduce", + Value: 3, + Capabilities: []string{"GroupNonUniformClustered",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "PartitionedReduceNV", + Value: 6, + Capabilities: []string{"GroupNonUniformPartitionedNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PartitionedInclusiveScanNV", + Value: 7, + Capabilities: []string{"GroupNonUniformPartitionedNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PartitionedExclusiveScanNV", + Value: 8, + Capabilities: []string{"GroupNonUniformPartitionedNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindKernelEnqueueFlags = &OperandKind { + Kind: "KernelEnqueueFlags", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "NoWait", + Value: 0, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "WaitKernel", + Value: 1, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "WaitWorkGroup", + Value: 2, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindCapability = &OperandKind { + Kind: "Capability", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Matrix", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Shader", + Value: 1, + Capabilities: []string{"Matrix",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Geometry", + Value: 2, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Tessellation", + Value: 3, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Addresses", + Value: 4, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Linkage", + Value: 5, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Kernel", + Value: 6, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Vector16", + Value: 7, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Float16Buffer", + Value: 8, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Float16", + Value: 9, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Float64", + Value: 10, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Int64", + Value: 11, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Int64Atomics", + Value: 12, + Capabilities: []string{"Int64",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageBasic", + Value: 13, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageReadWrite", + Value: 14, + Capabilities: []string{"ImageBasic",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageMipmap", + Value: 15, + Capabilities: []string{"ImageBasic",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Pipes", + Value: 17, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Groups", + Value: 18, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DeviceEnqueue", + Value: 19, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "LiteralSampler", + Value: 20, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "AtomicStorage", + Value: 21, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Int16", + Value: 22, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TessellationPointSize", + Value: 23, + Capabilities: []string{"Tessellation",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GeometryPointSize", + Value: 24, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageGatherExtended", + Value: 25, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "StorageImageMultisample", + Value: 27, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UniformBufferArrayDynamicIndexing", + Value: 28, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SampledImageArrayDynamicIndexing", + Value: 29, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "StorageBufferArrayDynamicIndexing", + Value: 30, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "StorageImageArrayDynamicIndexing", + Value: 31, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ClipDistance", + Value: 32, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "CullDistance", + Value: 33, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageCubeArray", + Value: 34, + Capabilities: []string{"SampledCubeArray",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SampleRateShading", + Value: 35, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageRect", + Value: 36, + Capabilities: []string{"SampledRect",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SampledRect", + Value: 37, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GenericPointer", + Value: 38, + Capabilities: []string{"Addresses",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Int8", + Value: 39, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InputAttachment", + Value: 40, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SparseResidency", + Value: 41, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "MinLod", + Value: 42, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Sampled1D", + Value: 43, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Image1D", + Value: 44, + Capabilities: []string{"Sampled1D",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SampledCubeArray", + Value: 45, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SampledBuffer", + Value: 46, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageBuffer", + Value: 47, + Capabilities: []string{"SampledBuffer",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageMSArray", + Value: 48, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "StorageImageExtendedFormats", + Value: 49, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImageQuery", + Value: 50, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "DerivativeControl", + Value: 51, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "InterpolationFunction", + Value: 52, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "TransformFeedback", + Value: 53, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "GeometryStreams", + Value: 54, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "StorageImageReadWithoutFormat", + Value: 55, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "StorageImageWriteWithoutFormat", + Value: 56, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "MultiViewport", + Value: 57, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SubgroupDispatch", + Value: 58, + Capabilities: []string{"DeviceEnqueue",}, + Parameters: []Parameter{}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "NamedBarrier", + Value: 59, + Capabilities: []string{"Kernel",}, + Parameters: []Parameter{}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "PipeStorage", + Value: 60, + Capabilities: []string{"Pipes",}, + Parameters: []Parameter{}, + Version: "1.1", + }, + Enumerant{ + Enumerant: "GroupNonUniform", + Value: 61, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "GroupNonUniformVote", + Value: 62, + Capabilities: []string{"GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "GroupNonUniformArithmetic", + Value: 63, + Capabilities: []string{"GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "GroupNonUniformBallot", + Value: 64, + Capabilities: []string{"GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "GroupNonUniformShuffle", + Value: 65, + Capabilities: []string{"GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "GroupNonUniformShuffleRelative", + Value: 66, + Capabilities: []string{"GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "GroupNonUniformClustered", + Value: 67, + Capabilities: []string{"GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "GroupNonUniformQuad", + Value: 68, + Capabilities: []string{"GroupNonUniform",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "ShaderLayer", + Value: 69, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "ShaderViewportIndex", + Value: 70, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "SubgroupBallotKHR", + Value: 4423, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "DrawParameters", + Value: 4427, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "SubgroupVoteKHR", + Value: 4431, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "StorageBuffer16BitAccess", + Value: 4433, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "StorageUniformBufferBlock16", + Value: 4433, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "UniformAndStorageBuffer16BitAccess", + Value: 4434, + Capabilities: []string{"StorageBuffer16BitAccess","StorageUniformBufferBlock16",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "StorageUniform16", + Value: 4434, + Capabilities: []string{"StorageBuffer16BitAccess","StorageUniformBufferBlock16",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "StoragePushConstant16", + Value: 4435, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "StorageInputOutput16", + Value: 4436, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "DeviceGroup", + Value: 4437, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "MultiView", + Value: 4439, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "VariablePointersStorageBuffer", + Value: 4441, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "VariablePointers", + Value: 4442, + Capabilities: []string{"VariablePointersStorageBuffer",}, + Parameters: []Parameter{}, + Version: "1.3", + }, + Enumerant{ + Enumerant: "AtomicStorageOps", + Value: 4445, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SampleMaskPostDepthCoverage", + Value: 4447, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "StorageBuffer8BitAccess", + Value: 4448, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "UniformAndStorageBuffer8BitAccess", + Value: 4449, + Capabilities: []string{"StorageBuffer8BitAccess",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StoragePushConstant8", + Value: 4450, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "DenormPreserve", + Value: 4464, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "DenormFlushToZero", + Value: 4465, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "SignedZeroInfNanPreserve", + Value: 4466, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "RoundingModeRTE", + Value: 4467, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "RoundingModeRTZ", + Value: 4468, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.4", + }, + Enumerant{ + Enumerant: "RayQueryProvisionalKHR", + Value: 4471, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayTraversalPrimitiveCullingProvisionalKHR", + Value: 4478, + Capabilities: []string{"RayQueryProvisionalKHR","RayTracingProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "Float16ImageAMD", + Value: 5008, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ImageGatherBiasLodAMD", + Value: 5009, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragmentMaskAMD", + Value: 5010, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "StencilExportEXT", + Value: 5013, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ImageReadWriteLodAMD", + Value: 5015, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderClockKHR", + Value: 5055, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SampleMaskOverrideCoverageNV", + Value: 5249, + Capabilities: []string{"SampleRateShading",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "GeometryShaderPassthroughNV", + Value: 5251, + Capabilities: []string{"Geometry",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderViewportIndexLayerEXT", + Value: 5254, + Capabilities: []string{"MultiViewport",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderViewportIndexLayerNV", + Value: 5254, + Capabilities: []string{"MultiViewport",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderViewportMaskNV", + Value: 5255, + Capabilities: []string{"ShaderViewportIndexLayerNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderStereoViewNV", + Value: 5259, + Capabilities: []string{"ShaderViewportMaskNV",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "PerViewAttributesNV", + Value: 5260, + Capabilities: []string{"MultiView",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragmentFullyCoveredEXT", + Value: 5265, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "MeshShadingNV", + Value: 5266, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ImageFootprintNV", + Value: 5282, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragmentBarycentricNV", + Value: 5284, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ComputeDerivativeGroupQuadsNV", + Value: 5288, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragmentDensityEXT", + Value: 5291, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShadingRateNV", + Value: 5291, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "GroupNonUniformPartitionedNV", + Value: 5297, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderNonUniform", + Value: 5301, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "ShaderNonUniformEXT", + Value: 5301, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "RuntimeDescriptorArray", + Value: 5302, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "RuntimeDescriptorArrayEXT", + Value: 5302, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "InputAttachmentArrayDynamicIndexing", + Value: 5303, + Capabilities: []string{"InputAttachment",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "InputAttachmentArrayDynamicIndexingEXT", + Value: 5303, + Capabilities: []string{"InputAttachment",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "UniformTexelBufferArrayDynamicIndexing", + Value: 5304, + Capabilities: []string{"SampledBuffer",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "UniformTexelBufferArrayDynamicIndexingEXT", + Value: 5304, + Capabilities: []string{"SampledBuffer",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StorageTexelBufferArrayDynamicIndexing", + Value: 5305, + Capabilities: []string{"ImageBuffer",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StorageTexelBufferArrayDynamicIndexingEXT", + Value: 5305, + Capabilities: []string{"ImageBuffer",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "UniformBufferArrayNonUniformIndexing", + Value: 5306, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "UniformBufferArrayNonUniformIndexingEXT", + Value: 5306, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "SampledImageArrayNonUniformIndexing", + Value: 5307, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "SampledImageArrayNonUniformIndexingEXT", + Value: 5307, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StorageBufferArrayNonUniformIndexing", + Value: 5308, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StorageBufferArrayNonUniformIndexingEXT", + Value: 5308, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StorageImageArrayNonUniformIndexing", + Value: 5309, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StorageImageArrayNonUniformIndexingEXT", + Value: 5309, + Capabilities: []string{"ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "InputAttachmentArrayNonUniformIndexing", + Value: 5310, + Capabilities: []string{"InputAttachment","ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "InputAttachmentArrayNonUniformIndexingEXT", + Value: 5310, + Capabilities: []string{"InputAttachment","ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "UniformTexelBufferArrayNonUniformIndexing", + Value: 5311, + Capabilities: []string{"SampledBuffer","ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "UniformTexelBufferArrayNonUniformIndexingEXT", + Value: 5311, + Capabilities: []string{"SampledBuffer","ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StorageTexelBufferArrayNonUniformIndexing", + Value: 5312, + Capabilities: []string{"ImageBuffer","ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "StorageTexelBufferArrayNonUniformIndexingEXT", + Value: 5312, + Capabilities: []string{"ImageBuffer","ShaderNonUniform",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "RayTracingNV", + Value: 5340, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "VulkanMemoryModel", + Value: 5345, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "VulkanMemoryModelKHR", + Value: 5345, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "VulkanMemoryModelDeviceScope", + Value: 5346, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "VulkanMemoryModelDeviceScopeKHR", + Value: 5346, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "PhysicalStorageBufferAddresses", + Value: 5347, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "PhysicalStorageBufferAddressesEXT", + Value: 5347, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "1.5", + }, + Enumerant{ + Enumerant: "ComputeDerivativeGroupLinearNV", + Value: 5350, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "RayTracingProvisionalKHR", + Value: 5353, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "CooperativeMatrixNV", + Value: 5357, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragmentShaderSampleInterlockEXT", + Value: 5363, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragmentShaderShadingRateInterlockEXT", + Value: 5372, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "ShaderSMBuiltinsNV", + Value: 5373, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "FragmentShaderPixelInterlockEXT", + Value: 5378, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "DemoteToHelperInvocationEXT", + Value: 5379, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SubgroupShuffleINTEL", + Value: 5568, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SubgroupBufferBlockIOINTEL", + Value: 5569, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SubgroupImageBlockIOINTEL", + Value: 5570, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SubgroupImageMediaBlockIOINTEL", + Value: 5579, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "IntegerFunctions2INTEL", + Value: 5584, + Capabilities: []string{"Shader",}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SubgroupAvcMotionEstimationINTEL", + Value: 5696, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SubgroupAvcMotionEstimationIntraINTEL", + Value: 5697, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + Enumerant{ + Enumerant: "SubgroupAvcMotionEstimationChromaINTEL", + Value: 5698, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "None", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindRayQueryIntersection = &OperandKind { + Kind: "RayQueryIntersection", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "RayQueryCandidateIntersectionKHR", + Value: 0, + Capabilities: []string{"RayQueryProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RayQueryCommittedIntersectionKHR", + Value: 1, + Capabilities: []string{"RayQueryProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindRayQueryCommittedIntersectionType = &OperandKind { + Kind: "RayQueryCommittedIntersectionType", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "RayQueryCommittedIntersectionNoneKHR", + Value: 0, + Capabilities: []string{"RayQueryProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RayQueryCommittedIntersectionTriangleKHR", + Value: 1, + Capabilities: []string{"RayQueryProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RayQueryCommittedIntersectionGeneratedKHR", + Value: 2, + Capabilities: []string{"RayQueryProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindRayQueryCandidateIntersectionType = &OperandKind { + Kind: "RayQueryCandidateIntersectionType", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "RayQueryCandidateIntersectionTriangleKHR", + Value: 0, + Capabilities: []string{"RayQueryProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RayQueryCandidateIntersectionAABBKHR", + Value: 1, + Capabilities: []string{"RayQueryProvisionalKHR",}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindIdResultType = &OperandKind { + Kind: "IdResultType", + Category: "Id", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindIdResult = &OperandKind { + Kind: "IdResult", + Category: "Id", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindIdMemorySemantics = &OperandKind { + Kind: "IdMemorySemantics", + Category: "Id", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindIdScope = &OperandKind { + Kind: "IdScope", + Category: "Id", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindIdRef = &OperandKind { + Kind: "IdRef", + Category: "Id", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindLiteralInteger = &OperandKind { + Kind: "LiteralInteger", + Category: "Literal", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindLiteralString = &OperandKind { + Kind: "LiteralString", + Category: "Literal", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindLiteralContextDependentNumber = &OperandKind { + Kind: "LiteralContextDependentNumber", + Category: "Literal", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindLiteralExtInstInteger = &OperandKind { + Kind: "LiteralExtInstInteger", + Category: "Literal", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindLiteralSpecConstantOpInteger = &OperandKind { + Kind: "LiteralSpecConstantOpInteger", + Category: "Literal", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {}, + } + OperandKindPairLiteralIntegerIdRef = &OperandKind { + Kind: "PairLiteralIntegerIdRef", + Category: "Composite", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {OperandKindLiteralInteger,OperandKindIdRef,}, + } + OperandKindPairIdRefLiteralInteger = &OperandKind { + Kind: "PairIdRefLiteralInteger", + Category: "Composite", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {OperandKindIdRef,OperandKindLiteralInteger,}, + } + OperandKindPairIdRefIdRef = &OperandKind { + Kind: "PairIdRefIdRef", + Category: "Composite", + Enumerants: []Enumerant { + }, + Bases: []*OperandKind {OperandKindIdRef,OperandKindIdRef,}, + } + OperandKindDebugInfoFlags = &OperandKind { + Kind: "DebugInfoFlags", + Category: "BitEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "FlagIsProtected", + Value: 0x01, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagIsPrivate", + Value: 0x02, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagIsPublic", + Value: 0x03, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagIsLocal", + Value: 0x04, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagIsDefinition", + Value: 0x08, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagFwdDecl", + Value: 0x10, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagArtificial", + Value: 0x20, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagExplicit", + Value: 0x40, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagPrototyped", + Value: 0x80, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagObjectPointer", + Value: 0x100, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagStaticMember", + Value: 0x200, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagIndirectVariable", + Value: 0x400, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagLValueReference", + Value: 0x800, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagRValueReference", + Value: 0x1000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagIsOptimized", + Value: 0x2000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagIsEnumClass", + Value: 0x4000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagTypePassByValue", + Value: 0x8000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "FlagTypePassByReference", + Value: 0x10000, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindDebugBaseTypeAttributeEncoding = &OperandKind { + Kind: "DebugBaseTypeAttributeEncoding", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Unspecified", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Address", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Boolean", + Value: 2, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Float", + Value: 3, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Signed", + Value: 4, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "SignedChar", + Value: 5, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Unsigned", + Value: 6, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "UnsignedChar", + Value: 7, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindDebugCompositeType = &OperandKind { + Kind: "DebugCompositeType", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Class", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Structure", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Union", + Value: 2, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindDebugTypeQualifier = &OperandKind { + Kind: "DebugTypeQualifier", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "ConstType", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "VolatileType", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "RestrictType", + Value: 2, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "AtomicType", + Value: 3, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindDebugOperation = &OperandKind { + Kind: "DebugOperation", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "Deref", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Plus", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Minus", + Value: 2, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "PlusUconst", + Value: 3, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "BitPiece", + Value: 4, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},{OperandKindLiteralInteger, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "Swap", + Value: 5, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Xderef", + Value: 6, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "StackValue", + Value: 7, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "Constu", + Value: 8, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},}, + Version: "", + }, + Enumerant{ + Enumerant: "Fragment", + Value: 9, + Capabilities: []string{}, + Parameters: []Parameter{{OperandKindLiteralInteger, ""},{OperandKindLiteralInteger, ""},}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + OperandKindDebugImportedEntity = &OperandKind { + Kind: "DebugImportedEntity", + Category: "ValueEnum", + Enumerants: []Enumerant { + Enumerant{ + Enumerant: "ImportedModule", + Value: 0, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + Enumerant{ + Enumerant: "ImportedDeclaration", + Value: 1, + Capabilities: []string{}, + Parameters: []Parameter{}, + Version: "", + }, + }, + Bases: []*OperandKind {}, + } + +) diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/schema/schema.go.tmpl b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/schema/schema.go.tmpl new file mode 100644 index 000000000000..987fcd0627f3 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/schema/schema.go.tmpl @@ -0,0 +1,156 @@ +// Copyright (C) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Generated by {{GenerateArguments}} +// Do not modify this file directly. + +package schema + +// Opcode holds information about a specific SPIR-V opcode. +type Opcode struct { + Opname string + Class string + Opcode int + Operands []Operand +} + +// Operand contains information about a logical operand for an instruction. +type Operand struct { + Kind *OperandKind + Name string + Quantifier Quantifier +} + +// OperandKind contains information about a specific operand kind. +type OperandKind struct { + Category OperandCategory + Kind string + Enumerants []Enumerant + Bases []*OperandKind +} + +// Enumerant contains information about an enumerant in an enum. +type Enumerant struct { + Enumerant string + Value interface{} + Capabilities []string + Parameters []Parameter + Version string +} + +// Parameter contains information about a logical parameter for an enumerant. +type Parameter struct { + Kind *OperandKind + Name string +} + +// Quantifier indicates the number of times the quantified term may appear. +type Quantifier string + +const ( + // Once indicates the quantified term may appear exactly once. + Once Quantifier = "" + + // ZeroOrOnce indicates the quantified term may appear zero or one + // time; an optional term. + ZeroOrOnce Quantifier = "?" + + // ZeroOrMany indicates the quantified term may appear any number of + // times. + ZeroOrMany Quantifier = "*" +) + +// OperandCategory is an enumerator that groups operand kinds. +type OperandCategory string + +const ( + // OperandCategoryBitEnum describes an operand kind where its value is a + // mask, which is formed by combining the bits specified as enumerants in an + // enum. + OperandCategoryBitEnum = "BitEnum" + + // OperandCategoryValueEnum describes an operand kind where its value is an + // enumerant from an enum. + OperandCategoryValueEnum = "ValueEnum" + + // OperandCategoryID describes and operand kind where its value is an + // definition or reference. + OperandCategoryID = "Id" + + // OperandCategoryLiteral describes and operand kind where its value is an + // literal number or string. + OperandCategoryLiteral = "Literal" + + // OperandCategoryComposite describes and operand kind where its value is + // composed from operand values from the above categories. + OperandCategoryComposite = "Composite" +) + +// OpcodeMap is a map of opcode name to Opcode type. +type OpcodeMap map[string]*Opcode + +var ( + // Opcodes is a map of opcode name to Opcode description. + Opcodes = OpcodeMap {•{{range $i := .SPIRV.Instructions}} + "{{$i.Opname}}": {{Title $i.Opname}},{{end}} + } + + // ExtOpcodes is a map of extension name to Opcode description list. + ExtOpcodes = map[string]OpcodeMap {•{{range $ext := .Extensions}} + "{{$ext.Name}}": {•{{range $i := $ext.Instructions}} + "{{$i.Opname}}": {{Global $ext.Name}}_{{$i.Opname}},{{end}} + },{{end}} + } + +{{range $i := .SPIRV.Instructions}} {{Title $i.Opname}} = &Opcode { + Opname: "{{$i.Opname}}", + Class: "{{$i.Class}}", + Opcode: {{$i.Opcode}}, + Operands: []Operand {•{{range $i := $i.Operands}} + Operand { + Kind: OperandKind{{$i.Kind}}, + Name: "{{Replace $i.Name "\n" " "}}", + Quantifier: "{{$i.Quantifier}}", + }, {{end}} + }, + } +{{end}} +{{range $ext := .Extensions}}{{range $i := $ext.Instructions}} {{Global $ext.Name}}_{{$i.Opname}} = &Opcode { + Opname: "{{$i.Opname}}", + Operands: []Operand {•{{range $i := $i.Operands}} + Operand { + Kind: OperandKind{{$i.Kind}}, + Name: "{{Replace $i.Name "\n" " "}}", + Quantifier: "{{$i.Quantifier}}", + }, {{end}} + }, + } +{{end}}{{end}} + +{{range $o := .All.OperandKinds}} OperandKind{{$o.Kind}} = &OperandKind { + Kind: "{{$o.Kind}}", + Category: "{{$o.Category}}", + Enumerants: []Enumerant {•{{range $e := $o.Enumerants}} + Enumerant{ + Enumerant: "{{$e.Enumerant}}", + Value: {{$e.Value}}, + Capabilities: []string{•{{range $c := $e.Capabilities}}"{{$c}}",{{end}}•}, + Parameters: []Parameter{•{{range $p := $e.Parameters}}{•OperandKind{{$p.Kind}}, "{{$p.Name}}"•},{{end}}•}, + Version: "{{$e.Version}}", + },{{end}} + }, + Bases: []*OperandKind {•{{range $b := $o.Bases}}OperandKind{{$b}},{{end}}•}, + } +{{end}} +) diff --git a/thirdparty/glslang/External/spirv-tools/utils/vscode/src/tools/gen-grammar.go b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/tools/gen-grammar.go new file mode 100644 index 000000000000..a1289ef9c928 --- /dev/null +++ b/thirdparty/glslang/External/spirv-tools/utils/vscode/src/tools/gen-grammar.go @@ -0,0 +1,239 @@ +// Copyright (C) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// gen-grammar generates the spirv.json grammar file from the official SPIR-V +// grammar JSON file. +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "runtime" + "strings" + "text/template" + + "github.com/pkg/errors" + + "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/grammar" +) + +type grammarDefinition struct { + name string + url string +} + +var ( + spirvGrammar = grammarDefinition{ + name: "SPIR-V", + url: "https://raw.githubusercontent.com/KhronosGroup/SPIRV-Headers/master/include/spirv/unified1/spirv.core.grammar.json", + } + + extensionGrammars = []grammarDefinition{ + { + name: "GLSL.std.450", + url: "https://raw.githubusercontent.com/KhronosGroup/SPIRV-Headers/master/include/spirv/unified1/extinst.glsl.std.450.grammar.json", + }, { + name: "OpenCL.std", + url: "https://raw.githubusercontent.com/KhronosGroup/SPIRV-Headers/master/include/spirv/unified1/extinst.opencl.std.100.grammar.json", + }, { + name: "OpenCL.DebugInfo.100", + url: "https://raw.githubusercontent.com/KhronosGroup/SPIRV-Headers/master/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json", + }, + } + + templatePath = flag.String("template", "", "Path to input template file (required)") + outputPath = flag.String("out", "", "Path to output generated file (required)") + cachePath = flag.String("cache", "", "Cache directory for downloaded files (optional)") + + thisDir = func() string { + _, file, _, _ := runtime.Caller(1) + return filepath.Dir(file) + }() +) + +func main() { + flag.Parse() + if *templatePath == "" || *outputPath == "" { + flag.Usage() + os.Exit(1) + } + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func run() error { + tf, err := ioutil.ReadFile(*templatePath) + if err != nil { + return errors.Wrap(err, "Could not open template file") + } + + type extension struct { + grammar.Root + Name string + } + + args := struct { + SPIRV grammar.Root + Extensions []extension + All grammar.Root // Combination of SPIRV + Extensions + }{} + + if args.SPIRV, err = parseGrammar(spirvGrammar); err != nil { + return errors.Wrap(err, "Failed to parse SPIR-V grammar file") + } + args.All.Instructions = append(args.All.Instructions, args.SPIRV.Instructions...) + args.All.OperandKinds = append(args.All.OperandKinds, args.SPIRV.OperandKinds...) + + for _, ext := range extensionGrammars { + root, err := parseGrammar(ext) + if err != nil { + return errors.Wrap(err, "Failed to parse extension grammar file: "+ext.name) + } + args.Extensions = append(args.Extensions, extension{Root: root, Name: ext.name}) + args.All.Instructions = append(args.All.Instructions, root.Instructions...) + args.All.OperandKinds = append(args.All.OperandKinds, root.OperandKinds...) + } + + t, err := template.New("tmpl"). + Funcs(template.FuncMap{ + "GenerateArguments": func() string { + relPath := func(path string) string { + rel, err := filepath.Rel(thisDir, path) + if err != nil { + return path + } + return rel + } + escape := func(str string) string { + return strings.ReplaceAll(str, `\`, `/`) + } + args := []string{ + "--template=" + escape(relPath(*templatePath)), + "--out=" + escape(relPath(*outputPath)), + } + return "gen-grammar.go " + strings.Join(args, " ") + }, + "OperandKindsMatch": func(k grammar.OperandKind) string { + sb := strings.Builder{} + for i, e := range k.Enumerants { + if i > 0 { + sb.WriteString("|") + } + sb.WriteString(e.Enumerant) + } + return sb.String() + }, + "AllExtOpcodes": func() string { + sb := strings.Builder{} + for _, ext := range args.Extensions { + for _, inst := range ext.Root.Instructions { + if sb.Len() > 0 { + sb.WriteString("|") + } + sb.WriteString(inst.Opname) + } + } + return sb.String() + }, + "Title": strings.Title, + "Replace": strings.ReplaceAll, + "Global": func(s string) string { + return strings.ReplaceAll(strings.Title(s), ".", "") + }, + }).Parse(string(tf)) + if err != nil { + return errors.Wrap(err, "Failed to parse template") + } + + buf := bytes.Buffer{} + if err := t.Execute(&buf, args); err != nil { + return errors.Wrap(err, "Failed to execute template") + } + + out := buf.String() + out = strings.ReplaceAll(out, "•", "") + + if err := ioutil.WriteFile(*outputPath, []byte(out), 0777); err != nil { + return errors.Wrap(err, "Failed to write output file") + } + + return nil +} + +// parseGrammar downloads (or loads from the cache) the grammar file and returns +// the parsed grammar.Root. +func parseGrammar(def grammarDefinition) (grammar.Root, error) { + file, err := getOrDownload(def.name, def.url) + if err != nil { + return grammar.Root{}, errors.Wrap(err, "Failed to load grammar file") + } + + g := grammar.Root{} + if err := json.NewDecoder(bytes.NewReader(file)).Decode(&g); err != nil { + return grammar.Root{}, errors.Wrap(err, "Failed to parse grammar file") + } + + return g, nil +} + +// getOrDownload loads the specific file from the cache, or downloads the file +// from the given url. +func getOrDownload(name, url string) ([]byte, error) { + if *cachePath != "" { + if err := os.MkdirAll(*cachePath, 0777); err == nil { + path := filepath.Join(*cachePath, name) + if isFile(path) { + return ioutil.ReadFile(path) + } + } + } + resp, err := http.Get(url) + if err != nil { + return nil, err + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if *cachePath != "" { + ioutil.WriteFile(filepath.Join(*cachePath, name), data, 0777) + } + return data, nil +} + +// isFile returns true if path is a file. +func isFile(path string) bool { + s, err := os.Stat(path) + if err != nil { + return false + } + return !s.IsDir() +} + +// isDir returns true if path is a directory. +func isDir(path string) bool { + s, err := os.Stat(path) + if err != nil { + return false + } + return s.IsDir() +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/GLSL.std.450.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/GLSL.std.450.h new file mode 100644 index 000000000000..54cc00e9a888 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/GLSL.std.450.h @@ -0,0 +1,131 @@ +/* +** Copyright (c) 2014-2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLstd450_H +#define GLSLstd450_H + +static const int GLSLstd450Version = 100; +static const int GLSLstd450Revision = 3; + +enum GLSLstd450 { + GLSLstd450Bad = 0, // Don't use + + GLSLstd450Round = 1, + GLSLstd450RoundEven = 2, + GLSLstd450Trunc = 3, + GLSLstd450FAbs = 4, + GLSLstd450SAbs = 5, + GLSLstd450FSign = 6, + GLSLstd450SSign = 7, + GLSLstd450Floor = 8, + GLSLstd450Ceil = 9, + GLSLstd450Fract = 10, + + GLSLstd450Radians = 11, + GLSLstd450Degrees = 12, + GLSLstd450Sin = 13, + GLSLstd450Cos = 14, + GLSLstd450Tan = 15, + GLSLstd450Asin = 16, + GLSLstd450Acos = 17, + GLSLstd450Atan = 18, + GLSLstd450Sinh = 19, + GLSLstd450Cosh = 20, + GLSLstd450Tanh = 21, + GLSLstd450Asinh = 22, + GLSLstd450Acosh = 23, + GLSLstd450Atanh = 24, + GLSLstd450Atan2 = 25, + + GLSLstd450Pow = 26, + GLSLstd450Exp = 27, + GLSLstd450Log = 28, + GLSLstd450Exp2 = 29, + GLSLstd450Log2 = 30, + GLSLstd450Sqrt = 31, + GLSLstd450InverseSqrt = 32, + + GLSLstd450Determinant = 33, + GLSLstd450MatrixInverse = 34, + + GLSLstd450Modf = 35, // second operand needs an OpVariable to write to + GLSLstd450ModfStruct = 36, // no OpVariable operand + GLSLstd450FMin = 37, + GLSLstd450UMin = 38, + GLSLstd450SMin = 39, + GLSLstd450FMax = 40, + GLSLstd450UMax = 41, + GLSLstd450SMax = 42, + GLSLstd450FClamp = 43, + GLSLstd450UClamp = 44, + GLSLstd450SClamp = 45, + GLSLstd450FMix = 46, + GLSLstd450IMix = 47, // Reserved + GLSLstd450Step = 48, + GLSLstd450SmoothStep = 49, + + GLSLstd450Fma = 50, + GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to + GLSLstd450FrexpStruct = 52, // no OpVariable operand + GLSLstd450Ldexp = 53, + + GLSLstd450PackSnorm4x8 = 54, + GLSLstd450PackUnorm4x8 = 55, + GLSLstd450PackSnorm2x16 = 56, + GLSLstd450PackUnorm2x16 = 57, + GLSLstd450PackHalf2x16 = 58, + GLSLstd450PackDouble2x32 = 59, + GLSLstd450UnpackSnorm2x16 = 60, + GLSLstd450UnpackUnorm2x16 = 61, + GLSLstd450UnpackHalf2x16 = 62, + GLSLstd450UnpackSnorm4x8 = 63, + GLSLstd450UnpackUnorm4x8 = 64, + GLSLstd450UnpackDouble2x32 = 65, + + GLSLstd450Length = 66, + GLSLstd450Distance = 67, + GLSLstd450Cross = 68, + GLSLstd450Normalize = 69, + GLSLstd450FaceForward = 70, + GLSLstd450Reflect = 71, + GLSLstd450Refract = 72, + + GLSLstd450FindILsb = 73, + GLSLstd450FindSMsb = 74, + GLSLstd450FindUMsb = 75, + + GLSLstd450InterpolateAtCentroid = 76, + GLSLstd450InterpolateAtSample = 77, + GLSLstd450InterpolateAtOffset = 78, + + GLSLstd450NMin = 79, + GLSLstd450NMax = 80, + GLSLstd450NClamp = 81, + + GLSLstd450Count +}; + +#endif // #ifndef GLSLstd450_H diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/OpenCL.std.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/OpenCL.std.h new file mode 100644 index 000000000000..19a6688490c7 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/OpenCL.std.h @@ -0,0 +1,210 @@ +/* +** Copyright (c) 2015-2017 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +namespace OpenCLLIB { + +enum Entrypoints { + + // Section 2.1: Math extended instructions + Acos = 0, + Acosh = 1, + Acospi = 2, + Asin = 3, + Asinh = 4, + Asinpi = 5, + Atan = 6, + Atan2 = 7, + Atanh = 8, + Atanpi = 9, + Atan2pi = 10, + Cbrt = 11, + Ceil = 12, + Copysign = 13, + Cos = 14, + Cosh = 15, + Cospi = 16, + Erfc = 17, + Erf = 18, + Exp = 19, + Exp2 = 20, + Exp10 = 21, + Expm1 = 22, + Fabs = 23, + Fdim = 24, + Floor = 25, + Fma = 26, + Fmax = 27, + Fmin = 28, + Fmod = 29, + Fract = 30, + Frexp = 31, + Hypot = 32, + Ilogb = 33, + Ldexp = 34, + Lgamma = 35, + Lgamma_r = 36, + Log = 37, + Log2 = 38, + Log10 = 39, + Log1p = 40, + Logb = 41, + Mad = 42, + Maxmag = 43, + Minmag = 44, + Modf = 45, + Nan = 46, + Nextafter = 47, + Pow = 48, + Pown = 49, + Powr = 50, + Remainder = 51, + Remquo = 52, + Rint = 53, + Rootn = 54, + Round = 55, + Rsqrt = 56, + Sin = 57, + Sincos = 58, + Sinh = 59, + Sinpi = 60, + Sqrt = 61, + Tan = 62, + Tanh = 63, + Tanpi = 64, + Tgamma = 65, + Trunc = 66, + Half_cos = 67, + Half_divide = 68, + Half_exp = 69, + Half_exp2 = 70, + Half_exp10 = 71, + Half_log = 72, + Half_log2 = 73, + Half_log10 = 74, + Half_powr = 75, + Half_recip = 76, + Half_rsqrt = 77, + Half_sin = 78, + Half_sqrt = 79, + Half_tan = 80, + Native_cos = 81, + Native_divide = 82, + Native_exp = 83, + Native_exp2 = 84, + Native_exp10 = 85, + Native_log = 86, + Native_log2 = 87, + Native_log10 = 88, + Native_powr = 89, + Native_recip = 90, + Native_rsqrt = 91, + Native_sin = 92, + Native_sqrt = 93, + Native_tan = 94, + + // Section 2.2: Integer instructions + SAbs = 141, + SAbs_diff = 142, + SAdd_sat = 143, + UAdd_sat = 144, + SHadd = 145, + UHadd = 146, + SRhadd = 147, + URhadd = 148, + SClamp = 149, + UClamp = 150, + Clz = 151, + Ctz = 152, + SMad_hi = 153, + UMad_sat = 154, + SMad_sat = 155, + SMax = 156, + UMax = 157, + SMin = 158, + UMin = 159, + SMul_hi = 160, + Rotate = 161, + SSub_sat = 162, + USub_sat = 163, + U_Upsample = 164, + S_Upsample = 165, + Popcount = 166, + SMad24 = 167, + UMad24 = 168, + SMul24 = 169, + UMul24 = 170, + UAbs = 201, + UAbs_diff = 202, + UMul_hi = 203, + UMad_hi = 204, + + // Section 2.3: Common instructions + FClamp = 95, + Degrees = 96, + FMax_common = 97, + FMin_common = 98, + Mix = 99, + Radians = 100, + Step = 101, + Smoothstep = 102, + Sign = 103, + + // Section 2.4: Geometric instructions + Cross = 104, + Distance = 105, + Length = 106, + Normalize = 107, + Fast_distance = 108, + Fast_length = 109, + Fast_normalize = 110, + + // Section 2.5: Relational instructions + Bitselect = 186, + Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + Vloadn = 171, + Vstoren = 172, + Vload_half = 173, + Vload_halfn = 174, + Vstore_half = 175, + Vstore_half_r = 176, + Vstore_halfn = 177, + Vstore_halfn_r = 178, + Vloada_halfn = 179, + Vstorea_halfn = 180, + Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + Shuffle = 182, + Shuffle2 = 183, + + // Section 2.8: Misc instructions + Printf = 184, + Prefetch = 185, +}; + +} // end namespace OpenCLLIB diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/extinst.glsl.std.450.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/extinst.glsl.std.450.grammar.json new file mode 100644 index 000000000000..3d9f39e76c9c --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/extinst.glsl.std.450.grammar.json @@ -0,0 +1,642 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "Round", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "RoundEven", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Trunc", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FAbs", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SAbs", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FSign", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SSign", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Floor", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ceil", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fract", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Radians", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "Degrees", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "Sin", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tan", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asin", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acos", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'y_over_x'" } + ] + }, + { + "opname" : "Sinh", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cosh", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tanh", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asinh", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acosh", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atanh", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan2", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Pow", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Exp", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Exp2", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log2", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Sqrt", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "InverseSqrt", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Determinant", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "MatrixInverse", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Modf", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "ModfStruct", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FMin", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMin", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMin", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FMax", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMax", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMax", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FClamp", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "UClamp", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "SClamp", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "FMix", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "IMix", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "Step", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SmoothStep", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fma", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "Frexp", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "FrexpStruct", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ldexp", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "PackSnorm4x8", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm4x8", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackSnorm2x16", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm2x16", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackHalf2x16", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackDouble2x32", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "UnpackSnorm2x16", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm2x16", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackHalf2x16", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "UnpackSnorm4x8", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm4x8", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackDouble2x32", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "Length", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Distance", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "Cross", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Normalize", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FaceForward", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'Nref'" } + ] + }, + { + "opname" : "Reflect", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" } + ] + }, + { + "opname" : "Refract", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'eta'" } + ] + }, + { + "opname" : "FindILsb", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindSMsb", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindUMsb", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "InterpolateAtCentroid", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtSample", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'sample'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtOffset", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "NMin", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NMax", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NClamp", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/extinst.opencl.std.100.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/extinst.opencl.std.100.grammar.json new file mode 100644 index 000000000000..4fe45060bb98 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/extinst.opencl.std.100.grammar.json @@ -0,0 +1,1279 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "acos", + "opcode" : 0, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acosh", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acospi", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asin", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinh", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinpi", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanh", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanpi", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2pi", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cbrt", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ceil", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "copysign", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cosh", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cospi", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erfc", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erf", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp2", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp10", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "expm1", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fabs", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fdim", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "floor", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fma", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fmax", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmod", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fract", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'ptr'" } + ] + }, + { + "opname" : "frexp", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "hypot", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "ilogb", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ldexp", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'k'" } + ] + }, + { + "opname" : "lgamma", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "lgamma_r", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'signp'" } + ] + }, + { + "opname" : "log", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log2", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log10", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log1p", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "logb", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "mad", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "maxmag", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "minmag", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "modf", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'iptr'" } + ] + }, + { + "opname" : "nan", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'nancode'" } + ] + }, + { + "opname" : "nextafter", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "pow", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y" } + ] + }, + { + "opname" : "pown", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "powr", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remainder", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remquo", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'quo'" } + ] + }, + { + "opname" : "rint", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rootn", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "round", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rsqrt", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sin", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sincos", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'cosval'" } + ] + }, + { + "opname" : "sinh", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sinpi", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sqrt", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tan", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanh", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanpi", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tgamma", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "trunc", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_cos", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_divide", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_exp", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp2", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp10", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log2", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log10", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_powr", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_recip", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_rsqrt", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sin", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sqrt", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_tan", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_cos", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_divide", + "opcode" : 82, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_exp", + "opcode" : 83, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp2", + "opcode" : 84, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp10", + "opcode" : 85, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log", + "opcode" : 86, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log2", + "opcode" : 87, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log10", + "opcode" : 88, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_powr", + "opcode" : 89, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_recip", + "opcode" : 90, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_rsqrt", + "opcode" : 91, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sin", + "opcode" : 92, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sqrt", + "opcode" : 93, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_tan", + "opcode" : 94, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs", + "opcode" : 141, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs_diff", + "opcode" : 142, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_add_sat", + "opcode" : 143, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_add_sat", + "opcode" : 144, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_hadd", + "opcode" : 145, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_hadd", + "opcode" : 146, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_rhadd", + "opcode" : 147, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_rhadd", + "opcode" : 148, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_clamp", + "opcode" : 149, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "u_clamp", + "opcode" : 150, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "clz", + "opcode" : 151, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ctz", + "opcode" : 152, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad_hi", + "opcode" : 153, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "u_mad_sat", + "opcode" : 154, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mad_sat", + "opcode" : 155, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_max", + "opcode" : 156, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_max", + "opcode" : 157, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_min", + "opcode" : 158, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_min", + "opcode" : 159, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_mul_hi", + "opcode" : 160, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "rotate", + "opcode" : 161, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "s_sub_sat", + "opcode" : 162, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_sub_sat", + "opcode" : 163, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_upsample", + "opcode" : 164, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "s_upsample", + "opcode" : 165, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "popcount", + "opcode" : 166, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad24", + "opcode" : 167, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "u_mad24", + "opcode" : 168, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mul24", + "opcode" : 169, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul24", + "opcode" : 170, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_abs", + "opcode" : 201, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "u_abs_diff", + "opcode" : 202, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul_hi", + "opcode" : 203, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mad_hi", + "opcode" : 204, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fclamp", + "opcode" : 95, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "degrees", + "opcode" :96, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "fmax_common", + "opcode" : 97, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin_common", + "opcode" : 98, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "mix", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "radians", + "opcode" : 100, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "step", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "smoothstep", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sign", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cross", + "opcode" : 104, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "distance", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "length", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "normalize", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_distance", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "fast_length", + "opcode" : 109, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_normalize", + "opcode" : 110, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "bitselect", + "opcode" : 186, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "select", + "opcode" : 187, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "vloadn", + "opcode" : 171, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstoren", + "opcode" : 172, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_half", + "opcode" : 173, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_halfn", + "opcode" : 174, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstore_half", + "opcode" : 175, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_half_r", + "opcode" : 176, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vstore_halfn", + "opcode" : 177, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_halfn_r", + "opcode" : 178, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vloada_halfn", + "opcode" : 179, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstorea_halfn", + "opcode" : 180, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstorea_halfn_r", + "opcode" : 181, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "shuffle", + "opcode" : 182, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "shuffle2", + "opcode" : 183, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "printf", + "opcode" : 184, + "operands" : [ + { "kind" : "IdRef", "name" : "'format'" }, + { "kind" : "IdRef", "name" : "'additional arguments'", "quantifier" : "*" } + ] + }, + { + "opname" : "prefetch", + "opcode" : 185, + "operands" : [ + { "kind" : "IdRef", "name" : "'ptr'" }, + { "kind" : "IdRef", "name" : "'num elements'" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.core.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.core.grammar.json new file mode 100644 index 000000000000..f3cfc4c299bf --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.core.grammar.json @@ -0,0 +1,5775 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "magic_number" : "0x07230203", + "major_version" : 1, + "minor_version" : 0, + "revision" : 12, + "instructions" : [ + { + "opname" : "OpNop", + "opcode" : 0 + }, + { + "opname" : "OpUndef", + "opcode" : 1, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSourceContinued", + "opcode" : 2, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Continued Source'" } + ] + }, + { + "opname" : "OpSource", + "opcode" : 3, + "operands" : [ + { "kind" : "SourceLanguage" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" }, + { "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" } + ] + }, + { + "opname" : "OpSourceExtension", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Extension'" } + ] + }, + { + "opname" : "OpName", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpMemberName", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpString", + "opcode" : 7, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'String'" } + ] + }, + { + "opname" : "OpLine", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "OpExtension", + "opcode" : 10, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInstImport", + "opcode" : 11, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInst", + "opcode" : 12, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ] + }, + { + "opname" : "OpMemoryModel", + "opcode" : 14, + "operands" : [ + { "kind" : "AddressingModel" }, + { "kind" : "MemoryModel" } + ] + }, + { + "opname" : "OpEntryPoint", + "opcode" : 15, + "operands" : [ + { "kind" : "ExecutionModel" }, + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } + ] + }, + { + "opname" : "OpExecutionMode", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ] + }, + { + "opname" : "OpCapability", + "opcode" : 17, + "operands" : [ + { "kind" : "Capability", "name" : "'Capability'" } + ] + }, + { + "opname" : "OpTypeVoid", + "opcode" : 19, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeBool", + "opcode" : 20, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeInt", + "opcode" : 21, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" }, + { "kind" : "LiteralInteger", "name" : "'Signedness'" } + ] + }, + { + "opname" : "OpTypeFloat", + "opcode" : 22, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" } + ] + }, + { + "opname" : "OpTypeVector", + "opcode" : 23, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "OpTypeMatrix", + "opcode" : 24, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Column Type'" }, + { "kind" : "LiteralInteger", "name" : "'Column Count'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpTypeImage", + "opcode" : 25, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Type'" }, + { "kind" : "Dim" }, + { "kind" : "LiteralInteger", "name" : "'Depth'" }, + { "kind" : "LiteralInteger", "name" : "'Arrayed'" }, + { "kind" : "LiteralInteger", "name" : "'MS'" }, + { "kind" : "LiteralInteger", "name" : "'Sampled'" }, + { "kind" : "ImageFormat" }, + { "kind" : "AccessQualifier", "quantifier" : "?" } + ] + }, + { + "opname" : "OpTypeSampler", + "opcode" : 26, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeSampledImage", + "opcode" : 27, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ] + }, + { + "opname" : "OpTypeArray", + "opcode" : 28, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" }, + { "kind" : "IdRef", "name" : "'Length'" } + ] + }, + { + "opname" : "OpTypeRuntimeArray", + "opcode" : 29, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpTypeStruct", + "opcode" : 30, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ] + }, + { + "opname" : "OpTypeOpaque", + "opcode" : 31, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "The name of the opaque type." } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypePointer", + "opcode" : 32, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "name" : "'Type'" } + ] + }, + { + "opname" : "OpTypeFunction", + "opcode" : 33, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." } + ] + }, + { + "opname" : "OpTypeEvent", + "opcode" : 34, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypeDeviceEvent", + "opcode" : 35, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypeReserveId", + "opcode" : 36, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeQueue", + "opcode" : 37, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypePipe", + "opcode" : 38, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "AccessQualifier", "name" : "'Qualifier'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeForwardPointer", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer Type'" }, + { "kind" : "StorageClass" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpConstantTrue", + "opcode" : 41, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstantFalse", + "opcode" : 42, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstant", + "opcode" : 43, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConstantComposite", + "opcode" : 44, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpConstantSampler", + "opcode" : 45, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "SamplerAddressingMode" }, + { "kind" : "LiteralInteger", "name" : "'Param'" }, + { "kind" : "SamplerFilterMode" } + ], + "capabilities" : [ "LiteralSampler" ] + }, + { + "opname" : "OpConstantNull", + "opcode" : 46, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantTrue", + "opcode" : 48, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantFalse", + "opcode" : 49, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstant", + "opcode" : 50, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpSpecConstantComposite", + "opcode" : 51, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpSpecConstantOp", + "opcode" : 52, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" } + ] + }, + { + "opname" : "OpFunction", + "opcode" : 54, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "FunctionControl" }, + { "kind" : "IdRef", "name" : "'Function Type'" } + ] + }, + { + "opname" : "OpFunctionParameter", + "opcode" : 55, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpFunctionEnd", + "opcode" : 56 + }, + { + "opname" : "OpFunctionCall", + "opcode" : 57, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." } + ] + }, + { + "opname" : "OpVariable", + "opcode" : 59, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" } + ] + }, + { + "opname" : "OpImageTexelPointer", + "opcode" : 60, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Sample'" } + ] + }, + { + "opname" : "OpLoad", + "opcode" : 61, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpStore", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemory", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemorySized", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpAccessChain", + "opcode" : 65, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpInBoundsAccessChain", + "opcode" : 66, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpPtrAccessChain", + "opcode" : 67, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ + "Addresses", + "VariablePointers", + "VariablePointersStorageBuffer" + ] + }, + { + "opname" : "OpArrayLength", + "opcode" : 68, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Structure'" }, + { "kind" : "LiteralInteger", "name" : "'Array member'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpGenericPtrMemSemantics", + "opcode" : 69, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpInBoundsPtrAccessChain", + "opcode" : 70, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpDecorate", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpMemberDecorate", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'Structure Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpDecorationGroup", + "opcode" : 73, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpGroupDecorate", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpGroupMemberDecorate", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpVectorExtractDynamic", + "opcode" : 77, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorInsertDynamic", + "opcode" : 78, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorShuffle", + "opcode" : 79, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" } + ] + }, + { + "opname" : "OpCompositeConstruct", + "opcode" : 80, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpCompositeExtract", + "opcode" : 81, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCompositeInsert", + "opcode" : 82, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCopyObject", + "opcode" : 83, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpTranspose", + "opcode" : 84, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpSampledImage", + "opcode" : 86, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ] + }, + { + "opname" : "OpImageSampleImplicitLod", + "opcode" : 87, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleExplicitLod", + "opcode" : 88, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ] + }, + { + "opname" : "OpImageSampleDrefImplicitLod", + "opcode" : 89, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleDrefExplicitLod", + "opcode" : 90, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjImplicitLod", + "opcode" : 91, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjExplicitLod", + "opcode" : 92, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefImplicitLod", + "opcode" : 93, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefExplicitLod", + "opcode" : 94, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageFetch", + "opcode" : 95, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageGather", + "opcode" : 96, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageDrefGather", + "opcode" : 97, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageRead", + "opcode" : 98, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageWrite", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Texel'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImage", + "opcode" : 100, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" } + ] + }, + { + "opname" : "OpImageQueryFormat", + "opcode" : 101, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQueryOrder", + "opcode" : 102, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQuerySizeLod", + "opcode" : 103, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Level of Detail'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySize", + "opcode" : 104, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLod", + "opcode" : 105, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLevels", + "opcode" : 106, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySamples", + "opcode" : 107, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpConvertFToU", + "opcode" : 109, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertFToS", + "opcode" : 110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertSToF", + "opcode" : 111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpConvertUToF", + "opcode" : 112, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpUConvert", + "opcode" : 113, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpSConvert", + "opcode" : 114, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpFConvert", + "opcode" : 115, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpQuantizeToF16", + "opcode" : 116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConvertPtrToU", + "opcode" : 117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpSatConvertSToU", + "opcode" : 118, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSatConvertUToS", + "opcode" : 119, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpConvertUToPtr", + "opcode" : 120, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Integer Value'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpPtrCastToGeneric", + "opcode" : 121, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtr", + "opcode" : 122, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtrExplicit", + "opcode" : 123, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "StorageClass", "name" : "'Storage'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpBitcast", + "opcode" : 124, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSNegate", + "opcode" : 126, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpFNegate", + "opcode" : 127, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpIAdd", + "opcode" : 128, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFAdd", + "opcode" : 129, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISub", + "opcode" : 130, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFSub", + "opcode" : 131, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpIMul", + "opcode" : 132, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMul", + "opcode" : 133, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUDiv", + "opcode" : 134, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSDiv", + "opcode" : 135, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFDiv", + "opcode" : 136, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMod", + "opcode" : 137, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSRem", + "opcode" : 138, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMod", + "opcode" : 139, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFRem", + "opcode" : 140, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMod", + "opcode" : 141, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpVectorTimesScalar", + "opcode" : 142, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ] + }, + { + "opname" : "OpMatrixTimesScalar", + "opcode" : 143, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpVectorTimesMatrix", + "opcode" : 144, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesVector", + "opcode" : 145, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesMatrix", + "opcode" : 146, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'LeftMatrix'" }, + { "kind" : "IdRef", "name" : "'RightMatrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpOuterProduct", + "opcode" : 147, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpDot", + "opcode" : 148, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ] + }, + { + "opname" : "OpIAddCarry", + "opcode" : 149, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISubBorrow", + "opcode" : 150, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMulExtended", + "opcode" : 151, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMulExtended", + "opcode" : 152, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpAny", + "opcode" : 154, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpAll", + "opcode" : 155, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpIsNan", + "opcode" : 156, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsInf", + "opcode" : 157, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsFinite", + "opcode" : 158, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpIsNormal", + "opcode" : 159, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSignBitSet", + "opcode" : 160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLessOrGreater", + "opcode" : 161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpOrdered", + "opcode" : 162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpUnordered", + "opcode" : 163, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLogicalEqual", + "opcode" : 164, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNotEqual", + "opcode" : 165, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalOr", + "opcode" : 166, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalAnd", + "opcode" : 167, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNot", + "opcode" : 168, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSelect", + "opcode" : 169, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'Object 1'" }, + { "kind" : "IdRef", "name" : "'Object 2'" } + ] + }, + { + "opname" : "OpIEqual", + "opcode" : 170, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpINotEqual", + "opcode" : 171, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThan", + "opcode" : 172, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThan", + "opcode" : 173, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThanEqual", + "opcode" : 174, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThanEqual", + "opcode" : 175, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThan", + "opcode" : 176, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThan", + "opcode" : 177, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThanEqual", + "opcode" : 178, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThanEqual", + "opcode" : 179, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdEqual", + "opcode" : 180, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordEqual", + "opcode" : 181, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdNotEqual", + "opcode" : 182, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordNotEqual", + "opcode" : 183, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThan", + "opcode" : 184, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThan", + "opcode" : 185, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThan", + "opcode" : 186, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThan", + "opcode" : 187, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThanEqual", + "opcode" : 188, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThanEqual", + "opcode" : 189, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThanEqual", + "opcode" : 190, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThanEqual", + "opcode" : 191, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpShiftRightLogical", + "opcode" : 194, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftRightArithmetic", + "opcode" : 195, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftLeftLogical", + "opcode" : 196, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpBitwiseOr", + "opcode" : 197, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseXor", + "opcode" : 198, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseAnd", + "opcode" : 199, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpNot", + "opcode" : 200, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpBitFieldInsert", + "opcode" : 201, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Insert'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldSExtract", + "opcode" : 202, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldUExtract", + "opcode" : 203, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitReverse", + "opcode" : 204, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitCount", + "opcode" : 205, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ] + }, + { + "opname" : "OpDPdx", + "opcode" : 207, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdy", + "opcode" : 208, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpFwidth", + "opcode" : 209, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdxFine", + "opcode" : 210, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyFine", + "opcode" : 211, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthFine", + "opcode" : 212, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdxCoarse", + "opcode" : 213, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyCoarse", + "opcode" : 214, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthCoarse", + "opcode" : 215, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpEmitVertex", + "opcode" : 218, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEndPrimitive", + "opcode" : 219, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEmitStreamVertex", + "opcode" : 220, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpEndStreamPrimitive", + "opcode" : 221, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpControlBarrier", + "opcode" : 224, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpMemoryBarrier", + "opcode" : 225, + "operands" : [ + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicLoad", + "opcode" : 227, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicStore", + "opcode" : 228, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicExchange", + "opcode" : 229, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicCompareExchange", + "opcode" : 230, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ] + }, + { + "opname" : "OpAtomicCompareExchangeWeak", + "opcode" : 231, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicIIncrement", + "opcode" : 232, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIDecrement", + "opcode" : 233, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIAdd", + "opcode" : 234, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicISub", + "opcode" : 235, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMin", + "opcode" : 236, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMin", + "opcode" : 237, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMax", + "opcode" : 238, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMax", + "opcode" : 239, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicAnd", + "opcode" : 240, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicOr", + "opcode" : 241, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicXor", + "opcode" : 242, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpPhi", + "opcode" : 245, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" } + ] + }, + { + "opname" : "OpLoopMerge", + "opcode" : 246, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "IdRef", "name" : "'Continue Target'" }, + { "kind" : "LoopControl" } + ] + }, + { + "opname" : "OpSelectionMerge", + "opcode" : 247, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "SelectionControl" } + ] + }, + { + "opname" : "OpLabel", + "opcode" : 248, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpBranch", + "opcode" : 249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target Label'" } + ] + }, + { + "opname" : "OpBranchConditional", + "opcode" : 250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'True Label'" }, + { "kind" : "IdRef", "name" : "'False Label'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" } + ] + }, + { + "opname" : "OpSwitch", + "opcode" : 251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Selector'" }, + { "kind" : "IdRef", "name" : "'Default'" }, + { "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" } + ] + }, + { + "opname" : "OpKill", + "opcode" : 252, + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpReturn", + "opcode" : 253 + }, + { + "opname" : "OpReturnValue", + "opcode" : 254, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpUnreachable", + "opcode" : 255 + }, + { + "opname" : "OpLifetimeStart", + "opcode" : 256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLifetimeStop", + "opcode" : 257, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAsyncCopy", + "opcode" : 259, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Destination'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Num Elements'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupWaitEvents", + "opcode" : 260, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Events List'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAll", + "opcode" : 261, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupAny", + "opcode" : 262, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupBroadcast", + "opcode" : 263, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'LocalId'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupIAdd", + "opcode" : 264, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAdd", + "opcode" : 265, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMin", + "opcode" : 266, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMin", + "opcode" : 267, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMin", + "opcode" : 268, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMax", + "opcode" : 269, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMax", + "opcode" : 270, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMax", + "opcode" : 271, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpReadPipe", + "opcode" : 274, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpWritePipe", + "opcode" : 275, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedReadPipe", + "opcode" : 276, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedWritePipe", + "opcode" : 277, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveReadPipePackets", + "opcode" : 278, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveWritePipePackets", + "opcode" : 279, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitReadPipe", + "opcode" : 280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitWritePipe", + "opcode" : 281, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpIsValidReserveId", + "opcode" : 282, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetNumPipePackets", + "opcode" : 283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetMaxPipePackets", + "opcode" : 284, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveReadPipePackets", + "opcode" : 285, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveWritePipePackets", + "opcode" : 286, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitReadPipe", + "opcode" : 287, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitWritePipe", + "opcode" : 288, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpEnqueueMarker", + "opcode" : 291, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpEnqueueKernel", + "opcode" : 292, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeSubGroupCount", + "opcode" : 293, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeMaxSubGroupSize", + "opcode" : 294, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelWorkGroupSize", + "opcode" : 295, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelPreferredWorkGroupSizeMultiple", + "opcode" : 296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpRetainEvent", + "opcode" : 297, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpReleaseEvent", + "opcode" : 298, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCreateUserEvent", + "opcode" : 299, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpIsValidEvent", + "opcode" : 300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpSetUserEventStatus", + "opcode" : 301, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Status'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCaptureEventProfilingInfo", + "opcode" : 302, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Profiling Info'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetDefaultQueue", + "opcode" : 303, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpBuildNDRange", + "opcode" : 304, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'GlobalWorkSize'" }, + { "kind" : "IdRef", "name" : "'LocalWorkSize'" }, + { "kind" : "IdRef", "name" : "'GlobalWorkOffset'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpImageSparseSampleImplicitLod", + "opcode" : 305, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleExplicitLod", + "opcode" : 306, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefImplicitLod", + "opcode" : 307, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefExplicitLod", + "opcode" : 308, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjImplicitLod", + "opcode" : 309, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjExplicitLod", + "opcode" : 310, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefImplicitLod", + "opcode" : 311, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefExplicitLod", + "opcode" : 312, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseFetch", + "opcode" : 313, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseGather", + "opcode" : 314, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseDrefGather", + "opcode" : 315, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseTexelsResident", + "opcode" : 316, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Resident Code'" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpNoLine", + "opcode" : 317 + }, + { + "opname" : "OpAtomicFlagTestAndSet", + "opcode" : 318, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicFlagClear", + "opcode" : 319, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageSparseRead", + "opcode" : 320, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpDecorateId", + "opcode" : 332, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "opname" : "OpSubgroupBallotKHR", + "opcode" : 4421, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupFirstInvocationKHR", + "opcode" : 4422, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupAllKHR", + "opcode" : 4428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAnyKHR", + "opcode" : 4429, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAllEqualKHR", + "opcode" : 4430, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupReadInvocationKHR", + "opcode" : 4432, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpGroupIAddNonUniformAMD", + "opcode" : 5000, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAddNonUniformAMD", + "opcode" : 5001, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMinNonUniformAMD", + "opcode" : 5002, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMinNonUniformAMD", + "opcode" : 5003, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMinNonUniformAMD", + "opcode" : 5004, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMaxNonUniformAMD", + "opcode" : 5005, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMaxNonUniformAMD", + "opcode" : 5006, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMaxNonUniformAMD", + "opcode" : 5007, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpFragmentMaskFetchAMD", + "opcode" : 5011, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpFragmentFetchAMD", + "opcode" : 5012, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Fragment Index'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpSubgroupShuffleINTEL", + "opcode" : 5571, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'InvocationId'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleDownINTEL", + "opcode" : 5572, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Next'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleUpINTEL", + "opcode" : 5573, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Previous'" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleXorINTEL", + "opcode" : 5574, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupBlockReadINTEL", + "opcode" : 5575, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupBlockWriteINTEL", + "opcode" : 5576, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockReadINTEL", + "opcode" : 5577, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockWriteINTEL", + "opcode" : 5578, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpDecorateStringGOOGLE", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + }, + { + "opname" : "OpMemberDecorateStringGOOGLE", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "ImageOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Bias", + "value" : "0x0001", + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Lod", + "value" : "0x0002", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Grad", + "value" : "0x0004", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffset", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Offset", + "value" : "0x0010", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffsets", + "value" : "0x0020", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Sample", + "value" : "0x0040", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "MinLod", + "value" : "0x0080", + "capabilities" : [ "MinLod" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FPFastMathMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "NotNaN", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NotInf", + "value" : "0x0002", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NSZ", + "value" : "0x0004", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AllowRecip", + "value" : "0x0008", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Fast", + "value" : "0x0010", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "SelectionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Flatten", + "value" : "0x0001" + }, + { + "enumerant" : "DontFlatten", + "value" : "0x0002" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "LoopControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Unroll", + "value" : "0x0001" + }, + { + "enumerant" : "DontUnroll", + "value" : "0x0002" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FunctionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Inline", + "value" : "0x0001" + }, + { + "enumerant" : "DontInline", + "value" : "0x0002" + }, + { + "enumerant" : "Pure", + "value" : "0x0004" + }, + { + "enumerant" : "Const", + "value" : "0x0008" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemorySemantics", + "enumerants" : [ + { + "enumerant" : "Relaxed", + "value" : "0x0000" + }, + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Acquire", + "value" : "0x0002" + }, + { + "enumerant" : "Release", + "value" : "0x0004" + }, + { + "enumerant" : "AcquireRelease", + "value" : "0x0008" + }, + { + "enumerant" : "SequentiallyConsistent", + "value" : "0x0010" + }, + { + "enumerant" : "UniformMemory", + "value" : "0x0040", + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupMemory", + "value" : "0x0080" + }, + { + "enumerant" : "WorkgroupMemory", + "value" : "0x0100" + }, + { + "enumerant" : "CrossWorkgroupMemory", + "value" : "0x0200" + }, + { + "enumerant" : "AtomicCounterMemory", + "value" : "0x0400", + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "ImageMemory", + "value" : "0x0800" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemoryAccess", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Volatile", + "value" : "0x0001" + }, + { + "enumerant" : "Aligned", + "value" : "0x0002", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Nontemporal", + "value" : "0x0004" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "KernelProfilingInfo", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "CmdExecTime", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SourceLanguage", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "ESSL", + "value" : 1 + }, + { + "enumerant" : "GLSL", + "value" : 2 + }, + { + "enumerant" : "OpenCL_C", + "value" : 3 + }, + { + "enumerant" : "OpenCL_CPP", + "value" : 4 + }, + { + "enumerant" : "HLSL", + "value" : 5 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionModel", + "enumerants" : [ + { + "enumerant" : "Vertex", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TessellationControl", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessellationEvaluation", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Geometry", + "value" : 3, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Fragment", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLCompute", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Kernel", + "value" : 6, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AddressingModel", + "enumerants" : [ + { + "enumerant" : "Logical", + "value" : 0 + }, + { + "enumerant" : "Physical32", + "value" : 1, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Physical64", + "value" : 2, + "capabilities" : [ "Addresses" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "MemoryModel", + "enumerants" : [ + { + "enumerant" : "Simple", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSL450", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OpenCL", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionMode", + "enumerants" : [ + { + "enumerant" : "Invocations", + "value" : 0, + "capabilities" : [ "Geometry" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of <>'" } + ] + }, + { + "enumerant" : "SpacingEqual", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalEven", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalOdd", + "value" : 3, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCw", + "value" : 4, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCcw", + "value" : 5, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PixelCenterInteger", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginUpperLeft", + "value" : 7, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginLowerLeft", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "EarlyFragmentTests", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointMode", + "value" : 10, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Xfb", + "value" : 11, + "capabilities" : [ "TransformFeedback" ] + }, + { + "enumerant" : "DepthReplacing", + "value" : 12, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthGreater", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthLess", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthUnchanged", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "LocalSize", + "value" : 17, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "LocalSizeHint", + "value" : 18, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "InputPoints", + "value" : 19, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLines", + "value" : 20, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLinesAdjacency", + "value" : 21, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Triangles", + "value" : 22, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InputTrianglesAdjacency", + "value" : 23, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Quads", + "value" : 24, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Isolines", + "value" : 25, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "OutputVertices", + "value" : 26, + "capabilities" : [ "Geometry", "Tessellation" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vertex count'" } + ] + }, + { + "enumerant" : "OutputPoints", + "value" : 27, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputLineStrip", + "value" : 28, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputTriangleStrip", + "value" : 29, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "VecTypeHint", + "value" : 30, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vector type'" } + ] + }, + { + "enumerant" : "ContractionOff", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "PostDepthCoverage", + "value" : 4446, + "capabilities" : [ "SampleMaskPostDepthCoverage" ] + }, + { + "enumerant" : "StencilRefReplacingEXT", + "value" : 5027, + "capabilities" : [ "StencilExportEXT" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StorageClass", + "enumerants" : [ + { + "enumerant" : "UniformConstant", + "value" : 0 + }, + { + "enumerant" : "Input", + "value" : 1 + }, + { + "enumerant" : "Uniform", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Output", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Workgroup", + "value" : 4 + }, + { + "enumerant" : "CrossWorkgroup", + "value" : 5 + }, + { + "enumerant" : "Private", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Function", + "value" : 7 + }, + { + "enumerant" : "Generic", + "value" : 8, + "capabilities" : [ "GenericPointer" ] + }, + { + "enumerant" : "PushConstant", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "AtomicCounter", + "value" : 10, + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "Image", + "value" : 11 + }, + { + "enumerant" : "StorageBuffer", + "value" : 12, + "extensions" : [ + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers" + ], + "capabilities" : [ "Shader" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Dim", + "enumerants" : [ + { + "enumerant" : "1D", + "value" : 0, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "2D", + "value" : 1 + }, + { + "enumerant" : "3D", + "value" : 2 + }, + { + "enumerant" : "Cube", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rect", + "value" : 4, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "Buffer", + "value" : 5, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "SubpassData", + "value" : 6, + "capabilities" : [ "InputAttachment" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerAddressingMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ClampToEdge", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Clamp", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Repeat", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RepeatMirrored", + "value" : 4, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerFilterMode", + "enumerants" : [ + { + "enumerant" : "Nearest", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Linear", + "value" : 1, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageFormat", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "Rgba32f", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16f", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32f", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8Snorm", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32f", + "value" : 6, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16f", + "value" : 7, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R11fG11fB10f", + "value" : 8, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16f", + "value" : 9, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16", + "value" : 10, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgb10A2", + "value" : 11, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16", + "value" : 12, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8", + "value" : 13, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16", + "value" : 14, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8", + "value" : 15, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16Snorm", + "value" : 16, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16Snorm", + "value" : 17, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8Snorm", + "value" : 18, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16Snorm", + "value" : 19, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8Snorm", + "value" : 20, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32i", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16i", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8i", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32i", + "value" : 24, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32i", + "value" : 25, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16i", + "value" : 26, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8i", + "value" : 27, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16i", + "value" : 28, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8i", + "value" : 29, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32ui", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16ui", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8ui", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32ui", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgb10a2ui", + "value" : 34, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg32ui", + "value" : 35, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16ui", + "value" : 36, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8ui", + "value" : 37, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16ui", + "value" : 38, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8ui", + "value" : 39, + "capabilities" : [ "StorageImageExtendedFormats" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelOrder", + "enumerants" : [ + { + "enumerant" : "R", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "A", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RG", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RA", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGB", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBA", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BGRA", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ARGB", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Intensity", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Luminance", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Rx", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGx", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBx", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Depth", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "DepthStencil", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGB", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBx", + "value" : 16, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBA", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sBGRA", + "value" : 18, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ABGR", + "value" : 19, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelDataType", + "enumerants" : [ + { + "enumerant" : "SnormInt8", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SnormInt16", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt8", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt16", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort565", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort555", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt8", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt16", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt32", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt8", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt16", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt32", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "HalfFloat", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt24", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010_2", + "value" : 16, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPRoundingMode", + "enumerants" : [ + { + "enumerant" : "RTE", + "value" : 0, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTZ", + "value" : 1, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTP", + "value" : 2, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTN", + "value" : 3, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LinkageType", + "enumerants" : [ + { + "enumerant" : "Export", + "value" : 0, + "capabilities" : [ "Linkage" ] + }, + { + "enumerant" : "Import", + "value" : 1, + "capabilities" : [ "Linkage" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AccessQualifier", + "enumerants" : [ + { + "enumerant" : "ReadOnly", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WriteOnly", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ReadWrite", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FunctionParameterAttribute", + "enumerants" : [ + { + "enumerant" : "Zext", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sext", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ByVal", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sret", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoAlias", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoCapture", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoWrite", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoReadWrite", + "value" : 7, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Decoration", + "enumerants" : [ + { + "enumerant" : "RelaxedPrecision", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SpecId", + "value" : 1, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" } + ] + }, + { + "enumerant" : "Block", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "BufferBlock", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "RowMajor", + "value" : 4, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ColMajor", + "value" : 5, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ArrayStride", + "value" : 6, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Array Stride'" } + ] + }, + { + "enumerant" : "MatrixStride", + "value" : 7, + "capabilities" : [ "Matrix" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Matrix Stride'" } + ] + }, + { + "enumerant" : "GLSLShared", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSLPacked", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CPacked", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BuiltIn", + "value" : 11, + "parameters" : [ + { "kind" : "BuiltIn" } + ] + }, + { + "enumerant" : "NoPerspective", + "value" : 13, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Flat", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Patch", + "value" : 15, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Centroid", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sample", + "value" : 17, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "Invariant", + "value" : 18, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Restrict", + "value" : 19 + }, + { + "enumerant" : "Aliased", + "value" : 20 + }, + { + "enumerant" : "Volatile", + "value" : 21 + }, + { + "enumerant" : "Constant", + "value" : 22, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Coherent", + "value" : 23 + }, + { + "enumerant" : "NonWritable", + "value" : 24 + }, + { + "enumerant" : "NonReadable", + "value" : 25 + }, + { + "enumerant" : "Uniform", + "value" : 26, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SaturatedConversion", + "value" : 28, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Stream", + "value" : 29, + "capabilities" : [ "GeometryStreams" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stream Number'" } + ] + }, + { + "enumerant" : "Location", + "value" : 30, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Location'" } + ] + }, + { + "enumerant" : "Component", + "value" : 31, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Component'" } + ] + }, + { + "enumerant" : "Index", + "value" : 32, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Index'" } + ] + }, + { + "enumerant" : "Binding", + "value" : 33, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Binding Point'" } + ] + }, + { + "enumerant" : "DescriptorSet", + "value" : 34, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Descriptor Set'" } + ] + }, + { + "enumerant" : "Offset", + "value" : 35, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Byte Offset'" } + ] + }, + { + "enumerant" : "XfbBuffer", + "value" : 36, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" } + ] + }, + { + "enumerant" : "XfbStride", + "value" : 37, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Stride'" } + ] + }, + { + "enumerant" : "FuncParamAttr", + "value" : 38, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" } + ] + }, + { + "enumerant" : "FPRoundingMode", + "value" : 39, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ], + "parameters" : [ + { "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" } + ] + }, + { + "enumerant" : "FPFastMathMode", + "value" : 40, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" } + ] + }, + { + "enumerant" : "LinkageAttributes", + "value" : 41, + "capabilities" : [ "Linkage" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "LinkageType", "name" : "'Linkage Type'" } + ] + }, + { + "enumerant" : "NoContraction", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InputAttachmentIndex", + "value" : 43, + "capabilities" : [ "InputAttachment" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Attachment Index'" } + ] + }, + { + "enumerant" : "Alignment", + "value" : 44, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Alignment'" } + ] + }, + { + "enumerant" : "ExplicitInterpAMD", + "value" : 4999 + }, + { + "enumerant" : "OverrideCoverageNV", + "value" : 5248, + "capabilities" : [ "SampleMaskOverrideCoverageNV" ] + }, + { + "enumerant" : "PassthroughNV", + "value" : 5250, + "capabilities" : [ "GeometryShaderPassthroughNV" ] + }, + { + "enumerant" : "ViewportRelativeNV", + "value" : 5252, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryViewportRelativeNV", + "value" : 5256, + "capabilities" : [ "ShaderStereoViewNV" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ] + }, + { + "enumerant" : "HlslCounterBufferGOOGLE", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "enumerant" : "HlslSemanticGOOGLE", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "BuiltIn", + "enumerants" : [ + { + "enumerant" : "Position", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointSize", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 3, + "capabilities" : [ "ClipDistance" ] + }, + { + "enumerant" : "CullDistance", + "value" : 4, + "capabilities" : [ "CullDistance" ] + }, + { + "enumerant" : "VertexId", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceId", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PrimitiveId", + "value" : 7, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InvocationId", + "value" : 8, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "Layer", + "value" : 9, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ViewportIndex", + "value" : 10, + "capabilities" : [ "MultiViewport" ] + }, + { + "enumerant" : "TessLevelOuter", + "value" : 11, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessLevelInner", + "value" : 12, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessCoord", + "value" : 13, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PatchVertices", + "value" : 14, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "FragCoord", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointCoord", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FrontFacing", + "value" : 17, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampleId", + "value" : 18, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SamplePosition", + "value" : 19, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SampleMask", + "value" : 20, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FragDepth", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "HelperInvocation", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "NumWorkgroups", + "value" : 24 + }, + { + "enumerant" : "WorkgroupSize", + "value" : 25 + }, + { + "enumerant" : "WorkgroupId", + "value" : 26 + }, + { + "enumerant" : "LocalInvocationId", + "value" : 27 + }, + { + "enumerant" : "GlobalInvocationId", + "value" : 28 + }, + { + "enumerant" : "LocalInvocationIndex", + "value" : 29 + }, + { + "enumerant" : "WorkDim", + "value" : 30, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalSize", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "EnqueuedWorkgroupSize", + "value" : 32, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalOffset", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalLinearId", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 36, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupMaxSize", + "value" : 37, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumSubgroups", + "value" : 38, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumEnqueuedSubgroups", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupId", + "value" : 40, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupLocalInvocationId", + "value" : 41, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "VertexIndex", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceIndex", + "value" : 43, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupEqMaskKHR", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGeMaskKHR", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGtMaskKHR", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLeMaskKHR", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLtMaskKHR", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "BaseVertex", + "value" : 4424, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "BaseInstance", + "value" : 4425, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DrawIndex", + "value" : 4426, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DeviceIndex", + "value" : 4438, + "capabilities" : [ "DeviceGroup" ] + }, + { + "enumerant" : "ViewIndex", + "value" : 4440, + "capabilities" : [ "MultiView" ] + }, + { + "enumerant" : "BaryCoordNoPerspAMD", + "value" : 4992 + }, + { + "enumerant" : "BaryCoordNoPerspCentroidAMD", + "value" : 4993 + }, + { + "enumerant" : "BaryCoordNoPerspSampleAMD", + "value" : 4994 + }, + { + "enumerant" : "BaryCoordSmoothAMD", + "value" : 4995 + }, + { + "enumerant" : "BaryCoordSmoothCentroidAMD", + "value" : 4996 + }, + { + "enumerant" : "BaryCoordSmoothSampleAMD", + "value" : 4997 + }, + { + "enumerant" : "BaryCoordPullModelAMD", + "value" : 4998 + }, + { + "enumerant" : "FragStencilRefEXT", + "value" : 5014, + "capabilities" : [ "StencilExportEXT" ] + }, + { + "enumerant" : "ViewportMaskNV", + "value" : 5253, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryPositionNV", + "value" : 5257, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "SecondaryViewportMaskNV", + "value" : 5258, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "PositionPerViewNV", + "value" : 5261, + "capabilities" : [ "PerViewAttributesNV" ] + }, + { + "enumerant" : "ViewportMaskPerViewNV", + "value" : 5262, + "capabilities" : [ "PerViewAttributesNV" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Scope", + "enumerants" : [ + { + "enumerant" : "CrossDevice", + "value" : 0 + }, + { + "enumerant" : "Device", + "value" : 1 + }, + { + "enumerant" : "Workgroup", + "value" : 2 + }, + { + "enumerant" : "Subgroup", + "value" : 3 + }, + { + "enumerant" : "Invocation", + "value" : 4 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "GroupOperation", + "enumerants" : [ + { + "enumerant" : "Reduce", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InclusiveScan", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ExclusiveScan", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "KernelEnqueueFlags", + "enumerants" : [ + { + "enumerant" : "NoWait", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitKernel", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitWorkGroup", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Capability", + "enumerants" : [ + { + "enumerant" : "Matrix", + "value" : 0 + }, + { + "enumerant" : "Shader", + "value" : 1, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "Geometry", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Tessellation", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Addresses", + "value" : 4 + }, + { + "enumerant" : "Linkage", + "value" : 5 + }, + { + "enumerant" : "Kernel", + "value" : 6 + }, + { + "enumerant" : "Vector16", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16Buffer", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16", + "value" : 9 + }, + { + "enumerant" : "Float64", + "value" : 10 + }, + { + "enumerant" : "Int64", + "value" : 11 + }, + { + "enumerant" : "Int64Atomics", + "value" : 12, + "capabilities" : [ "Int64" ] + }, + { + "enumerant" : "ImageBasic", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ImageReadWrite", + "value" : 14, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "ImageMipmap", + "value" : 15, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "Pipes", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Groups", + "value" : 18 + }, + { + "enumerant" : "DeviceEnqueue", + "value" : 19, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "LiteralSampler", + "value" : 20, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AtomicStorage", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Int16", + "value" : 22 + }, + { + "enumerant" : "TessellationPointSize", + "value" : 23, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "GeometryPointSize", + "value" : 24, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ImageGatherExtended", + "value" : 25, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageMultisample", + "value" : 27, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "UniformBufferArrayDynamicIndexing", + "value" : 28, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledImageArrayDynamicIndexing", + "value" : 29, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageBufferArrayDynamicIndexing", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageArrayDynamicIndexing", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CullDistance", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageCubeArray", + "value" : 34, + "capabilities" : [ "SampledCubeArray" ] + }, + { + "enumerant" : "SampleRateShading", + "value" : 35, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageRect", + "value" : 36, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "SampledRect", + "value" : 37, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GenericPointer", + "value" : 38, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Int8", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InputAttachment", + "value" : 40, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SparseResidency", + "value" : 41, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MinLod", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sampled1D", + "value" : 43 + }, + { + "enumerant" : "Image1D", + "value" : 44, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "SampledCubeArray", + "value" : 45, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledBuffer", + "value" : 46 + }, + { + "enumerant" : "ImageBuffer", + "value" : 47, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "ImageMSArray", + "value" : 48, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageExtendedFormats", + "value" : 49, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageQuery", + "value" : 50, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DerivativeControl", + "value" : 51, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InterpolationFunction", + "value" : 52, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TransformFeedback", + "value" : 53, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GeometryStreams", + "value" : 54, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "StorageImageReadWithoutFormat", + "value" : 55, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageWriteWithoutFormat", + "value" : 56, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MultiViewport", + "value" : 57, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "SubgroupBallotKHR", + "value" : 4423, + "extensions" : [ "SPV_KHR_shader_ballot" ] + }, + { + "enumerant" : "DrawParameters", + "value" : 4427, + "extensions" : [ "SPV_KHR_shader_draw_parameters" ] + }, + { + "enumerant" : "SubgroupVoteKHR", + "value" : 4431, + "extensions" : [ "SPV_KHR_subgroup_vote" ] + }, + { + "enumerant" : "StorageBuffer16BitAccess", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniformBufferBlock16", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "UniformAndStorageBuffer16BitAccess", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniform16", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StoragePushConstant16", + "value" : 4435, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageInputOutput16", + "value" : 4436, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "DeviceGroup", + "value" : 4437, + "extensions" : [ "SPV_KHR_device_group" ] + }, + { + "enumerant" : "MultiView", + "value" : 4439, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_multiview" ] + }, + { + "enumerant" : "VariablePointersStorageBuffer", + "value" : 4441, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant" : "VariablePointers", + "value" : 4442, + "capabilities" : [ "VariablePointersStorageBuffer" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant": "AtomicStorageOps", + "value": 4445, + "extensions": [ "SPV_KHR_shader_atomic_counter_ops" ] + }, + { + "enumerant" : "SampleMaskPostDepthCoverage", + "value" : 4447, + "extensions" : [ "SPV_KHR_post_depth_coverage" ] + }, + { + "enumerant" : "ImageGatherBiasLodAMD", + "value" : 5009, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_texture_gather_bias_lod" ] + }, + { + "enumerant" : "FragmentMaskAMD", + "value" : 5010, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ] + }, + { + "enumerant" : "StencilExportEXT", + "value" : 5013, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ] + }, + { + "enumerant" : "ImageReadWriteLodAMD", + "value" : 5015, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_image_load_store_lod" ] + }, + { + "enumerant" : "SampleMaskOverrideCoverageNV", + "value" : 5249, + "capabilities" : [ "SampleRateShading" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ] + }, + { + "enumerant" : "GeometryShaderPassthroughNV", + "value" : 5251, + "capabilities" : [ "Geometry" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerEXT", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_EXT_shader_viewport_index_layer" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerNV", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderViewportMaskNV", + "value" : 5255, + "capabilities" : [ "ShaderViewportIndexLayerNV" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderStereoViewNV", + "value" : 5259, + "capabilities" : [ "ShaderViewportMaskNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ] + }, + { + "enumerant" : "PerViewAttributesNV", + "value" : 5260, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes" ] + }, + { + "enumerant" : "SubgroupShuffleINTEL", + "value" : 5568, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupBufferBlockIOINTEL", + "value" : 5569, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupImageBlockIOINTEL", + "value" : 5570, + "extensions" : [ "SPV_INTEL_subgroups" ] + } + ] + }, + { + "category" : "Id", + "kind" : "IdResultType", + "doc" : "Reference to an representing the result's type of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdResult", + "doc" : "Definition of an representing the result of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdMemorySemantics", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the MemorySemantics operand kind" + }, + { + "category" : "Id", + "kind" : "IdScope", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the Scope operand kind" + }, + { + "category" : "Id", + "kind" : "IdRef", + "doc" : "Reference to an " + }, + { + "category" : "Literal", + "kind" : "LiteralInteger", + "doc" : "An integer consuming one or more words" + }, + { + "category" : "Literal", + "kind" : "LiteralString", + "doc" : "A null-terminated stream of characters consuming an integral number of words" + }, + { + "category" : "Literal", + "kind" : "LiteralContextDependentNumber", + "doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction" + }, + { + "category" : "Literal", + "kind" : "LiteralExtInstInteger", + "doc" : "A 32-bit unsigned integer indicating which instruction to use and determining the layout of following operands (for OpExtInst)" + }, + { + "category" : "Literal", + "kind" : "LiteralSpecConstantOpInteger", + "doc" : "An opcode indicating the operation to be performed and determining the layout of following operands (for OpSpecConstantOp)" + }, + { + "category" : "Composite", + "kind" : "PairLiteralIntegerIdRef", + "bases" : [ "LiteralInteger", "IdRef" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefLiteralInteger", + "bases" : [ "IdRef", "LiteralInteger" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefIdRef", + "bases" : [ "IdRef", "IdRef" ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.cs b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.cs new file mode 100644 index 000000000000..de325cc4aad5 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.cs @@ -0,0 +1,993 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C# +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + + public static class Specification + { + public const uint MagicNumber = 0x07230203; + public const uint Version = 0x00010000; + public const uint Revision = 12; + public const uint OpCodeMask = 0xffff; + public const uint WordCountShift = 16; + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + } + + public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + } + + public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + } + + public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + } + + public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + } + + public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + } + + public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + } + + public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + } + + public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + } + + public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + } + + public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + } + + public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + } + + public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + } + + public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + } + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.h new file mode 100644 index 000000000000..bd5a9b9593aa --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.h @@ -0,0 +1,993 @@ +/* +** Copyright (c) 2014-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10000 +#define SPV_REVISION 12 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010000; +static const unsigned int SpvRevision = 12; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpDecorateId = 332, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#endif // #ifndef spirv_H + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.hpp b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.hpp new file mode 100644 index 000000000000..e98a89cee74b --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.hpp @@ -0,0 +1,1002 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10000 +#define SPV_REVISION 12 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010000; +static const unsigned int Revision = 12; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationExplicitInterpAMD = 4999, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilityMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + OpMax = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.hpp11 b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.hpp11 new file mode 100644 index 000000000000..8896e81b7c40 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.hpp11 @@ -0,0 +1,1002 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10000 +#define SPV_REVISION 12 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010000; +static const unsigned int Revision = 12; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + Max = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.json new file mode 100644 index 000000000000..9b0a8f3de284 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.json @@ -0,0 +1,1020 @@ +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2018 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "", + "Some tokens act like mask values, which can be OR'd together,", + "while others are mutually exclusive. The mask-like ones have", + "\"Mask\" in their name, and a parallel enum that has the shift", + "amount (1 << x) for each corresponding enumerant." + ] + ], + "MagicNumber": 119734787, + "Version": 65536, + "Revision": 12, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "PostDepthCoverage": 4446, + "StencilRefReplacingEXT": 5027 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "ExplicitInterpAMD": 4999, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpDecorateId": 332, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpSubgroupReadInvocationKHR": 4432, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateStringGOOGLE": 5633 + } + } + ] + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.lua b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.lua new file mode 100644 index 000000000000..2bd33ba082b7 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.lua @@ -0,0 +1,949 @@ +-- Copyright (c) 2014-2018 The Khronos Group Inc. +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and/or associated documentation files (the "Materials"), +-- to deal in the Materials without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Materials, and to permit persons to whom the +-- Materials are furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Materials. +-- +-- MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +-- STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +-- HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +-- +-- THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +-- IN THE MATERIALS. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- +-- Some tokens act like mask values, which can be OR'd together, +-- while others are mutually exclusive. The mask-like ones have +-- "Mask" in their name, and a parallel enum that has the shift +-- amount (1 << x) for each corresponding enumerant. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010000, + Revision = 12, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + }, + +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.py b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.py new file mode 100644 index 000000000000..8a200e7655f8 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.0/spirv.py @@ -0,0 +1,949 @@ +# Copyright (c) 2014-2018 The Khronos Group Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and/or associated documentation files (the "Materials"), +# to deal in the Materials without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Materials, and to permit persons to whom the +# Materials are furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Materials. +# +# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +# STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +# HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +# +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +# IN THE MATERIALS. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# +# Some tokens act like mask values, which can be OR'd together, +# while others are mutually exclusive. The mask-like ones have +# "Mask" in their name, and a parallel enum that has the shift +# amount (1 << x) for each corresponding enumerant. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010000, + 'Revision' : 12, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'PostDepthCoverage' : 4446, + 'StencilRefReplacingEXT' : 5027, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'ExplicitInterpAMD' : 4999, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpDecorateId' : 332, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateStringGOOGLE' : 5633, + }, + +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/GLSL.std.450.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/GLSL.std.450.h new file mode 100644 index 000000000000..54cc00e9a888 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/GLSL.std.450.h @@ -0,0 +1,131 @@ +/* +** Copyright (c) 2014-2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLstd450_H +#define GLSLstd450_H + +static const int GLSLstd450Version = 100; +static const int GLSLstd450Revision = 3; + +enum GLSLstd450 { + GLSLstd450Bad = 0, // Don't use + + GLSLstd450Round = 1, + GLSLstd450RoundEven = 2, + GLSLstd450Trunc = 3, + GLSLstd450FAbs = 4, + GLSLstd450SAbs = 5, + GLSLstd450FSign = 6, + GLSLstd450SSign = 7, + GLSLstd450Floor = 8, + GLSLstd450Ceil = 9, + GLSLstd450Fract = 10, + + GLSLstd450Radians = 11, + GLSLstd450Degrees = 12, + GLSLstd450Sin = 13, + GLSLstd450Cos = 14, + GLSLstd450Tan = 15, + GLSLstd450Asin = 16, + GLSLstd450Acos = 17, + GLSLstd450Atan = 18, + GLSLstd450Sinh = 19, + GLSLstd450Cosh = 20, + GLSLstd450Tanh = 21, + GLSLstd450Asinh = 22, + GLSLstd450Acosh = 23, + GLSLstd450Atanh = 24, + GLSLstd450Atan2 = 25, + + GLSLstd450Pow = 26, + GLSLstd450Exp = 27, + GLSLstd450Log = 28, + GLSLstd450Exp2 = 29, + GLSLstd450Log2 = 30, + GLSLstd450Sqrt = 31, + GLSLstd450InverseSqrt = 32, + + GLSLstd450Determinant = 33, + GLSLstd450MatrixInverse = 34, + + GLSLstd450Modf = 35, // second operand needs an OpVariable to write to + GLSLstd450ModfStruct = 36, // no OpVariable operand + GLSLstd450FMin = 37, + GLSLstd450UMin = 38, + GLSLstd450SMin = 39, + GLSLstd450FMax = 40, + GLSLstd450UMax = 41, + GLSLstd450SMax = 42, + GLSLstd450FClamp = 43, + GLSLstd450UClamp = 44, + GLSLstd450SClamp = 45, + GLSLstd450FMix = 46, + GLSLstd450IMix = 47, // Reserved + GLSLstd450Step = 48, + GLSLstd450SmoothStep = 49, + + GLSLstd450Fma = 50, + GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to + GLSLstd450FrexpStruct = 52, // no OpVariable operand + GLSLstd450Ldexp = 53, + + GLSLstd450PackSnorm4x8 = 54, + GLSLstd450PackUnorm4x8 = 55, + GLSLstd450PackSnorm2x16 = 56, + GLSLstd450PackUnorm2x16 = 57, + GLSLstd450PackHalf2x16 = 58, + GLSLstd450PackDouble2x32 = 59, + GLSLstd450UnpackSnorm2x16 = 60, + GLSLstd450UnpackUnorm2x16 = 61, + GLSLstd450UnpackHalf2x16 = 62, + GLSLstd450UnpackSnorm4x8 = 63, + GLSLstd450UnpackUnorm4x8 = 64, + GLSLstd450UnpackDouble2x32 = 65, + + GLSLstd450Length = 66, + GLSLstd450Distance = 67, + GLSLstd450Cross = 68, + GLSLstd450Normalize = 69, + GLSLstd450FaceForward = 70, + GLSLstd450Reflect = 71, + GLSLstd450Refract = 72, + + GLSLstd450FindILsb = 73, + GLSLstd450FindSMsb = 74, + GLSLstd450FindUMsb = 75, + + GLSLstd450InterpolateAtCentroid = 76, + GLSLstd450InterpolateAtSample = 77, + GLSLstd450InterpolateAtOffset = 78, + + GLSLstd450NMin = 79, + GLSLstd450NMax = 80, + GLSLstd450NClamp = 81, + + GLSLstd450Count +}; + +#endif // #ifndef GLSLstd450_H diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/OpenCL.std.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/OpenCL.std.h new file mode 100644 index 000000000000..19a6688490c7 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/OpenCL.std.h @@ -0,0 +1,210 @@ +/* +** Copyright (c) 2015-2017 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +namespace OpenCLLIB { + +enum Entrypoints { + + // Section 2.1: Math extended instructions + Acos = 0, + Acosh = 1, + Acospi = 2, + Asin = 3, + Asinh = 4, + Asinpi = 5, + Atan = 6, + Atan2 = 7, + Atanh = 8, + Atanpi = 9, + Atan2pi = 10, + Cbrt = 11, + Ceil = 12, + Copysign = 13, + Cos = 14, + Cosh = 15, + Cospi = 16, + Erfc = 17, + Erf = 18, + Exp = 19, + Exp2 = 20, + Exp10 = 21, + Expm1 = 22, + Fabs = 23, + Fdim = 24, + Floor = 25, + Fma = 26, + Fmax = 27, + Fmin = 28, + Fmod = 29, + Fract = 30, + Frexp = 31, + Hypot = 32, + Ilogb = 33, + Ldexp = 34, + Lgamma = 35, + Lgamma_r = 36, + Log = 37, + Log2 = 38, + Log10 = 39, + Log1p = 40, + Logb = 41, + Mad = 42, + Maxmag = 43, + Minmag = 44, + Modf = 45, + Nan = 46, + Nextafter = 47, + Pow = 48, + Pown = 49, + Powr = 50, + Remainder = 51, + Remquo = 52, + Rint = 53, + Rootn = 54, + Round = 55, + Rsqrt = 56, + Sin = 57, + Sincos = 58, + Sinh = 59, + Sinpi = 60, + Sqrt = 61, + Tan = 62, + Tanh = 63, + Tanpi = 64, + Tgamma = 65, + Trunc = 66, + Half_cos = 67, + Half_divide = 68, + Half_exp = 69, + Half_exp2 = 70, + Half_exp10 = 71, + Half_log = 72, + Half_log2 = 73, + Half_log10 = 74, + Half_powr = 75, + Half_recip = 76, + Half_rsqrt = 77, + Half_sin = 78, + Half_sqrt = 79, + Half_tan = 80, + Native_cos = 81, + Native_divide = 82, + Native_exp = 83, + Native_exp2 = 84, + Native_exp10 = 85, + Native_log = 86, + Native_log2 = 87, + Native_log10 = 88, + Native_powr = 89, + Native_recip = 90, + Native_rsqrt = 91, + Native_sin = 92, + Native_sqrt = 93, + Native_tan = 94, + + // Section 2.2: Integer instructions + SAbs = 141, + SAbs_diff = 142, + SAdd_sat = 143, + UAdd_sat = 144, + SHadd = 145, + UHadd = 146, + SRhadd = 147, + URhadd = 148, + SClamp = 149, + UClamp = 150, + Clz = 151, + Ctz = 152, + SMad_hi = 153, + UMad_sat = 154, + SMad_sat = 155, + SMax = 156, + UMax = 157, + SMin = 158, + UMin = 159, + SMul_hi = 160, + Rotate = 161, + SSub_sat = 162, + USub_sat = 163, + U_Upsample = 164, + S_Upsample = 165, + Popcount = 166, + SMad24 = 167, + UMad24 = 168, + SMul24 = 169, + UMul24 = 170, + UAbs = 201, + UAbs_diff = 202, + UMul_hi = 203, + UMad_hi = 204, + + // Section 2.3: Common instructions + FClamp = 95, + Degrees = 96, + FMax_common = 97, + FMin_common = 98, + Mix = 99, + Radians = 100, + Step = 101, + Smoothstep = 102, + Sign = 103, + + // Section 2.4: Geometric instructions + Cross = 104, + Distance = 105, + Length = 106, + Normalize = 107, + Fast_distance = 108, + Fast_length = 109, + Fast_normalize = 110, + + // Section 2.5: Relational instructions + Bitselect = 186, + Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + Vloadn = 171, + Vstoren = 172, + Vload_half = 173, + Vload_halfn = 174, + Vstore_half = 175, + Vstore_half_r = 176, + Vstore_halfn = 177, + Vstore_halfn_r = 178, + Vloada_halfn = 179, + Vstorea_halfn = 180, + Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + Shuffle = 182, + Shuffle2 = 183, + + // Section 2.8: Misc instructions + Printf = 184, + Prefetch = 185, +}; + +} // end namespace OpenCLLIB diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/extinst.glsl.std.450.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/extinst.glsl.std.450.grammar.json new file mode 100644 index 000000000000..3d9f39e76c9c --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/extinst.glsl.std.450.grammar.json @@ -0,0 +1,642 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "Round", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "RoundEven", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Trunc", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FAbs", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SAbs", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FSign", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SSign", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Floor", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ceil", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fract", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Radians", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "Degrees", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "Sin", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tan", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asin", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acos", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'y_over_x'" } + ] + }, + { + "opname" : "Sinh", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cosh", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tanh", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asinh", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acosh", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atanh", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan2", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Pow", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Exp", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Exp2", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log2", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Sqrt", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "InverseSqrt", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Determinant", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "MatrixInverse", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Modf", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "ModfStruct", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FMin", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMin", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMin", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FMax", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMax", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMax", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FClamp", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "UClamp", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "SClamp", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "FMix", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "IMix", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "Step", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SmoothStep", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fma", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "Frexp", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "FrexpStruct", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ldexp", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "PackSnorm4x8", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm4x8", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackSnorm2x16", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm2x16", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackHalf2x16", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackDouble2x32", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "UnpackSnorm2x16", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm2x16", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackHalf2x16", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "UnpackSnorm4x8", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm4x8", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackDouble2x32", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "Length", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Distance", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "Cross", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Normalize", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FaceForward", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'Nref'" } + ] + }, + { + "opname" : "Reflect", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" } + ] + }, + { + "opname" : "Refract", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'eta'" } + ] + }, + { + "opname" : "FindILsb", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindSMsb", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindUMsb", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "InterpolateAtCentroid", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtSample", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'sample'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtOffset", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "NMin", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NMax", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NClamp", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/extinst.opencl.std.100.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/extinst.opencl.std.100.grammar.json new file mode 100644 index 000000000000..4fe45060bb98 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/extinst.opencl.std.100.grammar.json @@ -0,0 +1,1279 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "acos", + "opcode" : 0, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acosh", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acospi", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asin", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinh", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinpi", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanh", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanpi", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2pi", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cbrt", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ceil", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "copysign", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cosh", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cospi", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erfc", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erf", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp2", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp10", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "expm1", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fabs", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fdim", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "floor", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fma", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fmax", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmod", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fract", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'ptr'" } + ] + }, + { + "opname" : "frexp", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "hypot", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "ilogb", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ldexp", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'k'" } + ] + }, + { + "opname" : "lgamma", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "lgamma_r", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'signp'" } + ] + }, + { + "opname" : "log", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log2", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log10", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log1p", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "logb", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "mad", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "maxmag", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "minmag", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "modf", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'iptr'" } + ] + }, + { + "opname" : "nan", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'nancode'" } + ] + }, + { + "opname" : "nextafter", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "pow", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y" } + ] + }, + { + "opname" : "pown", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "powr", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remainder", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remquo", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'quo'" } + ] + }, + { + "opname" : "rint", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rootn", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "round", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rsqrt", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sin", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sincos", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'cosval'" } + ] + }, + { + "opname" : "sinh", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sinpi", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sqrt", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tan", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanh", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanpi", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tgamma", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "trunc", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_cos", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_divide", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_exp", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp2", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp10", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log2", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log10", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_powr", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_recip", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_rsqrt", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sin", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sqrt", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_tan", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_cos", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_divide", + "opcode" : 82, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_exp", + "opcode" : 83, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp2", + "opcode" : 84, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp10", + "opcode" : 85, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log", + "opcode" : 86, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log2", + "opcode" : 87, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log10", + "opcode" : 88, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_powr", + "opcode" : 89, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_recip", + "opcode" : 90, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_rsqrt", + "opcode" : 91, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sin", + "opcode" : 92, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sqrt", + "opcode" : 93, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_tan", + "opcode" : 94, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs", + "opcode" : 141, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs_diff", + "opcode" : 142, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_add_sat", + "opcode" : 143, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_add_sat", + "opcode" : 144, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_hadd", + "opcode" : 145, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_hadd", + "opcode" : 146, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_rhadd", + "opcode" : 147, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_rhadd", + "opcode" : 148, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_clamp", + "opcode" : 149, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "u_clamp", + "opcode" : 150, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "clz", + "opcode" : 151, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ctz", + "opcode" : 152, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad_hi", + "opcode" : 153, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "u_mad_sat", + "opcode" : 154, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mad_sat", + "opcode" : 155, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_max", + "opcode" : 156, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_max", + "opcode" : 157, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_min", + "opcode" : 158, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_min", + "opcode" : 159, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_mul_hi", + "opcode" : 160, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "rotate", + "opcode" : 161, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "s_sub_sat", + "opcode" : 162, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_sub_sat", + "opcode" : 163, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_upsample", + "opcode" : 164, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "s_upsample", + "opcode" : 165, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "popcount", + "opcode" : 166, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad24", + "opcode" : 167, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "u_mad24", + "opcode" : 168, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mul24", + "opcode" : 169, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul24", + "opcode" : 170, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_abs", + "opcode" : 201, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "u_abs_diff", + "opcode" : 202, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul_hi", + "opcode" : 203, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mad_hi", + "opcode" : 204, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fclamp", + "opcode" : 95, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "degrees", + "opcode" :96, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "fmax_common", + "opcode" : 97, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin_common", + "opcode" : 98, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "mix", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "radians", + "opcode" : 100, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "step", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "smoothstep", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sign", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cross", + "opcode" : 104, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "distance", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "length", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "normalize", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_distance", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "fast_length", + "opcode" : 109, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_normalize", + "opcode" : 110, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "bitselect", + "opcode" : 186, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "select", + "opcode" : 187, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "vloadn", + "opcode" : 171, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstoren", + "opcode" : 172, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_half", + "opcode" : 173, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_halfn", + "opcode" : 174, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstore_half", + "opcode" : 175, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_half_r", + "opcode" : 176, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vstore_halfn", + "opcode" : 177, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_halfn_r", + "opcode" : 178, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vloada_halfn", + "opcode" : 179, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstorea_halfn", + "opcode" : 180, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstorea_halfn_r", + "opcode" : 181, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "shuffle", + "opcode" : 182, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "shuffle2", + "opcode" : 183, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "printf", + "opcode" : 184, + "operands" : [ + { "kind" : "IdRef", "name" : "'format'" }, + { "kind" : "IdRef", "name" : "'additional arguments'", "quantifier" : "*" } + ] + }, + { + "opname" : "prefetch", + "opcode" : 185, + "operands" : [ + { "kind" : "IdRef", "name" : "'ptr'" }, + { "kind" : "IdRef", "name" : "'num elements'" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.core.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.core.grammar.json new file mode 100644 index 000000000000..c142e60a1750 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.core.grammar.json @@ -0,0 +1,5938 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "magic_number" : "0x07230203", + "major_version" : 1, + "minor_version" : 1, + "revision" : 8, + "instructions" : [ + { + "opname" : "OpNop", + "opcode" : 0 + }, + { + "opname" : "OpUndef", + "opcode" : 1, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSourceContinued", + "opcode" : 2, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Continued Source'" } + ] + }, + { + "opname" : "OpSource", + "opcode" : 3, + "operands" : [ + { "kind" : "SourceLanguage" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" }, + { "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" } + ] + }, + { + "opname" : "OpSourceExtension", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Extension'" } + ] + }, + { + "opname" : "OpName", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpMemberName", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpString", + "opcode" : 7, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'String'" } + ] + }, + { + "opname" : "OpLine", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "OpExtension", + "opcode" : 10, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInstImport", + "opcode" : 11, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInst", + "opcode" : 12, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ] + }, + { + "opname" : "OpMemoryModel", + "opcode" : 14, + "operands" : [ + { "kind" : "AddressingModel" }, + { "kind" : "MemoryModel" } + ] + }, + { + "opname" : "OpEntryPoint", + "opcode" : 15, + "operands" : [ + { "kind" : "ExecutionModel" }, + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } + ] + }, + { + "opname" : "OpExecutionMode", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ] + }, + { + "opname" : "OpCapability", + "opcode" : 17, + "operands" : [ + { "kind" : "Capability", "name" : "'Capability'" } + ] + }, + { + "opname" : "OpTypeVoid", + "opcode" : 19, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeBool", + "opcode" : 20, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeInt", + "opcode" : 21, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" }, + { "kind" : "LiteralInteger", "name" : "'Signedness'" } + ] + }, + { + "opname" : "OpTypeFloat", + "opcode" : 22, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" } + ] + }, + { + "opname" : "OpTypeVector", + "opcode" : 23, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "OpTypeMatrix", + "opcode" : 24, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Column Type'" }, + { "kind" : "LiteralInteger", "name" : "'Column Count'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpTypeImage", + "opcode" : 25, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Type'" }, + { "kind" : "Dim" }, + { "kind" : "LiteralInteger", "name" : "'Depth'" }, + { "kind" : "LiteralInteger", "name" : "'Arrayed'" }, + { "kind" : "LiteralInteger", "name" : "'MS'" }, + { "kind" : "LiteralInteger", "name" : "'Sampled'" }, + { "kind" : "ImageFormat" }, + { "kind" : "AccessQualifier", "quantifier" : "?" } + ] + }, + { + "opname" : "OpTypeSampler", + "opcode" : 26, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeSampledImage", + "opcode" : 27, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ] + }, + { + "opname" : "OpTypeArray", + "opcode" : 28, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" }, + { "kind" : "IdRef", "name" : "'Length'" } + ] + }, + { + "opname" : "OpTypeRuntimeArray", + "opcode" : 29, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpTypeStruct", + "opcode" : 30, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ] + }, + { + "opname" : "OpTypeOpaque", + "opcode" : 31, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "The name of the opaque type." } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypePointer", + "opcode" : 32, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "name" : "'Type'" } + ] + }, + { + "opname" : "OpTypeFunction", + "opcode" : 33, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." } + ] + }, + { + "opname" : "OpTypeEvent", + "opcode" : 34, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypeDeviceEvent", + "opcode" : 35, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypeReserveId", + "opcode" : 36, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeQueue", + "opcode" : 37, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypePipe", + "opcode" : 38, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "AccessQualifier", "name" : "'Qualifier'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeForwardPointer", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer Type'" }, + { "kind" : "StorageClass" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpConstantTrue", + "opcode" : 41, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstantFalse", + "opcode" : 42, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstant", + "opcode" : 43, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConstantComposite", + "opcode" : 44, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpConstantSampler", + "opcode" : 45, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "SamplerAddressingMode" }, + { "kind" : "LiteralInteger", "name" : "'Param'" }, + { "kind" : "SamplerFilterMode" } + ], + "capabilities" : [ "LiteralSampler" ] + }, + { + "opname" : "OpConstantNull", + "opcode" : 46, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantTrue", + "opcode" : 48, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantFalse", + "opcode" : 49, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstant", + "opcode" : 50, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpSpecConstantComposite", + "opcode" : 51, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpSpecConstantOp", + "opcode" : 52, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" } + ] + }, + { + "opname" : "OpFunction", + "opcode" : 54, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "FunctionControl" }, + { "kind" : "IdRef", "name" : "'Function Type'" } + ] + }, + { + "opname" : "OpFunctionParameter", + "opcode" : 55, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpFunctionEnd", + "opcode" : 56 + }, + { + "opname" : "OpFunctionCall", + "opcode" : 57, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." } + ] + }, + { + "opname" : "OpVariable", + "opcode" : 59, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" } + ] + }, + { + "opname" : "OpImageTexelPointer", + "opcode" : 60, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Sample'" } + ] + }, + { + "opname" : "OpLoad", + "opcode" : 61, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpStore", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemory", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemorySized", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpAccessChain", + "opcode" : 65, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpInBoundsAccessChain", + "opcode" : 66, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpPtrAccessChain", + "opcode" : 67, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ + "Addresses", + "VariablePointers", + "VariablePointersStorageBuffer" + ] + }, + { + "opname" : "OpArrayLength", + "opcode" : 68, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Structure'" }, + { "kind" : "LiteralInteger", "name" : "'Array member'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpGenericPtrMemSemantics", + "opcode" : 69, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpInBoundsPtrAccessChain", + "opcode" : 70, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpDecorate", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpMemberDecorate", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'Structure Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpDecorationGroup", + "opcode" : 73, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpGroupDecorate", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpGroupMemberDecorate", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpVectorExtractDynamic", + "opcode" : 77, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorInsertDynamic", + "opcode" : 78, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorShuffle", + "opcode" : 79, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" } + ] + }, + { + "opname" : "OpCompositeConstruct", + "opcode" : 80, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpCompositeExtract", + "opcode" : 81, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCompositeInsert", + "opcode" : 82, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCopyObject", + "opcode" : 83, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpTranspose", + "opcode" : 84, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpSampledImage", + "opcode" : 86, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ] + }, + { + "opname" : "OpImageSampleImplicitLod", + "opcode" : 87, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleExplicitLod", + "opcode" : 88, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ] + }, + { + "opname" : "OpImageSampleDrefImplicitLod", + "opcode" : 89, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleDrefExplicitLod", + "opcode" : 90, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjImplicitLod", + "opcode" : 91, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjExplicitLod", + "opcode" : 92, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefImplicitLod", + "opcode" : 93, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefExplicitLod", + "opcode" : 94, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageFetch", + "opcode" : 95, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageGather", + "opcode" : 96, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageDrefGather", + "opcode" : 97, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageRead", + "opcode" : 98, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageWrite", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Texel'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImage", + "opcode" : 100, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" } + ] + }, + { + "opname" : "OpImageQueryFormat", + "opcode" : 101, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQueryOrder", + "opcode" : 102, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQuerySizeLod", + "opcode" : 103, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Level of Detail'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySize", + "opcode" : 104, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLod", + "opcode" : 105, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLevels", + "opcode" : 106, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySamples", + "opcode" : 107, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpConvertFToU", + "opcode" : 109, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertFToS", + "opcode" : 110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertSToF", + "opcode" : 111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpConvertUToF", + "opcode" : 112, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpUConvert", + "opcode" : 113, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpSConvert", + "opcode" : 114, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpFConvert", + "opcode" : 115, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpQuantizeToF16", + "opcode" : 116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConvertPtrToU", + "opcode" : 117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpSatConvertSToU", + "opcode" : 118, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSatConvertUToS", + "opcode" : 119, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpConvertUToPtr", + "opcode" : 120, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Integer Value'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpPtrCastToGeneric", + "opcode" : 121, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtr", + "opcode" : 122, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtrExplicit", + "opcode" : 123, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "StorageClass", "name" : "'Storage'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpBitcast", + "opcode" : 124, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSNegate", + "opcode" : 126, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpFNegate", + "opcode" : 127, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpIAdd", + "opcode" : 128, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFAdd", + "opcode" : 129, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISub", + "opcode" : 130, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFSub", + "opcode" : 131, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpIMul", + "opcode" : 132, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMul", + "opcode" : 133, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUDiv", + "opcode" : 134, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSDiv", + "opcode" : 135, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFDiv", + "opcode" : 136, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMod", + "opcode" : 137, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSRem", + "opcode" : 138, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMod", + "opcode" : 139, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFRem", + "opcode" : 140, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMod", + "opcode" : 141, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpVectorTimesScalar", + "opcode" : 142, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ] + }, + { + "opname" : "OpMatrixTimesScalar", + "opcode" : 143, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpVectorTimesMatrix", + "opcode" : 144, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesVector", + "opcode" : 145, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesMatrix", + "opcode" : 146, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'LeftMatrix'" }, + { "kind" : "IdRef", "name" : "'RightMatrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpOuterProduct", + "opcode" : 147, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpDot", + "opcode" : 148, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ] + }, + { + "opname" : "OpIAddCarry", + "opcode" : 149, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISubBorrow", + "opcode" : 150, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMulExtended", + "opcode" : 151, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMulExtended", + "opcode" : 152, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpAny", + "opcode" : 154, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpAll", + "opcode" : 155, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpIsNan", + "opcode" : 156, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsInf", + "opcode" : 157, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsFinite", + "opcode" : 158, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpIsNormal", + "opcode" : 159, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSignBitSet", + "opcode" : 160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLessOrGreater", + "opcode" : 161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpOrdered", + "opcode" : 162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpUnordered", + "opcode" : 163, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLogicalEqual", + "opcode" : 164, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNotEqual", + "opcode" : 165, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalOr", + "opcode" : 166, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalAnd", + "opcode" : 167, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNot", + "opcode" : 168, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSelect", + "opcode" : 169, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'Object 1'" }, + { "kind" : "IdRef", "name" : "'Object 2'" } + ] + }, + { + "opname" : "OpIEqual", + "opcode" : 170, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpINotEqual", + "opcode" : 171, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThan", + "opcode" : 172, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThan", + "opcode" : 173, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThanEqual", + "opcode" : 174, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThanEqual", + "opcode" : 175, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThan", + "opcode" : 176, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThan", + "opcode" : 177, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThanEqual", + "opcode" : 178, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThanEqual", + "opcode" : 179, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdEqual", + "opcode" : 180, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordEqual", + "opcode" : 181, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdNotEqual", + "opcode" : 182, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordNotEqual", + "opcode" : 183, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThan", + "opcode" : 184, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThan", + "opcode" : 185, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThan", + "opcode" : 186, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThan", + "opcode" : 187, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThanEqual", + "opcode" : 188, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThanEqual", + "opcode" : 189, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThanEqual", + "opcode" : 190, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThanEqual", + "opcode" : 191, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpShiftRightLogical", + "opcode" : 194, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftRightArithmetic", + "opcode" : 195, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftLeftLogical", + "opcode" : 196, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpBitwiseOr", + "opcode" : 197, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseXor", + "opcode" : 198, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseAnd", + "opcode" : 199, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpNot", + "opcode" : 200, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpBitFieldInsert", + "opcode" : 201, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Insert'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldSExtract", + "opcode" : 202, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldUExtract", + "opcode" : 203, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitReverse", + "opcode" : 204, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitCount", + "opcode" : 205, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ] + }, + { + "opname" : "OpDPdx", + "opcode" : 207, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdy", + "opcode" : 208, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpFwidth", + "opcode" : 209, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdxFine", + "opcode" : 210, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyFine", + "opcode" : 211, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthFine", + "opcode" : 212, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdxCoarse", + "opcode" : 213, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyCoarse", + "opcode" : 214, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthCoarse", + "opcode" : 215, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpEmitVertex", + "opcode" : 218, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEndPrimitive", + "opcode" : 219, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEmitStreamVertex", + "opcode" : 220, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpEndStreamPrimitive", + "opcode" : 221, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpControlBarrier", + "opcode" : 224, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpMemoryBarrier", + "opcode" : 225, + "operands" : [ + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicLoad", + "opcode" : 227, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicStore", + "opcode" : 228, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicExchange", + "opcode" : 229, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicCompareExchange", + "opcode" : 230, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ] + }, + { + "opname" : "OpAtomicCompareExchangeWeak", + "opcode" : 231, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicIIncrement", + "opcode" : 232, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIDecrement", + "opcode" : 233, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIAdd", + "opcode" : 234, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicISub", + "opcode" : 235, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMin", + "opcode" : 236, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMin", + "opcode" : 237, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMax", + "opcode" : 238, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMax", + "opcode" : 239, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicAnd", + "opcode" : 240, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicOr", + "opcode" : 241, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicXor", + "opcode" : 242, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpPhi", + "opcode" : 245, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" } + ] + }, + { + "opname" : "OpLoopMerge", + "opcode" : 246, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "IdRef", "name" : "'Continue Target'" }, + { "kind" : "LoopControl" } + ] + }, + { + "opname" : "OpSelectionMerge", + "opcode" : 247, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "SelectionControl" } + ] + }, + { + "opname" : "OpLabel", + "opcode" : 248, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpBranch", + "opcode" : 249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target Label'" } + ] + }, + { + "opname" : "OpBranchConditional", + "opcode" : 250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'True Label'" }, + { "kind" : "IdRef", "name" : "'False Label'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" } + ] + }, + { + "opname" : "OpSwitch", + "opcode" : 251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Selector'" }, + { "kind" : "IdRef", "name" : "'Default'" }, + { "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" } + ] + }, + { + "opname" : "OpKill", + "opcode" : 252, + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpReturn", + "opcode" : 253 + }, + { + "opname" : "OpReturnValue", + "opcode" : 254, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpUnreachable", + "opcode" : 255 + }, + { + "opname" : "OpLifetimeStart", + "opcode" : 256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLifetimeStop", + "opcode" : 257, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAsyncCopy", + "opcode" : 259, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Destination'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Num Elements'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupWaitEvents", + "opcode" : 260, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Events List'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAll", + "opcode" : 261, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupAny", + "opcode" : 262, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupBroadcast", + "opcode" : 263, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'LocalId'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupIAdd", + "opcode" : 264, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAdd", + "opcode" : 265, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMin", + "opcode" : 266, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMin", + "opcode" : 267, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMin", + "opcode" : 268, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMax", + "opcode" : 269, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMax", + "opcode" : 270, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMax", + "opcode" : 271, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpReadPipe", + "opcode" : 274, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpWritePipe", + "opcode" : 275, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedReadPipe", + "opcode" : 276, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedWritePipe", + "opcode" : 277, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveReadPipePackets", + "opcode" : 278, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveWritePipePackets", + "opcode" : 279, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitReadPipe", + "opcode" : 280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitWritePipe", + "opcode" : 281, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpIsValidReserveId", + "opcode" : 282, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetNumPipePackets", + "opcode" : 283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetMaxPipePackets", + "opcode" : 284, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveReadPipePackets", + "opcode" : 285, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveWritePipePackets", + "opcode" : 286, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitReadPipe", + "opcode" : 287, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitWritePipe", + "opcode" : 288, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpEnqueueMarker", + "opcode" : 291, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpEnqueueKernel", + "opcode" : 292, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeSubGroupCount", + "opcode" : 293, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeMaxSubGroupSize", + "opcode" : 294, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelWorkGroupSize", + "opcode" : 295, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelPreferredWorkGroupSizeMultiple", + "opcode" : 296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpRetainEvent", + "opcode" : 297, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpReleaseEvent", + "opcode" : 298, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCreateUserEvent", + "opcode" : 299, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpIsValidEvent", + "opcode" : 300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpSetUserEventStatus", + "opcode" : 301, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Status'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCaptureEventProfilingInfo", + "opcode" : 302, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Profiling Info'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetDefaultQueue", + "opcode" : 303, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpBuildNDRange", + "opcode" : 304, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'GlobalWorkSize'" }, + { "kind" : "IdRef", "name" : "'LocalWorkSize'" }, + { "kind" : "IdRef", "name" : "'GlobalWorkOffset'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpImageSparseSampleImplicitLod", + "opcode" : 305, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleExplicitLod", + "opcode" : 306, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefImplicitLod", + "opcode" : 307, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefExplicitLod", + "opcode" : 308, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjImplicitLod", + "opcode" : 309, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjExplicitLod", + "opcode" : 310, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefImplicitLod", + "opcode" : 311, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefExplicitLod", + "opcode" : 312, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseFetch", + "opcode" : 313, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseGather", + "opcode" : 314, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseDrefGather", + "opcode" : 315, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseTexelsResident", + "opcode" : 316, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Resident Code'" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpNoLine", + "opcode" : 317 + }, + { + "opname" : "OpAtomicFlagTestAndSet", + "opcode" : 318, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicFlagClear", + "opcode" : 319, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageSparseRead", + "opcode" : 320, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpSizeOf", + "opcode" : 321, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpTypePipeStorage", + "opcode" : 322, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpConstantPipeStorage", + "opcode" : 323, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Packet Size'" }, + { "kind" : "LiteralInteger", "name" : "'Packet Alignment'" }, + { "kind" : "LiteralInteger", "name" : "'Capacity'" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpCreatePipeFromPipeStorage", + "opcode" : 324, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe Storage'" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpGetKernelLocalSizeForSubgroupCount", + "opcode" : 325, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ] + }, + { + "opname" : "OpGetKernelMaxNumSubgroups", + "opcode" : 326, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ] + }, + { + "opname" : "OpTypeNamedBarrier", + "opcode" : 327, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpNamedBarrierInitialize", + "opcode" : 328, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpMemoryNamedBarrier", + "opcode" : 329, + "operands" : [ + { "kind" : "IdRef", "name" : "'Named Barrier'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpModuleProcessed", + "opcode" : 330, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Process'" } + ] + }, + { + "opname" : "OpDecorateId", + "opcode" : 332, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "opname" : "OpSubgroupBallotKHR", + "opcode" : 4421, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupFirstInvocationKHR", + "opcode" : 4422, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupAllKHR", + "opcode" : 4428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAnyKHR", + "opcode" : 4429, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAllEqualKHR", + "opcode" : 4430, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupReadInvocationKHR", + "opcode" : 4432, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpGroupIAddNonUniformAMD", + "opcode" : 5000, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAddNonUniformAMD", + "opcode" : 5001, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMinNonUniformAMD", + "opcode" : 5002, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMinNonUniformAMD", + "opcode" : 5003, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMinNonUniformAMD", + "opcode" : 5004, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMaxNonUniformAMD", + "opcode" : 5005, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMaxNonUniformAMD", + "opcode" : 5006, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMaxNonUniformAMD", + "opcode" : 5007, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpFragmentMaskFetchAMD", + "opcode" : 5011, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpFragmentFetchAMD", + "opcode" : 5012, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Fragment Index'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpSubgroupShuffleINTEL", + "opcode" : 5571, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'InvocationId'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleDownINTEL", + "opcode" : 5572, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Next'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleUpINTEL", + "opcode" : 5573, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Previous'" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleXorINTEL", + "opcode" : 5574, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupBlockReadINTEL", + "opcode" : 5575, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupBlockWriteINTEL", + "opcode" : 5576, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockReadINTEL", + "opcode" : 5577, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockWriteINTEL", + "opcode" : 5578, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpDecorateStringGOOGLE", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + }, + { + "opname" : "OpMemberDecorateStringGOOGLE", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "ImageOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Bias", + "value" : "0x0001", + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Lod", + "value" : "0x0002", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Grad", + "value" : "0x0004", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffset", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Offset", + "value" : "0x0010", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffsets", + "value" : "0x0020", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Sample", + "value" : "0x0040", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "MinLod", + "value" : "0x0080", + "capabilities" : [ "MinLod" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FPFastMathMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "NotNaN", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NotInf", + "value" : "0x0002", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NSZ", + "value" : "0x0004", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AllowRecip", + "value" : "0x0008", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Fast", + "value" : "0x0010", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "SelectionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Flatten", + "value" : "0x0001" + }, + { + "enumerant" : "DontFlatten", + "value" : "0x0002" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "LoopControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Unroll", + "value" : "0x0001" + }, + { + "enumerant" : "DontUnroll", + "value" : "0x0002" + }, + { + "enumerant" : "DependencyInfinite", + "value" : "0x0004" + }, + { + "enumerant" : "DependencyLength", + "value" : "0x0008", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FunctionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Inline", + "value" : "0x0001" + }, + { + "enumerant" : "DontInline", + "value" : "0x0002" + }, + { + "enumerant" : "Pure", + "value" : "0x0004" + }, + { + "enumerant" : "Const", + "value" : "0x0008" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemorySemantics", + "enumerants" : [ + { + "enumerant" : "Relaxed", + "value" : "0x0000" + }, + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Acquire", + "value" : "0x0002" + }, + { + "enumerant" : "Release", + "value" : "0x0004" + }, + { + "enumerant" : "AcquireRelease", + "value" : "0x0008" + }, + { + "enumerant" : "SequentiallyConsistent", + "value" : "0x0010" + }, + { + "enumerant" : "UniformMemory", + "value" : "0x0040", + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupMemory", + "value" : "0x0080" + }, + { + "enumerant" : "WorkgroupMemory", + "value" : "0x0100" + }, + { + "enumerant" : "CrossWorkgroupMemory", + "value" : "0x0200" + }, + { + "enumerant" : "AtomicCounterMemory", + "value" : "0x0400", + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "ImageMemory", + "value" : "0x0800" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemoryAccess", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Volatile", + "value" : "0x0001" + }, + { + "enumerant" : "Aligned", + "value" : "0x0002", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Nontemporal", + "value" : "0x0004" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "KernelProfilingInfo", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "CmdExecTime", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SourceLanguage", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "ESSL", + "value" : 1 + }, + { + "enumerant" : "GLSL", + "value" : 2 + }, + { + "enumerant" : "OpenCL_C", + "value" : 3 + }, + { + "enumerant" : "OpenCL_CPP", + "value" : 4 + }, + { + "enumerant" : "HLSL", + "value" : 5 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionModel", + "enumerants" : [ + { + "enumerant" : "Vertex", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TessellationControl", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessellationEvaluation", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Geometry", + "value" : 3, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Fragment", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLCompute", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Kernel", + "value" : 6, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AddressingModel", + "enumerants" : [ + { + "enumerant" : "Logical", + "value" : 0 + }, + { + "enumerant" : "Physical32", + "value" : 1, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Physical64", + "value" : 2, + "capabilities" : [ "Addresses" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "MemoryModel", + "enumerants" : [ + { + "enumerant" : "Simple", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSL450", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OpenCL", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionMode", + "enumerants" : [ + { + "enumerant" : "Invocations", + "value" : 0, + "capabilities" : [ "Geometry" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of <>'" } + ] + }, + { + "enumerant" : "SpacingEqual", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalEven", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalOdd", + "value" : 3, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCw", + "value" : 4, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCcw", + "value" : 5, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PixelCenterInteger", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginUpperLeft", + "value" : 7, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginLowerLeft", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "EarlyFragmentTests", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointMode", + "value" : 10, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Xfb", + "value" : 11, + "capabilities" : [ "TransformFeedback" ] + }, + { + "enumerant" : "DepthReplacing", + "value" : 12, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthGreater", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthLess", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthUnchanged", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "LocalSize", + "value" : 17, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "LocalSizeHint", + "value" : 18, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "InputPoints", + "value" : 19, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLines", + "value" : 20, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLinesAdjacency", + "value" : 21, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Triangles", + "value" : 22, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InputTrianglesAdjacency", + "value" : 23, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Quads", + "value" : 24, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Isolines", + "value" : 25, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "OutputVertices", + "value" : 26, + "capabilities" : [ "Geometry", "Tessellation" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vertex count'" } + ] + }, + { + "enumerant" : "OutputPoints", + "value" : 27, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputLineStrip", + "value" : 28, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputTriangleStrip", + "value" : 29, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "VecTypeHint", + "value" : 30, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vector type'" } + ] + }, + { + "enumerant" : "ContractionOff", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Initializer", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Finalizer", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 35, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroup Size'" } + ] + }, + { + "enumerant" : "SubgroupsPerWorkgroup", + "value" : 36, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroups Per Workgroup'" } + ] + }, + { + "enumerant" : "PostDepthCoverage", + "value" : 4446, + "capabilities" : [ "SampleMaskPostDepthCoverage" ] + }, + { + "enumerant" : "StencilRefReplacingEXT", + "value" : 5027, + "capabilities" : [ "StencilExportEXT" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StorageClass", + "enumerants" : [ + { + "enumerant" : "UniformConstant", + "value" : 0 + }, + { + "enumerant" : "Input", + "value" : 1 + }, + { + "enumerant" : "Uniform", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Output", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Workgroup", + "value" : 4 + }, + { + "enumerant" : "CrossWorkgroup", + "value" : 5 + }, + { + "enumerant" : "Private", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Function", + "value" : 7 + }, + { + "enumerant" : "Generic", + "value" : 8, + "capabilities" : [ "GenericPointer" ] + }, + { + "enumerant" : "PushConstant", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "AtomicCounter", + "value" : 10, + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "Image", + "value" : 11 + }, + { + "enumerant" : "StorageBuffer", + "value" : 12, + "extensions" : [ + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers" + ], + "capabilities" : [ "Shader" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Dim", + "enumerants" : [ + { + "enumerant" : "1D", + "value" : 0, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "2D", + "value" : 1 + }, + { + "enumerant" : "3D", + "value" : 2 + }, + { + "enumerant" : "Cube", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rect", + "value" : 4, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "Buffer", + "value" : 5, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "SubpassData", + "value" : 6, + "capabilities" : [ "InputAttachment" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerAddressingMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ClampToEdge", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Clamp", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Repeat", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RepeatMirrored", + "value" : 4, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerFilterMode", + "enumerants" : [ + { + "enumerant" : "Nearest", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Linear", + "value" : 1, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageFormat", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "Rgba32f", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16f", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32f", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8Snorm", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32f", + "value" : 6, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16f", + "value" : 7, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R11fG11fB10f", + "value" : 8, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16f", + "value" : 9, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16", + "value" : 10, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgb10A2", + "value" : 11, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16", + "value" : 12, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8", + "value" : 13, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16", + "value" : 14, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8", + "value" : 15, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16Snorm", + "value" : 16, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16Snorm", + "value" : 17, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8Snorm", + "value" : 18, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16Snorm", + "value" : 19, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8Snorm", + "value" : 20, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32i", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16i", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8i", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32i", + "value" : 24, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32i", + "value" : 25, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16i", + "value" : 26, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8i", + "value" : 27, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16i", + "value" : 28, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8i", + "value" : 29, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32ui", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16ui", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8ui", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32ui", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgb10a2ui", + "value" : 34, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg32ui", + "value" : 35, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16ui", + "value" : 36, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8ui", + "value" : 37, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16ui", + "value" : 38, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8ui", + "value" : 39, + "capabilities" : [ "StorageImageExtendedFormats" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelOrder", + "enumerants" : [ + { + "enumerant" : "R", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "A", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RG", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RA", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGB", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBA", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BGRA", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ARGB", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Intensity", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Luminance", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Rx", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGx", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBx", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Depth", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "DepthStencil", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGB", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBx", + "value" : 16, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBA", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sBGRA", + "value" : 18, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ABGR", + "value" : 19, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelDataType", + "enumerants" : [ + { + "enumerant" : "SnormInt8", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SnormInt16", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt8", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt16", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort565", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort555", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt8", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt16", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt32", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt8", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt16", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt32", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "HalfFloat", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt24", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010_2", + "value" : 16, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPRoundingMode", + "enumerants" : [ + { + "enumerant" : "RTE", + "value" : 0, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTZ", + "value" : 1, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTP", + "value" : 2, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTN", + "value" : 3, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LinkageType", + "enumerants" : [ + { + "enumerant" : "Export", + "value" : 0, + "capabilities" : [ "Linkage" ] + }, + { + "enumerant" : "Import", + "value" : 1, + "capabilities" : [ "Linkage" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AccessQualifier", + "enumerants" : [ + { + "enumerant" : "ReadOnly", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WriteOnly", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ReadWrite", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FunctionParameterAttribute", + "enumerants" : [ + { + "enumerant" : "Zext", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sext", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ByVal", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sret", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoAlias", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoCapture", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoWrite", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoReadWrite", + "value" : 7, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Decoration", + "enumerants" : [ + { + "enumerant" : "RelaxedPrecision", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SpecId", + "value" : 1, + "capabilities" : [ "Shader", "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" } + ] + }, + { + "enumerant" : "Block", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "BufferBlock", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "RowMajor", + "value" : 4, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ColMajor", + "value" : 5, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ArrayStride", + "value" : 6, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Array Stride'" } + ] + }, + { + "enumerant" : "MatrixStride", + "value" : 7, + "capabilities" : [ "Matrix" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Matrix Stride'" } + ] + }, + { + "enumerant" : "GLSLShared", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSLPacked", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CPacked", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BuiltIn", + "value" : 11, + "parameters" : [ + { "kind" : "BuiltIn" } + ] + }, + { + "enumerant" : "NoPerspective", + "value" : 13, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Flat", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Patch", + "value" : 15, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Centroid", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sample", + "value" : 17, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "Invariant", + "value" : 18, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Restrict", + "value" : 19 + }, + { + "enumerant" : "Aliased", + "value" : 20 + }, + { + "enumerant" : "Volatile", + "value" : 21 + }, + { + "enumerant" : "Constant", + "value" : 22, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Coherent", + "value" : 23 + }, + { + "enumerant" : "NonWritable", + "value" : 24 + }, + { + "enumerant" : "NonReadable", + "value" : 25 + }, + { + "enumerant" : "Uniform", + "value" : 26, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SaturatedConversion", + "value" : 28, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Stream", + "value" : 29, + "capabilities" : [ "GeometryStreams" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stream Number'" } + ] + }, + { + "enumerant" : "Location", + "value" : 30, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Location'" } + ] + }, + { + "enumerant" : "Component", + "value" : 31, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Component'" } + ] + }, + { + "enumerant" : "Index", + "value" : 32, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Index'" } + ] + }, + { + "enumerant" : "Binding", + "value" : 33, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Binding Point'" } + ] + }, + { + "enumerant" : "DescriptorSet", + "value" : 34, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Descriptor Set'" } + ] + }, + { + "enumerant" : "Offset", + "value" : 35, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Byte Offset'" } + ] + }, + { + "enumerant" : "XfbBuffer", + "value" : 36, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" } + ] + }, + { + "enumerant" : "XfbStride", + "value" : 37, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Stride'" } + ] + }, + { + "enumerant" : "FuncParamAttr", + "value" : 38, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" } + ] + }, + { + "enumerant" : "FPRoundingMode", + "value" : 39, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ], + "parameters" : [ + { "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" } + ] + }, + { + "enumerant" : "FPFastMathMode", + "value" : 40, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" } + ] + }, + { + "enumerant" : "LinkageAttributes", + "value" : 41, + "capabilities" : [ "Linkage" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "LinkageType", "name" : "'Linkage Type'" } + ] + }, + { + "enumerant" : "NoContraction", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InputAttachmentIndex", + "value" : 43, + "capabilities" : [ "InputAttachment" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Attachment Index'" } + ] + }, + { + "enumerant" : "Alignment", + "value" : 44, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Alignment'" } + ] + }, + { + "enumerant" : "MaxByteOffset", + "value" : 45, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Max Byte Offset'" } + ] + }, + { + "enumerant" : "ExplicitInterpAMD", + "value" : 4999 + }, + { + "enumerant" : "OverrideCoverageNV", + "value" : 5248, + "capabilities" : [ "SampleMaskOverrideCoverageNV" ] + }, + { + "enumerant" : "PassthroughNV", + "value" : 5250, + "capabilities" : [ "GeometryShaderPassthroughNV" ] + }, + { + "enumerant" : "ViewportRelativeNV", + "value" : 5252, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryViewportRelativeNV", + "value" : 5256, + "capabilities" : [ "ShaderStereoViewNV" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ] + }, + { + "enumerant" : "HlslCounterBufferGOOGLE", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "enumerant" : "HlslSemanticGOOGLE", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "BuiltIn", + "enumerants" : [ + { + "enumerant" : "Position", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointSize", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 3, + "capabilities" : [ "ClipDistance" ] + }, + { + "enumerant" : "CullDistance", + "value" : 4, + "capabilities" : [ "CullDistance" ] + }, + { + "enumerant" : "VertexId", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceId", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PrimitiveId", + "value" : 7, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InvocationId", + "value" : 8, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "Layer", + "value" : 9, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ViewportIndex", + "value" : 10, + "capabilities" : [ "MultiViewport" ] + }, + { + "enumerant" : "TessLevelOuter", + "value" : 11, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessLevelInner", + "value" : 12, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessCoord", + "value" : 13, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PatchVertices", + "value" : 14, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "FragCoord", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointCoord", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FrontFacing", + "value" : 17, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampleId", + "value" : 18, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SamplePosition", + "value" : 19, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SampleMask", + "value" : 20, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FragDepth", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "HelperInvocation", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "NumWorkgroups", + "value" : 24 + }, + { + "enumerant" : "WorkgroupSize", + "value" : 25 + }, + { + "enumerant" : "WorkgroupId", + "value" : 26 + }, + { + "enumerant" : "LocalInvocationId", + "value" : 27 + }, + { + "enumerant" : "GlobalInvocationId", + "value" : 28 + }, + { + "enumerant" : "LocalInvocationIndex", + "value" : 29 + }, + { + "enumerant" : "WorkDim", + "value" : 30, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalSize", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "EnqueuedWorkgroupSize", + "value" : 32, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalOffset", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalLinearId", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 36, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupMaxSize", + "value" : 37, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumSubgroups", + "value" : 38, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumEnqueuedSubgroups", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupId", + "value" : 40, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupLocalInvocationId", + "value" : 41, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "VertexIndex", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceIndex", + "value" : 43, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupEqMaskKHR", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGeMaskKHR", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGtMaskKHR", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLeMaskKHR", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLtMaskKHR", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "BaseVertex", + "value" : 4424, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "BaseInstance", + "value" : 4425, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DrawIndex", + "value" : 4426, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DeviceIndex", + "value" : 4438, + "capabilities" : [ "DeviceGroup" ] + }, + { + "enumerant" : "ViewIndex", + "value" : 4440, + "capabilities" : [ "MultiView" ] + }, + { + "enumerant" : "BaryCoordNoPerspAMD", + "value" : 4992 + }, + { + "enumerant" : "BaryCoordNoPerspCentroidAMD", + "value" : 4993 + }, + { + "enumerant" : "BaryCoordNoPerspSampleAMD", + "value" : 4994 + }, + { + "enumerant" : "BaryCoordSmoothAMD", + "value" : 4995 + }, + { + "enumerant" : "BaryCoordSmoothCentroidAMD", + "value" : 4996 + }, + { + "enumerant" : "BaryCoordSmoothSampleAMD", + "value" : 4997 + }, + { + "enumerant" : "BaryCoordPullModelAMD", + "value" : 4998 + }, + { + "enumerant" : "FragStencilRefEXT", + "value" : 5014, + "capabilities" : [ "StencilExportEXT" ] + }, + { + "enumerant" : "ViewportMaskNV", + "value" : 5253, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryPositionNV", + "value" : 5257, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "SecondaryViewportMaskNV", + "value" : 5258, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "PositionPerViewNV", + "value" : 5261, + "capabilities" : [ "PerViewAttributesNV" ] + }, + { + "enumerant" : "ViewportMaskPerViewNV", + "value" : 5262, + "capabilities" : [ "PerViewAttributesNV" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Scope", + "enumerants" : [ + { + "enumerant" : "CrossDevice", + "value" : 0 + }, + { + "enumerant" : "Device", + "value" : 1 + }, + { + "enumerant" : "Workgroup", + "value" : 2 + }, + { + "enumerant" : "Subgroup", + "value" : 3 + }, + { + "enumerant" : "Invocation", + "value" : 4 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "GroupOperation", + "enumerants" : [ + { + "enumerant" : "Reduce", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InclusiveScan", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ExclusiveScan", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "KernelEnqueueFlags", + "enumerants" : [ + { + "enumerant" : "NoWait", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitKernel", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitWorkGroup", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Capability", + "enumerants" : [ + { + "enumerant" : "Matrix", + "value" : 0 + }, + { + "enumerant" : "Shader", + "value" : 1, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "Geometry", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Tessellation", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Addresses", + "value" : 4 + }, + { + "enumerant" : "Linkage", + "value" : 5 + }, + { + "enumerant" : "Kernel", + "value" : 6 + }, + { + "enumerant" : "Vector16", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16Buffer", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16", + "value" : 9 + }, + { + "enumerant" : "Float64", + "value" : 10 + }, + { + "enumerant" : "Int64", + "value" : 11 + }, + { + "enumerant" : "Int64Atomics", + "value" : 12, + "capabilities" : [ "Int64" ] + }, + { + "enumerant" : "ImageBasic", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ImageReadWrite", + "value" : 14, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "ImageMipmap", + "value" : 15, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "Pipes", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Groups", + "value" : 18 + }, + { + "enumerant" : "DeviceEnqueue", + "value" : 19, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "LiteralSampler", + "value" : 20, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AtomicStorage", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Int16", + "value" : 22 + }, + { + "enumerant" : "TessellationPointSize", + "value" : 23, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "GeometryPointSize", + "value" : 24, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ImageGatherExtended", + "value" : 25, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageMultisample", + "value" : 27, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "UniformBufferArrayDynamicIndexing", + "value" : 28, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledImageArrayDynamicIndexing", + "value" : 29, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageBufferArrayDynamicIndexing", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageArrayDynamicIndexing", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CullDistance", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageCubeArray", + "value" : 34, + "capabilities" : [ "SampledCubeArray" ] + }, + { + "enumerant" : "SampleRateShading", + "value" : 35, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageRect", + "value" : 36, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "SampledRect", + "value" : 37, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GenericPointer", + "value" : 38, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Int8", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InputAttachment", + "value" : 40, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SparseResidency", + "value" : 41, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MinLod", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sampled1D", + "value" : 43 + }, + { + "enumerant" : "Image1D", + "value" : 44, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "SampledCubeArray", + "value" : 45, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledBuffer", + "value" : 46 + }, + { + "enumerant" : "ImageBuffer", + "value" : 47, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "ImageMSArray", + "value" : 48, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageExtendedFormats", + "value" : 49, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageQuery", + "value" : 50, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DerivativeControl", + "value" : 51, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InterpolationFunction", + "value" : 52, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TransformFeedback", + "value" : 53, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GeometryStreams", + "value" : 54, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "StorageImageReadWithoutFormat", + "value" : 55, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageWriteWithoutFormat", + "value" : 56, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MultiViewport", + "value" : 57, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "SubgroupDispatch", + "value" : 58, + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "enumerant" : "NamedBarrier", + "value" : 59, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "PipeStorage", + "value" : 60, + "capabilities" : [ "Pipes" ] + }, + { + "enumerant" : "SubgroupBallotKHR", + "value" : 4423, + "extensions" : [ "SPV_KHR_shader_ballot" ] + }, + { + "enumerant" : "DrawParameters", + "value" : 4427, + "extensions" : [ "SPV_KHR_shader_draw_parameters" ] + }, + { + "enumerant" : "SubgroupVoteKHR", + "value" : 4431, + "extensions" : [ "SPV_KHR_subgroup_vote" ] + }, + { + "enumerant" : "StorageBuffer16BitAccess", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniformBufferBlock16", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "UniformAndStorageBuffer16BitAccess", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniform16", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StoragePushConstant16", + "value" : 4435, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageInputOutput16", + "value" : 4436, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "DeviceGroup", + "value" : 4437, + "extensions" : [ "SPV_KHR_device_group" ] + }, + { + "enumerant" : "MultiView", + "value" : 4439, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_multiview" ] + }, + { + "enumerant" : "VariablePointersStorageBuffer", + "value" : 4441, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant" : "VariablePointers", + "value" : 4442, + "capabilities" : [ "VariablePointersStorageBuffer" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant": "AtomicStorageOps", + "value": 4445, + "extensions": [ "SPV_KHR_shader_atomic_counter_ops" ] + }, + { + "enumerant" : "SampleMaskPostDepthCoverage", + "value" : 4447, + "extensions" : [ "SPV_KHR_post_depth_coverage" ] + }, + { + "enumerant" : "ImageGatherBiasLodAMD", + "value" : 5009, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_texture_gather_bias_lod" ] + }, + { + "enumerant" : "FragmentMaskAMD", + "value" : 5010, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ] + }, + { + "enumerant" : "StencilExportEXT", + "value" : 5013, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ] + }, + { + "enumerant" : "ImageReadWriteLodAMD", + "value" : 5015, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_image_load_store_lod" ] + }, + { + "enumerant" : "SampleMaskOverrideCoverageNV", + "value" : 5249, + "capabilities" : [ "SampleRateShading" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ] + }, + { + "enumerant" : "GeometryShaderPassthroughNV", + "value" : 5251, + "capabilities" : [ "Geometry" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerEXT", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_EXT_shader_viewport_index_layer" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerNV", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderViewportMaskNV", + "value" : 5255, + "capabilities" : [ "ShaderViewportIndexLayerNV" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderStereoViewNV", + "value" : 5259, + "capabilities" : [ "ShaderViewportMaskNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ] + }, + { + "enumerant" : "PerViewAttributesNV", + "value" : 5260, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes" ] + }, + { + "enumerant" : "SubgroupShuffleINTEL", + "value" : 5568, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupBufferBlockIOINTEL", + "value" : 5569, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupImageBlockIOINTEL", + "value" : 5570, + "extensions" : [ "SPV_INTEL_subgroups" ] + } + ] + }, + { + "category" : "Id", + "kind" : "IdResultType", + "doc" : "Reference to an representing the result's type of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdResult", + "doc" : "Definition of an representing the result of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdMemorySemantics", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the MemorySemantics operand kind" + }, + { + "category" : "Id", + "kind" : "IdScope", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the Scope operand kind" + }, + { + "category" : "Id", + "kind" : "IdRef", + "doc" : "Reference to an " + }, + { + "category" : "Literal", + "kind" : "LiteralInteger", + "doc" : "An integer consuming one or more words" + }, + { + "category" : "Literal", + "kind" : "LiteralString", + "doc" : "A null-terminated stream of characters consuming an integral number of words" + }, + { + "category" : "Literal", + "kind" : "LiteralContextDependentNumber", + "doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction" + }, + { + "category" : "Literal", + "kind" : "LiteralExtInstInteger", + "doc" : "A 32-bit unsigned integer indicating which instruction to use and determining the layout of following operands (for OpExtInst)" + }, + { + "category" : "Literal", + "kind" : "LiteralSpecConstantOpInteger", + "doc" : "An opcode indicating the operation to be performed and determining the layout of following operands (for OpSpecConstantOp)" + }, + { + "category" : "Composite", + "kind" : "PairLiteralIntegerIdRef", + "bases" : [ "LiteralInteger", "IdRef" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefLiteralInteger", + "bases" : [ "IdRef", "LiteralInteger" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefIdRef", + "bases" : [ "IdRef", "IdRef" ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.cs b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.cs new file mode 100644 index 000000000000..99194e514503 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.cs @@ -0,0 +1,1015 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C# +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + + public static class Specification + { + public const uint MagicNumber = 0x07230203; + public const uint Version = 0x00010100; + public const uint Revision = 8; + public const uint OpCodeMask = 0xffff; + public const uint WordCountShift = 16; + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + } + + public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + } + + public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + } + + public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + } + + public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + } + + public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + } + + public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + } + + public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + } + + public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + } + + public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + } + + public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + } + + public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + } + + public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + } + + public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + } + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.h new file mode 100644 index 000000000000..971c3be6d25d --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.h @@ -0,0 +1,1015 @@ +/* +** Copyright (c) 2014-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10100 +#define SPV_REVISION 8 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010100; +static const unsigned int SpvRevision = 8; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModeInitializer = 33, + SpvExecutionModeFinalizer = 34, + SpvExecutionModeSubgroupSize = 35, + SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationMaxByteOffset = 45, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlDependencyInfiniteShift = 2, + SpvLoopControlDependencyLengthShift = 3, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, + SpvLoopControlDependencyInfiniteMask = 0x00000004, + SpvLoopControlDependencyLengthMask = 0x00000008, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupDispatch = 58, + SpvCapabilityNamedBarrier = 59, + SpvCapabilityPipeStorage = 60, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpSizeOf = 321, + SpvOpTypePipeStorage = 322, + SpvOpConstantPipeStorage = 323, + SpvOpCreatePipeFromPipeStorage = 324, + SpvOpGetKernelLocalSizeForSubgroupCount = 325, + SpvOpGetKernelMaxNumSubgroups = 326, + SpvOpTypeNamedBarrier = 327, + SpvOpNamedBarrierInitialize = 328, + SpvOpMemoryNamedBarrier = 329, + SpvOpModuleProcessed = 330, + SpvOpDecorateId = 332, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#endif // #ifndef spirv_H + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.hpp b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.hpp new file mode 100644 index 000000000000..c26ac1f26c6d --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.hpp @@ -0,0 +1,1024 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10100 +#define SPV_REVISION 8 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010100; +static const unsigned int Revision = 8; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModeInitializer = 33, + ExecutionModeFinalizer = 34, + ExecutionModeSubgroupSize = 35, + ExecutionModeSubgroupsPerWorkgroup = 36, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationMaxByteOffset = 45, + DecorationExplicitInterpAMD = 4999, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlDependencyInfiniteShift = 2, + LoopControlDependencyLengthShift = 3, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, + LoopControlDependencyInfiniteMask = 0x00000004, + LoopControlDependencyLengthMask = 0x00000008, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupDispatch = 58, + CapabilityNamedBarrier = 59, + CapabilityPipeStorage = 60, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilityMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + OpMax = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.hpp11 b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.hpp11 new file mode 100644 index 000000000000..992d43b5f542 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.hpp11 @@ -0,0 +1,1024 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10100 +#define SPV_REVISION 8 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010100; +static const unsigned int Revision = 8; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + Max = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.json new file mode 100644 index 000000000000..4c18e0192a36 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.json @@ -0,0 +1,1040 @@ +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2018 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "", + "Some tokens act like mask values, which can be OR'd together,", + "while others are mutually exclusive. The mask-like ones have", + "\"Mask\" in their name, and a parallel enum that has the shift", + "amount (1 << x) for each corresponding enumerant." + ] + ], + "MagicNumber": 119734787, + "Version": 65792, + "Revision": 8, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "Initializer": 33, + "Finalizer": 34, + "SubgroupSize": 35, + "SubgroupsPerWorkgroup": 36, + "PostDepthCoverage": 4446, + "StencilRefReplacingEXT": 5027 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "MaxByteOffset": 45, + "ExplicitInterpAMD": 4999, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1, + "DependencyInfinite": 2, + "DependencyLength": 3 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupDispatch": 58, + "NamedBarrier": 59, + "PipeStorage": 60, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpSizeOf": 321, + "OpTypePipeStorage": 322, + "OpConstantPipeStorage": 323, + "OpCreatePipeFromPipeStorage": 324, + "OpGetKernelLocalSizeForSubgroupCount": 325, + "OpGetKernelMaxNumSubgroups": 326, + "OpTypeNamedBarrier": 327, + "OpNamedBarrierInitialize": 328, + "OpMemoryNamedBarrier": 329, + "OpModuleProcessed": 330, + "OpDecorateId": 332, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpSubgroupReadInvocationKHR": 4432, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateStringGOOGLE": 5633 + } + } + ] + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.lua b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.lua new file mode 100644 index 000000000000..ad34e0abe9d5 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.lua @@ -0,0 +1,971 @@ +-- Copyright (c) 2014-2018 The Khronos Group Inc. +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and/or associated documentation files (the "Materials"), +-- to deal in the Materials without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Materials, and to permit persons to whom the +-- Materials are furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Materials. +-- +-- MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +-- STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +-- HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +-- +-- THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +-- IN THE MATERIALS. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- +-- Some tokens act like mask values, which can be OR'd together, +-- while others are mutually exclusive. The mask-like ones have +-- "Mask" in their name, and a parallel enum that has the shift +-- amount (1 << x) for each corresponding enumerant. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010100, + Revision = 8, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + }, + +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.py b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.py new file mode 100644 index 000000000000..519a59710d19 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.1/spirv.py @@ -0,0 +1,971 @@ +# Copyright (c) 2014-2018 The Khronos Group Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and/or associated documentation files (the "Materials"), +# to deal in the Materials without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Materials, and to permit persons to whom the +# Materials are furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Materials. +# +# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +# STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +# HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +# +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +# IN THE MATERIALS. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# +# Some tokens act like mask values, which can be OR'd together, +# while others are mutually exclusive. The mask-like ones have +# "Mask" in their name, and a parallel enum that has the shift +# amount (1 << x) for each corresponding enumerant. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010100, + 'Revision' : 8, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'Initializer' : 33, + 'Finalizer' : 34, + 'SubgroupSize' : 35, + 'SubgroupsPerWorkgroup' : 36, + 'PostDepthCoverage' : 4446, + 'StencilRefReplacingEXT' : 5027, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'MaxByteOffset' : 45, + 'ExplicitInterpAMD' : 4999, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + 'DependencyInfinite' : 2, + 'DependencyLength' : 3, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + 'DependencyInfinite' : 0x00000004, + 'DependencyLength' : 0x00000008, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupDispatch' : 58, + 'NamedBarrier' : 59, + 'PipeStorage' : 60, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpSizeOf' : 321, + 'OpTypePipeStorage' : 322, + 'OpConstantPipeStorage' : 323, + 'OpCreatePipeFromPipeStorage' : 324, + 'OpGetKernelLocalSizeForSubgroupCount' : 325, + 'OpGetKernelMaxNumSubgroups' : 326, + 'OpTypeNamedBarrier' : 327, + 'OpNamedBarrierInitialize' : 328, + 'OpMemoryNamedBarrier' : 329, + 'OpModuleProcessed' : 330, + 'OpDecorateId' : 332, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateStringGOOGLE' : 5633, + }, + +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/GLSL.std.450.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/GLSL.std.450.h new file mode 100644 index 000000000000..54cc00e9a888 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/GLSL.std.450.h @@ -0,0 +1,131 @@ +/* +** Copyright (c) 2014-2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLstd450_H +#define GLSLstd450_H + +static const int GLSLstd450Version = 100; +static const int GLSLstd450Revision = 3; + +enum GLSLstd450 { + GLSLstd450Bad = 0, // Don't use + + GLSLstd450Round = 1, + GLSLstd450RoundEven = 2, + GLSLstd450Trunc = 3, + GLSLstd450FAbs = 4, + GLSLstd450SAbs = 5, + GLSLstd450FSign = 6, + GLSLstd450SSign = 7, + GLSLstd450Floor = 8, + GLSLstd450Ceil = 9, + GLSLstd450Fract = 10, + + GLSLstd450Radians = 11, + GLSLstd450Degrees = 12, + GLSLstd450Sin = 13, + GLSLstd450Cos = 14, + GLSLstd450Tan = 15, + GLSLstd450Asin = 16, + GLSLstd450Acos = 17, + GLSLstd450Atan = 18, + GLSLstd450Sinh = 19, + GLSLstd450Cosh = 20, + GLSLstd450Tanh = 21, + GLSLstd450Asinh = 22, + GLSLstd450Acosh = 23, + GLSLstd450Atanh = 24, + GLSLstd450Atan2 = 25, + + GLSLstd450Pow = 26, + GLSLstd450Exp = 27, + GLSLstd450Log = 28, + GLSLstd450Exp2 = 29, + GLSLstd450Log2 = 30, + GLSLstd450Sqrt = 31, + GLSLstd450InverseSqrt = 32, + + GLSLstd450Determinant = 33, + GLSLstd450MatrixInverse = 34, + + GLSLstd450Modf = 35, // second operand needs an OpVariable to write to + GLSLstd450ModfStruct = 36, // no OpVariable operand + GLSLstd450FMin = 37, + GLSLstd450UMin = 38, + GLSLstd450SMin = 39, + GLSLstd450FMax = 40, + GLSLstd450UMax = 41, + GLSLstd450SMax = 42, + GLSLstd450FClamp = 43, + GLSLstd450UClamp = 44, + GLSLstd450SClamp = 45, + GLSLstd450FMix = 46, + GLSLstd450IMix = 47, // Reserved + GLSLstd450Step = 48, + GLSLstd450SmoothStep = 49, + + GLSLstd450Fma = 50, + GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to + GLSLstd450FrexpStruct = 52, // no OpVariable operand + GLSLstd450Ldexp = 53, + + GLSLstd450PackSnorm4x8 = 54, + GLSLstd450PackUnorm4x8 = 55, + GLSLstd450PackSnorm2x16 = 56, + GLSLstd450PackUnorm2x16 = 57, + GLSLstd450PackHalf2x16 = 58, + GLSLstd450PackDouble2x32 = 59, + GLSLstd450UnpackSnorm2x16 = 60, + GLSLstd450UnpackUnorm2x16 = 61, + GLSLstd450UnpackHalf2x16 = 62, + GLSLstd450UnpackSnorm4x8 = 63, + GLSLstd450UnpackUnorm4x8 = 64, + GLSLstd450UnpackDouble2x32 = 65, + + GLSLstd450Length = 66, + GLSLstd450Distance = 67, + GLSLstd450Cross = 68, + GLSLstd450Normalize = 69, + GLSLstd450FaceForward = 70, + GLSLstd450Reflect = 71, + GLSLstd450Refract = 72, + + GLSLstd450FindILsb = 73, + GLSLstd450FindSMsb = 74, + GLSLstd450FindUMsb = 75, + + GLSLstd450InterpolateAtCentroid = 76, + GLSLstd450InterpolateAtSample = 77, + GLSLstd450InterpolateAtOffset = 78, + + GLSLstd450NMin = 79, + GLSLstd450NMax = 80, + GLSLstd450NClamp = 81, + + GLSLstd450Count +}; + +#endif // #ifndef GLSLstd450_H diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/OpenCL.std.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/OpenCL.std.h new file mode 100644 index 000000000000..19a6688490c7 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/OpenCL.std.h @@ -0,0 +1,210 @@ +/* +** Copyright (c) 2015-2017 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +namespace OpenCLLIB { + +enum Entrypoints { + + // Section 2.1: Math extended instructions + Acos = 0, + Acosh = 1, + Acospi = 2, + Asin = 3, + Asinh = 4, + Asinpi = 5, + Atan = 6, + Atan2 = 7, + Atanh = 8, + Atanpi = 9, + Atan2pi = 10, + Cbrt = 11, + Ceil = 12, + Copysign = 13, + Cos = 14, + Cosh = 15, + Cospi = 16, + Erfc = 17, + Erf = 18, + Exp = 19, + Exp2 = 20, + Exp10 = 21, + Expm1 = 22, + Fabs = 23, + Fdim = 24, + Floor = 25, + Fma = 26, + Fmax = 27, + Fmin = 28, + Fmod = 29, + Fract = 30, + Frexp = 31, + Hypot = 32, + Ilogb = 33, + Ldexp = 34, + Lgamma = 35, + Lgamma_r = 36, + Log = 37, + Log2 = 38, + Log10 = 39, + Log1p = 40, + Logb = 41, + Mad = 42, + Maxmag = 43, + Minmag = 44, + Modf = 45, + Nan = 46, + Nextafter = 47, + Pow = 48, + Pown = 49, + Powr = 50, + Remainder = 51, + Remquo = 52, + Rint = 53, + Rootn = 54, + Round = 55, + Rsqrt = 56, + Sin = 57, + Sincos = 58, + Sinh = 59, + Sinpi = 60, + Sqrt = 61, + Tan = 62, + Tanh = 63, + Tanpi = 64, + Tgamma = 65, + Trunc = 66, + Half_cos = 67, + Half_divide = 68, + Half_exp = 69, + Half_exp2 = 70, + Half_exp10 = 71, + Half_log = 72, + Half_log2 = 73, + Half_log10 = 74, + Half_powr = 75, + Half_recip = 76, + Half_rsqrt = 77, + Half_sin = 78, + Half_sqrt = 79, + Half_tan = 80, + Native_cos = 81, + Native_divide = 82, + Native_exp = 83, + Native_exp2 = 84, + Native_exp10 = 85, + Native_log = 86, + Native_log2 = 87, + Native_log10 = 88, + Native_powr = 89, + Native_recip = 90, + Native_rsqrt = 91, + Native_sin = 92, + Native_sqrt = 93, + Native_tan = 94, + + // Section 2.2: Integer instructions + SAbs = 141, + SAbs_diff = 142, + SAdd_sat = 143, + UAdd_sat = 144, + SHadd = 145, + UHadd = 146, + SRhadd = 147, + URhadd = 148, + SClamp = 149, + UClamp = 150, + Clz = 151, + Ctz = 152, + SMad_hi = 153, + UMad_sat = 154, + SMad_sat = 155, + SMax = 156, + UMax = 157, + SMin = 158, + UMin = 159, + SMul_hi = 160, + Rotate = 161, + SSub_sat = 162, + USub_sat = 163, + U_Upsample = 164, + S_Upsample = 165, + Popcount = 166, + SMad24 = 167, + UMad24 = 168, + SMul24 = 169, + UMul24 = 170, + UAbs = 201, + UAbs_diff = 202, + UMul_hi = 203, + UMad_hi = 204, + + // Section 2.3: Common instructions + FClamp = 95, + Degrees = 96, + FMax_common = 97, + FMin_common = 98, + Mix = 99, + Radians = 100, + Step = 101, + Smoothstep = 102, + Sign = 103, + + // Section 2.4: Geometric instructions + Cross = 104, + Distance = 105, + Length = 106, + Normalize = 107, + Fast_distance = 108, + Fast_length = 109, + Fast_normalize = 110, + + // Section 2.5: Relational instructions + Bitselect = 186, + Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + Vloadn = 171, + Vstoren = 172, + Vload_half = 173, + Vload_halfn = 174, + Vstore_half = 175, + Vstore_half_r = 176, + Vstore_halfn = 177, + Vstore_halfn_r = 178, + Vloada_halfn = 179, + Vstorea_halfn = 180, + Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + Shuffle = 182, + Shuffle2 = 183, + + // Section 2.8: Misc instructions + Printf = 184, + Prefetch = 185, +}; + +} // end namespace OpenCLLIB diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/extinst.glsl.std.450.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/extinst.glsl.std.450.grammar.json new file mode 100644 index 000000000000..3d9f39e76c9c --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/extinst.glsl.std.450.grammar.json @@ -0,0 +1,642 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "Round", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "RoundEven", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Trunc", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FAbs", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SAbs", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FSign", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SSign", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Floor", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ceil", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fract", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Radians", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "Degrees", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "Sin", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tan", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asin", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acos", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'y_over_x'" } + ] + }, + { + "opname" : "Sinh", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cosh", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tanh", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asinh", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acosh", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atanh", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan2", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Pow", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Exp", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Exp2", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log2", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Sqrt", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "InverseSqrt", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Determinant", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "MatrixInverse", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Modf", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "ModfStruct", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FMin", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMin", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMin", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FMax", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMax", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMax", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FClamp", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "UClamp", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "SClamp", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "FMix", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "IMix", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "Step", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SmoothStep", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fma", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "Frexp", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "FrexpStruct", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ldexp", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "PackSnorm4x8", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm4x8", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackSnorm2x16", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm2x16", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackHalf2x16", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackDouble2x32", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "UnpackSnorm2x16", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm2x16", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackHalf2x16", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "UnpackSnorm4x8", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm4x8", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackDouble2x32", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "Length", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Distance", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "Cross", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Normalize", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FaceForward", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'Nref'" } + ] + }, + { + "opname" : "Reflect", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" } + ] + }, + { + "opname" : "Refract", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'eta'" } + ] + }, + { + "opname" : "FindILsb", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindSMsb", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindUMsb", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "InterpolateAtCentroid", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtSample", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'sample'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtOffset", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "NMin", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NMax", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NClamp", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/extinst.opencl.std.100.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/extinst.opencl.std.100.grammar.json new file mode 100644 index 000000000000..4fe45060bb98 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/extinst.opencl.std.100.grammar.json @@ -0,0 +1,1279 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "acos", + "opcode" : 0, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acosh", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acospi", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asin", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinh", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinpi", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanh", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanpi", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2pi", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cbrt", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ceil", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "copysign", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cosh", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cospi", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erfc", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erf", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp2", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp10", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "expm1", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fabs", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fdim", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "floor", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fma", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fmax", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmod", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fract", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'ptr'" } + ] + }, + { + "opname" : "frexp", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "hypot", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "ilogb", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ldexp", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'k'" } + ] + }, + { + "opname" : "lgamma", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "lgamma_r", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'signp'" } + ] + }, + { + "opname" : "log", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log2", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log10", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log1p", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "logb", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "mad", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "maxmag", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "minmag", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "modf", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'iptr'" } + ] + }, + { + "opname" : "nan", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'nancode'" } + ] + }, + { + "opname" : "nextafter", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "pow", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y" } + ] + }, + { + "opname" : "pown", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "powr", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remainder", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remquo", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'quo'" } + ] + }, + { + "opname" : "rint", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rootn", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "round", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rsqrt", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sin", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sincos", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'cosval'" } + ] + }, + { + "opname" : "sinh", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sinpi", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sqrt", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tan", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanh", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanpi", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tgamma", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "trunc", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_cos", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_divide", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_exp", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp2", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp10", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log2", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log10", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_powr", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_recip", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_rsqrt", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sin", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sqrt", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_tan", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_cos", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_divide", + "opcode" : 82, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_exp", + "opcode" : 83, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp2", + "opcode" : 84, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp10", + "opcode" : 85, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log", + "opcode" : 86, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log2", + "opcode" : 87, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log10", + "opcode" : 88, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_powr", + "opcode" : 89, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_recip", + "opcode" : 90, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_rsqrt", + "opcode" : 91, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sin", + "opcode" : 92, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sqrt", + "opcode" : 93, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_tan", + "opcode" : 94, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs", + "opcode" : 141, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs_diff", + "opcode" : 142, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_add_sat", + "opcode" : 143, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_add_sat", + "opcode" : 144, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_hadd", + "opcode" : 145, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_hadd", + "opcode" : 146, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_rhadd", + "opcode" : 147, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_rhadd", + "opcode" : 148, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_clamp", + "opcode" : 149, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "u_clamp", + "opcode" : 150, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "clz", + "opcode" : 151, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ctz", + "opcode" : 152, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad_hi", + "opcode" : 153, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "u_mad_sat", + "opcode" : 154, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mad_sat", + "opcode" : 155, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_max", + "opcode" : 156, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_max", + "opcode" : 157, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_min", + "opcode" : 158, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_min", + "opcode" : 159, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_mul_hi", + "opcode" : 160, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "rotate", + "opcode" : 161, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "s_sub_sat", + "opcode" : 162, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_sub_sat", + "opcode" : 163, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_upsample", + "opcode" : 164, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "s_upsample", + "opcode" : 165, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "popcount", + "opcode" : 166, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad24", + "opcode" : 167, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "u_mad24", + "opcode" : 168, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mul24", + "opcode" : 169, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul24", + "opcode" : 170, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_abs", + "opcode" : 201, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "u_abs_diff", + "opcode" : 202, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul_hi", + "opcode" : 203, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mad_hi", + "opcode" : 204, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fclamp", + "opcode" : 95, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "degrees", + "opcode" :96, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "fmax_common", + "opcode" : 97, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin_common", + "opcode" : 98, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "mix", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "radians", + "opcode" : 100, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "step", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "smoothstep", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sign", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cross", + "opcode" : 104, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "distance", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "length", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "normalize", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_distance", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "fast_length", + "opcode" : 109, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_normalize", + "opcode" : 110, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "bitselect", + "opcode" : 186, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "select", + "opcode" : 187, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "vloadn", + "opcode" : 171, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstoren", + "opcode" : 172, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_half", + "opcode" : 173, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_halfn", + "opcode" : 174, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstore_half", + "opcode" : 175, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_half_r", + "opcode" : 176, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vstore_halfn", + "opcode" : 177, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_halfn_r", + "opcode" : 178, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vloada_halfn", + "opcode" : 179, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstorea_halfn", + "opcode" : 180, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstorea_halfn_r", + "opcode" : 181, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "shuffle", + "opcode" : 182, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "shuffle2", + "opcode" : 183, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "printf", + "opcode" : 184, + "operands" : [ + { "kind" : "IdRef", "name" : "'format'" }, + { "kind" : "IdRef", "name" : "'additional arguments'", "quantifier" : "*" } + ] + }, + { + "opname" : "prefetch", + "opcode" : 185, + "operands" : [ + { "kind" : "IdRef", "name" : "'ptr'" }, + { "kind" : "IdRef", "name" : "'num elements'" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.core.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.core.grammar.json new file mode 100644 index 000000000000..393ee3c8497d --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.core.grammar.json @@ -0,0 +1,5986 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "magic_number" : "0x07230203", + "major_version" : 1, + "minor_version" : 2, + "revision" : 2, + "instructions" : [ + { + "opname" : "OpNop", + "opcode" : 0 + }, + { + "opname" : "OpUndef", + "opcode" : 1, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSourceContinued", + "opcode" : 2, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Continued Source'" } + ] + }, + { + "opname" : "OpSource", + "opcode" : 3, + "operands" : [ + { "kind" : "SourceLanguage" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" }, + { "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" } + ] + }, + { + "opname" : "OpSourceExtension", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Extension'" } + ] + }, + { + "opname" : "OpName", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpMemberName", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpString", + "opcode" : 7, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'String'" } + ] + }, + { + "opname" : "OpLine", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "OpExtension", + "opcode" : 10, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInstImport", + "opcode" : 11, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInst", + "opcode" : 12, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ] + }, + { + "opname" : "OpMemoryModel", + "opcode" : 14, + "operands" : [ + { "kind" : "AddressingModel" }, + { "kind" : "MemoryModel" } + ] + }, + { + "opname" : "OpEntryPoint", + "opcode" : 15, + "operands" : [ + { "kind" : "ExecutionModel" }, + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } + ] + }, + { + "opname" : "OpExecutionMode", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ] + }, + { + "opname" : "OpCapability", + "opcode" : 17, + "operands" : [ + { "kind" : "Capability", "name" : "'Capability'" } + ] + }, + { + "opname" : "OpTypeVoid", + "opcode" : 19, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeBool", + "opcode" : 20, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeInt", + "opcode" : 21, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" }, + { "kind" : "LiteralInteger", "name" : "'Signedness'" } + ] + }, + { + "opname" : "OpTypeFloat", + "opcode" : 22, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" } + ] + }, + { + "opname" : "OpTypeVector", + "opcode" : 23, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "OpTypeMatrix", + "opcode" : 24, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Column Type'" }, + { "kind" : "LiteralInteger", "name" : "'Column Count'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpTypeImage", + "opcode" : 25, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Type'" }, + { "kind" : "Dim" }, + { "kind" : "LiteralInteger", "name" : "'Depth'" }, + { "kind" : "LiteralInteger", "name" : "'Arrayed'" }, + { "kind" : "LiteralInteger", "name" : "'MS'" }, + { "kind" : "LiteralInteger", "name" : "'Sampled'" }, + { "kind" : "ImageFormat" }, + { "kind" : "AccessQualifier", "quantifier" : "?" } + ] + }, + { + "opname" : "OpTypeSampler", + "opcode" : 26, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeSampledImage", + "opcode" : 27, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ] + }, + { + "opname" : "OpTypeArray", + "opcode" : 28, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" }, + { "kind" : "IdRef", "name" : "'Length'" } + ] + }, + { + "opname" : "OpTypeRuntimeArray", + "opcode" : 29, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpTypeStruct", + "opcode" : 30, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ] + }, + { + "opname" : "OpTypeOpaque", + "opcode" : 31, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "The name of the opaque type." } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypePointer", + "opcode" : 32, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "name" : "'Type'" } + ] + }, + { + "opname" : "OpTypeFunction", + "opcode" : 33, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." } + ] + }, + { + "opname" : "OpTypeEvent", + "opcode" : 34, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypeDeviceEvent", + "opcode" : 35, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypeReserveId", + "opcode" : 36, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeQueue", + "opcode" : 37, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypePipe", + "opcode" : 38, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "AccessQualifier", "name" : "'Qualifier'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeForwardPointer", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer Type'" }, + { "kind" : "StorageClass" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpConstantTrue", + "opcode" : 41, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstantFalse", + "opcode" : 42, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstant", + "opcode" : 43, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConstantComposite", + "opcode" : 44, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpConstantSampler", + "opcode" : 45, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "SamplerAddressingMode" }, + { "kind" : "LiteralInteger", "name" : "'Param'" }, + { "kind" : "SamplerFilterMode" } + ], + "capabilities" : [ "LiteralSampler" ] + }, + { + "opname" : "OpConstantNull", + "opcode" : 46, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantTrue", + "opcode" : 48, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantFalse", + "opcode" : 49, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstant", + "opcode" : 50, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpSpecConstantComposite", + "opcode" : 51, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpSpecConstantOp", + "opcode" : 52, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" } + ] + }, + { + "opname" : "OpFunction", + "opcode" : 54, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "FunctionControl" }, + { "kind" : "IdRef", "name" : "'Function Type'" } + ] + }, + { + "opname" : "OpFunctionParameter", + "opcode" : 55, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpFunctionEnd", + "opcode" : 56 + }, + { + "opname" : "OpFunctionCall", + "opcode" : 57, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." } + ] + }, + { + "opname" : "OpVariable", + "opcode" : 59, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" } + ] + }, + { + "opname" : "OpImageTexelPointer", + "opcode" : 60, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Sample'" } + ] + }, + { + "opname" : "OpLoad", + "opcode" : 61, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpStore", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemory", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemorySized", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpAccessChain", + "opcode" : 65, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpInBoundsAccessChain", + "opcode" : 66, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpPtrAccessChain", + "opcode" : 67, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ + "Addresses", + "VariablePointers", + "VariablePointersStorageBuffer" + ] + }, + { + "opname" : "OpArrayLength", + "opcode" : 68, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Structure'" }, + { "kind" : "LiteralInteger", "name" : "'Array member'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpGenericPtrMemSemantics", + "opcode" : 69, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpInBoundsPtrAccessChain", + "opcode" : 70, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpDecorate", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpMemberDecorate", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'Structure Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpDecorationGroup", + "opcode" : 73, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpGroupDecorate", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpGroupMemberDecorate", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpVectorExtractDynamic", + "opcode" : 77, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorInsertDynamic", + "opcode" : 78, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorShuffle", + "opcode" : 79, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" } + ] + }, + { + "opname" : "OpCompositeConstruct", + "opcode" : 80, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpCompositeExtract", + "opcode" : 81, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCompositeInsert", + "opcode" : 82, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCopyObject", + "opcode" : 83, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpTranspose", + "opcode" : 84, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpSampledImage", + "opcode" : 86, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ] + }, + { + "opname" : "OpImageSampleImplicitLod", + "opcode" : 87, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleExplicitLod", + "opcode" : 88, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ] + }, + { + "opname" : "OpImageSampleDrefImplicitLod", + "opcode" : 89, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleDrefExplicitLod", + "opcode" : 90, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjImplicitLod", + "opcode" : 91, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjExplicitLod", + "opcode" : 92, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefImplicitLod", + "opcode" : 93, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefExplicitLod", + "opcode" : 94, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageFetch", + "opcode" : 95, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageGather", + "opcode" : 96, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageDrefGather", + "opcode" : 97, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageRead", + "opcode" : 98, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageWrite", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Texel'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImage", + "opcode" : 100, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" } + ] + }, + { + "opname" : "OpImageQueryFormat", + "opcode" : 101, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQueryOrder", + "opcode" : 102, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQuerySizeLod", + "opcode" : 103, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Level of Detail'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySize", + "opcode" : 104, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLod", + "opcode" : 105, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLevels", + "opcode" : 106, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySamples", + "opcode" : 107, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpConvertFToU", + "opcode" : 109, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertFToS", + "opcode" : 110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertSToF", + "opcode" : 111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpConvertUToF", + "opcode" : 112, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpUConvert", + "opcode" : 113, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpSConvert", + "opcode" : 114, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpFConvert", + "opcode" : 115, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpQuantizeToF16", + "opcode" : 116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConvertPtrToU", + "opcode" : 117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpSatConvertSToU", + "opcode" : 118, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSatConvertUToS", + "opcode" : 119, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpConvertUToPtr", + "opcode" : 120, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Integer Value'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpPtrCastToGeneric", + "opcode" : 121, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtr", + "opcode" : 122, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtrExplicit", + "opcode" : 123, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "StorageClass", "name" : "'Storage'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpBitcast", + "opcode" : 124, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSNegate", + "opcode" : 126, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpFNegate", + "opcode" : 127, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpIAdd", + "opcode" : 128, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFAdd", + "opcode" : 129, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISub", + "opcode" : 130, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFSub", + "opcode" : 131, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpIMul", + "opcode" : 132, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMul", + "opcode" : 133, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUDiv", + "opcode" : 134, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSDiv", + "opcode" : 135, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFDiv", + "opcode" : 136, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMod", + "opcode" : 137, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSRem", + "opcode" : 138, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMod", + "opcode" : 139, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFRem", + "opcode" : 140, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMod", + "opcode" : 141, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpVectorTimesScalar", + "opcode" : 142, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ] + }, + { + "opname" : "OpMatrixTimesScalar", + "opcode" : 143, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpVectorTimesMatrix", + "opcode" : 144, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesVector", + "opcode" : 145, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesMatrix", + "opcode" : 146, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'LeftMatrix'" }, + { "kind" : "IdRef", "name" : "'RightMatrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpOuterProduct", + "opcode" : 147, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpDot", + "opcode" : 148, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ] + }, + { + "opname" : "OpIAddCarry", + "opcode" : 149, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISubBorrow", + "opcode" : 150, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMulExtended", + "opcode" : 151, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMulExtended", + "opcode" : 152, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpAny", + "opcode" : 154, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpAll", + "opcode" : 155, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpIsNan", + "opcode" : 156, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsInf", + "opcode" : 157, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsFinite", + "opcode" : 158, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpIsNormal", + "opcode" : 159, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSignBitSet", + "opcode" : 160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLessOrGreater", + "opcode" : 161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpOrdered", + "opcode" : 162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpUnordered", + "opcode" : 163, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLogicalEqual", + "opcode" : 164, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNotEqual", + "opcode" : 165, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalOr", + "opcode" : 166, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalAnd", + "opcode" : 167, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNot", + "opcode" : 168, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSelect", + "opcode" : 169, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'Object 1'" }, + { "kind" : "IdRef", "name" : "'Object 2'" } + ] + }, + { + "opname" : "OpIEqual", + "opcode" : 170, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpINotEqual", + "opcode" : 171, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThan", + "opcode" : 172, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThan", + "opcode" : 173, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThanEqual", + "opcode" : 174, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThanEqual", + "opcode" : 175, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThan", + "opcode" : 176, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThan", + "opcode" : 177, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThanEqual", + "opcode" : 178, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThanEqual", + "opcode" : 179, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdEqual", + "opcode" : 180, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordEqual", + "opcode" : 181, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdNotEqual", + "opcode" : 182, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordNotEqual", + "opcode" : 183, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThan", + "opcode" : 184, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThan", + "opcode" : 185, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThan", + "opcode" : 186, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThan", + "opcode" : 187, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThanEqual", + "opcode" : 188, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThanEqual", + "opcode" : 189, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThanEqual", + "opcode" : 190, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThanEqual", + "opcode" : 191, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpShiftRightLogical", + "opcode" : 194, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftRightArithmetic", + "opcode" : 195, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftLeftLogical", + "opcode" : 196, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpBitwiseOr", + "opcode" : 197, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseXor", + "opcode" : 198, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseAnd", + "opcode" : 199, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpNot", + "opcode" : 200, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpBitFieldInsert", + "opcode" : 201, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Insert'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldSExtract", + "opcode" : 202, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldUExtract", + "opcode" : 203, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitReverse", + "opcode" : 204, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitCount", + "opcode" : 205, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ] + }, + { + "opname" : "OpDPdx", + "opcode" : 207, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdy", + "opcode" : 208, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpFwidth", + "opcode" : 209, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdxFine", + "opcode" : 210, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyFine", + "opcode" : 211, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthFine", + "opcode" : 212, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdxCoarse", + "opcode" : 213, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyCoarse", + "opcode" : 214, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthCoarse", + "opcode" : 215, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpEmitVertex", + "opcode" : 218, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEndPrimitive", + "opcode" : 219, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEmitStreamVertex", + "opcode" : 220, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpEndStreamPrimitive", + "opcode" : 221, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpControlBarrier", + "opcode" : 224, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpMemoryBarrier", + "opcode" : 225, + "operands" : [ + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicLoad", + "opcode" : 227, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicStore", + "opcode" : 228, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicExchange", + "opcode" : 229, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicCompareExchange", + "opcode" : 230, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ] + }, + { + "opname" : "OpAtomicCompareExchangeWeak", + "opcode" : 231, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicIIncrement", + "opcode" : 232, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIDecrement", + "opcode" : 233, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIAdd", + "opcode" : 234, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicISub", + "opcode" : 235, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMin", + "opcode" : 236, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMin", + "opcode" : 237, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMax", + "opcode" : 238, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMax", + "opcode" : 239, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicAnd", + "opcode" : 240, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicOr", + "opcode" : 241, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicXor", + "opcode" : 242, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpPhi", + "opcode" : 245, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" } + ] + }, + { + "opname" : "OpLoopMerge", + "opcode" : 246, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "IdRef", "name" : "'Continue Target'" }, + { "kind" : "LoopControl" } + ] + }, + { + "opname" : "OpSelectionMerge", + "opcode" : 247, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "SelectionControl" } + ] + }, + { + "opname" : "OpLabel", + "opcode" : 248, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpBranch", + "opcode" : 249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target Label'" } + ] + }, + { + "opname" : "OpBranchConditional", + "opcode" : 250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'True Label'" }, + { "kind" : "IdRef", "name" : "'False Label'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" } + ] + }, + { + "opname" : "OpSwitch", + "opcode" : 251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Selector'" }, + { "kind" : "IdRef", "name" : "'Default'" }, + { "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" } + ] + }, + { + "opname" : "OpKill", + "opcode" : 252, + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpReturn", + "opcode" : 253 + }, + { + "opname" : "OpReturnValue", + "opcode" : 254, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpUnreachable", + "opcode" : 255 + }, + { + "opname" : "OpLifetimeStart", + "opcode" : 256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLifetimeStop", + "opcode" : 257, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAsyncCopy", + "opcode" : 259, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Destination'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Num Elements'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupWaitEvents", + "opcode" : 260, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Events List'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAll", + "opcode" : 261, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupAny", + "opcode" : 262, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupBroadcast", + "opcode" : 263, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'LocalId'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupIAdd", + "opcode" : 264, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAdd", + "opcode" : 265, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMin", + "opcode" : 266, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMin", + "opcode" : 267, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMin", + "opcode" : 268, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMax", + "opcode" : 269, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMax", + "opcode" : 270, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMax", + "opcode" : 271, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpReadPipe", + "opcode" : 274, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpWritePipe", + "opcode" : 275, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedReadPipe", + "opcode" : 276, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedWritePipe", + "opcode" : 277, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveReadPipePackets", + "opcode" : 278, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveWritePipePackets", + "opcode" : 279, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitReadPipe", + "opcode" : 280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitWritePipe", + "opcode" : 281, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpIsValidReserveId", + "opcode" : 282, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetNumPipePackets", + "opcode" : 283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetMaxPipePackets", + "opcode" : 284, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveReadPipePackets", + "opcode" : 285, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveWritePipePackets", + "opcode" : 286, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitReadPipe", + "opcode" : 287, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitWritePipe", + "opcode" : 288, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpEnqueueMarker", + "opcode" : 291, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpEnqueueKernel", + "opcode" : 292, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeSubGroupCount", + "opcode" : 293, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeMaxSubGroupSize", + "opcode" : 294, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelWorkGroupSize", + "opcode" : 295, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelPreferredWorkGroupSizeMultiple", + "opcode" : 296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpRetainEvent", + "opcode" : 297, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpReleaseEvent", + "opcode" : 298, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCreateUserEvent", + "opcode" : 299, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpIsValidEvent", + "opcode" : 300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpSetUserEventStatus", + "opcode" : 301, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Status'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCaptureEventProfilingInfo", + "opcode" : 302, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Profiling Info'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetDefaultQueue", + "opcode" : 303, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpBuildNDRange", + "opcode" : 304, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'GlobalWorkSize'" }, + { "kind" : "IdRef", "name" : "'LocalWorkSize'" }, + { "kind" : "IdRef", "name" : "'GlobalWorkOffset'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpImageSparseSampleImplicitLod", + "opcode" : 305, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleExplicitLod", + "opcode" : 306, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefImplicitLod", + "opcode" : 307, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefExplicitLod", + "opcode" : 308, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjImplicitLod", + "opcode" : 309, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjExplicitLod", + "opcode" : 310, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefImplicitLod", + "opcode" : 311, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefExplicitLod", + "opcode" : 312, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseFetch", + "opcode" : 313, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseGather", + "opcode" : 314, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseDrefGather", + "opcode" : 315, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseTexelsResident", + "opcode" : 316, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Resident Code'" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpNoLine", + "opcode" : 317 + }, + { + "opname" : "OpAtomicFlagTestAndSet", + "opcode" : 318, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicFlagClear", + "opcode" : 319, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageSparseRead", + "opcode" : 320, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpSizeOf", + "opcode" : 321, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpTypePipeStorage", + "opcode" : 322, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpConstantPipeStorage", + "opcode" : 323, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Packet Size'" }, + { "kind" : "LiteralInteger", "name" : "'Packet Alignment'" }, + { "kind" : "LiteralInteger", "name" : "'Capacity'" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpCreatePipeFromPipeStorage", + "opcode" : 324, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe Storage'" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpGetKernelLocalSizeForSubgroupCount", + "opcode" : 325, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ] + }, + { + "opname" : "OpGetKernelMaxNumSubgroups", + "opcode" : 326, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ] + }, + { + "opname" : "OpTypeNamedBarrier", + "opcode" : 327, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpNamedBarrierInitialize", + "opcode" : 328, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpMemoryNamedBarrier", + "opcode" : 329, + "operands" : [ + { "kind" : "IdRef", "name" : "'Named Barrier'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpModuleProcessed", + "opcode" : 330, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Process'" } + ] + }, + { + "opname" : "OpExecutionModeId", + "opcode" : 331, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ] + }, + { + "opname" : "OpDecorateId", + "opcode" : 332, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpSubgroupBallotKHR", + "opcode" : 4421, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupFirstInvocationKHR", + "opcode" : 4422, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupAllKHR", + "opcode" : 4428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAnyKHR", + "opcode" : 4429, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAllEqualKHR", + "opcode" : 4430, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupReadInvocationKHR", + "opcode" : 4432, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpGroupIAddNonUniformAMD", + "opcode" : 5000, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAddNonUniformAMD", + "opcode" : 5001, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMinNonUniformAMD", + "opcode" : 5002, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMinNonUniformAMD", + "opcode" : 5003, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMinNonUniformAMD", + "opcode" : 5004, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMaxNonUniformAMD", + "opcode" : 5005, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMaxNonUniformAMD", + "opcode" : 5006, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMaxNonUniformAMD", + "opcode" : 5007, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpFragmentMaskFetchAMD", + "opcode" : 5011, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpFragmentFetchAMD", + "opcode" : 5012, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Fragment Index'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpSubgroupShuffleINTEL", + "opcode" : 5571, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'InvocationId'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleDownINTEL", + "opcode" : 5572, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Next'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleUpINTEL", + "opcode" : 5573, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Previous'" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleXorINTEL", + "opcode" : 5574, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupBlockReadINTEL", + "opcode" : 5575, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupBlockWriteINTEL", + "opcode" : 5576, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockReadINTEL", + "opcode" : 5577, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockWriteINTEL", + "opcode" : 5578, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpDecorateStringGOOGLE", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + }, + { + "opname" : "OpMemberDecorateStringGOOGLE", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "ImageOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Bias", + "value" : "0x0001", + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Lod", + "value" : "0x0002", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Grad", + "value" : "0x0004", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffset", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Offset", + "value" : "0x0010", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffsets", + "value" : "0x0020", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Sample", + "value" : "0x0040", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "MinLod", + "value" : "0x0080", + "capabilities" : [ "MinLod" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FPFastMathMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "NotNaN", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NotInf", + "value" : "0x0002", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NSZ", + "value" : "0x0004", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AllowRecip", + "value" : "0x0008", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Fast", + "value" : "0x0010", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "SelectionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Flatten", + "value" : "0x0001" + }, + { + "enumerant" : "DontFlatten", + "value" : "0x0002" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "LoopControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Unroll", + "value" : "0x0001" + }, + { + "enumerant" : "DontUnroll", + "value" : "0x0002" + }, + { + "enumerant" : "DependencyInfinite", + "value" : "0x0004" + }, + { + "enumerant" : "DependencyLength", + "value" : "0x0008", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FunctionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Inline", + "value" : "0x0001" + }, + { + "enumerant" : "DontInline", + "value" : "0x0002" + }, + { + "enumerant" : "Pure", + "value" : "0x0004" + }, + { + "enumerant" : "Const", + "value" : "0x0008" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemorySemantics", + "enumerants" : [ + { + "enumerant" : "Relaxed", + "value" : "0x0000" + }, + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Acquire", + "value" : "0x0002" + }, + { + "enumerant" : "Release", + "value" : "0x0004" + }, + { + "enumerant" : "AcquireRelease", + "value" : "0x0008" + }, + { + "enumerant" : "SequentiallyConsistent", + "value" : "0x0010" + }, + { + "enumerant" : "UniformMemory", + "value" : "0x0040", + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupMemory", + "value" : "0x0080" + }, + { + "enumerant" : "WorkgroupMemory", + "value" : "0x0100" + }, + { + "enumerant" : "CrossWorkgroupMemory", + "value" : "0x0200" + }, + { + "enumerant" : "AtomicCounterMemory", + "value" : "0x0400", + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "ImageMemory", + "value" : "0x0800" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemoryAccess", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Volatile", + "value" : "0x0001" + }, + { + "enumerant" : "Aligned", + "value" : "0x0002", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Nontemporal", + "value" : "0x0004" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "KernelProfilingInfo", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "CmdExecTime", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SourceLanguage", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "ESSL", + "value" : 1 + }, + { + "enumerant" : "GLSL", + "value" : 2 + }, + { + "enumerant" : "OpenCL_C", + "value" : 3 + }, + { + "enumerant" : "OpenCL_CPP", + "value" : 4 + }, + { + "enumerant" : "HLSL", + "value" : 5 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionModel", + "enumerants" : [ + { + "enumerant" : "Vertex", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TessellationControl", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessellationEvaluation", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Geometry", + "value" : 3, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Fragment", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLCompute", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Kernel", + "value" : 6, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AddressingModel", + "enumerants" : [ + { + "enumerant" : "Logical", + "value" : 0 + }, + { + "enumerant" : "Physical32", + "value" : 1, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Physical64", + "value" : 2, + "capabilities" : [ "Addresses" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "MemoryModel", + "enumerants" : [ + { + "enumerant" : "Simple", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSL450", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OpenCL", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionMode", + "enumerants" : [ + { + "enumerant" : "Invocations", + "value" : 0, + "capabilities" : [ "Geometry" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of <>'" } + ] + }, + { + "enumerant" : "SpacingEqual", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalEven", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalOdd", + "value" : 3, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCw", + "value" : 4, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCcw", + "value" : 5, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PixelCenterInteger", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginUpperLeft", + "value" : 7, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginLowerLeft", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "EarlyFragmentTests", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointMode", + "value" : 10, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Xfb", + "value" : 11, + "capabilities" : [ "TransformFeedback" ] + }, + { + "enumerant" : "DepthReplacing", + "value" : 12, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthGreater", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthLess", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthUnchanged", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "LocalSize", + "value" : 17, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "LocalSizeHint", + "value" : 18, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "InputPoints", + "value" : 19, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLines", + "value" : 20, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLinesAdjacency", + "value" : 21, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Triangles", + "value" : 22, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InputTrianglesAdjacency", + "value" : 23, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Quads", + "value" : 24, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Isolines", + "value" : 25, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "OutputVertices", + "value" : 26, + "capabilities" : [ "Geometry", "Tessellation" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vertex count'" } + ] + }, + { + "enumerant" : "OutputPoints", + "value" : 27, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputLineStrip", + "value" : 28, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputTriangleStrip", + "value" : 29, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "VecTypeHint", + "value" : 30, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vector type'" } + ] + }, + { + "enumerant" : "ContractionOff", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Initializer", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Finalizer", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 35, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroup Size'" } + ] + }, + { + "enumerant" : "SubgroupsPerWorkgroup", + "value" : 36, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroups Per Workgroup'" } + ] + }, + { + "enumerant" : "SubgroupsPerWorkgroupId", + "value" : 37, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Subgroups Per Workgroup'" } + ] + }, + { + "enumerant" : "LocalSizeId", + "value" : 38, + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size'" }, + { "kind" : "IdRef", "name" : "'y size'" }, + { "kind" : "IdRef", "name" : "'z size'" } + ] + }, + { + "enumerant" : "LocalSizeHintId", + "value" : 39, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Local Size Hint'" } + ] + }, + { + "enumerant" : "PostDepthCoverage", + "value" : 4446, + "capabilities" : [ "SampleMaskPostDepthCoverage" ] + }, + { + "enumerant" : "StencilRefReplacingEXT", + "value" : 5027, + "capabilities" : [ "StencilExportEXT" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StorageClass", + "enumerants" : [ + { + "enumerant" : "UniformConstant", + "value" : 0 + }, + { + "enumerant" : "Input", + "value" : 1 + }, + { + "enumerant" : "Uniform", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Output", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Workgroup", + "value" : 4 + }, + { + "enumerant" : "CrossWorkgroup", + "value" : 5 + }, + { + "enumerant" : "Private", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Function", + "value" : 7 + }, + { + "enumerant" : "Generic", + "value" : 8, + "capabilities" : [ "GenericPointer" ] + }, + { + "enumerant" : "PushConstant", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "AtomicCounter", + "value" : 10, + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "Image", + "value" : 11 + }, + { + "enumerant" : "StorageBuffer", + "value" : 12, + "extensions" : [ + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers" + ], + "capabilities" : [ "Shader" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Dim", + "enumerants" : [ + { + "enumerant" : "1D", + "value" : 0, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "2D", + "value" : 1 + }, + { + "enumerant" : "3D", + "value" : 2 + }, + { + "enumerant" : "Cube", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rect", + "value" : 4, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "Buffer", + "value" : 5, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "SubpassData", + "value" : 6, + "capabilities" : [ "InputAttachment" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerAddressingMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ClampToEdge", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Clamp", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Repeat", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RepeatMirrored", + "value" : 4, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerFilterMode", + "enumerants" : [ + { + "enumerant" : "Nearest", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Linear", + "value" : 1, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageFormat", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "Rgba32f", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16f", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32f", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8Snorm", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32f", + "value" : 6, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16f", + "value" : 7, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R11fG11fB10f", + "value" : 8, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16f", + "value" : 9, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16", + "value" : 10, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgb10A2", + "value" : 11, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16", + "value" : 12, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8", + "value" : 13, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16", + "value" : 14, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8", + "value" : 15, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16Snorm", + "value" : 16, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16Snorm", + "value" : 17, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8Snorm", + "value" : 18, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16Snorm", + "value" : 19, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8Snorm", + "value" : 20, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32i", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16i", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8i", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32i", + "value" : 24, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32i", + "value" : 25, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16i", + "value" : 26, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8i", + "value" : 27, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16i", + "value" : 28, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8i", + "value" : 29, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32ui", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16ui", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8ui", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32ui", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgb10a2ui", + "value" : 34, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg32ui", + "value" : 35, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16ui", + "value" : 36, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8ui", + "value" : 37, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16ui", + "value" : 38, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8ui", + "value" : 39, + "capabilities" : [ "StorageImageExtendedFormats" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelOrder", + "enumerants" : [ + { + "enumerant" : "R", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "A", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RG", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RA", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGB", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBA", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BGRA", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ARGB", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Intensity", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Luminance", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Rx", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGx", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBx", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Depth", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "DepthStencil", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGB", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBx", + "value" : 16, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBA", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sBGRA", + "value" : 18, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ABGR", + "value" : 19, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelDataType", + "enumerants" : [ + { + "enumerant" : "SnormInt8", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SnormInt16", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt8", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt16", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort565", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort555", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt8", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt16", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt32", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt8", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt16", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt32", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "HalfFloat", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt24", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010_2", + "value" : 16, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPRoundingMode", + "enumerants" : [ + { + "enumerant" : "RTE", + "value" : 0, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTZ", + "value" : 1, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTP", + "value" : 2, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTN", + "value" : 3, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LinkageType", + "enumerants" : [ + { + "enumerant" : "Export", + "value" : 0, + "capabilities" : [ "Linkage" ] + }, + { + "enumerant" : "Import", + "value" : 1, + "capabilities" : [ "Linkage" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AccessQualifier", + "enumerants" : [ + { + "enumerant" : "ReadOnly", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WriteOnly", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ReadWrite", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FunctionParameterAttribute", + "enumerants" : [ + { + "enumerant" : "Zext", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sext", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ByVal", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sret", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoAlias", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoCapture", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoWrite", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoReadWrite", + "value" : 7, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Decoration", + "enumerants" : [ + { + "enumerant" : "RelaxedPrecision", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SpecId", + "value" : 1, + "capabilities" : [ "Shader", "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" } + ] + }, + { + "enumerant" : "Block", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "BufferBlock", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "RowMajor", + "value" : 4, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ColMajor", + "value" : 5, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ArrayStride", + "value" : 6, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Array Stride'" } + ] + }, + { + "enumerant" : "MatrixStride", + "value" : 7, + "capabilities" : [ "Matrix" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Matrix Stride'" } + ] + }, + { + "enumerant" : "GLSLShared", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSLPacked", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CPacked", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BuiltIn", + "value" : 11, + "parameters" : [ + { "kind" : "BuiltIn" } + ] + }, + { + "enumerant" : "NoPerspective", + "value" : 13, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Flat", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Patch", + "value" : 15, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Centroid", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sample", + "value" : 17, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "Invariant", + "value" : 18, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Restrict", + "value" : 19 + }, + { + "enumerant" : "Aliased", + "value" : 20 + }, + { + "enumerant" : "Volatile", + "value" : 21 + }, + { + "enumerant" : "Constant", + "value" : 22, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Coherent", + "value" : 23 + }, + { + "enumerant" : "NonWritable", + "value" : 24 + }, + { + "enumerant" : "NonReadable", + "value" : 25 + }, + { + "enumerant" : "Uniform", + "value" : 26, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SaturatedConversion", + "value" : 28, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Stream", + "value" : 29, + "capabilities" : [ "GeometryStreams" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stream Number'" } + ] + }, + { + "enumerant" : "Location", + "value" : 30, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Location'" } + ] + }, + { + "enumerant" : "Component", + "value" : 31, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Component'" } + ] + }, + { + "enumerant" : "Index", + "value" : 32, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Index'" } + ] + }, + { + "enumerant" : "Binding", + "value" : 33, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Binding Point'" } + ] + }, + { + "enumerant" : "DescriptorSet", + "value" : 34, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Descriptor Set'" } + ] + }, + { + "enumerant" : "Offset", + "value" : 35, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Byte Offset'" } + ] + }, + { + "enumerant" : "XfbBuffer", + "value" : 36, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" } + ] + }, + { + "enumerant" : "XfbStride", + "value" : 37, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Stride'" } + ] + }, + { + "enumerant" : "FuncParamAttr", + "value" : 38, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" } + ] + }, + { + "enumerant" : "FPRoundingMode", + "value" : 39, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ], + "parameters" : [ + { "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" } + ] + }, + { + "enumerant" : "FPFastMathMode", + "value" : 40, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" } + ] + }, + { + "enumerant" : "LinkageAttributes", + "value" : 41, + "capabilities" : [ "Linkage" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "LinkageType", "name" : "'Linkage Type'" } + ] + }, + { + "enumerant" : "NoContraction", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InputAttachmentIndex", + "value" : 43, + "capabilities" : [ "InputAttachment" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Attachment Index'" } + ] + }, + { + "enumerant" : "Alignment", + "value" : 44, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Alignment'" } + ] + }, + { + "enumerant" : "MaxByteOffset", + "value" : 45, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Max Byte Offset'" } + ] + }, + { + "enumerant" : "AlignmentId", + "value" : 46, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Alignment'" } + ] + }, + { + "enumerant" : "MaxByteOffsetId", + "value" : 47, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Max Byte Offset'" } + ] + }, + { + "enumerant" : "ExplicitInterpAMD", + "value" : 4999 + }, + { + "enumerant" : "OverrideCoverageNV", + "value" : 5248, + "capabilities" : [ "SampleMaskOverrideCoverageNV" ] + }, + { + "enumerant" : "PassthroughNV", + "value" : 5250, + "capabilities" : [ "GeometryShaderPassthroughNV" ] + }, + { + "enumerant" : "ViewportRelativeNV", + "value" : 5252, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryViewportRelativeNV", + "value" : 5256, + "capabilities" : [ "ShaderStereoViewNV" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ] + }, + { + "enumerant" : "HlslCounterBufferGOOGLE", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "enumerant" : "HlslSemanticGOOGLE", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "BuiltIn", + "enumerants" : [ + { + "enumerant" : "Position", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointSize", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 3, + "capabilities" : [ "ClipDistance" ] + }, + { + "enumerant" : "CullDistance", + "value" : 4, + "capabilities" : [ "CullDistance" ] + }, + { + "enumerant" : "VertexId", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceId", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PrimitiveId", + "value" : 7, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InvocationId", + "value" : 8, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "Layer", + "value" : 9, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ViewportIndex", + "value" : 10, + "capabilities" : [ "MultiViewport" ] + }, + { + "enumerant" : "TessLevelOuter", + "value" : 11, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessLevelInner", + "value" : 12, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessCoord", + "value" : 13, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PatchVertices", + "value" : 14, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "FragCoord", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointCoord", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FrontFacing", + "value" : 17, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampleId", + "value" : 18, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SamplePosition", + "value" : 19, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SampleMask", + "value" : 20, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FragDepth", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "HelperInvocation", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "NumWorkgroups", + "value" : 24 + }, + { + "enumerant" : "WorkgroupSize", + "value" : 25 + }, + { + "enumerant" : "WorkgroupId", + "value" : 26 + }, + { + "enumerant" : "LocalInvocationId", + "value" : 27 + }, + { + "enumerant" : "GlobalInvocationId", + "value" : 28 + }, + { + "enumerant" : "LocalInvocationIndex", + "value" : 29 + }, + { + "enumerant" : "WorkDim", + "value" : 30, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalSize", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "EnqueuedWorkgroupSize", + "value" : 32, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalOffset", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalLinearId", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 36, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupMaxSize", + "value" : 37, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumSubgroups", + "value" : 38, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumEnqueuedSubgroups", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupId", + "value" : 40, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupLocalInvocationId", + "value" : 41, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "VertexIndex", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceIndex", + "value" : 43, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupEqMaskKHR", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGeMaskKHR", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGtMaskKHR", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLeMaskKHR", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLtMaskKHR", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "BaseVertex", + "value" : 4424, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "BaseInstance", + "value" : 4425, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DrawIndex", + "value" : 4426, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DeviceIndex", + "value" : 4438, + "capabilities" : [ "DeviceGroup" ] + }, + { + "enumerant" : "ViewIndex", + "value" : 4440, + "capabilities" : [ "MultiView" ] + }, + { + "enumerant" : "BaryCoordNoPerspAMD", + "value" : 4992 + }, + { + "enumerant" : "BaryCoordNoPerspCentroidAMD", + "value" : 4993 + }, + { + "enumerant" : "BaryCoordNoPerspSampleAMD", + "value" : 4994 + }, + { + "enumerant" : "BaryCoordSmoothAMD", + "value" : 4995 + }, + { + "enumerant" : "BaryCoordSmoothCentroidAMD", + "value" : 4996 + }, + { + "enumerant" : "BaryCoordSmoothSampleAMD", + "value" : 4997 + }, + { + "enumerant" : "BaryCoordPullModelAMD", + "value" : 4998 + }, + { + "enumerant" : "FragStencilRefEXT", + "value" : 5014, + "capabilities" : [ "StencilExportEXT" ] + }, + { + "enumerant" : "ViewportMaskNV", + "value" : 5253, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryPositionNV", + "value" : 5257, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "SecondaryViewportMaskNV", + "value" : 5258, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "PositionPerViewNV", + "value" : 5261, + "capabilities" : [ "PerViewAttributesNV" ] + }, + { + "enumerant" : "ViewportMaskPerViewNV", + "value" : 5262, + "capabilities" : [ "PerViewAttributesNV" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Scope", + "enumerants" : [ + { + "enumerant" : "CrossDevice", + "value" : 0 + }, + { + "enumerant" : "Device", + "value" : 1 + }, + { + "enumerant" : "Workgroup", + "value" : 2 + }, + { + "enumerant" : "Subgroup", + "value" : 3 + }, + { + "enumerant" : "Invocation", + "value" : 4 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "GroupOperation", + "enumerants" : [ + { + "enumerant" : "Reduce", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InclusiveScan", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ExclusiveScan", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "KernelEnqueueFlags", + "enumerants" : [ + { + "enumerant" : "NoWait", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitKernel", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitWorkGroup", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Capability", + "enumerants" : [ + { + "enumerant" : "Matrix", + "value" : 0 + }, + { + "enumerant" : "Shader", + "value" : 1, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "Geometry", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Tessellation", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Addresses", + "value" : 4 + }, + { + "enumerant" : "Linkage", + "value" : 5 + }, + { + "enumerant" : "Kernel", + "value" : 6 + }, + { + "enumerant" : "Vector16", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16Buffer", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16", + "value" : 9 + }, + { + "enumerant" : "Float64", + "value" : 10 + }, + { + "enumerant" : "Int64", + "value" : 11 + }, + { + "enumerant" : "Int64Atomics", + "value" : 12, + "capabilities" : [ "Int64" ] + }, + { + "enumerant" : "ImageBasic", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ImageReadWrite", + "value" : 14, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "ImageMipmap", + "value" : 15, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "Pipes", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Groups", + "value" : 18 + }, + { + "enumerant" : "DeviceEnqueue", + "value" : 19, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "LiteralSampler", + "value" : 20, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AtomicStorage", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Int16", + "value" : 22 + }, + { + "enumerant" : "TessellationPointSize", + "value" : 23, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "GeometryPointSize", + "value" : 24, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ImageGatherExtended", + "value" : 25, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageMultisample", + "value" : 27, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "UniformBufferArrayDynamicIndexing", + "value" : 28, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledImageArrayDynamicIndexing", + "value" : 29, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageBufferArrayDynamicIndexing", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageArrayDynamicIndexing", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CullDistance", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageCubeArray", + "value" : 34, + "capabilities" : [ "SampledCubeArray" ] + }, + { + "enumerant" : "SampleRateShading", + "value" : 35, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageRect", + "value" : 36, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "SampledRect", + "value" : 37, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GenericPointer", + "value" : 38, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Int8", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InputAttachment", + "value" : 40, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SparseResidency", + "value" : 41, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MinLod", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sampled1D", + "value" : 43 + }, + { + "enumerant" : "Image1D", + "value" : 44, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "SampledCubeArray", + "value" : 45, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledBuffer", + "value" : 46 + }, + { + "enumerant" : "ImageBuffer", + "value" : 47, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "ImageMSArray", + "value" : 48, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageExtendedFormats", + "value" : 49, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageQuery", + "value" : 50, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DerivativeControl", + "value" : 51, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InterpolationFunction", + "value" : 52, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TransformFeedback", + "value" : 53, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GeometryStreams", + "value" : 54, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "StorageImageReadWithoutFormat", + "value" : 55, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageWriteWithoutFormat", + "value" : 56, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MultiViewport", + "value" : 57, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "SubgroupDispatch", + "value" : 58, + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "enumerant" : "NamedBarrier", + "value" : 59, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "PipeStorage", + "value" : 60, + "capabilities" : [ "Pipes" ] + }, + { + "enumerant" : "SubgroupBallotKHR", + "value" : 4423, + "extensions" : [ "SPV_KHR_shader_ballot" ] + }, + { + "enumerant" : "DrawParameters", + "value" : 4427, + "extensions" : [ "SPV_KHR_shader_draw_parameters" ] + }, + { + "enumerant" : "SubgroupVoteKHR", + "value" : 4431, + "extensions" : [ "SPV_KHR_subgroup_vote" ] + }, + { + "enumerant" : "StorageBuffer16BitAccess", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniformBufferBlock16", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "UniformAndStorageBuffer16BitAccess", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniform16", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StoragePushConstant16", + "value" : 4435, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageInputOutput16", + "value" : 4436, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "DeviceGroup", + "value" : 4437, + "extensions" : [ "SPV_KHR_device_group" ] + }, + { + "enumerant" : "MultiView", + "value" : 4439, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_multiview" ] + }, + { + "enumerant" : "VariablePointersStorageBuffer", + "value" : 4441, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant" : "VariablePointers", + "value" : 4442, + "capabilities" : [ "VariablePointersStorageBuffer" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant": "AtomicStorageOps", + "value": 4445, + "extensions": [ "SPV_KHR_shader_atomic_counter_ops" ] + }, + { + "enumerant" : "SampleMaskPostDepthCoverage", + "value" : 4447, + "extensions" : [ "SPV_KHR_post_depth_coverage" ] + }, + { + "enumerant" : "ImageGatherBiasLodAMD", + "value" : 5009, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_texture_gather_bias_lod" ] + }, + { + "enumerant" : "FragmentMaskAMD", + "value" : 5010, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ] + }, + { + "enumerant" : "StencilExportEXT", + "value" : 5013, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ] + }, + { + "enumerant" : "ImageReadWriteLodAMD", + "value" : 5015, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_image_load_store_lod" ] + }, + { + "enumerant" : "SampleMaskOverrideCoverageNV", + "value" : 5249, + "capabilities" : [ "SampleRateShading" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ] + }, + { + "enumerant" : "GeometryShaderPassthroughNV", + "value" : 5251, + "capabilities" : [ "Geometry" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerEXT", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_EXT_shader_viewport_index_layer" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerNV", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderViewportMaskNV", + "value" : 5255, + "capabilities" : [ "ShaderViewportIndexLayerNV" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderStereoViewNV", + "value" : 5259, + "capabilities" : [ "ShaderViewportMaskNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ] + }, + { + "enumerant" : "PerViewAttributesNV", + "value" : 5260, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes" ] + }, + { + "enumerant" : "SubgroupShuffleINTEL", + "value" : 5568, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupBufferBlockIOINTEL", + "value" : 5569, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupImageBlockIOINTEL", + "value" : 5570, + "extensions" : [ "SPV_INTEL_subgroups" ] + } + ] + }, + { + "category" : "Id", + "kind" : "IdResultType", + "doc" : "Reference to an representing the result's type of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdResult", + "doc" : "Definition of an representing the result of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdMemorySemantics", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the MemorySemantics operand kind" + }, + { + "category" : "Id", + "kind" : "IdScope", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the Scope operand kind" + }, + { + "category" : "Id", + "kind" : "IdRef", + "doc" : "Reference to an " + }, + { + "category" : "Literal", + "kind" : "LiteralInteger", + "doc" : "An integer consuming one or more words" + }, + { + "category" : "Literal", + "kind" : "LiteralString", + "doc" : "A null-terminated stream of characters consuming an integral number of words" + }, + { + "category" : "Literal", + "kind" : "LiteralContextDependentNumber", + "doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction" + }, + { + "category" : "Literal", + "kind" : "LiteralExtInstInteger", + "doc" : "A 32-bit unsigned integer indicating which instruction to use and determining the layout of following operands (for OpExtInst)" + }, + { + "category" : "Literal", + "kind" : "LiteralSpecConstantOpInteger", + "doc" : "An opcode indicating the operation to be performed and determining the layout of following operands (for OpSpecConstantOp)" + }, + { + "category" : "Composite", + "kind" : "PairLiteralIntegerIdRef", + "bases" : [ "LiteralInteger", "IdRef" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefLiteralInteger", + "bases" : [ "IdRef", "LiteralInteger" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefIdRef", + "bases" : [ "IdRef", "IdRef" ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.cs b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.cs new file mode 100644 index 000000000000..493303d6ab08 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.cs @@ -0,0 +1,1021 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C# +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + + public static class Specification + { + public const uint MagicNumber = 0x07230203; + public const uint Version = 0x00010200; + public const uint Revision = 2; + public const uint OpCodeMask = 0xffff; + public const uint WordCountShift = 16; + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + } + + public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + } + + public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + } + + public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + } + + public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + } + + public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + } + + public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + } + + public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + } + + public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + } + + public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + } + + public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + } + + public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + } + + public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + } + + public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + } + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.h b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.h new file mode 100644 index 000000000000..7c6d884d8e49 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.h @@ -0,0 +1,1021 @@ +/* +** Copyright (c) 2014-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10200 +#define SPV_REVISION 2 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010200; +static const unsigned int SpvRevision = 2; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModeInitializer = 33, + SpvExecutionModeFinalizer = 34, + SpvExecutionModeSubgroupSize = 35, + SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModeSubgroupsPerWorkgroupId = 37, + SpvExecutionModeLocalSizeId = 38, + SpvExecutionModeLocalSizeHintId = 39, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationMaxByteOffset = 45, + SpvDecorationAlignmentId = 46, + SpvDecorationMaxByteOffsetId = 47, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlDependencyInfiniteShift = 2, + SpvLoopControlDependencyLengthShift = 3, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, + SpvLoopControlDependencyInfiniteMask = 0x00000004, + SpvLoopControlDependencyLengthMask = 0x00000008, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupDispatch = 58, + SpvCapabilityNamedBarrier = 59, + SpvCapabilityPipeStorage = 60, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpSizeOf = 321, + SpvOpTypePipeStorage = 322, + SpvOpConstantPipeStorage = 323, + SpvOpCreatePipeFromPipeStorage = 324, + SpvOpGetKernelLocalSizeForSubgroupCount = 325, + SpvOpGetKernelMaxNumSubgroups = 326, + SpvOpTypeNamedBarrier = 327, + SpvOpNamedBarrierInitialize = 328, + SpvOpMemoryNamedBarrier = 329, + SpvOpModuleProcessed = 330, + SpvOpExecutionModeId = 331, + SpvOpDecorateId = 332, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#endif // #ifndef spirv_H + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.hpp b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.hpp new file mode 100644 index 000000000000..57bd97a02109 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.hpp @@ -0,0 +1,1030 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10200 +#define SPV_REVISION 2 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010200; +static const unsigned int Revision = 2; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModeInitializer = 33, + ExecutionModeFinalizer = 34, + ExecutionModeSubgroupSize = 35, + ExecutionModeSubgroupsPerWorkgroup = 36, + ExecutionModeSubgroupsPerWorkgroupId = 37, + ExecutionModeLocalSizeId = 38, + ExecutionModeLocalSizeHintId = 39, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationMaxByteOffset = 45, + DecorationAlignmentId = 46, + DecorationMaxByteOffsetId = 47, + DecorationExplicitInterpAMD = 4999, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlDependencyInfiniteShift = 2, + LoopControlDependencyLengthShift = 3, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, + LoopControlDependencyInfiniteMask = 0x00000004, + LoopControlDependencyLengthMask = 0x00000008, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupDispatch = 58, + CapabilityNamedBarrier = 59, + CapabilityPipeStorage = 60, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilityMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + OpMax = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.hpp11 b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.hpp11 new file mode 100644 index 000000000000..7a875fdb1665 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.hpp11 @@ -0,0 +1,1030 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10200 +#define SPV_REVISION 2 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010200; +static const unsigned int Revision = 2; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + Max = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.json b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.json new file mode 100644 index 000000000000..9c0ff0a43e32 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.json @@ -0,0 +1,1046 @@ +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2018 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "", + "Some tokens act like mask values, which can be OR'd together,", + "while others are mutually exclusive. The mask-like ones have", + "\"Mask\" in their name, and a parallel enum that has the shift", + "amount (1 << x) for each corresponding enumerant." + ] + ], + "MagicNumber": 119734787, + "Version": 66048, + "Revision": 2, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "Initializer": 33, + "Finalizer": 34, + "SubgroupSize": 35, + "SubgroupsPerWorkgroup": 36, + "SubgroupsPerWorkgroupId": 37, + "LocalSizeId": 38, + "LocalSizeHintId": 39, + "PostDepthCoverage": 4446, + "StencilRefReplacingEXT": 5027 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "MaxByteOffset": 45, + "AlignmentId": 46, + "MaxByteOffsetId": 47, + "ExplicitInterpAMD": 4999, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1, + "DependencyInfinite": 2, + "DependencyLength": 3 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupDispatch": 58, + "NamedBarrier": 59, + "PipeStorage": 60, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpSizeOf": 321, + "OpTypePipeStorage": 322, + "OpConstantPipeStorage": 323, + "OpCreatePipeFromPipeStorage": 324, + "OpGetKernelLocalSizeForSubgroupCount": 325, + "OpGetKernelMaxNumSubgroups": 326, + "OpTypeNamedBarrier": 327, + "OpNamedBarrierInitialize": 328, + "OpMemoryNamedBarrier": 329, + "OpModuleProcessed": 330, + "OpExecutionModeId": 331, + "OpDecorateId": 332, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpSubgroupReadInvocationKHR": 4432, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateStringGOOGLE": 5633 + } + } + ] + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.lua b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.lua new file mode 100644 index 000000000000..0de507d5c913 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.lua @@ -0,0 +1,977 @@ +-- Copyright (c) 2014-2018 The Khronos Group Inc. +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and/or associated documentation files (the "Materials"), +-- to deal in the Materials without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Materials, and to permit persons to whom the +-- Materials are furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Materials. +-- +-- MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +-- STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +-- HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +-- +-- THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +-- IN THE MATERIALS. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- +-- Some tokens act like mask values, which can be OR'd together, +-- while others are mutually exclusive. The mask-like ones have +-- "Mask" in their name, and a parallel enum that has the shift +-- amount (1 << x) for each corresponding enumerant. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010200, + Revision = 2, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + }, + +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.py b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.py new file mode 100644 index 000000000000..cefee4d66ac4 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/1.2/spirv.py @@ -0,0 +1,977 @@ +# Copyright (c) 2014-2018 The Khronos Group Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and/or associated documentation files (the "Materials"), +# to deal in the Materials without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Materials, and to permit persons to whom the +# Materials are furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Materials. +# +# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +# STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +# HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +# +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +# IN THE MATERIALS. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# +# Some tokens act like mask values, which can be OR'd together, +# while others are mutually exclusive. The mask-like ones have +# "Mask" in their name, and a parallel enum that has the shift +# amount (1 << x) for each corresponding enumerant. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010200, + 'Revision' : 2, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'Initializer' : 33, + 'Finalizer' : 34, + 'SubgroupSize' : 35, + 'SubgroupsPerWorkgroup' : 36, + 'SubgroupsPerWorkgroupId' : 37, + 'LocalSizeId' : 38, + 'LocalSizeHintId' : 39, + 'PostDepthCoverage' : 4446, + 'StencilRefReplacingEXT' : 5027, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'MaxByteOffset' : 45, + 'AlignmentId' : 46, + 'MaxByteOffsetId' : 47, + 'ExplicitInterpAMD' : 4999, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + 'DependencyInfinite' : 2, + 'DependencyLength' : 3, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + 'DependencyInfinite' : 0x00000004, + 'DependencyLength' : 0x00000008, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupDispatch' : 58, + 'NamedBarrier' : 59, + 'PipeStorage' : 60, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpSizeOf' : 321, + 'OpTypePipeStorage' : 322, + 'OpConstantPipeStorage' : 323, + 'OpCreatePipeFromPipeStorage' : 324, + 'OpGetKernelLocalSizeForSubgroupCount' : 325, + 'OpGetKernelMaxNumSubgroups' : 326, + 'OpTypeNamedBarrier' : 327, + 'OpNamedBarrierInitialize' : 328, + 'OpMemoryNamedBarrier' : 329, + 'OpModuleProcessed' : 330, + 'OpExecutionModeId' : 331, + 'OpDecorateId' : 332, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateStringGOOGLE' : 5633, + }, + +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/spir-v.xml b/thirdparty/glslang/SPIRV-Headers/spirv/spir-v.xml new file mode 100644 index 000000000000..4a2de831410f --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/spir-v.xml @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_gcn_shader.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_gcn_shader.h new file mode 100644 index 000000000000..e626a7a9568d --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_gcn_shader.h @@ -0,0 +1,52 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_AMD_gcn_shader_H_ +#define SPIRV_UNIFIED1_AMD_gcn_shader_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AMD_gcn_shaderRevision = 2, + AMD_gcn_shaderRevision_BitWidthPadding = 0x7fffffff +}; + +enum AMD_gcn_shaderInstructions { + AMD_gcn_shaderCubeFaceIndexAMD = 1, + AMD_gcn_shaderCubeFaceCoordAMD = 2, + AMD_gcn_shaderTimeAMD = 3, + AMD_gcn_shaderInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_AMD_gcn_shader_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_ballot.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_ballot.h new file mode 100644 index 000000000000..563c0b622d51 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_ballot.h @@ -0,0 +1,53 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_AMD_shader_ballot_H_ +#define SPIRV_UNIFIED1_AMD_shader_ballot_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AMD_shader_ballotRevision = 5, + AMD_shader_ballotRevision_BitWidthPadding = 0x7fffffff +}; + +enum AMD_shader_ballotInstructions { + AMD_shader_ballotSwizzleInvocationsAMD = 1, + AMD_shader_ballotSwizzleInvocationsMaskedAMD = 2, + AMD_shader_ballotWriteInvocationAMD = 3, + AMD_shader_ballotMbcntAMD = 4, + AMD_shader_ballotInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_AMD_shader_ballot_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_explicit_vertex_parameter.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_explicit_vertex_parameter.h new file mode 100644 index 000000000000..e663330c19fa --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_explicit_vertex_parameter.h @@ -0,0 +1,50 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_AMD_shader_explicit_vertex_parameter_H_ +#define SPIRV_UNIFIED1_AMD_shader_explicit_vertex_parameter_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AMD_shader_explicit_vertex_parameterRevision = 4, + AMD_shader_explicit_vertex_parameterRevision_BitWidthPadding = 0x7fffffff +}; + +enum AMD_shader_explicit_vertex_parameterInstructions { + AMD_shader_explicit_vertex_parameterInterpolateAtVertexAMD = 1, + AMD_shader_explicit_vertex_parameterInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_AMD_shader_explicit_vertex_parameter_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_trinary_minmax.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_trinary_minmax.h new file mode 100644 index 000000000000..dd51c5fc81f7 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/AMD_shader_trinary_minmax.h @@ -0,0 +1,58 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_AMD_shader_trinary_minmax_H_ +#define SPIRV_UNIFIED1_AMD_shader_trinary_minmax_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AMD_shader_trinary_minmaxRevision = 4, + AMD_shader_trinary_minmaxRevision_BitWidthPadding = 0x7fffffff +}; + +enum AMD_shader_trinary_minmaxInstructions { + AMD_shader_trinary_minmaxFMin3AMD = 1, + AMD_shader_trinary_minmaxUMin3AMD = 2, + AMD_shader_trinary_minmaxSMin3AMD = 3, + AMD_shader_trinary_minmaxFMax3AMD = 4, + AMD_shader_trinary_minmaxUMax3AMD = 5, + AMD_shader_trinary_minmaxSMax3AMD = 6, + AMD_shader_trinary_minmaxFMid3AMD = 7, + AMD_shader_trinary_minmaxUMid3AMD = 8, + AMD_shader_trinary_minmaxSMid3AMD = 9, + AMD_shader_trinary_minmaxInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_AMD_shader_trinary_minmax_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/DebugInfo.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/DebugInfo.h new file mode 100644 index 000000000000..a3c0af456203 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/DebugInfo.h @@ -0,0 +1,144 @@ +// Copyright (c) 2017-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +#ifndef SPIRV_UNIFIED1_DebugInfo_H_ +#define SPIRV_UNIFIED1_DebugInfo_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + DebugInfoVersion = 100, + DebugInfoVersion_BitWidthPadding = 0x7fffffff +}; +enum { + DebugInfoRevision = 1, + DebugInfoRevision_BitWidthPadding = 0x7fffffff +}; + +enum DebugInfoInstructions { + DebugInfoDebugInfoNone = 0, + DebugInfoDebugCompilationUnit = 1, + DebugInfoDebugTypeBasic = 2, + DebugInfoDebugTypePointer = 3, + DebugInfoDebugTypeQualifier = 4, + DebugInfoDebugTypeArray = 5, + DebugInfoDebugTypeVector = 6, + DebugInfoDebugTypedef = 7, + DebugInfoDebugTypeFunction = 8, + DebugInfoDebugTypeEnum = 9, + DebugInfoDebugTypeComposite = 10, + DebugInfoDebugTypeMember = 11, + DebugInfoDebugTypeInheritance = 12, + DebugInfoDebugTypePtrToMember = 13, + DebugInfoDebugTypeTemplate = 14, + DebugInfoDebugTypeTemplateParameter = 15, + DebugInfoDebugTypeTemplateTemplateParameter = 16, + DebugInfoDebugTypeTemplateParameterPack = 17, + DebugInfoDebugGlobalVariable = 18, + DebugInfoDebugFunctionDeclaration = 19, + DebugInfoDebugFunction = 20, + DebugInfoDebugLexicalBlock = 21, + DebugInfoDebugLexicalBlockDiscriminator = 22, + DebugInfoDebugScope = 23, + DebugInfoDebugNoScope = 24, + DebugInfoDebugInlinedAt = 25, + DebugInfoDebugLocalVariable = 26, + DebugInfoDebugInlinedVariable = 27, + DebugInfoDebugDeclare = 28, + DebugInfoDebugValue = 29, + DebugInfoDebugOperation = 30, + DebugInfoDebugExpression = 31, + DebugInfoDebugMacroDef = 32, + DebugInfoDebugMacroUndef = 33, + DebugInfoInstructionsMax = 0x7fffffff +}; + + +enum DebugInfoDebugInfoFlags { + DebugInfoNone = 0x0000, + DebugInfoFlagIsProtected = 0x01, + DebugInfoFlagIsPrivate = 0x02, + DebugInfoFlagIsPublic = 0x03, + DebugInfoFlagIsLocal = 0x04, + DebugInfoFlagIsDefinition = 0x08, + DebugInfoFlagFwdDecl = 0x10, + DebugInfoFlagArtificial = 0x20, + DebugInfoFlagExplicit = 0x40, + DebugInfoFlagPrototyped = 0x80, + DebugInfoFlagObjectPointer = 0x100, + DebugInfoFlagStaticMember = 0x200, + DebugInfoFlagIndirectVariable = 0x400, + DebugInfoFlagLValueReference = 0x800, + DebugInfoFlagRValueReference = 0x1000, + DebugInfoFlagIsOptimized = 0x2000, + DebugInfoDebugInfoFlagsMax = 0x7fffffff +}; + +enum DebugInfoDebugBaseTypeAttributeEncoding { + DebugInfoUnspecified = 0, + DebugInfoAddress = 1, + DebugInfoBoolean = 2, + DebugInfoFloat = 4, + DebugInfoSigned = 5, + DebugInfoSignedChar = 6, + DebugInfoUnsigned = 7, + DebugInfoUnsignedChar = 8, + DebugInfoDebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum DebugInfoDebugCompositeType { + DebugInfoClass = 0, + DebugInfoStructure = 1, + DebugInfoUnion = 2, + DebugInfoDebugCompositeTypeMax = 0x7fffffff +}; + +enum DebugInfoDebugTypeQualifier { + DebugInfoConstType = 0, + DebugInfoVolatileType = 1, + DebugInfoRestrictType = 2, + DebugInfoDebugTypeQualifierMax = 0x7fffffff +}; + +enum DebugInfoDebugOperation { + DebugInfoDeref = 0, + DebugInfoPlus = 1, + DebugInfoMinus = 2, + DebugInfoPlusUconst = 3, + DebugInfoBitPiece = 4, + DebugInfoSwap = 5, + DebugInfoXderef = 6, + DebugInfoStackValue = 7, + DebugInfoConstu = 8, + DebugInfoDebugOperationMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_DebugInfo_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/GLSL.std.450.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/GLSL.std.450.h new file mode 100644 index 000000000000..0594f907a145 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/GLSL.std.450.h @@ -0,0 +1,131 @@ +/* +** Copyright (c) 2014-2024 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLstd450_H +#define GLSLstd450_H + +static const int GLSLstd450Version = 100; +static const int GLSLstd450Revision = 3; + +enum GLSLstd450 { + GLSLstd450Bad = 0, // Don't use + + GLSLstd450Round = 1, + GLSLstd450RoundEven = 2, + GLSLstd450Trunc = 3, + GLSLstd450FAbs = 4, + GLSLstd450SAbs = 5, + GLSLstd450FSign = 6, + GLSLstd450SSign = 7, + GLSLstd450Floor = 8, + GLSLstd450Ceil = 9, + GLSLstd450Fract = 10, + + GLSLstd450Radians = 11, + GLSLstd450Degrees = 12, + GLSLstd450Sin = 13, + GLSLstd450Cos = 14, + GLSLstd450Tan = 15, + GLSLstd450Asin = 16, + GLSLstd450Acos = 17, + GLSLstd450Atan = 18, + GLSLstd450Sinh = 19, + GLSLstd450Cosh = 20, + GLSLstd450Tanh = 21, + GLSLstd450Asinh = 22, + GLSLstd450Acosh = 23, + GLSLstd450Atanh = 24, + GLSLstd450Atan2 = 25, + + GLSLstd450Pow = 26, + GLSLstd450Exp = 27, + GLSLstd450Log = 28, + GLSLstd450Exp2 = 29, + GLSLstd450Log2 = 30, + GLSLstd450Sqrt = 31, + GLSLstd450InverseSqrt = 32, + + GLSLstd450Determinant = 33, + GLSLstd450MatrixInverse = 34, + + GLSLstd450Modf = 35, // second operand needs an OpVariable to write to + GLSLstd450ModfStruct = 36, // no OpVariable operand + GLSLstd450FMin = 37, + GLSLstd450UMin = 38, + GLSLstd450SMin = 39, + GLSLstd450FMax = 40, + GLSLstd450UMax = 41, + GLSLstd450SMax = 42, + GLSLstd450FClamp = 43, + GLSLstd450UClamp = 44, + GLSLstd450SClamp = 45, + GLSLstd450FMix = 46, + GLSLstd450IMix = 47, // Reserved + GLSLstd450Step = 48, + GLSLstd450SmoothStep = 49, + + GLSLstd450Fma = 50, + GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to + GLSLstd450FrexpStruct = 52, // no OpVariable operand + GLSLstd450Ldexp = 53, + + GLSLstd450PackSnorm4x8 = 54, + GLSLstd450PackUnorm4x8 = 55, + GLSLstd450PackSnorm2x16 = 56, + GLSLstd450PackUnorm2x16 = 57, + GLSLstd450PackHalf2x16 = 58, + GLSLstd450PackDouble2x32 = 59, + GLSLstd450UnpackSnorm2x16 = 60, + GLSLstd450UnpackUnorm2x16 = 61, + GLSLstd450UnpackHalf2x16 = 62, + GLSLstd450UnpackSnorm4x8 = 63, + GLSLstd450UnpackUnorm4x8 = 64, + GLSLstd450UnpackDouble2x32 = 65, + + GLSLstd450Length = 66, + GLSLstd450Distance = 67, + GLSLstd450Cross = 68, + GLSLstd450Normalize = 69, + GLSLstd450FaceForward = 70, + GLSLstd450Reflect = 71, + GLSLstd450Refract = 72, + + GLSLstd450FindILsb = 73, + GLSLstd450FindSMsb = 74, + GLSLstd450FindUMsb = 75, + + GLSLstd450InterpolateAtCentroid = 76, + GLSLstd450InterpolateAtSample = 77, + GLSLstd450InterpolateAtOffset = 78, + + GLSLstd450NMin = 79, + GLSLstd450NMax = 80, + GLSLstd450NClamp = 81, + + GLSLstd450Count +}; + +#endif // #ifndef GLSLstd450_H diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticClspvReflection.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticClspvReflection.h new file mode 100644 index 000000000000..b6c27fa9b9e0 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticClspvReflection.h @@ -0,0 +1,97 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticClspvReflection_H_ +#define SPIRV_UNIFIED1_NonSemanticClspvReflection_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticClspvReflectionRevision = 6, + NonSemanticClspvReflectionRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticClspvReflectionInstructions { + NonSemanticClspvReflectionKernel = 1, + NonSemanticClspvReflectionArgumentInfo = 2, + NonSemanticClspvReflectionArgumentStorageBuffer = 3, + NonSemanticClspvReflectionArgumentUniform = 4, + NonSemanticClspvReflectionArgumentPodStorageBuffer = 5, + NonSemanticClspvReflectionArgumentPodUniform = 6, + NonSemanticClspvReflectionArgumentPodPushConstant = 7, + NonSemanticClspvReflectionArgumentSampledImage = 8, + NonSemanticClspvReflectionArgumentStorageImage = 9, + NonSemanticClspvReflectionArgumentSampler = 10, + NonSemanticClspvReflectionArgumentWorkgroup = 11, + NonSemanticClspvReflectionSpecConstantWorkgroupSize = 12, + NonSemanticClspvReflectionSpecConstantGlobalOffset = 13, + NonSemanticClspvReflectionSpecConstantWorkDim = 14, + NonSemanticClspvReflectionPushConstantGlobalOffset = 15, + NonSemanticClspvReflectionPushConstantEnqueuedLocalSize = 16, + NonSemanticClspvReflectionPushConstantGlobalSize = 17, + NonSemanticClspvReflectionPushConstantRegionOffset = 18, + NonSemanticClspvReflectionPushConstantNumWorkgroups = 19, + NonSemanticClspvReflectionPushConstantRegionGroupOffset = 20, + NonSemanticClspvReflectionConstantDataStorageBuffer = 21, + NonSemanticClspvReflectionConstantDataUniform = 22, + NonSemanticClspvReflectionLiteralSampler = 23, + NonSemanticClspvReflectionPropertyRequiredWorkgroupSize = 24, + NonSemanticClspvReflectionSpecConstantSubgroupMaxSize = 25, + NonSemanticClspvReflectionArgumentPointerPushConstant = 26, + NonSemanticClspvReflectionArgumentPointerUniform = 27, + NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer = 28, + NonSemanticClspvReflectionProgramScopeVariablePointerRelocation = 29, + NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant = 30, + NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant = 31, + NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform = 32, + NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform = 33, + NonSemanticClspvReflectionArgumentStorageTexelBuffer = 34, + NonSemanticClspvReflectionArgumentUniformTexelBuffer = 35, + NonSemanticClspvReflectionConstantDataPointerPushConstant = 36, + NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant = 37, + NonSemanticClspvReflectionPrintfInfo = 38, + NonSemanticClspvReflectionPrintfBufferStorageBuffer = 39, + NonSemanticClspvReflectionPrintfBufferPointerPushConstant = 40, + NonSemanticClspvReflectionNormalizedSamplerMaskPushConstant = 41, + NonSemanticClspvReflectionInstructionsMax = 0x7fffffff +}; + + +enum NonSemanticClspvReflectionKernelPropertyFlags { + NonSemanticClspvReflectionNone = 0x0, + NonSemanticClspvReflectionMayUsePrintf = 0x1, + NonSemanticClspvReflectionKernelPropertyFlagsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticClspvReflection_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticDebugBreak.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticDebugBreak.h new file mode 100644 index 000000000000..8604fe7842f0 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticDebugBreak.h @@ -0,0 +1,50 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticDebugBreak_H_ +#define SPIRV_UNIFIED1_NonSemanticDebugBreak_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticDebugBreakRevision = 1, + NonSemanticDebugBreakRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticDebugBreakInstructions { + NonSemanticDebugBreakDebugBreak = 1, + NonSemanticDebugBreakInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticDebugBreak_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticDebugPrintf.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticDebugPrintf.h new file mode 100644 index 000000000000..bc24683ec040 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticDebugPrintf.h @@ -0,0 +1,50 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ +#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticDebugPrintfRevision = 1, + NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticDebugPrintfInstructions { + NonSemanticDebugPrintfDebugPrintf = 1, + NonSemanticDebugPrintfInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticShaderDebugInfo100.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticShaderDebugInfo100.h new file mode 100644 index 000000000000..b276b560cbc8 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticShaderDebugInfo100.h @@ -0,0 +1,171 @@ +// Copyright (c) 2018-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +#ifndef SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ +#define SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticShaderDebugInfo100Version = 100, + NonSemanticShaderDebugInfo100Version_BitWidthPadding = 0x7fffffff +}; +enum { + NonSemanticShaderDebugInfo100Revision = 6, + NonSemanticShaderDebugInfo100Revision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100Instructions { + NonSemanticShaderDebugInfo100DebugInfoNone = 0, + NonSemanticShaderDebugInfo100DebugCompilationUnit = 1, + NonSemanticShaderDebugInfo100DebugTypeBasic = 2, + NonSemanticShaderDebugInfo100DebugTypePointer = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifier = 4, + NonSemanticShaderDebugInfo100DebugTypeArray = 5, + NonSemanticShaderDebugInfo100DebugTypeVector = 6, + NonSemanticShaderDebugInfo100DebugTypedef = 7, + NonSemanticShaderDebugInfo100DebugTypeFunction = 8, + NonSemanticShaderDebugInfo100DebugTypeEnum = 9, + NonSemanticShaderDebugInfo100DebugTypeComposite = 10, + NonSemanticShaderDebugInfo100DebugTypeMember = 11, + NonSemanticShaderDebugInfo100DebugTypeInheritance = 12, + NonSemanticShaderDebugInfo100DebugTypePtrToMember = 13, + NonSemanticShaderDebugInfo100DebugTypeTemplate = 14, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameter = 15, + NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter = 16, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack = 17, + NonSemanticShaderDebugInfo100DebugGlobalVariable = 18, + NonSemanticShaderDebugInfo100DebugFunctionDeclaration = 19, + NonSemanticShaderDebugInfo100DebugFunction = 20, + NonSemanticShaderDebugInfo100DebugLexicalBlock = 21, + NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator = 22, + NonSemanticShaderDebugInfo100DebugScope = 23, + NonSemanticShaderDebugInfo100DebugNoScope = 24, + NonSemanticShaderDebugInfo100DebugInlinedAt = 25, + NonSemanticShaderDebugInfo100DebugLocalVariable = 26, + NonSemanticShaderDebugInfo100DebugInlinedVariable = 27, + NonSemanticShaderDebugInfo100DebugDeclare = 28, + NonSemanticShaderDebugInfo100DebugValue = 29, + NonSemanticShaderDebugInfo100DebugOperation = 30, + NonSemanticShaderDebugInfo100DebugExpression = 31, + NonSemanticShaderDebugInfo100DebugMacroDef = 32, + NonSemanticShaderDebugInfo100DebugMacroUndef = 33, + NonSemanticShaderDebugInfo100DebugImportedEntity = 34, + NonSemanticShaderDebugInfo100DebugSource = 35, + NonSemanticShaderDebugInfo100DebugFunctionDefinition = 101, + NonSemanticShaderDebugInfo100DebugSourceContinued = 102, + NonSemanticShaderDebugInfo100DebugLine = 103, + NonSemanticShaderDebugInfo100DebugNoLine = 104, + NonSemanticShaderDebugInfo100DebugBuildIdentifier = 105, + NonSemanticShaderDebugInfo100DebugStoragePath = 106, + NonSemanticShaderDebugInfo100DebugEntryPoint = 107, + NonSemanticShaderDebugInfo100DebugTypeMatrix = 108, + NonSemanticShaderDebugInfo100InstructionsMax = 0x7fffffff +}; + + +enum NonSemanticShaderDebugInfo100DebugInfoFlags { + NonSemanticShaderDebugInfo100None = 0x0000, + NonSemanticShaderDebugInfo100FlagIsProtected = 0x01, + NonSemanticShaderDebugInfo100FlagIsPrivate = 0x02, + NonSemanticShaderDebugInfo100FlagIsPublic = 0x03, + NonSemanticShaderDebugInfo100FlagIsLocal = 0x04, + NonSemanticShaderDebugInfo100FlagIsDefinition = 0x08, + NonSemanticShaderDebugInfo100FlagFwdDecl = 0x10, + NonSemanticShaderDebugInfo100FlagArtificial = 0x20, + NonSemanticShaderDebugInfo100FlagExplicit = 0x40, + NonSemanticShaderDebugInfo100FlagPrototyped = 0x80, + NonSemanticShaderDebugInfo100FlagObjectPointer = 0x100, + NonSemanticShaderDebugInfo100FlagStaticMember = 0x200, + NonSemanticShaderDebugInfo100FlagIndirectVariable = 0x400, + NonSemanticShaderDebugInfo100FlagLValueReference = 0x800, + NonSemanticShaderDebugInfo100FlagRValueReference = 0x1000, + NonSemanticShaderDebugInfo100FlagIsOptimized = 0x2000, + NonSemanticShaderDebugInfo100FlagIsEnumClass = 0x4000, + NonSemanticShaderDebugInfo100FlagTypePassByValue = 0x8000, + NonSemanticShaderDebugInfo100FlagTypePassByReference = 0x10000, + NonSemanticShaderDebugInfo100FlagUnknownPhysicalLayout = 0x20000, + NonSemanticShaderDebugInfo100DebugInfoFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100BuildIdentifierFlags { + NonSemanticShaderDebugInfo100IdentifierPossibleDuplicates = 0x01, + NonSemanticShaderDebugInfo100BuildIdentifierFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncoding { + NonSemanticShaderDebugInfo100Unspecified = 0, + NonSemanticShaderDebugInfo100Address = 1, + NonSemanticShaderDebugInfo100Boolean = 2, + NonSemanticShaderDebugInfo100Float = 3, + NonSemanticShaderDebugInfo100Signed = 4, + NonSemanticShaderDebugInfo100SignedChar = 5, + NonSemanticShaderDebugInfo100Unsigned = 6, + NonSemanticShaderDebugInfo100UnsignedChar = 7, + NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugCompositeType { + NonSemanticShaderDebugInfo100Class = 0, + NonSemanticShaderDebugInfo100Structure = 1, + NonSemanticShaderDebugInfo100Union = 2, + NonSemanticShaderDebugInfo100DebugCompositeTypeMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugTypeQualifier { + NonSemanticShaderDebugInfo100ConstType = 0, + NonSemanticShaderDebugInfo100VolatileType = 1, + NonSemanticShaderDebugInfo100RestrictType = 2, + NonSemanticShaderDebugInfo100AtomicType = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifierMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugOperation { + NonSemanticShaderDebugInfo100Deref = 0, + NonSemanticShaderDebugInfo100Plus = 1, + NonSemanticShaderDebugInfo100Minus = 2, + NonSemanticShaderDebugInfo100PlusUconst = 3, + NonSemanticShaderDebugInfo100BitPiece = 4, + NonSemanticShaderDebugInfo100Swap = 5, + NonSemanticShaderDebugInfo100Xderef = 6, + NonSemanticShaderDebugInfo100StackValue = 7, + NonSemanticShaderDebugInfo100Constu = 8, + NonSemanticShaderDebugInfo100Fragment = 9, + NonSemanticShaderDebugInfo100DebugOperationMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugImportedEntity { + NonSemanticShaderDebugInfo100ImportedModule = 0, + NonSemanticShaderDebugInfo100ImportedDeclaration = 1, + NonSemanticShaderDebugInfo100DebugImportedEntityMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticVkspReflection.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticVkspReflection.h new file mode 100644 index 000000000000..0ef478a8caac --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/NonSemanticVkspReflection.h @@ -0,0 +1,57 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticVkspReflection_H_ +#define SPIRV_UNIFIED1_NonSemanticVkspReflection_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticVkspReflectionRevision = 1, + NonSemanticVkspReflectionRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticVkspReflectionInstructions { + NonSemanticVkspReflectionConfiguration = 1, + NonSemanticVkspReflectionStartCounter = 2, + NonSemanticVkspReflectionStopCounter = 3, + NonSemanticVkspReflectionPushConstants = 4, + NonSemanticVkspReflectionSpecializationMapEntry = 5, + NonSemanticVkspReflectionDescriptorSetBuffer = 6, + NonSemanticVkspReflectionDescriptorSetImage = 7, + NonSemanticVkspReflectionDescriptorSetSampler = 8, + NonSemanticVkspReflectionInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticVkspReflection_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/OpenCL.std.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/OpenCL.std.h new file mode 100644 index 000000000000..ed74f203e196 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/OpenCL.std.h @@ -0,0 +1,401 @@ +/* +** Copyright (c) 2015-2024 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef OPENCLstd_H +#define OPENCLstd_H + +#ifdef __cplusplus +namespace OpenCLLIB { + +enum Entrypoints { + + // Section 2.1: Math extended instructions + Acos = 0, + Acosh = 1, + Acospi = 2, + Asin = 3, + Asinh = 4, + Asinpi = 5, + Atan = 6, + Atan2 = 7, + Atanh = 8, + Atanpi = 9, + Atan2pi = 10, + Cbrt = 11, + Ceil = 12, + Copysign = 13, + Cos = 14, + Cosh = 15, + Cospi = 16, + Erfc = 17, + Erf = 18, + Exp = 19, + Exp2 = 20, + Exp10 = 21, + Expm1 = 22, + Fabs = 23, + Fdim = 24, + Floor = 25, + Fma = 26, + Fmax = 27, + Fmin = 28, + Fmod = 29, + Fract = 30, + Frexp = 31, + Hypot = 32, + Ilogb = 33, + Ldexp = 34, + Lgamma = 35, + Lgamma_r = 36, + Log = 37, + Log2 = 38, + Log10 = 39, + Log1p = 40, + Logb = 41, + Mad = 42, + Maxmag = 43, + Minmag = 44, + Modf = 45, + Nan = 46, + Nextafter = 47, + Pow = 48, + Pown = 49, + Powr = 50, + Remainder = 51, + Remquo = 52, + Rint = 53, + Rootn = 54, + Round = 55, + Rsqrt = 56, + Sin = 57, + Sincos = 58, + Sinh = 59, + Sinpi = 60, + Sqrt = 61, + Tan = 62, + Tanh = 63, + Tanpi = 64, + Tgamma = 65, + Trunc = 66, + Half_cos = 67, + Half_divide = 68, + Half_exp = 69, + Half_exp2 = 70, + Half_exp10 = 71, + Half_log = 72, + Half_log2 = 73, + Half_log10 = 74, + Half_powr = 75, + Half_recip = 76, + Half_rsqrt = 77, + Half_sin = 78, + Half_sqrt = 79, + Half_tan = 80, + Native_cos = 81, + Native_divide = 82, + Native_exp = 83, + Native_exp2 = 84, + Native_exp10 = 85, + Native_log = 86, + Native_log2 = 87, + Native_log10 = 88, + Native_powr = 89, + Native_recip = 90, + Native_rsqrt = 91, + Native_sin = 92, + Native_sqrt = 93, + Native_tan = 94, + + // Section 2.2: Integer instructions + SAbs = 141, + SAbs_diff = 142, + SAdd_sat = 143, + UAdd_sat = 144, + SHadd = 145, + UHadd = 146, + SRhadd = 147, + URhadd = 148, + SClamp = 149, + UClamp = 150, + Clz = 151, + Ctz = 152, + SMad_hi = 153, + UMad_sat = 154, + SMad_sat = 155, + SMax = 156, + UMax = 157, + SMin = 158, + UMin = 159, + SMul_hi = 160, + Rotate = 161, + SSub_sat = 162, + USub_sat = 163, + U_Upsample = 164, + S_Upsample = 165, + Popcount = 166, + SMad24 = 167, + UMad24 = 168, + SMul24 = 169, + UMul24 = 170, + UAbs = 201, + UAbs_diff = 202, + UMul_hi = 203, + UMad_hi = 204, + + // Section 2.3: Common instructions + FClamp = 95, + Degrees = 96, + FMax_common = 97, + FMin_common = 98, + Mix = 99, + Radians = 100, + Step = 101, + Smoothstep = 102, + Sign = 103, + + // Section 2.4: Geometric instructions + Cross = 104, + Distance = 105, + Length = 106, + Normalize = 107, + Fast_distance = 108, + Fast_length = 109, + Fast_normalize = 110, + + // Section 2.5: Relational instructions + Bitselect = 186, + Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + Vloadn = 171, + Vstoren = 172, + Vload_half = 173, + Vload_halfn = 174, + Vstore_half = 175, + Vstore_half_r = 176, + Vstore_halfn = 177, + Vstore_halfn_r = 178, + Vloada_halfn = 179, + Vstorea_halfn = 180, + Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + Shuffle = 182, + Shuffle2 = 183, + + // Section 2.8: Misc instructions + Printf = 184, + Prefetch = 185, +}; + +} // end namespace OpenCLLIB + +#else + +enum OpenCLstd_Entrypoints { + + // Section 2.1: Math extended instructions + OpenCLstd_Acos = 0, + OpenCLstd_Acosh = 1, + OpenCLstd_Acospi = 2, + OpenCLstd_Asin = 3, + OpenCLstd_Asinh = 4, + OpenCLstd_Asinpi = 5, + OpenCLstd_Atan = 6, + OpenCLstd_Atan2 = 7, + OpenCLstd_Atanh = 8, + OpenCLstd_Atanpi = 9, + OpenCLstd_Atan2pi = 10, + OpenCLstd_Cbrt = 11, + OpenCLstd_Ceil = 12, + OpenCLstd_Copysign = 13, + OpenCLstd_Cos = 14, + OpenCLstd_Cosh = 15, + OpenCLstd_Cospi = 16, + OpenCLstd_Erfc = 17, + OpenCLstd_Erf = 18, + OpenCLstd_Exp = 19, + OpenCLstd_Exp2 = 20, + OpenCLstd_Exp10 = 21, + OpenCLstd_Expm1 = 22, + OpenCLstd_Fabs = 23, + OpenCLstd_Fdim = 24, + OpenCLstd_Floor = 25, + OpenCLstd_Fma = 26, + OpenCLstd_Fmax = 27, + OpenCLstd_Fmin = 28, + OpenCLstd_Fmod = 29, + OpenCLstd_Fract = 30, + OpenCLstd_Frexp = 31, + OpenCLstd_Hypot = 32, + OpenCLstd_Ilogb = 33, + OpenCLstd_Ldexp = 34, + OpenCLstd_Lgamma = 35, + OpenCLstd_Lgamma_r = 36, + OpenCLstd_Log = 37, + OpenCLstd_Log2 = 38, + OpenCLstd_Log10 = 39, + OpenCLstd_Log1p = 40, + OpenCLstd_Logb = 41, + OpenCLstd_Mad = 42, + OpenCLstd_Maxmag = 43, + OpenCLstd_Minmag = 44, + OpenCLstd_Modf = 45, + OpenCLstd_Nan = 46, + OpenCLstd_Nextafter = 47, + OpenCLstd_Pow = 48, + OpenCLstd_Pown = 49, + OpenCLstd_Powr = 50, + OpenCLstd_Remainder = 51, + OpenCLstd_Remquo = 52, + OpenCLstd_Rint = 53, + OpenCLstd_Rootn = 54, + OpenCLstd_Round = 55, + OpenCLstd_Rsqrt = 56, + OpenCLstd_Sin = 57, + OpenCLstd_Sincos = 58, + OpenCLstd_Sinh = 59, + OpenCLstd_Sinpi = 60, + OpenCLstd_Sqrt = 61, + OpenCLstd_Tan = 62, + OpenCLstd_Tanh = 63, + OpenCLstd_Tanpi = 64, + OpenCLstd_Tgamma = 65, + OpenCLstd_Trunc = 66, + OpenCLstd_Half_cos = 67, + OpenCLstd_Half_divide = 68, + OpenCLstd_Half_exp = 69, + OpenCLstd_Half_exp2 = 70, + OpenCLstd_Half_exp10 = 71, + OpenCLstd_Half_log = 72, + OpenCLstd_Half_log2 = 73, + OpenCLstd_Half_log10 = 74, + OpenCLstd_Half_powr = 75, + OpenCLstd_Half_recip = 76, + OpenCLstd_Half_rsqrt = 77, + OpenCLstd_Half_sin = 78, + OpenCLstd_Half_sqrt = 79, + OpenCLstd_Half_tan = 80, + OpenCLstd_Native_cos = 81, + OpenCLstd_Native_divide = 82, + OpenCLstd_Native_exp = 83, + OpenCLstd_Native_exp2 = 84, + OpenCLstd_Native_exp10 = 85, + OpenCLstd_Native_log = 86, + OpenCLstd_Native_log2 = 87, + OpenCLstd_Native_log10 = 88, + OpenCLstd_Native_powr = 89, + OpenCLstd_Native_recip = 90, + OpenCLstd_Native_rsqrt = 91, + OpenCLstd_Native_sin = 92, + OpenCLstd_Native_sqrt = 93, + OpenCLstd_Native_tan = 94, + + // Section 2.2: Integer instructions + OpenCLstd_SAbs = 141, + OpenCLstd_SAbs_diff = 142, + OpenCLstd_SAdd_sat = 143, + OpenCLstd_UAdd_sat = 144, + OpenCLstd_SHadd = 145, + OpenCLstd_UHadd = 146, + OpenCLstd_SRhadd = 147, + OpenCLstd_URhadd = 148, + OpenCLstd_SClamp = 149, + OpenCLstd_UClamp = 150, + OpenCLstd_Clz = 151, + OpenCLstd_Ctz = 152, + OpenCLstd_SMad_hi = 153, + OpenCLstd_UMad_sat = 154, + OpenCLstd_SMad_sat = 155, + OpenCLstd_SMax = 156, + OpenCLstd_UMax = 157, + OpenCLstd_SMin = 158, + OpenCLstd_UMin = 159, + OpenCLstd_SMul_hi = 160, + OpenCLstd_Rotate = 161, + OpenCLstd_SSub_sat = 162, + OpenCLstd_USub_sat = 163, + OpenCLstd_U_Upsample = 164, + OpenCLstd_S_Upsample = 165, + OpenCLstd_Popcount = 166, + OpenCLstd_SMad24 = 167, + OpenCLstd_UMad24 = 168, + OpenCLstd_SMul24 = 169, + OpenCLstd_UMul24 = 170, + OpenCLstd_UAbs = 201, + OpenCLstd_UAbs_diff = 202, + OpenCLstd_UMul_hi = 203, + OpenCLstd_UMad_hi = 204, + + // Section 2.3: Common instructions + OpenCLstd_FClamp = 95, + OpenCLstd_Degrees = 96, + OpenCLstd_FMax_common = 97, + OpenCLstd_FMin_common = 98, + OpenCLstd_Mix = 99, + OpenCLstd_Radians = 100, + OpenCLstd_Step = 101, + OpenCLstd_Smoothstep = 102, + OpenCLstd_Sign = 103, + + // Section 2.4: Geometric instructions + OpenCLstd_Cross = 104, + OpenCLstd_Distance = 105, + OpenCLstd_Length = 106, + OpenCLstd_Normalize = 107, + OpenCLstd_Fast_distance = 108, + OpenCLstd_Fast_length = 109, + OpenCLstd_Fast_normalize = 110, + + // Section 2.5: Relational instructions + OpenCLstd_Bitselect = 186, + OpenCLstd_Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + OpenCLstd_Vloadn = 171, + OpenCLstd_Vstoren = 172, + OpenCLstd_Vload_half = 173, + OpenCLstd_Vload_halfn = 174, + OpenCLstd_Vstore_half = 175, + OpenCLstd_Vstore_half_r = 176, + OpenCLstd_Vstore_halfn = 177, + OpenCLstd_Vstore_halfn_r = 178, + OpenCLstd_Vloada_halfn = 179, + OpenCLstd_Vstorea_halfn = 180, + OpenCLstd_Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + OpenCLstd_Shuffle = 182, + OpenCLstd_Shuffle2 = 183, + + // Section 2.8: Misc instructions + OpenCLstd_Printf = 184, + OpenCLstd_Prefetch = 185, +}; + +#endif + +#endif // #ifndef OPENCLstd_H diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/OpenCLDebugInfo100.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/OpenCLDebugInfo100.h new file mode 100644 index 000000000000..ffbd16f1d732 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/OpenCLDebugInfo100.h @@ -0,0 +1,158 @@ +// Copyright (c) 2018-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +#ifndef SPIRV_UNIFIED1_OpenCLDebugInfo100_H_ +#define SPIRV_UNIFIED1_OpenCLDebugInfo100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + OpenCLDebugInfo100Version = 200, + OpenCLDebugInfo100Version_BitWidthPadding = 0x7fffffff +}; +enum { + OpenCLDebugInfo100Revision = 2, + OpenCLDebugInfo100Revision_BitWidthPadding = 0x7fffffff +}; + +enum OpenCLDebugInfo100Instructions { + OpenCLDebugInfo100DebugInfoNone = 0, + OpenCLDebugInfo100DebugCompilationUnit = 1, + OpenCLDebugInfo100DebugTypeBasic = 2, + OpenCLDebugInfo100DebugTypePointer = 3, + OpenCLDebugInfo100DebugTypeQualifier = 4, + OpenCLDebugInfo100DebugTypeArray = 5, + OpenCLDebugInfo100DebugTypeVector = 6, + OpenCLDebugInfo100DebugTypedef = 7, + OpenCLDebugInfo100DebugTypeFunction = 8, + OpenCLDebugInfo100DebugTypeEnum = 9, + OpenCLDebugInfo100DebugTypeComposite = 10, + OpenCLDebugInfo100DebugTypeMember = 11, + OpenCLDebugInfo100DebugTypeInheritance = 12, + OpenCLDebugInfo100DebugTypePtrToMember = 13, + OpenCLDebugInfo100DebugTypeTemplate = 14, + OpenCLDebugInfo100DebugTypeTemplateParameter = 15, + OpenCLDebugInfo100DebugTypeTemplateTemplateParameter = 16, + OpenCLDebugInfo100DebugTypeTemplateParameterPack = 17, + OpenCLDebugInfo100DebugGlobalVariable = 18, + OpenCLDebugInfo100DebugFunctionDeclaration = 19, + OpenCLDebugInfo100DebugFunction = 20, + OpenCLDebugInfo100DebugLexicalBlock = 21, + OpenCLDebugInfo100DebugLexicalBlockDiscriminator = 22, + OpenCLDebugInfo100DebugScope = 23, + OpenCLDebugInfo100DebugNoScope = 24, + OpenCLDebugInfo100DebugInlinedAt = 25, + OpenCLDebugInfo100DebugLocalVariable = 26, + OpenCLDebugInfo100DebugInlinedVariable = 27, + OpenCLDebugInfo100DebugDeclare = 28, + OpenCLDebugInfo100DebugValue = 29, + OpenCLDebugInfo100DebugOperation = 30, + OpenCLDebugInfo100DebugExpression = 31, + OpenCLDebugInfo100DebugMacroDef = 32, + OpenCLDebugInfo100DebugMacroUndef = 33, + OpenCLDebugInfo100DebugImportedEntity = 34, + OpenCLDebugInfo100DebugSource = 35, + OpenCLDebugInfo100DebugModuleINTEL = 36, + OpenCLDebugInfo100InstructionsMax = 0x7fffffff +}; + + +enum OpenCLDebugInfo100DebugInfoFlags { + OpenCLDebugInfo100None = 0x0000, + OpenCLDebugInfo100FlagIsProtected = 0x01, + OpenCLDebugInfo100FlagIsPrivate = 0x02, + OpenCLDebugInfo100FlagIsPublic = 0x03, + OpenCLDebugInfo100FlagIsLocal = 0x04, + OpenCLDebugInfo100FlagIsDefinition = 0x08, + OpenCLDebugInfo100FlagFwdDecl = 0x10, + OpenCLDebugInfo100FlagArtificial = 0x20, + OpenCLDebugInfo100FlagExplicit = 0x40, + OpenCLDebugInfo100FlagPrototyped = 0x80, + OpenCLDebugInfo100FlagObjectPointer = 0x100, + OpenCLDebugInfo100FlagStaticMember = 0x200, + OpenCLDebugInfo100FlagIndirectVariable = 0x400, + OpenCLDebugInfo100FlagLValueReference = 0x800, + OpenCLDebugInfo100FlagRValueReference = 0x1000, + OpenCLDebugInfo100FlagIsOptimized = 0x2000, + OpenCLDebugInfo100FlagIsEnumClass = 0x4000, + OpenCLDebugInfo100FlagTypePassByValue = 0x8000, + OpenCLDebugInfo100FlagTypePassByReference = 0x10000, + OpenCLDebugInfo100DebugInfoFlagsMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugBaseTypeAttributeEncoding { + OpenCLDebugInfo100Unspecified = 0, + OpenCLDebugInfo100Address = 1, + OpenCLDebugInfo100Boolean = 2, + OpenCLDebugInfo100Float = 3, + OpenCLDebugInfo100Signed = 4, + OpenCLDebugInfo100SignedChar = 5, + OpenCLDebugInfo100Unsigned = 6, + OpenCLDebugInfo100UnsignedChar = 7, + OpenCLDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugCompositeType { + OpenCLDebugInfo100Class = 0, + OpenCLDebugInfo100Structure = 1, + OpenCLDebugInfo100Union = 2, + OpenCLDebugInfo100DebugCompositeTypeMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugTypeQualifier { + OpenCLDebugInfo100ConstType = 0, + OpenCLDebugInfo100VolatileType = 1, + OpenCLDebugInfo100RestrictType = 2, + OpenCLDebugInfo100AtomicType = 3, + OpenCLDebugInfo100DebugTypeQualifierMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugOperation { + OpenCLDebugInfo100Deref = 0, + OpenCLDebugInfo100Plus = 1, + OpenCLDebugInfo100Minus = 2, + OpenCLDebugInfo100PlusUconst = 3, + OpenCLDebugInfo100BitPiece = 4, + OpenCLDebugInfo100Swap = 5, + OpenCLDebugInfo100Xderef = 6, + OpenCLDebugInfo100StackValue = 7, + OpenCLDebugInfo100Constu = 8, + OpenCLDebugInfo100Fragment = 9, + OpenCLDebugInfo100DebugOperationMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugImportedEntity { + OpenCLDebugInfo100ImportedModule = 0, + OpenCLDebugInfo100ImportedDeclaration = 1, + OpenCLDebugInfo100DebugImportedEntityMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_OpenCLDebugInfo100_H_ diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.debuginfo.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.debuginfo.grammar.json new file mode 100644 index 000000000000..918a9e547be4 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.debuginfo.grammar.json @@ -0,0 +1,572 @@ +{ + "copyright" : [ + "Copyright (c) 2017-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 1, + "instructions" : [ + { + "opname" : "DebugInfoNone", + "opcode" : 0 + }, + { + "opname" : "DebugCompilationUnit", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "LiteralInteger", "name" : "'DWARF Version'" } + ] + }, + { + "opname" : "DebugTypeBasic", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugBaseTypeAttributeEncoding", "name" : "'Encoding'" } + ] + }, + { + "opname" : "DebugTypePointer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "StorageClass", "name" : "'Storage Class'" }, + { "kind" : "DebugInfoFlags", "name" : "'Literal Flags'" } + ] + }, + { + "opname" : "DebugTypeQualifier", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "DebugTypeQualifier", "name" : "'Type Qualifier'" } + ] + }, + { + "opname" : "DebugTypeArray", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeVector", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "DebugTypedef", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeFunction", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "name" : "'Paramter Types'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeEnum", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Underlying Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeComposite", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "DebugCompositeType", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeMember", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugTypeInheritance", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'Child'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePtrToMember", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'Member Type'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeTemplate", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeTemplateParameter", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Actual Type'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateTemplateParameter", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Template Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateParameterPack", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugGlobalVariable", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDeclaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugFunction", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "LiteralInteger", "name" : "'Scope Line'" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlock", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlockDiscriminator", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "LiteralInteger", "name" : "'Discriminator'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugScope", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugNoScope", + "opcode" : 24 + }, + { + "opname" : "DebugInlinedAt", + "opcode" : 25, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLocalVariable", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "LiteralInteger", "name" : "'Arg Number'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugInlinedVariable", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Inlined'" } + ] + }, + { + "opname" : "DebugDeclare", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Expression'" } + ] + }, + { + "opname" : "DebugValue", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugOperation", + "opcode" : 30, + "operands" : [ + { "kind" : "DebugOperation", "name" : "'OpCode'" }, + { "kind" : "LiteralInteger", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugExpression", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugMacroDef", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugMacroUndef", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Macro'" } + ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "DebugInfoFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "FlagIsProtected", + "value" : "0x01" + }, + { + "enumerant" : "FlagIsPrivate", + "value" : "0x02" + }, + { + "enumerant" : "FlagIsPublic", + "value" : "0x03" + }, + { + "enumerant" : "FlagIsLocal", + "value" : "0x04" + }, + { + "enumerant" : "FlagIsDefinition", + "value" : "0x08" + }, + { + "enumerant" : "FlagFwdDecl", + "value" : "0x10" + }, + { + "enumerant" : "FlagArtificial", + "value" : "0x20" + }, + { + "enumerant" : "FlagExplicit", + "value" : "0x40" + }, + { + "enumerant" : "FlagPrototyped", + "value" : "0x80" + }, + { + "enumerant" : "FlagObjectPointer", + "value" : "0x100" + }, + { + "enumerant" : "FlagStaticMember", + "value" : "0x200" + }, + { + "enumerant" : "FlagIndirectVariable", + "value" : "0x400" + }, + { + "enumerant" : "FlagLValueReference", + "value" : "0x800" + }, + { + "enumerant" : "FlagRValueReference", + "value" : "0x1000" + }, + { + "enumerant" : "FlagIsOptimized", + "value" : "0x2000" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugBaseTypeAttributeEncoding", + "enumerants" : [ + { + "enumerant" : "Unspecified", + "value" : "0" + }, + { + "enumerant" : "Address", + "value" : "1" + }, + { + "enumerant" : "Boolean", + "value" : "2" + }, + { + "enumerant" : "Float", + "value" : "4" + }, + { + "enumerant" : "Signed", + "value" : "5" + }, + { + "enumerant" : "SignedChar", + "value" : "6" + }, + { + "enumerant" : "Unsigned", + "value" : "7" + }, + { + "enumerant" : "UnsignedChar", + "value" : "8" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugCompositeType", + "enumerants" : [ + { + "enumerant" : "Class", + "value" : "0" + }, + { + "enumerant" : "Structure", + "value" : "1" + }, + { + "enumerant" : "Union", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugTypeQualifier", + "enumerants" : [ + { + "enumerant" : "ConstType", + "value" : "0" + }, + { + "enumerant" : "VolatileType", + "value" : "1" + }, + { + "enumerant" : "RestrictType", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugOperation", + "enumerants" : [ + { + "enumerant" : "Deref", + "value" : "0" + }, + { + "enumerant" : "Plus", + "value" : "1" + }, + { + "enumerant" : "Minus", + "value" : "2" + }, + { + "enumerant" : "PlusUconst", + "value" : "3", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "BitPiece", + "value" : "4", + "parameters" : [ + { "kind" : "LiteralInteger" }, + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Swap", + "value" : "5" + }, + { + "enumerant" : "Xderef", + "value" : "6" + }, + { + "enumerant" : "StackValue", + "value" : "7" + }, + { + "enumerant" : "Constu", + "value" : "8", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.glsl.std.450.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.glsl.std.450.grammar.json new file mode 100644 index 000000000000..ac8fc6dda6ed --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.glsl.std.450.grammar.json @@ -0,0 +1,642 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "Round", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "RoundEven", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Trunc", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FAbs", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SAbs", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FSign", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SSign", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Floor", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ceil", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fract", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Radians", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "Degrees", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "Sin", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tan", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asin", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acos", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'y_over_x'" } + ] + }, + { + "opname" : "Sinh", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cosh", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tanh", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asinh", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acosh", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atanh", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan2", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Pow", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Exp", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Exp2", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log2", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Sqrt", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "InverseSqrt", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Determinant", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "MatrixInverse", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Modf", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "ModfStruct", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FMin", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMin", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMin", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FMax", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMax", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMax", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FClamp", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "UClamp", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "SClamp", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "FMix", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "IMix", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "Step", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SmoothStep", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fma", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "Frexp", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "FrexpStruct", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ldexp", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "PackSnorm4x8", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm4x8", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackSnorm2x16", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm2x16", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackHalf2x16", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackDouble2x32", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "UnpackSnorm2x16", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm2x16", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackHalf2x16", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "UnpackSnorm4x8", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm4x8", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackDouble2x32", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "Length", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Distance", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "Cross", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Normalize", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FaceForward", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'Nref'" } + ] + }, + { + "opname" : "Reflect", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" } + ] + }, + { + "opname" : "Refract", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'eta'" } + ] + }, + { + "opname" : "FindILsb", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindSMsb", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindUMsb", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "InterpolateAtCentroid", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtSample", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'sample'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtOffset", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "NMin", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NMax", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NClamp", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json new file mode 100644 index 000000000000..cfccc80b6d57 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json @@ -0,0 +1,426 @@ +{ + "revision" : 6, + "instructions" : [ + { + "opname" : "Kernel", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Name" }, + { "kind" : "IdRef", "name" : "NumArguments", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Flags", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Attributes", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentInfo", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "Name" }, + { "kind" : "IdRef", "name" : "Type Name", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Address Qualifier", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Access Qualifier", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Type Qualifier", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentStorageBuffer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentUniform", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentPodStorageBuffer", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentPodUniform", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentPodPushConstant", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentSampledImage", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentStorageImage", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentSampler", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentWorkgroup", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "SpecId" }, + { "kind" : "IdRef", "name" : "ElemSize" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "SpecConstantWorkgroupSize", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "X" }, + { "kind" : "IdRef", "name" : "Y" }, + { "kind" : "IdRef", "name" : "Z" } + ] + }, + { + "opname" : "SpecConstantGlobalOffset", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "X" }, + { "kind" : "IdRef", "name" : "Y" }, + { "kind" : "IdRef", "name" : "Z" } + ] + }, + { + "opname" : "SpecConstantWorkDim", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "Dim" } + ] + }, + { + "opname" : "PushConstantGlobalOffset", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantEnqueuedLocalSize", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantGlobalSize", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantRegionOffset", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantNumWorkgroups", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantRegionGroupOffset", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ConstantDataStorageBuffer", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "ConstantDataUniform", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "LiteralSampler", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Mask" } + ] + }, + { + "opname" : "PropertyRequiredWorkgroupSize", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "X" }, + { "kind" : "IdRef", "name" : "Y" }, + { "kind" : "IdRef", "name" : "Z" } + ] + }, + { + "opname" : "SpecConstantSubgroupMaxSize", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ArgumentPointerPushConstant", + "opcode" : 26, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentPointerUniform", + "opcode" : 27, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ProgramScopeVariablesStorageBuffer", + "opcode" : 28, + "operands": [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "ProgramScopeVariablePointerRelocation", + "opcode" : 29, + "operands": [ + { "kind" : "IdRef", "name" : "ObjectOffset" }, + { "kind" : "IdRef", "name" : "PointerOffset" }, + { "kind" : "IdRef", "name" : "PointerSize" } + ] + }, + { + "opname" : "ImageArgumentInfoChannelOrderPushConstant", + "opcode" : 30, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ImageArgumentInfoChannelDataTypePushConstant", + "opcode" : 31, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ImageArgumentInfoChannelOrderUniform", + "opcode" : 32, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ImageArgumentInfoChannelDataTypeUniform", + "opcode" : 33, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ArgumentStorageTexelBuffer", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentUniformTexelBuffer", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ConstantDataPointerPushConstant", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset"}, + { "kind" : "IdRef", "name" : "Size"}, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "ProgramScopeVariablePointerPushConstant", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset"}, + { "kind" : "IdRef", "name" : "Size"}, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "PrintfInfo", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "PrintfID" }, + { "kind" : "IdRef", "name" : "FormatString" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "ArgumentSizes"} + ] + }, + { + "opname" : "PrintfBufferStorageBuffer", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "BufferSize"} + ] + }, + { + "opname" : "PrintfBufferPointerPushConstant", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size"}, + { "kind" : "IdRef", "name" : "BufferSize"} + ] + }, + { + "opname" : "NormalizedSamplerMaskPushConstant", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "KernelPropertyFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0" + }, + { + "enumerant" : "MayUsePrintf", + "value" : "0x1" + } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json new file mode 100644 index 000000000000..ae288833811d --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json @@ -0,0 +1,9 @@ +{ + "revision" : 1, + "instructions" : [ + { + "opname" : "DebugBreak", + "opcode" : 1 + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json new file mode 100644 index 000000000000..71fa7112cfed --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json @@ -0,0 +1,13 @@ +{ + "revision" : 1, + "instructions" : [ + { + "opname" : "DebugPrintf", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'Format'" }, + { "kind" : "IdRef", "quantifier" : "*" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json new file mode 100644 index 000000000000..1eb2859a1093 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json @@ -0,0 +1,713 @@ +{ + "copyright" : [ + "Copyright (c) 2018-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 6, + "instructions" : [ + { + "opname" : "DebugInfoNone", + "opcode" : 0 + }, + { + "opname" : "DebugCompilationUnit", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'Version'" }, + { "kind" : "IdRef", "name" : "'DWARF Version'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Language'" } + ] + }, + { + "opname" : "DebugTypeBasic", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Encoding'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePointer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Storage Class'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypeQualifier", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Type Qualifier'" } + ] + }, + { + "opname" : "DebugTypeArray", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeVector", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Count'" } + ] + }, + { + "opname" : "DebugTypedef", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeFunction", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "name" : "'Parameter Types'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeEnum", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Underlying Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeComposite", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeMember", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugTypeInheritance", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePtrToMember", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'Member Type'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeTemplate", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeTemplateParameter", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Actual Type'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateTemplateParameter", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Template Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateParameterPack", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugGlobalVariable", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDeclaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugFunction", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Scope Line'" }, + { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlock", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlockDiscriminator", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Discriminator'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugScope", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugNoScope", + "opcode" : 24 + }, + { + "opname" : "DebugInlinedAt", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLocalVariable", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Arg Number'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugInlinedVariable", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Inlined'" } + ] + }, + { + "opname" : "DebugDeclare", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugValue", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugOperation", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'OpCode'" }, + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugExpression", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugMacroDef", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugMacroUndef", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Macro'" } + ] + }, + { + "opname" : "DebugImportedEntity", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Entity'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugSource", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "IdRef", "name" : "'Text'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDefinition", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "name" : "'Definition'" } + ] + }, + { + "opname" : "DebugSourceContinued", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'Text'" } + ] + }, + { + "opname" : "DebugLine", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line Start'" }, + { "kind" : "IdRef", "name" : "'Line End'" }, + { "kind" : "IdRef", "name" : "'Column Start'" }, + { "kind" : "IdRef", "name" : "'Column End'" } + ] + }, + { + "opname" : "DebugNoLine", + "opcode" : 104 + }, + { + "opname" : "DebugBuildIdentifier", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'Identifier'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugStoragePath", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'Path'" } + ] + }, + { + "opname" : "DebugEntryPoint", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "IdRef", "name" : "'Compilation Unit'" }, + { "kind" : "IdRef", "name" : "'Compiler Signature'" }, + { "kind" : "IdRef", "name" : "'Command-line Arguments'" } + ] + }, + { + "opname" : "DebugTypeMatrix", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'Vector Type'" }, + { "kind" : "IdRef", "name" : "'Vector Count'" }, + { "kind" : "IdRef", "name" : "'Column Major'" } + ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "DebugInfoFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "FlagIsProtected", + "value" : "0x01" + }, + { + "enumerant" : "FlagIsPrivate", + "value" : "0x02" + }, + { + "enumerant" : "FlagIsPublic", + "value" : "0x03" + }, + { + "enumerant" : "FlagIsLocal", + "value" : "0x04" + }, + { + "enumerant" : "FlagIsDefinition", + "value" : "0x08" + }, + { + "enumerant" : "FlagFwdDecl", + "value" : "0x10" + }, + { + "enumerant" : "FlagArtificial", + "value" : "0x20" + }, + { + "enumerant" : "FlagExplicit", + "value" : "0x40" + }, + { + "enumerant" : "FlagPrototyped", + "value" : "0x80" + }, + { + "enumerant" : "FlagObjectPointer", + "value" : "0x100" + }, + { + "enumerant" : "FlagStaticMember", + "value" : "0x200" + }, + { + "enumerant" : "FlagIndirectVariable", + "value" : "0x400" + }, + { + "enumerant" : "FlagLValueReference", + "value" : "0x800" + }, + { + "enumerant" : "FlagRValueReference", + "value" : "0x1000" + }, + { + "enumerant" : "FlagIsOptimized", + "value" : "0x2000" + }, + { + "enumerant" : "FlagIsEnumClass", + "value" : "0x4000" + }, + { + "enumerant" : "FlagTypePassByValue", + "value" : "0x8000" + }, + { + "enumerant" : "FlagTypePassByReference", + "value" : "0x10000" + }, + { + "enumerant" : "FlagUnknownPhysicalLayout", + "value" : "0x20000" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "BuildIdentifierFlags", + "enumerants" : [ + { + "enumerant" : "IdentifierPossibleDuplicates", + "value" : "0x01" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugBaseTypeAttributeEncoding", + "enumerants" : [ + { + "enumerant" : "Unspecified", + "value" : "0" + }, + { + "enumerant" : "Address", + "value" : "1" + }, + { + "enumerant" : "Boolean", + "value" : "2" + }, + { + "enumerant" : "Float", + "value" : "3" + }, + { + "enumerant" : "Signed", + "value" : "4" + }, + { + "enumerant" : "SignedChar", + "value" : "5" + }, + { + "enumerant" : "Unsigned", + "value" : "6" + }, + { + "enumerant" : "UnsignedChar", + "value" : "7" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugCompositeType", + "enumerants" : [ + { + "enumerant" : "Class", + "value" : "0" + }, + { + "enumerant" : "Structure", + "value" : "1" + }, + { + "enumerant" : "Union", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugTypeQualifier", + "enumerants" : [ + { + "enumerant" : "ConstType", + "value" : "0" + }, + { + "enumerant" : "VolatileType", + "value" : "1" + }, + { + "enumerant" : "RestrictType", + "value" : "2" + }, + { + "enumerant" : "AtomicType", + "value" : "3" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugOperation", + "enumerants" : [ + { + "enumerant" : "Deref", + "value" : "0" + }, + { + "enumerant" : "Plus", + "value" : "1" + }, + { + "enumerant" : "Minus", + "value" : "2" + }, + { + "enumerant" : "PlusUconst", + "value" : "3", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "BitPiece", + "value" : "4", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Swap", + "value" : "5" + }, + { + "enumerant" : "Xderef", + "value" : "6" + }, + { + "enumerant" : "StackValue", + "value" : "7" + }, + { + "enumerant" : "Constu", + "value" : "8", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Fragment", + "value" : "9", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugImportedEntity", + "enumerants" : [ + { + "enumerant" : "ImportedModule", + "value" : "0" + }, + { + "enumerant" : "ImportedDeclaration", + "value" : "1" + } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json new file mode 100644 index 000000000000..bee1bea3f9b8 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json @@ -0,0 +1,135 @@ +{ + "revision" : 1, + "instructions" : [ + { + "opname" : "Configuration", + "opcode" : 1, + "operands" : [ + {"kind" : "LiteralString", "name" : "enabledExtensionNames" }, + {"kind" : "LiteralInteger", "name" : "specializationInfoDataSize" }, + {"kind" : "LiteralString", "name" : "specializationInfoData" }, + {"kind" : "LiteralString", "name" : "shaderName" }, + {"kind" : "LiteralString", "name" : "EntryPoint" }, + {"kind" : "LiteralInteger", "name" : "groupCountX" }, + {"kind" : "LiteralInteger", "name" : "groupCountY" }, + {"kind" : "LiteralInteger", "name" : "groupCountZ" } + ] + }, + { + "opname" : "StartCounter", + "opcode" : 2, + "operands" : [ + {"kind" : "LiteralString", "name" : "name" } + ] + }, + { + "opname" : "StopCounter", + "opcode" : 3, + "operands" : [ + {"kind" : "IdRef", "name" : "counter" } + ] + }, + { + "opname" : "PushConstants", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "offset" }, + { "kind" : "LiteralInteger", "name" : "size" }, + { "kind" : "LiteralString", "name" : "pValues" }, + { "kind" : "LiteralInteger", "name" : "stageFlags" } + ] + }, + { + "opname" : "SpecializationMapEntry", + "opcode" : 5, + "operands" : [ + {"kind" : "LiteralInteger", "name" : "constantID" }, + {"kind" : "LiteralInteger", "name" : "offset" }, + {"kind" : "LiteralInteger", "name" : "size" } + ] + }, + { + "opname" : "DescriptorSetBuffer", + "opcode" : 6, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "ds" }, + { "kind" : "LiteralInteger", "name" : "binding" }, + { "kind" : "LiteralInteger", "name" : "type" }, + { "kind" : "LiteralInteger", "name" : "flags" }, + { "kind" : "LiteralInteger", "name" : "queueFamilyIndexCount" }, + { "kind" : "LiteralInteger", "name" : "sharingMode" }, + { "kind" : "LiteralInteger", "name" : "size" }, + { "kind" : "LiteralInteger", "name" : "usage" }, + { "kind" : "LiteralInteger", "name" : "range" }, + { "kind" : "LiteralInteger", "name" : "offset" }, + { "kind" : "LiteralInteger", "name" : "memorySize" }, + { "kind" : "LiteralInteger", "name" : "memoryType" }, + { "kind" : "LiteralInteger", "name" : "bindOffset" } + ] + }, + { + "opname" : "DescriptorSetImage", + "opcode" : 7, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "ds" }, + { "kind" : "LiteralInteger", "name" : "binding" }, + { "kind" : "LiteralInteger", "name" : "type" }, + { "kind" : "LiteralInteger", "name" : "imageLayout"}, + { "kind" : "LiteralInteger", "name" : "imageFlags"}, + { "kind" : "LiteralInteger", "name" : "imageType"}, + { "kind" : "LiteralInteger", "name" : "imageformat"}, + { "kind" : "LiteralInteger", "name" : "width"}, + { "kind" : "LiteralInteger", "name" : "height"}, + { "kind" : "LiteralInteger", "name" : "depth"}, + { "kind" : "LiteralInteger", "name" : "mipLevels"}, + { "kind" : "LiteralInteger", "name" : "arrayLayers"}, + { "kind" : "LiteralInteger", "name" : "samples"}, + { "kind" : "LiteralInteger", "name" : "tiling"}, + { "kind" : "LiteralInteger", "name" : "usage"}, + { "kind" : "LiteralInteger", "name" : "sharingMode"}, + { "kind" : "LiteralInteger", "name" : "queueFamilyIndexCount"}, + { "kind" : "LiteralInteger", "name" : "initialLayout"}, + { "kind" : "LiteralInteger", "name" : "aspectMask"}, + { "kind" : "LiteralInteger", "name" : "baseMipLevel"}, + { "kind" : "LiteralInteger", "name" : "levelCount"}, + { "kind" : "LiteralInteger", "name" : "baseArrayLayer"}, + { "kind" : "LiteralInteger", "name" : "layerCount"}, + { "kind" : "LiteralInteger", "name" : "viewFlags"}, + { "kind" : "LiteralInteger", "name" : "viewType"}, + { "kind" : "LiteralInteger", "name" : "viewFormat"}, + { "kind" : "LiteralInteger", "name" : "component_a"}, + { "kind" : "LiteralInteger", "name" : "component_b"}, + { "kind" : "LiteralInteger", "name" : "component_g"}, + { "kind" : "LiteralInteger", "name" : "component_r"}, + { "kind" : "LiteralInteger", "name" : "memorySize" }, + { "kind" : "LiteralInteger", "name" : "memoryType" }, + { "kind" : "LiteralInteger", "name" : "bindOffset"} + ] + }, + { + "opname" : "DescriptorSetSampler", + "opcode" : 8, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "ds" }, + { "kind" : "LiteralInteger", "name" : "binding" }, + { "kind" : "LiteralInteger", "name" : "type" }, + { "kind" : "LiteralInteger", "name" : "flags"}, + { "kind" : "LiteralInteger", "name" : "magFilter"}, + { "kind" : "LiteralInteger", "name" : "minFilter"}, + { "kind" : "LiteralInteger", "name" : "mipmapMode"}, + { "kind" : "LiteralInteger", "name" : "addressModeU"}, + { "kind" : "LiteralInteger", "name" : "addressModeV"}, + { "kind" : "LiteralInteger", "name" : "addressModeW"}, + { "kind" : "LiteralFloat", "name" : "mipLodBias"}, + { "kind" : "LiteralInteger", "name" : "anisotropyEnable"}, + { "kind" : "LiteralFloat", "name" : "maxAnisotropy"}, + { "kind" : "LiteralInteger", "name" : "compareEnable"}, + { "kind" : "LiteralInteger", "name" : "compareOp"}, + { "kind" : "LiteralFloat", "name" : "minLod"}, + { "kind" : "LiteralFloat", "name" : "maxLod"}, + { "kind" : "LiteralInteger", "name" : "borderColor"}, + { "kind" : "LiteralInteger", "name" : "unnormalizedCoordinates"} + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json new file mode 100644 index 000000000000..53b001c530d4 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json @@ -0,0 +1,651 @@ +{ + "copyright" : [ + "Copyright (c) 2018-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 200, + "revision" : 2, + "instructions" : [ + { + "opname" : "DebugInfoNone", + "opcode" : 0 + }, + { + "opname" : "DebugCompilationUnit", + "opcode" : 1, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "LiteralInteger", "name" : "'DWARF Version'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "SourceLanguage", "name" : "'Language'" } + ] + }, + { + "opname" : "DebugTypeBasic", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugBaseTypeAttributeEncoding", "name" : "'Encoding'" } + ] + }, + { + "opname" : "DebugTypePointer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "StorageClass", "name" : "'Storage Class'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypeQualifier", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "DebugTypeQualifier", "name" : "'Type Qualifier'" } + ] + }, + { + "opname" : "DebugTypeArray", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeVector", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "DebugTypedef", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeFunction", + "opcode" : 8, + "operands" : [ + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "name" : "'Parameter Types'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeEnum", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Underlying Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeComposite", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "DebugCompositeType", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeMember", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugTypeInheritance", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'Child'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePtrToMember", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'Member Type'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeTemplate", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeTemplateParameter", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Actual Type'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateTemplateParameter", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Template Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateParameterPack", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugGlobalVariable", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDeclaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugFunction", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "LiteralInteger", "name" : "'Scope Line'" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlock", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlockDiscriminator", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Discriminator'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugScope", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugNoScope", + "opcode" : 24 + }, + { + "opname" : "DebugInlinedAt", + "opcode" : 25, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLocalVariable", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "LiteralInteger", "name" : "'Arg Number'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugInlinedVariable", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Inlined'" } + ] + }, + { + "opname" : "DebugDeclare", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Expression'" } + ] + }, + { + "opname" : "DebugValue", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugOperation", + "opcode" : 30, + "operands" : [ + { "kind" : "DebugOperation", "name" : "'OpCode'" }, + { "kind" : "LiteralInteger", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugExpression", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugMacroDef", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugMacroUndef", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Macro'" } + ] + }, + { + "opname" : "DebugImportedEntity", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "DebugImportedEntity", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Entity'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugSource", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "IdRef", "name" : "'Text'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugModuleINTEL", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'ConfigurationMacros'" }, + { "kind" : "IdRef", "name" : "'IncludePath'" }, + { "kind" : "IdRef", "name" : "'APINotesFile'" }, + { "kind" : "LiteralInteger", "name" : "'IsDeclaration'" } + ], + "capability" : "DebugInfoModuleINTEL" + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "DebugInfoFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "FlagIsProtected", + "value" : "0x01" + }, + { + "enumerant" : "FlagIsPrivate", + "value" : "0x02" + }, + { + "enumerant" : "FlagIsPublic", + "value" : "0x03" + }, + { + "enumerant" : "FlagIsLocal", + "value" : "0x04" + }, + { + "enumerant" : "FlagIsDefinition", + "value" : "0x08" + }, + { + "enumerant" : "FlagFwdDecl", + "value" : "0x10" + }, + { + "enumerant" : "FlagArtificial", + "value" : "0x20" + }, + { + "enumerant" : "FlagExplicit", + "value" : "0x40" + }, + { + "enumerant" : "FlagPrototyped", + "value" : "0x80" + }, + { + "enumerant" : "FlagObjectPointer", + "value" : "0x100" + }, + { + "enumerant" : "FlagStaticMember", + "value" : "0x200" + }, + { + "enumerant" : "FlagIndirectVariable", + "value" : "0x400" + }, + { + "enumerant" : "FlagLValueReference", + "value" : "0x800" + }, + { + "enumerant" : "FlagRValueReference", + "value" : "0x1000" + }, + { + "enumerant" : "FlagIsOptimized", + "value" : "0x2000" + }, + { + "enumerant" : "FlagIsEnumClass", + "value" : "0x4000" + }, + { + "enumerant" : "FlagTypePassByValue", + "value" : "0x8000" + }, + { + "enumerant" : "FlagTypePassByReference", + "value" : "0x10000" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugBaseTypeAttributeEncoding", + "enumerants" : [ + { + "enumerant" : "Unspecified", + "value" : "0" + }, + { + "enumerant" : "Address", + "value" : "1" + }, + { + "enumerant" : "Boolean", + "value" : "2" + }, + { + "enumerant" : "Float", + "value" : "3" + }, + { + "enumerant" : "Signed", + "value" : "4" + }, + { + "enumerant" : "SignedChar", + "value" : "5" + }, + { + "enumerant" : "Unsigned", + "value" : "6" + }, + { + "enumerant" : "UnsignedChar", + "value" : "7" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugCompositeType", + "enumerants" : [ + { + "enumerant" : "Class", + "value" : "0" + }, + { + "enumerant" : "Structure", + "value" : "1" + }, + { + "enumerant" : "Union", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugTypeQualifier", + "enumerants" : [ + { + "enumerant" : "ConstType", + "value" : "0" + }, + { + "enumerant" : "VolatileType", + "value" : "1" + }, + { + "enumerant" : "RestrictType", + "value" : "2" + }, + { + "enumerant" : "AtomicType", + "value" : "3" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugOperation", + "enumerants" : [ + { + "enumerant" : "Deref", + "value" : "0" + }, + { + "enumerant" : "Plus", + "value" : "1" + }, + { + "enumerant" : "Minus", + "value" : "2" + }, + { + "enumerant" : "PlusUconst", + "value" : "3", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "BitPiece", + "value" : "4", + "parameters" : [ + { "kind" : "LiteralInteger" }, + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Swap", + "value" : "5" + }, + { + "enumerant" : "Xderef", + "value" : "6" + }, + { + "enumerant" : "StackValue", + "value" : "7" + }, + { + "enumerant" : "Constu", + "value" : "8", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Fragment", + "value" : "9", + "parameters" : [ + { "kind" : "LiteralInteger" }, + { "kind" : "LiteralInteger" } + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugImportedEntity", + "enumerants" : [ + { + "enumerant" : "ImportedModule", + "value" : "0" + }, + { + "enumerant" : "ImportedDeclaration", + "value" : "1" + } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.opencl.std.100.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.opencl.std.100.grammar.json new file mode 100644 index 000000000000..21b7876b0e64 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.opencl.std.100.grammar.json @@ -0,0 +1,1279 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "acos", + "opcode" : 0, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acosh", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acospi", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asin", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinh", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinpi", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanh", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanpi", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2pi", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cbrt", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ceil", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "copysign", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cosh", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cospi", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erfc", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erf", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp2", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp10", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "expm1", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fabs", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fdim", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "floor", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fma", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fmax", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmod", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fract", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'ptr'" } + ] + }, + { + "opname" : "frexp", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "hypot", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "ilogb", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ldexp", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'k'" } + ] + }, + { + "opname" : "lgamma", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "lgamma_r", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'signp'" } + ] + }, + { + "opname" : "log", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log2", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log10", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log1p", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "logb", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "mad", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "maxmag", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "minmag", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "modf", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'iptr'" } + ] + }, + { + "opname" : "nan", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'nancode'" } + ] + }, + { + "opname" : "nextafter", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "pow", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y" } + ] + }, + { + "opname" : "pown", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "powr", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remainder", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remquo", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'quo'" } + ] + }, + { + "opname" : "rint", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rootn", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "round", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rsqrt", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sin", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sincos", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'cosval'" } + ] + }, + { + "opname" : "sinh", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sinpi", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sqrt", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tan", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanh", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanpi", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tgamma", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "trunc", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_cos", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_divide", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_exp", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp2", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp10", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log2", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log10", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_powr", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_recip", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_rsqrt", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sin", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sqrt", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_tan", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_cos", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_divide", + "opcode" : 82, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_exp", + "opcode" : 83, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp2", + "opcode" : 84, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp10", + "opcode" : 85, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log", + "opcode" : 86, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log2", + "opcode" : 87, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log10", + "opcode" : 88, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_powr", + "opcode" : 89, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_recip", + "opcode" : 90, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_rsqrt", + "opcode" : 91, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sin", + "opcode" : 92, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sqrt", + "opcode" : 93, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_tan", + "opcode" : 94, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs", + "opcode" : 141, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs_diff", + "opcode" : 142, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_add_sat", + "opcode" : 143, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_add_sat", + "opcode" : 144, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_hadd", + "opcode" : 145, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_hadd", + "opcode" : 146, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_rhadd", + "opcode" : 147, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_rhadd", + "opcode" : 148, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_clamp", + "opcode" : 149, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "u_clamp", + "opcode" : 150, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "clz", + "opcode" : 151, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ctz", + "opcode" : 152, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad_hi", + "opcode" : 153, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "u_mad_sat", + "opcode" : 154, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mad_sat", + "opcode" : 155, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_max", + "opcode" : 156, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_max", + "opcode" : 157, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_min", + "opcode" : 158, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_min", + "opcode" : 159, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_mul_hi", + "opcode" : 160, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "rotate", + "opcode" : 161, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "s_sub_sat", + "opcode" : 162, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_sub_sat", + "opcode" : 163, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_upsample", + "opcode" : 164, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "s_upsample", + "opcode" : 165, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "popcount", + "opcode" : 166, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad24", + "opcode" : 167, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "u_mad24", + "opcode" : 168, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mul24", + "opcode" : 169, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul24", + "opcode" : 170, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_abs", + "opcode" : 201, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "u_abs_diff", + "opcode" : 202, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul_hi", + "opcode" : 203, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mad_hi", + "opcode" : 204, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fclamp", + "opcode" : 95, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "degrees", + "opcode" :96, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "fmax_common", + "opcode" : 97, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin_common", + "opcode" : 98, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "mix", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "radians", + "opcode" : 100, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "step", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "smoothstep", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sign", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cross", + "opcode" : 104, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "distance", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "length", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "normalize", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_distance", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "fast_length", + "opcode" : 109, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_normalize", + "opcode" : 110, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "bitselect", + "opcode" : 186, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "select", + "opcode" : 187, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "vloadn", + "opcode" : 171, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstoren", + "opcode" : 172, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_half", + "opcode" : 173, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_halfn", + "opcode" : 174, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstore_half", + "opcode" : 175, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_half_r", + "opcode" : 176, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vstore_halfn", + "opcode" : 177, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_halfn_r", + "opcode" : 178, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vloada_halfn", + "opcode" : 179, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstorea_halfn", + "opcode" : 180, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstorea_halfn_r", + "opcode" : 181, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "shuffle", + "opcode" : 182, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "shuffle2", + "opcode" : 183, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "printf", + "opcode" : 184, + "operands" : [ + { "kind" : "IdRef", "name" : "'format'" }, + { "kind" : "IdRef", "name" : "'additional arguments'", "quantifier" : "*" } + ] + }, + { + "opname" : "prefetch", + "opcode" : 185, + "operands" : [ + { "kind" : "IdRef", "name" : "'ptr'" }, + { "kind" : "IdRef", "name" : "'num elements'" } + ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json new file mode 100644 index 000000000000..e18251bba1b2 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json @@ -0,0 +1,26 @@ +{ + "revision" : 2, + "instructions" : [ + { + "opname" : "CubeFaceIndexAMD", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'P'" } + ], + "extensions" : [ "SPV_AMD_gcn_shader" ] + }, + { + "opname" : "CubeFaceCoordAMD", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'P'" } + ], + "extensions" : [ "SPV_AMD_gcn_shader" ] + }, + { + "opname" : "TimeAMD", + "opcode" : 3, + "extensions" : [ "SPV_AMD_gcn_shader" ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json new file mode 100644 index 000000000000..62a470eeb658 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json @@ -0,0 +1,41 @@ +{ + "revision" : 5, + "instructions" : [ + { + "opname" : "SwizzleInvocationsAMD", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "extensions" : [ "SPV_AMD_shader_ballot" ] + }, + { + "opname" : "SwizzleInvocationsMaskedAMD", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'mask'" } + ], + "extensions" : [ "SPV_AMD_shader_ballot" ] + }, + { + "opname" : "WriteInvocationAMD", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'inputValue'" }, + { "kind" : "IdRef", "name" : "'writeValue'" }, + { "kind" : "IdRef", "name" : "'invocationIndex'" } + ], + "extensions" : [ "SPV_AMD_shader_ballot" ] + }, + { + "opname" : "MbcntAMD", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'mask'" } + ], + "extensions" : [ "SPV_AMD_shader_ballot" ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json new file mode 100644 index 000000000000..e156b1b6f817 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json @@ -0,0 +1,14 @@ +{ + "revision" : 4, + "instructions" : [ + { + "opname" : "InterpolateAtVertexAMD", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'vertexIdx'" } + ], + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json new file mode 100644 index 000000000000..c681976fe924 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json @@ -0,0 +1,95 @@ +{ + "revision" : 4, + "instructions" : [ + { + "opname" : "FMin3AMD", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "UMin3AMD", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "SMin3AMD", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "FMax3AMD", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "UMax3AMD", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "SMax3AMD", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "FMid3AMD", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "UMid3AMD", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "SMid3AMD", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.bf b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.bf new file mode 100644 index 000000000000..c1fa60bba6fa --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.bf @@ -0,0 +1,2149 @@ +// Copyright (c) 2014-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + using System; + + public static class Specification + { + public const uint32 MagicNumber = 0x07230203; + public const uint32 Version = 0x00010600; + public const uint32 Revision = 1; + public const uint32 OpCodeMask = 0xffff; + public const uint32 WordCountShift = 16; + + [AllowDuplicates, CRepr] public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + } + + [AllowDuplicates, CRepr] public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + } + + [AllowDuplicates, CRepr] public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + } + + [AllowDuplicates, CRepr] public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + } + + [AllowDuplicates, CRepr] public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + } + + [AllowDuplicates, CRepr] public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + NodeOutputPayloadAMDX = 5076, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + } + + [AllowDuplicates, CRepr] public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + } + + [AllowDuplicates, CRepr] public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + [AllowDuplicates, CRepr] public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + [AllowDuplicates, CRepr] public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + } + + [AllowDuplicates, CRepr] public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + [AllowDuplicates, CRepr] public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + } + + [AllowDuplicates, CRepr] public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + } + + [AllowDuplicates, CRepr] public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, + } + + [AllowDuplicates, CRepr] public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + } + + [AllowDuplicates, CRepr] public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, + } + + [AllowDuplicates, CRepr] public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + [AllowDuplicates, CRepr] public enum LinkageType + { + Export = 0, + Import = 1, + LinkOnceODR = 2, + } + + [AllowDuplicates, CRepr] public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + [AllowDuplicates, CRepr] public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + } + + [AllowDuplicates, CRepr] public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + } + + [AllowDuplicates, CRepr] public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + CoalescedInputCountAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + } + + [AllowDuplicates, CRepr] public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + [AllowDuplicates, CRepr] public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + [AllowDuplicates, CRepr] public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + } + + [AllowDuplicates, CRepr] public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, + } + + [AllowDuplicates, CRepr] public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, + } + + [AllowDuplicates, CRepr] public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, + } + + [AllowDuplicates, CRepr] public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + } + + [AllowDuplicates, CRepr] public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, + } + + [AllowDuplicates, CRepr] public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + } + + [AllowDuplicates, CRepr] public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, + } + + [AllowDuplicates, CRepr] public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + } + + [AllowDuplicates, CRepr] public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + } + + [AllowDuplicates, CRepr] public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + [AllowDuplicates, CRepr] public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + [AllowDuplicates, CRepr] public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + [AllowDuplicates, CRepr] public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + } + + [AllowDuplicates, CRepr] public enum RayFlagsShift + { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + } + + [AllowDuplicates, CRepr] public enum RayFlagsMask + { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, + } + + [AllowDuplicates, CRepr] public enum RayQueryIntersection + { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + } + + [AllowDuplicates, CRepr] public enum RayQueryCommittedIntersectionType + { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + } + + [AllowDuplicates, CRepr] public enum RayQueryCandidateIntersectionType + { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + } + + [AllowDuplicates, CRepr] public enum FragmentShadingRateShift + { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + } + + [AllowDuplicates, CRepr] public enum FragmentShadingRateMask + { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, + } + + [AllowDuplicates, CRepr] public enum FPDenormMode + { + Preserve = 0, + FlushToZero = 1, + } + + [AllowDuplicates, CRepr] public enum FPOperationMode + { + IEEE = 0, + ALT = 1, + } + + [AllowDuplicates, CRepr] public enum QuantizationModes + { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + } + + [AllowDuplicates, CRepr] public enum OverflowModes + { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + } + + [AllowDuplicates, CRepr] public enum PackedVectorFormat + { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + } + + [AllowDuplicates, CRepr] public enum CooperativeMatrixOperandsShift + { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + } + + [AllowDuplicates, CRepr] public enum CooperativeMatrixOperandsMask + { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, + } + + [AllowDuplicates, CRepr] public enum CooperativeMatrixLayout + { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + } + + [AllowDuplicates, CRepr] public enum CooperativeMatrixUse + { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + } + + [AllowDuplicates, CRepr] public enum InitializationModeQualifier + { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + } + + [AllowDuplicates, CRepr] public enum HostAccessQualifier + { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + } + + [AllowDuplicates, CRepr] public enum LoadCacheControl + { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + } + + [AllowDuplicates, CRepr] public enum StoreCacheControl + { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + } + + [AllowDuplicates, CRepr] public enum NamedMaximumNumberOfRegisters + { + AutoINTEL = 0, + } + + [AllowDuplicates, CRepr] public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + } + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.core.grammar.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.core.grammar.json new file mode 100644 index 000000000000..ba449335262a --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.core.grammar.json @@ -0,0 +1,16853 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "magic_number" : "0x07230203", + "major_version" : 1, + "minor_version" : 6, + "revision" : 1, + "instruction_printing_class" : [ + { + "tag" : "@exclude" + }, + { + "tag" : "Miscellaneous", + "heading" : "Miscellaneous Instructions" + }, + { + "tag" : "Debug", + "heading" : "Debug Instructions" + }, + { + "tag" : "Annotation", + "heading" : "Annotation Instructions" + }, + { + "tag" : "Extension", + "heading" : "Extension Instructions" + }, + { + "tag" : "Mode-Setting", + "heading" : "Mode-Setting Instructions" + }, + { + "tag" : "Type-Declaration", + "heading" : "Type-Declaration Instructions" + }, + { + "tag" : "Constant-Creation", + "heading" : "Constant-Creation Instructions" + }, + { + "tag" : "Memory", + "heading" : "Memory Instructions" + }, + { + "tag" : "Function", + "heading" : "Function Instructions" + }, + { + "tag" : "Image", + "heading" : "Image Instructions" + }, + { + "tag" : "Conversion", + "heading" : "Conversion Instructions" + }, + { + "tag" : "Composite", + "heading" : "Composite Instructions" + }, + { + "tag" : "Arithmetic", + "heading" : "Arithmetic Instructions" + }, + { + "tag" : "Bit", + "heading" : "Bit Instructions" + }, + { + "tag" : "Relational_and_Logical", + "heading" : "Relational and Logical Instructions" + }, + { + "tag" : "Derivative", + "heading" : "Derivative Instructions" + }, + { + "tag" : "Control-Flow", + "heading" : "Control-Flow Instructions" + }, + { + "tag" : "Atomic", + "heading" : "Atomic Instructions" + }, + { + "tag" : "Primitive", + "heading" : "Primitive Instructions" + }, + { + "tag" : "Barrier", + "heading" : "Barrier Instructions" + }, + { + "tag" : "Group", + "heading" : "Group and Subgroup Instructions" + }, + { + "tag" : "Device-Side_Enqueue", + "heading" : "Device-Side Enqueue Instructions" + }, + { + "tag" : "Pipe", + "heading" : "Pipe Instructions" + }, + { + "tag" : "Non-Uniform", + "heading" : "Non-Uniform Instructions" + }, + { + "tag" : "Reserved", + "heading" : "Reserved Instructions" + } + ], + "instructions" : [ + { + "opname" : "OpNop", + "class" : "Miscellaneous", + "opcode" : 0, + "version" : "1.0" + }, + { + "opname" : "OpUndef", + "class" : "Miscellaneous", + "opcode" : 1, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version" : "1.0" + }, + { + "opname" : "OpSourceContinued", + "class" : "Debug", + "opcode" : 2, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Continued Source'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSource", + "class" : "Debug", + "opcode" : 3, + "operands" : [ + { "kind" : "SourceLanguage" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" }, + { "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSourceExtension", + "class" : "Debug", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Extension'" } + ], + "version": "1.0" + }, + { + "opname" : "OpName", + "class" : "Debug", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "version": "1.0" + }, + { + "opname" : "OpMemberName", + "class" : "Debug", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "version": "1.0" + }, + { + "opname" : "OpString", + "class" : "Debug", + "opcode" : 7, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'String'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLine", + "class" : "Debug", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ], + "version": "1.0" + }, + { + "opname" : "OpExtension", + "class" : "Extension", + "opcode" : 10, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "version": "1.0" + }, + { + "opname" : "OpExtInstImport", + "class" : "Extension", + "opcode" : 11, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "version": "1.0" + }, + { + "opname" : "OpExtInst", + "class" : "Extension", + "opcode" : 12, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ], + "version": "1.0" + }, + { + "opname" : "OpMemoryModel", + "class" : "Mode-Setting", + "opcode" : 14, + "operands" : [ + { "kind" : "AddressingModel" }, + { "kind" : "MemoryModel" } + ], + "version": "1.0" + }, + { + "opname" : "OpEntryPoint", + "class" : "Mode-Setting", + "opcode" : 15, + "operands" : [ + { "kind" : "ExecutionModel" }, + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } + ], + "version": "1.0" + }, + { + "opname" : "OpExecutionMode", + "class" : "Mode-Setting", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCapability", + "class" : "Mode-Setting", + "opcode" : 17, + "operands" : [ + { "kind" : "Capability", "name" : "'Capability'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeVoid", + "class" : "Type-Declaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeBool", + "class" : "Type-Declaration", + "opcode" : 20, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeInt", + "class" : "Type-Declaration", + "opcode" : 21, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" }, + { "kind" : "LiteralInteger", "name" : "'Signedness'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeFloat", + "class" : "Type-Declaration", + "opcode" : 22, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeVector", + "class" : "Type-Declaration", + "opcode" : 23, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeMatrix", + "class" : "Type-Declaration", + "opcode" : 24, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Column Type'" }, + { "kind" : "LiteralInteger", "name" : "'Column Count'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpTypeImage", + "class" : "Type-Declaration", + "opcode" : 25, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Type'" }, + { "kind" : "Dim" }, + { "kind" : "LiteralInteger", "name" : "'Depth'" }, + { "kind" : "LiteralInteger", "name" : "'Arrayed'" }, + { "kind" : "LiteralInteger", "name" : "'MS'" }, + { "kind" : "LiteralInteger", "name" : "'Sampled'" }, + { "kind" : "ImageFormat" }, + { "kind" : "AccessQualifier", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeSampler", + "class" : "Type-Declaration", + "opcode" : 26, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeSampledImage", + "class" : "Type-Declaration", + "opcode" : 27, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeArray", + "class" : "Type-Declaration", + "opcode" : 28, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" }, + { "kind" : "IdRef", "name" : "'Length'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeRuntimeArray", + "class" : "Type-Declaration", + "opcode" : 29, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpTypeStruct", + "class" : "Type-Declaration", + "opcode" : 30, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeOpaque", + "class" : "Type-Declaration", + "opcode" : 31, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "The name of the opaque type." } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpTypePointer", + "class" : "Type-Declaration", + "opcode" : 32, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "name" : "'Type'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeFunction", + "class" : "Type-Declaration", + "opcode" : 33, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeEvent", + "class" : "Type-Declaration", + "opcode" : 34, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpTypeDeviceEvent", + "class" : "Type-Declaration", + "opcode" : 35, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpTypeReserveId", + "class" : "Type-Declaration", + "opcode" : 36, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpTypeQueue", + "class" : "Type-Declaration", + "opcode" : 37, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpTypePipe", + "class" : "Type-Declaration", + "opcode" : 38, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "AccessQualifier", "name" : "'Qualifier'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpTypeForwardPointer", + "class" : "Type-Declaration", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer Type'" }, + { "kind" : "StorageClass" } + ], + "capabilities" : [ + "Addresses", + "PhysicalStorageBufferAddresses" + ], + "version": "1.0" + }, + { + "opname" : "OpConstantTrue", + "class" : "Constant-Creation", + "opcode" : 41, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpConstantFalse", + "class" : "Constant-Creation", + "opcode" : 42, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpConstant", + "class" : "Constant-Creation", + "opcode" : 43, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConstantComposite", + "class" : "Constant-Creation", + "opcode" : 44, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConstantSampler", + "class" : "Constant-Creation", + "opcode" : 45, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "SamplerAddressingMode" }, + { "kind" : "LiteralInteger", "name" : "'Param'" }, + { "kind" : "SamplerFilterMode" } + ], + "capabilities" : [ "LiteralSampler" ], + "version": "1.0" + }, + { + "opname" : "OpConstantNull", + "class" : "Constant-Creation", + "opcode" : 46, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstantTrue", + "class" : "Constant-Creation", + "opcode" : 48, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstantFalse", + "class" : "Constant-Creation", + "opcode" : 49, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstant", + "class" : "Constant-Creation", + "opcode" : 50, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstantComposite", + "class" : "Constant-Creation", + "opcode" : 51, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstantOp", + "class" : "Constant-Creation", + "opcode" : 52, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFunction", + "class" : "Function", + "opcode" : 54, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "FunctionControl" }, + { "kind" : "IdRef", "name" : "'Function Type'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFunctionParameter", + "class" : "Function", + "opcode" : 55, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpFunctionEnd", + "class" : "Function", + "opcode" : 56, + "version" : "1.0" + }, + { + "opname" : "OpFunctionCall", + "class" : "Function", + "opcode" : 57, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." } + ], + "version": "1.0" + }, + { + "opname" : "OpVariable", + "class" : "Memory", + "opcode" : 59, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageTexelPointer", + "class" : "Memory", + "opcode" : 60, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Sample'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLoad", + "class" : "Memory", + "opcode" : 61, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpStore", + "class" : "Memory", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpCopyMemory", + "class" : "Memory", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpCopyMemorySized", + "class" : "Memory", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "opname" : "OpAccessChain", + "class" : "Memory", + "opcode" : 65, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "version": "1.0" + }, + { + "opname" : "OpInBoundsAccessChain", + "class" : "Memory", + "opcode" : 66, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "version": "1.0" + }, + { + "opname" : "OpPtrAccessChain", + "class" : "Memory", + "opcode" : 67, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ + "Addresses", + "VariablePointers", + "VariablePointersStorageBuffer", + "PhysicalStorageBufferAddresses" + ], + "version": "1.0" + }, + { + "opname" : "OpArrayLength", + "class" : "Memory", + "opcode" : 68, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Structure'" }, + { "kind" : "LiteralInteger", "name" : "'Array member'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpGenericPtrMemSemantics", + "class" : "Memory", + "opcode" : 69, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpInBoundsPtrAccessChain", + "class" : "Memory", + "opcode" : 70, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "opname" : "OpDecorate", + "class" : "Annotation", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "version": "1.0" + }, + { + "opname" : "OpMemberDecorate", + "class" : "Annotation", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'Structure Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "version": "1.0" + }, + { + "opname" : "OpDecorationGroup", + "class" : "Annotation", + "opcode" : 73, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpGroupDecorate", + "class" : "Annotation", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" } + ], + "version": "1.0" + }, + { + "opname" : "OpGroupMemberDecorate", + "class" : "Annotation", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" } + ], + "version": "1.0" + }, + { + "opname" : "OpVectorExtractDynamic", + "class" : "Composite", + "opcode" : 77, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "version": "1.0" + }, + { + "opname" : "OpVectorInsertDynamic", + "class" : "Composite", + "opcode" : 78, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "version": "1.0" + }, + { + "opname" : "OpVectorShuffle", + "class" : "Composite", + "opcode" : 79, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCompositeConstruct", + "class" : "Composite", + "opcode" : 80, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCompositeExtract", + "class" : "Composite", + "opcode" : 81, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCompositeInsert", + "class" : "Composite", + "opcode" : 82, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCopyObject", + "class" : "Composite", + "opcode" : 83, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTranspose", + "class" : "Composite", + "opcode" : 84, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpSampledImage", + "class" : "Image", + "opcode" : 86, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleImplicitLod", + "class" : "Image", + "opcode" : 87, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleExplicitLod", + "class" : "Image", + "opcode" : 88, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleDrefImplicitLod", + "class" : "Image", + "opcode" : 89, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleDrefExplicitLod", + "class" : "Image", + "opcode" : 90, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleProjImplicitLod", + "class" : "Image", + "opcode" : 91, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleProjExplicitLod", + "class" : "Image", + "opcode" : 92, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleProjDrefImplicitLod", + "class" : "Image", + "opcode" : 93, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleProjDrefExplicitLod", + "class" : "Image", + "opcode" : 94, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageFetch", + "class" : "Image", + "opcode" : 95, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageGather", + "class" : "Image", + "opcode" : 96, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageDrefGather", + "class" : "Image", + "opcode" : 97, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageRead", + "class" : "Image", + "opcode" : 98, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageWrite", + "class" : "Image", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Texel'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpImage", + "class" : "Image", + "opcode" : 100, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageQueryFormat", + "class" : "Image", + "opcode" : 101, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpImageQueryOrder", + "class" : "Image", + "opcode" : 102, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpImageQuerySizeLod", + "class" : "Image", + "opcode" : 103, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Level of Detail'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpImageQuerySize", + "class" : "Image", + "opcode" : 104, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpImageQueryLod", + "class" : "Image", + "opcode" : 105, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpImageQueryLevels", + "class" : "Image", + "opcode" : 106, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpImageQuerySamples", + "class" : "Image", + "opcode" : 107, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpConvertFToU", + "class" : "Conversion", + "opcode" : 109, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConvertFToS", + "class" : "Conversion", + "opcode" : 110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConvertSToF", + "class" : "Conversion", + "opcode" : 111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConvertUToF", + "class" : "Conversion", + "opcode" : 112, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUConvert", + "class" : "Conversion", + "opcode" : 113, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSConvert", + "class" : "Conversion", + "opcode" : 114, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFConvert", + "class" : "Conversion", + "opcode" : 115, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpQuantizeToF16", + "class" : "Conversion", + "opcode" : 116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConvertPtrToU", + "class" : "Conversion", + "opcode" : 117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ + "Addresses", + "PhysicalStorageBufferAddresses" + ], + "version": "1.0" + }, + { + "opname" : "OpSatConvertSToU", + "class" : "Conversion", + "opcode" : 118, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpSatConvertUToS", + "class" : "Conversion", + "opcode" : 119, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpConvertUToPtr", + "class" : "Conversion", + "opcode" : 120, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Integer Value'" } + ], + "capabilities" : [ + "Addresses", + "PhysicalStorageBufferAddresses" + ], + "version": "1.0" + }, + { + "opname" : "OpPtrCastToGeneric", + "class" : "Conversion", + "opcode" : 121, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGenericCastToPtr", + "class" : "Conversion", + "opcode" : 122, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGenericCastToPtrExplicit", + "class" : "Conversion", + "opcode" : 123, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "StorageClass", "name" : "'Storage'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpBitcast", + "class" : "Conversion", + "opcode" : 124, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSNegate", + "class" : "Arithmetic", + "opcode" : 126, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFNegate", + "class" : "Arithmetic", + "opcode" : 127, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIAdd", + "class" : "Arithmetic", + "opcode" : 128, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFAdd", + "class" : "Arithmetic", + "opcode" : 129, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpISub", + "class" : "Arithmetic", + "opcode" : 130, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFSub", + "class" : "Arithmetic", + "opcode" : 131, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIMul", + "class" : "Arithmetic", + "opcode" : 132, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFMul", + "class" : "Arithmetic", + "opcode" : 133, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUDiv", + "class" : "Arithmetic", + "opcode" : 134, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSDiv", + "class" : "Arithmetic", + "opcode" : 135, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFDiv", + "class" : "Arithmetic", + "opcode" : 136, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUMod", + "class" : "Arithmetic", + "opcode" : 137, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSRem", + "class" : "Arithmetic", + "opcode" : 138, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSMod", + "class" : "Arithmetic", + "opcode" : 139, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFRem", + "class" : "Arithmetic", + "opcode" : 140, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFMod", + "class" : "Arithmetic", + "opcode" : 141, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpVectorTimesScalar", + "class" : "Arithmetic", + "opcode" : 142, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "version": "1.0" + }, + { + "opname" : "OpMatrixTimesScalar", + "class" : "Arithmetic", + "opcode" : 143, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpVectorTimesMatrix", + "class" : "Arithmetic", + "opcode" : 144, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpMatrixTimesVector", + "class" : "Arithmetic", + "opcode" : 145, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpMatrixTimesMatrix", + "class" : "Arithmetic", + "opcode" : 146, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'LeftMatrix'" }, + { "kind" : "IdRef", "name" : "'RightMatrix'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpOuterProduct", + "class" : "Arithmetic", + "opcode" : 147, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpDot", + "class" : "Arithmetic", + "opcode" : 148, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIAddCarry", + "class" : "Arithmetic", + "opcode" : 149, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpISubBorrow", + "class" : "Arithmetic", + "opcode" : 150, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUMulExtended", + "class" : "Arithmetic", + "opcode" : 151, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSMulExtended", + "class" : "Arithmetic", + "opcode" : 152, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAny", + "class" : "Relational_and_Logical", + "opcode" : 154, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAll", + "class" : "Relational_and_Logical", + "opcode" : 155, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIsNan", + "class" : "Relational_and_Logical", + "opcode" : 156, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIsInf", + "class" : "Relational_and_Logical", + "opcode" : 157, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIsFinite", + "class" : "Relational_and_Logical", + "opcode" : 158, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpIsNormal", + "class" : "Relational_and_Logical", + "opcode" : 159, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpSignBitSet", + "class" : "Relational_and_Logical", + "opcode" : 160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpLessOrGreater", + "class" : "Relational_and_Logical", + "opcode" : 161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ], + "version" : "1.0", + "lastVersion" : "1.5" + }, + { + "opname" : "OpOrdered", + "class" : "Relational_and_Logical", + "opcode" : 162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpUnordered", + "class" : "Relational_and_Logical", + "opcode" : 163, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpLogicalEqual", + "class" : "Relational_and_Logical", + "opcode" : 164, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLogicalNotEqual", + "class" : "Relational_and_Logical", + "opcode" : 165, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLogicalOr", + "class" : "Relational_and_Logical", + "opcode" : 166, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLogicalAnd", + "class" : "Relational_and_Logical", + "opcode" : 167, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version" : "1.0" + }, + { + "opname" : "OpLogicalNot", + "class" : "Relational_and_Logical", + "opcode" : 168, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSelect", + "class" : "Relational_and_Logical", + "opcode" : 169, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'Object 1'" }, + { "kind" : "IdRef", "name" : "'Object 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIEqual", + "class" : "Relational_and_Logical", + "opcode" : 170, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpINotEqual", + "class" : "Relational_and_Logical", + "opcode" : 171, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUGreaterThan", + "class" : "Relational_and_Logical", + "opcode" : 172, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSGreaterThan", + "class" : "Relational_and_Logical", + "opcode" : 173, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUGreaterThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 174, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSGreaterThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 175, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpULessThan", + "class" : "Relational_and_Logical", + "opcode" : 176, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSLessThan", + "class" : "Relational_and_Logical", + "opcode" : 177, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpULessThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 178, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSLessThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 179, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdEqual", + "class" : "Relational_and_Logical", + "opcode" : 180, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordEqual", + "class" : "Relational_and_Logical", + "opcode" : 181, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdNotEqual", + "class" : "Relational_and_Logical", + "opcode" : 182, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordNotEqual", + "class" : "Relational_and_Logical", + "opcode" : 183, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdLessThan", + "class" : "Relational_and_Logical", + "opcode" : 184, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordLessThan", + "class" : "Relational_and_Logical", + "opcode" : 185, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdGreaterThan", + "class" : "Relational_and_Logical", + "opcode" : 186, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordGreaterThan", + "class" : "Relational_and_Logical", + "opcode" : 187, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdLessThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 188, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordLessThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 189, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdGreaterThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 190, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordGreaterThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 191, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpShiftRightLogical", + "class" : "Bit", + "opcode" : 194, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ], + "version": "1.0" + }, + { + "opname" : "OpShiftRightArithmetic", + "class" : "Bit", + "opcode" : 195, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ], + "version": "1.0" + }, + { + "opname" : "OpShiftLeftLogical", + "class" : "Bit", + "opcode" : 196, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBitwiseOr", + "class" : "Bit", + "opcode" : 197, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBitwiseXor", + "class" : "Bit", + "opcode" : 198, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBitwiseAnd", + "class" : "Bit", + "opcode" : 199, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpNot", + "class" : "Bit", + "opcode" : 200, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBitFieldInsert", + "class" : "Bit", + "opcode" : 201, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Insert'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader", "BitInstructions" ], + "version": "1.0" + }, + { + "opname" : "OpBitFieldSExtract", + "class" : "Bit", + "opcode" : 202, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader", "BitInstructions" ], + "version": "1.0" + }, + { + "opname" : "OpBitFieldUExtract", + "class" : "Bit", + "opcode" : 203, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader", "BitInstructions" ], + "version": "1.0" + }, + { + "opname" : "OpBitReverse", + "class" : "Bit", + "opcode" : 204, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "capabilities" : [ "Shader", "BitInstructions" ], + "version": "1.0" + }, + { + "opname" : "OpBitCount", + "class" : "Bit", + "opcode" : 205, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "version": "1.0" + }, + { + "opname" : "OpDPdx", + "class" : "Derivative", + "opcode" : 207, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpDPdy", + "class" : "Derivative", + "opcode" : 208, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpFwidth", + "class" : "Derivative", + "opcode" : 209, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpDPdxFine", + "class" : "Derivative", + "opcode" : 210, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpDPdyFine", + "class" : "Derivative", + "opcode" : 211, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpFwidthFine", + "class" : "Derivative", + "opcode" : 212, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpDPdxCoarse", + "class" : "Derivative", + "opcode" : 213, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpDPdyCoarse", + "class" : "Derivative", + "opcode" : 214, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpFwidthCoarse", + "class" : "Derivative", + "opcode" : 215, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpEmitVertex", + "class" : "Primitive", + "opcode" : 218, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "opname" : "OpEndPrimitive", + "class" : "Primitive", + "opcode" : 219, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "opname" : "OpEmitStreamVertex", + "class" : "Primitive", + "opcode" : 220, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ], + "version": "1.0" + }, + { + "opname" : "OpEndStreamPrimitive", + "class" : "Primitive", + "opcode" : 221, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ], + "version": "1.0" + }, + { + "opname" : "OpControlBarrier", + "class" : "Barrier", + "opcode" : 224, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpMemoryBarrier", + "class" : "Barrier", + "opcode" : 225, + "operands" : [ + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicLoad", + "class" : "Atomic", + "opcode" : 227, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicStore", + "class" : "Atomic", + "opcode" : 228, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicExchange", + "class" : "Atomic", + "opcode" : 229, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicCompareExchange", + "class" : "Atomic", + "opcode" : 230, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicCompareExchangeWeak", + "class" : "Atomic", + "opcode" : 231, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "capabilities" : [ "Kernel" ], + "version" : "1.0", + "lastVersion" : "1.3" + }, + { + "opname" : "OpAtomicIIncrement", + "class" : "Atomic", + "opcode" : 232, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicIDecrement", + "class" : "Atomic", + "opcode" : 233, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicIAdd", + "class" : "Atomic", + "opcode" : 234, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicISub", + "class" : "Atomic", + "opcode" : 235, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicSMin", + "class" : "Atomic", + "opcode" : 236, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicUMin", + "class" : "Atomic", + "opcode" : 237, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicSMax", + "class" : "Atomic", + "opcode" : 238, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicUMax", + "class" : "Atomic", + "opcode" : 239, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicAnd", + "class" : "Atomic", + "opcode" : 240, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicOr", + "class" : "Atomic", + "opcode" : 241, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicXor", + "class" : "Atomic", + "opcode" : 242, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpPhi", + "class" : "Control-Flow", + "opcode" : 245, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLoopMerge", + "class" : "Control-Flow", + "opcode" : 246, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "IdRef", "name" : "'Continue Target'" }, + { "kind" : "LoopControl" } + ], + "version": "1.0" + }, + { + "opname" : "OpSelectionMerge", + "class" : "Control-Flow", + "opcode" : 247, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "SelectionControl" } + ], + "version": "1.0" + }, + { + "opname" : "OpLabel", + "class" : "Control-Flow", + "opcode" : 248, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpBranch", + "class" : "Control-Flow", + "opcode" : 249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target Label'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBranchConditional", + "class" : "Control-Flow", + "opcode" : 250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'True Label'" }, + { "kind" : "IdRef", "name" : "'False Label'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSwitch", + "class" : "Control-Flow", + "opcode" : 251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Selector'" }, + { "kind" : "IdRef", "name" : "'Default'" }, + { "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" } + ], + "version": "1.0" + }, + { + "opname" : "OpKill", + "class" : "Control-Flow", + "opcode" : 252, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpReturn", + "class" : "Control-Flow", + "opcode" : 253, + "version" : "1.0" + }, + { + "opname" : "OpReturnValue", + "class" : "Control-Flow", + "opcode" : 254, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUnreachable", + "class" : "Control-Flow", + "opcode" : 255, + "version" : "1.0" + }, + { + "opname" : "OpLifetimeStart", + "class" : "Control-Flow", + "opcode" : 256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpLifetimeStop", + "class" : "Control-Flow", + "opcode" : 257, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGroupAsyncCopy", + "class" : "Group", + "opcode" : 259, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Destination'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Num Elements'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGroupWaitEvents", + "class" : "Group", + "opcode" : 260, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Events List'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGroupAll", + "class" : "Group", + "opcode" : 261, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupAny", + "class" : "Group", + "opcode" : 262, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupBroadcast", + "class" : "Group", + "opcode" : 263, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'LocalId'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupIAdd", + "class" : "Group", + "opcode" : 264, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupFAdd", + "class" : "Group", + "opcode" : 265, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupFMin", + "class" : "Group", + "opcode" : 266, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupUMin", + "class" : "Group", + "opcode" : 267, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupSMin", + "class" : "Group", + "opcode" : 268, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupFMax", + "class" : "Group", + "opcode" : 269, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupUMax", + "class" : "Group", + "opcode" : 270, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupSMax", + "class" : "Group", + "opcode" : 271, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpReadPipe", + "class" : "Pipe", + "opcode" : 274, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpWritePipe", + "class" : "Pipe", + "opcode" : 275, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpReservedReadPipe", + "class" : "Pipe", + "opcode" : 276, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpReservedWritePipe", + "class" : "Pipe", + "opcode" : 277, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpReserveReadPipePackets", + "class" : "Pipe", + "opcode" : 278, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpReserveWritePipePackets", + "class" : "Pipe", + "opcode" : 279, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpCommitReadPipe", + "class" : "Pipe", + "opcode" : 280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpCommitWritePipe", + "class" : "Pipe", + "opcode" : 281, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpIsValidReserveId", + "class" : "Pipe", + "opcode" : 282, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGetNumPipePackets", + "class" : "Pipe", + "opcode" : 283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGetMaxPipePackets", + "class" : "Pipe", + "opcode" : 284, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGroupReserveReadPipePackets", + "class" : "Pipe", + "opcode" : 285, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGroupReserveWritePipePackets", + "class" : "Pipe", + "opcode" : 286, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGroupCommitReadPipe", + "class" : "Pipe", + "opcode" : 287, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGroupCommitWritePipe", + "class" : "Pipe", + "opcode" : 288, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpEnqueueMarker", + "class" : "Device-Side_Enqueue", + "opcode" : 291, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpEnqueueKernel", + "class" : "Device-Side_Enqueue", + "opcode" : 292, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetKernelNDrangeSubGroupCount", + "class" : "Device-Side_Enqueue", + "opcode" : 293, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetKernelNDrangeMaxSubGroupSize", + "class" : "Device-Side_Enqueue", + "opcode" : 294, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetKernelWorkGroupSize", + "class" : "Device-Side_Enqueue", + "opcode" : 295, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetKernelPreferredWorkGroupSizeMultiple", + "class" : "Device-Side_Enqueue", + "opcode" : 296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpRetainEvent", + "class" : "Device-Side_Enqueue", + "opcode" : 297, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpReleaseEvent", + "class" : "Device-Side_Enqueue", + "opcode" : 298, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpCreateUserEvent", + "class" : "Device-Side_Enqueue", + "opcode" : 299, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpIsValidEvent", + "class" : "Device-Side_Enqueue", + "opcode" : 300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpSetUserEventStatus", + "class" : "Device-Side_Enqueue", + "opcode" : 301, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Status'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpCaptureEventProfilingInfo", + "class" : "Device-Side_Enqueue", + "opcode" : 302, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Profiling Info'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetDefaultQueue", + "class" : "Device-Side_Enqueue", + "opcode" : 303, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpBuildNDRange", + "class" : "Device-Side_Enqueue", + "opcode" : 304, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'GlobalWorkSize'" }, + { "kind" : "IdRef", "name" : "'LocalWorkSize'" }, + { "kind" : "IdRef", "name" : "'GlobalWorkOffset'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleImplicitLod", + "class" : "Image", + "opcode" : 305, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleExplicitLod", + "class" : "Image", + "opcode" : 306, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleDrefImplicitLod", + "class" : "Image", + "opcode" : 307, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleDrefExplicitLod", + "class" : "Image", + "opcode" : 308, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleProjImplicitLod", + "class" : "Image", + "opcode" : 309, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version" : "None" + }, + { + "opname" : "OpImageSparseSampleProjExplicitLod", + "class" : "Image", + "opcode" : 310, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ], + "version" : "None" + }, + { + "opname" : "OpImageSparseSampleProjDrefImplicitLod", + "class" : "Image", + "opcode" : 311, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version" : "None" + }, + { + "opname" : "OpImageSparseSampleProjDrefExplicitLod", + "class" : "Image", + "opcode" : 312, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ], + "version" : "None" + }, + { + "opname" : "OpImageSparseFetch", + "class" : "Image", + "opcode" : 313, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseGather", + "class" : "Image", + "opcode" : 314, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseDrefGather", + "class" : "Image", + "opcode" : 315, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseTexelsResident", + "class" : "Image", + "opcode" : 316, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Resident Code'" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpNoLine", + "class" : "Debug", + "opcode" : 317, + "version" : "1.0" + }, + { + "opname" : "OpAtomicFlagTestAndSet", + "class" : "Atomic", + "opcode" : 318, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpAtomicFlagClear", + "class" : "Atomic", + "opcode" : 319, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseRead", + "class" : "Image", + "opcode" : 320, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpSizeOf", + "class" : "Miscellaneous", + "opcode" : 321, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ], + "version" : "1.1" + }, + { + "opname" : "OpTypePipeStorage", + "class" : "Type-Declaration", + "opcode" : 322, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "PipeStorage" ], + "version" : "1.1" + }, + { + "opname" : "OpConstantPipeStorage", + "class" : "Pipe", + "opcode" : 323, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Packet Size'" }, + { "kind" : "LiteralInteger", "name" : "'Packet Alignment'" }, + { "kind" : "LiteralInteger", "name" : "'Capacity'" } + ], + "capabilities" : [ "PipeStorage" ], + "version" : "1.1" + }, + { + "opname" : "OpCreatePipeFromPipeStorage", + "class" : "Pipe", + "opcode" : 324, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe Storage'" } + ], + "capabilities" : [ "PipeStorage" ], + "version" : "1.1" + }, + { + "opname" : "OpGetKernelLocalSizeForSubgroupCount", + "class" : "Device-Side_Enqueue", + "opcode" : 325, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ], + "version" : "1.1" + }, + { + "opname" : "OpGetKernelMaxNumSubgroups", + "class" : "Device-Side_Enqueue", + "opcode" : 326, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ], + "version" : "1.1" + }, + { + "opname" : "OpTypeNamedBarrier", + "class" : "Type-Declaration", + "opcode" : 327, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "NamedBarrier" ], + "version" : "1.1" + }, + { + "opname" : "OpNamedBarrierInitialize", + "class" : "Barrier", + "opcode" : 328, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" } + ], + "capabilities" : [ "NamedBarrier" ], + "version" : "1.1" + }, + { + "opname" : "OpMemoryNamedBarrier", + "class" : "Barrier", + "opcode" : 329, + "operands" : [ + { "kind" : "IdRef", "name" : "'Named Barrier'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "NamedBarrier" ], + "version" : "1.1" + }, + { + "opname" : "OpModuleProcessed", + "class" : "Debug", + "opcode" : 330, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Process'" } + ], + "version" : "1.1" + }, + { + "opname" : "OpExecutionModeId", + "class" : "Mode-Setting", + "opcode" : 331, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ], + "version" : "1.2" + }, + { + "opname" : "OpDecorateId", + "class" : "Annotation", + "opcode" : 332, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.2" + }, + { + "opname" : "OpGroupNonUniformElect", + "class" : "Non-Uniform", + "opcode" : 333, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" } + ], + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformAll", + "class" : "Non-Uniform", + "opcode" : 334, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "GroupNonUniformVote" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformAny", + "class" : "Non-Uniform", + "opcode" : 335, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "GroupNonUniformVote" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformAllEqual", + "class" : "Non-Uniform", + "opcode" : 336, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformVote" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBroadcast", + "class" : "Non-Uniform", + "opcode" : 337, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Id'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBroadcastFirst", + "class" : "Non-Uniform", + "opcode" : 338, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallot", + "class" : "Non-Uniform", + "opcode" : 339, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformInverseBallot", + "class" : "Non-Uniform", + "opcode" : 340, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallotBitExtract", + "class" : "Non-Uniform", + "opcode" : 341, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallotBitCount", + "class" : "Non-Uniform", + "opcode" : 342, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallotFindLSB", + "class" : "Non-Uniform", + "opcode" : 343, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallotFindMSB", + "class" : "Non-Uniform", + "opcode" : 344, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformShuffle", + "class" : "Non-Uniform", + "opcode" : 345, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Id'" } + ], + "capabilities" : [ "GroupNonUniformShuffle" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformShuffleXor", + "class" : "Non-Uniform", + "opcode" : 346, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Mask'" } + ], + "capabilities" : [ "GroupNonUniformShuffle" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformShuffleUp", + "class" : "Non-Uniform", + "opcode" : 347, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "GroupNonUniformShuffleRelative" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformShuffleDown", + "class" : "Non-Uniform", + "opcode" : 348, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "GroupNonUniformShuffleRelative" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformIAdd", + "class" : "Non-Uniform", + "opcode" : 349, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformFAdd", + "class" : "Non-Uniform", + "opcode" : 350, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformIMul", + "class" : "Non-Uniform", + "opcode" : 351, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformFMul", + "class" : "Non-Uniform", + "opcode" : 352, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformSMin", + "class" : "Non-Uniform", + "opcode" : 353, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformUMin", + "class" : "Non-Uniform", + "opcode" : 354, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformFMin", + "class" : "Non-Uniform", + "opcode" : 355, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformSMax", + "class" : "Non-Uniform", + "opcode" : 356, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformUMax", + "class" : "Non-Uniform", + "opcode" : 357, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformFMax", + "class" : "Non-Uniform", + "opcode" : 358, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBitwiseAnd", + "class" : "Non-Uniform", + "opcode" : 359, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBitwiseOr", + "class" : "Non-Uniform", + "opcode" : 360, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBitwiseXor", + "class" : "Non-Uniform", + "opcode" : 361, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformLogicalAnd", + "class" : "Non-Uniform", + "opcode" : 362, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformLogicalOr", + "class" : "Non-Uniform", + "opcode" : 363, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformLogicalXor", + "class" : "Non-Uniform", + "opcode" : 364, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformQuadBroadcast", + "class" : "Non-Uniform", + "opcode" : 365, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "GroupNonUniformQuad" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformQuadSwap", + "class" : "Non-Uniform", + "opcode" : 366, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "GroupNonUniformQuad" ], + "version" : "1.3" + }, + { + "opname" : "OpCopyLogical", + "class" : "Composite", + "opcode" : 400, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version" : "1.4" + }, + { + "opname" : "OpPtrEqual", + "class" : "Memory", + "opcode" : 401, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version" : "1.4" + }, + { + "opname" : "OpPtrNotEqual", + "class" : "Memory", + "opcode" : 402, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version" : "1.4" + }, + { + "opname" : "OpPtrDiff", + "class" : "Memory", + "opcode" : 403, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "Addresses", "VariablePointers", "VariablePointersStorageBuffer" ], + "version" : "1.4" + }, + { + "opname" : "OpColorAttachmentReadEXT", + "class" : "Image", + "opcode" : 4160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Attachment'" }, + { "kind" : "IdRef", "name" : "'Sample'", "quantifier" : "?" } + ], + "capabilities": [ "TileImageColorReadAccessEXT" ], + "version" : "None" + }, + { + "opname" : "OpDepthAttachmentReadEXT", + "class" : "Image", + "opcode" : 4161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sample'", "quantifier" : "?" } + ], + "capabilities" : [ "TileImageDepthReadAccessEXT" ], + "version" : "None" + }, + { + "opname" : "OpStencilAttachmentReadEXT", + "class" : "Image", + "opcode" : 4162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sample'", "quantifier" : "?" } + ], + "capabilities" : [ "TileImageStencilReadAccessEXT" ], + "version" : "None" + }, + { + "opname" : "OpTerminateInvocation", + "class" : "Control-Flow", + "opcode" : 4416, + "extensions" : [ + "SPV_KHR_terminate_invocation" + ], + "capabilities" : [ "Shader" ], + "version" : "1.6" + }, + { + "opname" : "OpSubgroupBallotKHR", + "class" : "Group", + "opcode" : 4421, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupFirstInvocationKHR", + "class" : "Group", + "opcode" : 4422, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAllKHR", + "class" : "Group", + "opcode" : 4428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "extensions" : [ + "SPV_KHR_subgroup_vote" + ], + "capabilities" : [ "SubgroupVoteKHR" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAnyKHR", + "class" : "Group", + "opcode" : 4429, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "extensions" : [ + "SPV_KHR_subgroup_vote" + ], + "capabilities" : [ "SubgroupVoteKHR" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAllEqualKHR", + "class" : "Group", + "opcode" : 4430, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "extensions" : [ + "SPV_KHR_subgroup_vote" + ], + "capabilities" : [ "SubgroupVoteKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupNonUniformRotateKHR", + "class" : "Group", + "opcode" : 4431, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Delta'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformRotateKHR" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupReadInvocationKHR", + "class" : "Group", + "opcode" : 4432, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpTraceRayKHR", + "class" : "Reserved", + "opcode" : 4445, + "operands" : [ + + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Ray Flags'" }, + { "kind" : "IdRef", "name" : "'Cull Mask'" }, + { "kind" : "IdRef", "name" : "'SBT Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Stride'" }, + { "kind" : "IdRef", "name" : "'Miss Index'" }, + { "kind" : "IdRef", "name" : "'Ray Origin'" }, + { "kind" : "IdRef", "name" : "'Ray Tmin'" }, + { "kind" : "IdRef", "name" : "'Ray Direction'" }, + { "kind" : "IdRef", "name" : "'Ray Tmax'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpExecuteCallableKHR", + "class" : "Reserved", + "opcode" : 4446, + "operands" : [ + + { "kind" : "IdRef", "name" : "'SBT Index'" }, + { "kind" : "IdRef", "name" : "'Callable Data'" } + ], + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpConvertUToAccelerationStructureKHR", + "class" : "Reserved", + "opcode" : 4447, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Accel'" } + ], + "capabilities" : [ "RayTracingKHR", "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing", "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpIgnoreIntersectionKHR", + "class" : "Reserved", + "opcode" : 4448, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTerminateRayKHR", + "class" : "Reserved", + "opcode" : 4449, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpSDot", + "class" : "Arithmetic", + "opcode" : 4450, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpSDotKHR", + "class" : "Arithmetic", + "opcode" : 4450, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpUDot", + "class" : "Arithmetic", + "opcode" : 4451, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpUDotKHR", + "class" : "Arithmetic", + "opcode" : 4451, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpSUDot", + "class" : "Arithmetic", + "opcode" : 4452, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpSUDotKHR", + "class" : "Arithmetic", + "opcode" : 4452, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpSDotAccSat", + "class" : "Arithmetic", + "opcode" : 4453, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpSDotAccSatKHR", + "class" : "Arithmetic", + "opcode" : 4453, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpUDotAccSat", + "class" : "Arithmetic", + "opcode" : 4454, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpUDotAccSatKHR", + "class" : "Arithmetic", + "opcode" : 4454, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpSUDotAccSat", + "class" : "Arithmetic", + "opcode" : 4455, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpSUDotAccSatKHR", + "class" : "Arithmetic", + "opcode" : 4455, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpTypeCooperativeMatrixKHR", + "class" : "Type-Declaration", + "opcode" : 4456, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Rows'" }, + { "kind" : "IdRef", "name" : "'Columns'" }, + { "kind" : "IdRef", "name" : "'Use'" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixLoadKHR", + "class" : "Memory", + "opcode" : 4457, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'MemoryLayout'" }, + { "kind" : "IdRef", "name" : "'Stride'", "quantifier": "?" }, + { "kind" : "MemoryAccess", "name" : "'Memory Operand'", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixStoreKHR", + "class" : "Memory", + "opcode" : 4458, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'MemoryLayout'" }, + { "kind" : "IdRef", "name" : "'Stride'", "quantifier": "?" }, + { "kind" : "MemoryAccess", "name" : "'Memory Operand'", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixMulAddKHR", + "class" : "Arithmetic", + "opcode" : 4459, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "IdRef", "name" : "'C'" }, + { "kind" : "CooperativeMatrixOperands", "name" : "'Cooperative Matrix Operands'", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixLengthKHR", + "class" : "Miscellaneous", + "opcode" : 4460, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Type'" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpTypeRayQueryKHR", + "class" : "Type-Declaration", + "opcode" : 4472, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryInitializeKHR", + "class" : "Reserved", + "opcode" : 4473, + "operands" : [ + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Accel'" + }, + { + "kind" : "IdRef", + "name" : "'RayFlags'" + }, + { + "kind" : "IdRef", + "name" : "'CullMask'" + }, + { + "kind" : "IdRef", + "name" : "'RayOrigin'" + }, + { + "kind" : "IdRef", + "name" : "'RayTMin'" + }, + { + "kind" : "IdRef", + "name" : "'RayDirection'" + }, + { + "kind" : "IdRef", + "name" : "'RayTMax'" + } + + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryTerminateKHR", + "class" : "Reserved", + "opcode" : 4474, + "operands" : [ + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGenerateIntersectionKHR", + "class" : "Reserved", + "opcode" : 4475, + "operands" : [ + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'HitT'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryConfirmIntersectionKHR", + "class" : "Reserved", + "opcode" : 4476, + "operands" : [ + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryProceedKHR", + "class" : "Reserved", + "opcode" : 4477, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionTypeKHR", + "class" : "Reserved", + "opcode" : 4479, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpImageSampleWeightedQCOM", + "class" : "Image", + "opcode" : 4480, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Texture'" }, + { "kind" : "IdRef", "name" : "'Coordinates'" }, + { "kind" : "IdRef", "name" : "'Weights'" } + ], + "capabilities" : [ "TextureSampleWeightedQCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBoxFilterQCOM", + "class" : "Image", + "opcode" : 4481, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Texture'" }, + { "kind" : "IdRef", "name" : "'Coordinates'" }, + { "kind" : "IdRef", "name" : "'Box Size'" } + ], + "capabilities" : [ "TextureBoxFilterQCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchSSDQCOM", + "class" : "Image", + "opcode" : 4482, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatchQCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchSADQCOM", + "class" : "Image", + "opcode" : 4483, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatchQCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchWindowSSDQCOM", + "class" : "Image", + "opcode" : 4500, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatch2QCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchWindowSADQCOM", + "class" : "Image", + "opcode" : 4501, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatch2QCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchGatherSSDQCOM", + "class" : "Image", + "opcode" : 4502, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatch2QCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchGatherSADQCOM", + "class" : "Image", + "opcode" : 4503, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatch2QCOM" ], + "version" : "None" + }, + { + "opname" : "OpGroupIAddNonUniformAMD", + "class" : "Group", + "opcode" : 5000, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupFAddNonUniformAMD", + "class" : "Group", + "opcode" : 5001, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupFMinNonUniformAMD", + "class" : "Group", + "opcode" : 5002, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupUMinNonUniformAMD", + "class" : "Group", + "opcode" : 5003, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupSMinNonUniformAMD", + "class" : "Group", + "opcode" : 5004, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupFMaxNonUniformAMD", + "class" : "Group", + "opcode" : 5005, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupUMaxNonUniformAMD", + "class" : "Group", + "opcode" : 5006, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupSMaxNonUniformAMD", + "class" : "Group", + "opcode" : 5007, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpFragmentMaskFetchAMD", + "class" : "Reserved", + "opcode" : 5011, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "FragmentMaskAMD" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ], + "version" : "None" + }, + { + "opname" : "OpFragmentFetchAMD", + "class" : "Reserved", + "opcode" : 5012, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Fragment Index'" } + ], + "capabilities" : [ "FragmentMaskAMD" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ], + "version" : "None" + }, + { + "opname" : "OpReadClockKHR", + "class" : "Reserved", + "opcode" : 5056, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Scope'" } + ], + "capabilities" : [ "ShaderClockKHR" ], + "version" : "None" + }, + { + "opname" : "OpFinalizeNodePayloadsAMDX", + "class" : "Reserved", + "opcode" : 5075, + "operands" : [ + { "kind" : "IdRef", "name": "'Payload Array'" } + ], + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "opname" : "OpFinishWritingNodePayloadAMDX", + "class" : "Reserved", + "opcode" : 5078, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name": "'Payload'" } + ], + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "opname" : "OpInitializeNodePayloadsAMDX", + "class" : "Reserved", + "opcode" : 5090, + "operands" : [ + { "kind" : "IdRef", "name": "'Payload Array'" }, + { "kind" : "IdScope", "name": "'Visibility'" }, + { "kind" : "IdRef", "name": "'Payload Count'" }, + { "kind" : "IdRef", "name": "'Node Index'" } + ], + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "opname" : "OpGroupNonUniformQuadAllKHR", + "class" : "Non-Uniform", + "opcode" : 5110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "QuadControlKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupNonUniformQuadAnyKHR", + "class" : "Non-Uniform", + "opcode" : 5111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "QuadControlKHR" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordHitMotionNV", + "class" : "Reserved", + "opcode" : 5249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'" }, + { "kind" : "IdRef", "name" : "'InstanceId'" }, + { "kind" : "IdRef", "name" : "'PrimitiveId'" }, + { "kind" : "IdRef", "name" : "'GeometryIndex'" }, + { "kind" : "IdRef", "name" : "'Hit Kind'" }, + { "kind" : "IdRef", "name" : "'SBT Record Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Record Stride'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'Current Time'" }, + { "kind" : "IdRef", "name" : "'HitObject Attributes'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV", "RayTracingMotionBlurNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordHitWithIndexMotionNV", + "class" : "Reserved", + "opcode" : 5250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'" }, + { "kind" : "IdRef", "name" : "'InstanceId'" }, + { "kind" : "IdRef", "name" : "'PrimitiveId'" }, + { "kind" : "IdRef", "name" : "'GeometryIndex'" }, + { "kind" : "IdRef", "name" : "'Hit Kind'" }, + { "kind" : "IdRef", "name" : "'SBT Record Index'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'Current Time'" }, + { "kind" : "IdRef", "name" : "'HitObject Attributes'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV", "RayTracingMotionBlurNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordMissMotionNV", + "class" : "Reserved", + "opcode" : 5251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'SBT Index'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'Current Time'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV", "RayTracingMotionBlurNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetWorldToObjectNV", + "class" : "Reserved", + "opcode" : 5252, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetObjectToWorldNV", + "class" : "Reserved", + "opcode" : 5253, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetObjectRayDirectionNV", + "class" : "Reserved", + "opcode" : 5254, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetObjectRayOriginNV", + "class" : "Reserved", + "opcode" : 5255, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectTraceRayMotionNV", + "class" : "Reserved", + "opcode" : 5256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'"}, + { "kind" : "IdRef", "name" : "'RayFlags'"}, + { "kind" : "IdRef", "name" : "'Cullmask'"}, + { "kind" : "IdRef", "name" : "'SBT Record Offset'"}, + { "kind" : "IdRef", "name" : "'SBT Record Stride'"}, + { "kind" : "IdRef", "name" : "'Miss Index'"}, + { "kind" : "IdRef", "name" : "'Origin'"}, + { "kind" : "IdRef", "name" : "'TMin'"}, + { "kind" : "IdRef", "name" : "'Direction'"}, + { "kind" : "IdRef", "name" : "'TMax'"}, + { "kind" : "IdRef", "name" : "'Time'"}, + { "kind" : "IdRef", "name" : "'Payload'"} + ], + "capabilities" : [ "ShaderInvocationReorderNV", "RayTracingMotionBlurNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetShaderRecordBufferHandleNV", + "class" : "Reserved", + "opcode" : 5257, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetShaderBindingTableRecordIndexNV", + "class" : "Reserved", + "opcode" : 5258, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordEmptyNV", + "class" : "Reserved", + "opcode" : 5259, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectTraceRayNV", + "class" : "Reserved", + "opcode" : 5260, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'"}, + { "kind" : "IdRef", "name" : "'RayFlags'"}, + { "kind" : "IdRef", "name" : "'Cullmask'"}, + { "kind" : "IdRef", "name" : "'SBT Record Offset'"}, + { "kind" : "IdRef", "name" : "'SBT Record Stride'"}, + { "kind" : "IdRef", "name" : "'Miss Index'"}, + { "kind" : "IdRef", "name" : "'Origin'"}, + { "kind" : "IdRef", "name" : "'TMin'"}, + { "kind" : "IdRef", "name" : "'Direction'"}, + { "kind" : "IdRef", "name" : "'TMax'"}, + { "kind" : "IdRef", "name" : "'Payload'"} + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordHitNV", + "class" : "Reserved", + "opcode" : 5261, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'" }, + { "kind" : "IdRef", "name" : "'InstanceId'" }, + { "kind" : "IdRef", "name" : "'PrimitiveId'" }, + { "kind" : "IdRef", "name" : "'GeometryIndex'" }, + { "kind" : "IdRef", "name" : "'Hit Kind'" }, + { "kind" : "IdRef", "name" : "'SBT Record Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Record Stride'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'HitObject Attributes'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordHitWithIndexNV", + "class" : "Reserved", + "opcode" : 5262, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'" }, + { "kind" : "IdRef", "name" : "'InstanceId'" }, + { "kind" : "IdRef", "name" : "'PrimitiveId'" }, + { "kind" : "IdRef", "name" : "'GeometryIndex'" }, + { "kind" : "IdRef", "name" : "'Hit Kind'" }, + { "kind" : "IdRef", "name" : "'SBT Record Index'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'HitObject Attributes'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordMissNV", + "class" : "Reserved", + "opcode" : 5263, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'SBT Index'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectExecuteShaderNV", + "class" : "Reserved", + "opcode" : 5264, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetCurrentTimeNV", + "class" : "Reserved", + "opcode" : 5265, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetAttributesNV", + "class" : "Reserved", + "opcode" : 5266, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Hit Object Attribute'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetHitKindNV", + "class" : "Reserved", + "opcode" : 5267, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetPrimitiveIndexNV", + "class" : "Reserved", + "opcode" : 5268, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetGeometryIndexNV", + "class" : "Reserved", + "opcode" : 5269, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetInstanceIdNV", + "class" : "Reserved", + "opcode" : 5270, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetInstanceCustomIndexNV", + "class" : "Reserved", + "opcode" : 5271, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetWorldRayDirectionNV", + "class" : "Reserved", + "opcode" : 5272, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetWorldRayOriginNV", + "class" : "Reserved", + "opcode" : 5273, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetRayTMaxNV", + "class" : "Reserved", + "opcode" : 5274, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetRayTMinNV", + "class" : "Reserved", + "opcode" : 5275, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectIsEmptyNV", + "class" : "Reserved", + "opcode" : 5276, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectIsHitNV", + "class" : "Reserved", + "opcode" : 5277, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectIsMissNV", + "class" : "Reserved", + "opcode" : 5278, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpReorderThreadWithHitObjectNV", + "class" : "Reserved", + "opcode" : 5279, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Hint'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Bits'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpReorderThreadWithHintNV", + "class" : "Reserved", + "opcode" : 5280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hint'" }, + { "kind" : "IdRef", "name" : "'Bits'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpTypeHitObjectNV", + "class" : "Type-Declaration", + "opcode" : 5281, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpImageSampleFootprintNV", + "class" : "Image", + "opcode" : 5283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Granularity'" }, + { "kind" : "IdRef", "name" : "'Coarse'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "ImageFootprintNV" ], + "extensions" : [ "SPV_NV_shader_image_footprint" ], + "version" : "None" + }, + { + "opname" : "OpEmitMeshTasksEXT", + "class" : "Reserved", + "opcode" : 5294, + "operands" : [ + { "kind" : "IdRef", "name" : "'Group Count X'" }, + { "kind" : "IdRef", "name" : "'Group Count Y'" }, + { "kind" : "IdRef", "name" : "'Group Count Z'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Payload'" } + ], + "capabilities" : [ "MeshShadingEXT" ], + "version" : "None" + }, + { + "opname" : "OpSetMeshOutputsEXT", + "class" : "Reserved", + "opcode" : 5295, + "operands" : [ + { "kind" : "IdRef", "name" : "'Vertex Count'" }, + { "kind" : "IdRef", "name" : "'Primitive Count'" } + ], + "capabilities" : [ "MeshShadingEXT" ], + "version" : "None" + }, + { + "opname" : "OpGroupNonUniformPartitionNV", + "class" : "Non-Uniform", + "opcode" : 5296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformPartitionedNV" ], + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + }, + { + "opname" : "OpWritePackedPrimitiveIndices4x8NV", + "class" : "Reserved", + "opcode" : 5299, + "operands" : [ + { "kind" : "IdRef", "name" : "'Index Offset'" }, + { "kind" : "IdRef", "name" : "'Packed Indices'" } + ], + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "opname" : "OpFetchMicroTriangleVertexPositionNV", + "class" : "Reserved", + "opcode" : 5300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Instance Id'" }, + { "kind" : "IdRef", "name" : "'Geometry Index'" }, + { "kind" : "IdRef", "name" : "'Primitive Index'" }, + { "kind" : "IdRef", "name" : "'Barycentric'" } + ], + "capabilities" : [ "DisplacementMicromapNV" ], + "version" : "None" + }, + { + "opname" : "OpFetchMicroTriangleVertexBarycentricNV", + "class" : "Reserved", + "opcode" : 5301, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Instance Id'" }, + { "kind" : "IdRef", "name" : "'Geometry Index'" }, + { "kind" : "IdRef", "name" : "'Primitive Index'" }, + { "kind" : "IdRef", "name" : "'Barycentric'" } + ], + "capabilities" : [ "DisplacementMicromapNV" ], + "version" : "None" + }, + { + "opname" : "OpReportIntersectionNV", + "class" : "Reserved", + "opcode" : 5334, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Hit'" }, + { "kind" : "IdRef", "name" : "'HitKind'" } + ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpReportIntersectionKHR", + "class" : "Reserved", + "opcode" : 5334, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Hit'" }, + { "kind" : "IdRef", "name" : "'HitKind'" } + ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpIgnoreIntersectionNV", + "class" : "Reserved", + "opcode" : 5335, + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTerminateRayNV", + "class" : "Reserved", + "opcode" : 5336, + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTraceNV", + "class" : "Reserved", + "opcode" : 5337, + "operands" : [ + + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Ray Flags'" }, + { "kind" : "IdRef", "name" : "'Cull Mask'" }, + { "kind" : "IdRef", "name" : "'SBT Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Stride'" }, + { "kind" : "IdRef", "name" : "'Miss Index'" }, + { "kind" : "IdRef", "name" : "'Ray Origin'" }, + { "kind" : "IdRef", "name" : "'Ray Tmin'" }, + { "kind" : "IdRef", "name" : "'Ray Direction'" }, + { "kind" : "IdRef", "name" : "'Ray Tmax'" }, + { "kind" : "IdRef", "name" : "'PayloadId'" } + ], + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTraceMotionNV", + "class" : "Reserved", + "opcode" : 5338, + "operands" : [ + + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Ray Flags'" }, + { "kind" : "IdRef", "name" : "'Cull Mask'" }, + { "kind" : "IdRef", "name" : "'SBT Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Stride'" }, + { "kind" : "IdRef", "name" : "'Miss Index'" }, + { "kind" : "IdRef", "name" : "'Ray Origin'" }, + { "kind" : "IdRef", "name" : "'Ray Tmin'" }, + { "kind" : "IdRef", "name" : "'Ray Direction'" }, + { "kind" : "IdRef", "name" : "'Ray Tmax'" }, + { "kind" : "IdRef", "name" : "'Time'" }, + { "kind" : "IdRef", "name" : "'PayloadId'" } + ], + "capabilities" : [ "RayTracingMotionBlurNV" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, + { + "opname" : "OpTraceRayMotionNV", + "class" : "Reserved", + "opcode" : 5339, + "operands" : [ + + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Ray Flags'" }, + { "kind" : "IdRef", "name" : "'Cull Mask'" }, + { "kind" : "IdRef", "name" : "'SBT Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Stride'" }, + { "kind" : "IdRef", "name" : "'Miss Index'" }, + { "kind" : "IdRef", "name" : "'Ray Origin'" }, + { "kind" : "IdRef", "name" : "'Ray Tmin'" }, + { "kind" : "IdRef", "name" : "'Ray Direction'" }, + { "kind" : "IdRef", "name" : "'Ray Tmax'" }, + { "kind" : "IdRef", "name" : "'Time'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "RayTracingMotionBlurNV" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionTriangleVertexPositionsKHR", + "class" : "Reserved", + "opcode" : 5340, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryPositionFetchKHR" ], + "version" : "None" + }, + { + "opname" : "OpTypeAccelerationStructureNV", + "class" : "Type-Declaration", + "opcode" : 5341, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR", "RayQueryKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing", "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpTypeAccelerationStructureKHR", + "class" : "Type-Declaration", + "opcode" : 5341, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR", "RayQueryKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing", "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpExecuteCallableNV", + "class" : "Reserved", + "opcode" : 5344, + "operands" : [ + + { "kind" : "IdRef", "name" : "'SBT Index'" }, + { "kind" : "IdRef", "name" : "'Callable DataId'" } + ], + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTypeCooperativeMatrixNV", + "class" : "Type-Declaration", + "opcode" : 5358, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Rows'" }, + { "kind" : "IdRef", "name" : "'Columns'" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixLoadNV", + "class" : "Reserved", + "opcode" : 5359, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Column Major'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixStoreNV", + "class" : "Reserved", + "opcode" : 5360, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Column Major'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixMulAddNV", + "class" : "Reserved", + "opcode" : 5361, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "IdRef", "name" : "'C'" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixLengthNV", + "class" : "Reserved", + "opcode" : 5362, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Type'" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpBeginInvocationInterlockEXT", + "class" : "Reserved", + "opcode" : 5364, + "capabilities" : [ "FragmentShaderSampleInterlockEXT", "FragmentShaderPixelInterlockEXT", "FragmentShaderShadingRateInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "opname" : "OpEndInvocationInterlockEXT", + "class" : "Reserved", + "opcode" : 5365, + "capabilities" : [ "FragmentShaderSampleInterlockEXT", "FragmentShaderPixelInterlockEXT", "FragmentShaderShadingRateInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "opname" : "OpDemoteToHelperInvocation", + "class" : "Control-Flow", + "opcode" : 5380, + "capabilities" : [ "DemoteToHelperInvocation" ], + "version" : "1.6" + }, + { + "opname" : "OpDemoteToHelperInvocationEXT", + "class" : "Control-Flow", + "opcode" : 5380, + "capabilities" : [ "DemoteToHelperInvocationEXT" ], + "version" : "1.6" + }, + { + "opname" : "OpIsHelperInvocationEXT", + "class" : "Reserved", + "opcode" : 5381, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DemoteToHelperInvocationEXT" ], + "extensions" : [ "SPV_EXT_demote_to_helper_invocation" ], + "version" : "None" + }, + { + "opname" : "OpConvertUToImageNV", + "class" : "Reserved", + "opcode" : 5391, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertUToSamplerNV", + "class" : "Reserved", + "opcode" : 5392, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertImageToUNV", + "class" : "Reserved", + "opcode" : 5393, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertSamplerToUNV", + "class" : "Reserved", + "opcode" : 5394, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertUToSampledImageNV", + "class" : "Reserved", + "opcode" : 5395, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertSampledImageToUNV", + "class" : "Reserved", + "opcode" : 5396, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpSamplerImageAddressingModeNV", + "class" : "Reserved", + "opcode" : 5397, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Bit Width'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupShuffleINTEL", + "class" : "Group", + "opcode" : 5571, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'InvocationId'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupShuffleDownINTEL", + "class" : "Group", + "opcode" : 5572, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Next'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupShuffleUpINTEL", + "class" : "Group", + "opcode" : 5573, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Previous'" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupShuffleXorINTEL", + "class" : "Group", + "opcode" : 5574, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupBlockReadINTEL", + "class" : "Group", + "opcode" : 5575, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupBlockWriteINTEL", + "class" : "Group", + "opcode" : 5576, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupImageBlockReadINTEL", + "class" : "Group", + "opcode" : 5577, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupImageBlockWriteINTEL", + "class" : "Group", + "opcode" : 5578, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupImageMediaBlockReadINTEL", + "class" : "Group", + "opcode" : 5580, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Width'" }, + { "kind" : "IdRef", "name" : "'Height'" } + ], + "capabilities" : [ "SubgroupImageMediaBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupImageMediaBlockWriteINTEL", + "class" : "Group", + "opcode" : 5581, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Width'" }, + { "kind" : "IdRef", "name" : "'Height'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageMediaBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpUCountLeadingZerosINTEL", + "class" : "Reserved", + "opcode" : 5585, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUCountTrailingZerosINTEL", + "class" : "Reserved", + "opcode" : 5586, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpAbsISubINTEL", + "class" : "Reserved", + "opcode" : 5587, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpAbsUSubINTEL", + "class" : "Reserved", + "opcode" : 5588, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpIAddSatINTEL", + "class" : "Reserved", + "opcode" : 5589, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUAddSatINTEL", + "class" : "Reserved", + "opcode" : 5590, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpIAverageINTEL", + "class" : "Reserved", + "opcode" : 5591, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUAverageINTEL", + "class" : "Reserved", + "opcode" : 5592, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpIAverageRoundedINTEL", + "class" : "Reserved", + "opcode" : 5593, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUAverageRoundedINTEL", + "class" : "Reserved", + "opcode" : 5594, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpISubSatINTEL", + "class" : "Reserved", + "opcode" : 5595, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUSubSatINTEL", + "class" : "Reserved", + "opcode" : 5596, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpIMul32x16INTEL", + "class" : "Reserved", + "opcode" : 5597, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUMul32x16INTEL", + "class" : "Reserved", + "opcode" : 5598, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpConstantFunctionPointerINTEL", + "class" : "@exclude", + "opcode" : 5600, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" } + ], + "capabilities" : [ "FunctionPointersINTEL" ], + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "opname" : "OpFunctionPointerCallINTEL", + "class" : "@exclude", + "opcode" : 5601, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1'" } + ], + "capabilities" : [ "FunctionPointersINTEL" ], + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "opname" : "OpAsmTargetINTEL", + "class" : "@exclude", + "opcode" : 5609, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Asm target'" } + ], + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "opname" : "OpAsmINTEL", + "class" : "@exclude", + "opcode" : 5610, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Asm type'" }, + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Asm instructions'" }, + { "kind" : "LiteralString", "name" : "'Constraints'" } + ], + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "opname" : "OpAsmCallINTEL", + "class" : "@exclude", + "opcode" : 5611, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Asm'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0'" } + ], + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "opname" : "OpAtomicFMinEXT", + "class" : "Atomic", + "opcode" : 5614, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "AtomicFloat16MinMaxEXT", "AtomicFloat32MinMaxEXT", "AtomicFloat64MinMaxEXT", "AtomicFloat16VectorNV" ], + "version" : "None" + }, + { + "opname" : "OpAtomicFMaxEXT", + "class" : "Atomic", + "opcode" : 5615, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "AtomicFloat16MinMaxEXT", "AtomicFloat32MinMaxEXT", "AtomicFloat64MinMaxEXT", "AtomicFloat16VectorNV" ], + "version" : "None" + }, + { + "opname" : "OpAssumeTrueKHR", + "class" : "Miscellaneous", + "opcode" : 5630, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" } + ], + "capabilities" : [ "ExpectAssumeKHR" ], + "extensions" : [ "SPV_KHR_expect_assume" ], + "version" : "None" + }, + { + "opname" : "OpExpectKHR", + "class" : "Miscellaneous", + "opcode" : 5631, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ExpectedValue'" } + ], + "capabilities" : [ "ExpectAssumeKHR" ], + "extensions" : [ "SPV_KHR_expect_assume" ], + "version" : "None" + }, + { + "opname" : "OpDecorateString", + "class" : "Annotation", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.4" + }, + { + "opname" : "OpDecorateStringGOOGLE", + "class" : "Annotation", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.4" + }, + { + "opname" : "OpMemberDecorateString", + "class" : "Annotation", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.4" + }, + { + "opname" : "OpMemberDecorateStringGOOGLE", + "class" : "Annotation", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.4" + }, + { + "opname" : "OpVmeImageINTEL", + "class" : "@exclude", + "opcode" : 5699, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeVmeImageINTEL", + "class" : "@exclude", + "opcode" : 5700, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImePayloadINTEL", + "class" : "@exclude", + "opcode" : 5701, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcRefPayloadINTEL", + "class" : "@exclude", + "opcode" : 5702, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcSicPayloadINTEL", + "class" : "@exclude", + "opcode" : 5703, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcMcePayloadINTEL", + "class" : "@exclude", + "opcode" : 5704, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcMceResultINTEL", + "class" : "@exclude", + "opcode" : 5705, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeResultINTEL", + "class" : "@exclude", + "opcode" : 5706, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeResultSingleReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5707, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeResultDualReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5708, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeSingleReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5709, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeDualReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5710, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcRefResultINTEL", + "class" : "@exclude", + "opcode" : 5711, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcSicResultINTEL", + "class" : "@exclude", + "opcode" : 5712, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5713, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5714, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reference Base Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5715, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetInterShapePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5716, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Shape Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL", + "class" : "@exclude", + "opcode" : 5717, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL", + "class" : "@exclude", + "opcode" : 5718, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Direction Cost'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5719, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL", + "class" : "@exclude", + "opcode" : 5720, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL", + "class" : "@exclude", + "opcode" : 5721, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL", + "class" : "@exclude", + "opcode" : 5722, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL", + "class" : "@exclude", + "opcode" : 5723, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL", + "class" : "@exclude", + "opcode" : 5724, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Cost Center Delta'" }, + { "kind" : "IdRef", "name" : "'Packed Cost Table'" }, + { "kind" : "IdRef", "name" : "'Cost Precision'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5725, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL", + "class" : "@exclude", + "opcode" : 5726, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5727, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationChromaINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetAcOnlyHaarINTEL", + "class" : "@exclude", + "opcode" : 5728, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL", + "class" : "@exclude", + "opcode" : 5729, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Source Field Polarity'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL", + "class" : "@exclude", + "opcode" : 5730, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reference Field Polarity'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL", + "class" : "@exclude", + "opcode" : 5731, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Forward Reference Field Polarity'" }, + { "kind" : "IdRef", "name" : "'Backward Reference Field Polarity'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToImePayloadINTEL", + "class" : "@exclude", + "opcode" : 5732, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToImeResultINTEL", + "class" : "@exclude", + "opcode" : 5733, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToRefPayloadINTEL", + "class" : "@exclude", + "opcode" : 5734, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToRefResultINTEL", + "class" : "@exclude", + "opcode" : 5735, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToSicPayloadINTEL", + "class" : "@exclude", + "opcode" : 5736, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToSicResultINTEL", + "class" : "@exclude", + "opcode" : 5737, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetMotionVectorsINTEL", + "class" : "@exclude", + "opcode" : 5738, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterDistortionsINTEL", + "class" : "@exclude", + "opcode" : 5739, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetBestInterDistortionsINTEL", + "class" : "@exclude", + "opcode" : 5740, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterMajorShapeINTEL", + "class" : "@exclude", + "opcode" : 5741, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterMinorShapeINTEL", + "class" : "@exclude", + "opcode" : 5742, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterDirectionsINTEL", + "class" : "@exclude", + "opcode" : 5743, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterMotionVectorCountINTEL", + "class" : "@exclude", + "opcode" : 5744, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterReferenceIdsINTEL", + "class" : "@exclude", + "opcode" : 5745, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL", + "class" : "@exclude", + "opcode" : 5746, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Parameter Field Polarities'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeInitializeINTEL", + "class" : "@exclude", + "opcode" : 5747, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Coord'" }, + { "kind" : "IdRef", "name" : "'Partition Mask'" }, + { "kind" : "IdRef", "name" : "'SAD Adjustment'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetSingleReferenceINTEL", + "class" : "@exclude", + "opcode" : 5748, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ref Offset'" }, + { "kind" : "IdRef", "name" : "'Search Window Config'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetDualReferenceINTEL", + "class" : "@exclude", + "opcode" : 5749, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Offset'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Offset'" }, + { "kind" : "IdRef", "name" : "'id> Search Window Config'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeRefWindowSizeINTEL", + "class" : "@exclude", + "opcode" : 5750, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Search Window Config'" }, + { "kind" : "IdRef", "name" : "'Dual Ref'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeAdjustRefOffsetINTEL", + "class" : "@exclude", + "opcode" : 5751, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ref Offset'" }, + { "kind" : "IdRef", "name" : "'Src Coord'" }, + { "kind" : "IdRef", "name" : "'Ref Window Size'" }, + { "kind" : "IdRef", "name" : "'Image Size'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeConvertToMcePayloadINTEL", + "class" : "@exclude", + "opcode" : 5752, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL", + "class" : "@exclude", + "opcode" : 5753, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Max Motion Vector Count'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL", + "class" : "@exclude", + "opcode" : 5754, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL", + "class" : "@exclude", + "opcode" : 5755, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Threshold'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetWeightedSadINTEL", + "class" : "@exclude", + "opcode" : 5756, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Sad Weights'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL", + "class" : "@exclude", + "opcode" : 5757, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL", + "class" : "@exclude", + "opcode" : 5758, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5759, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Streamin Components'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5760, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Streamin Components'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5761, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5762, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL", + "class" : "@exclude", + "opcode" : 5763, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Streamin Components'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL", + "class" : "@exclude", + "opcode" : 5764, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Streamin Components'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeConvertToMceResultINTEL", + "class" : "@exclude", + "opcode" : 5765, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5766, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetDualReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5767, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5768, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5769, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL", + "class" : "@exclude", + "opcode" : 5770, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL", + "class" : "@exclude", + "opcode" : 5771, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL", + "class" : "@exclude", + "opcode" : 5772, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL", + "class" : "@exclude", + "opcode" : 5773, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL", + "class" : "@exclude", + "opcode" : 5774, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL", + "class" : "@exclude", + "opcode" : 5775, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetBorderReachedINTEL", + "class" : "@exclude", + "opcode" : 5776, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Select'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL", + "class" : "@exclude", + "opcode" : 5777, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL", + "class" : "@exclude", + "opcode" : 5778, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL", + "class" : "@exclude", + "opcode" : 5779, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL", + "class" : "@exclude", + "opcode" : 5780, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcFmeInitializeINTEL", + "class" : "@exclude", + "opcode" : 5781, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Coord'" }, + { "kind" : "IdRef", "name" : "'Motion Vectors'" }, + { "kind" : "IdRef", "name" : "'Major Shapes'" }, + { "kind" : "IdRef", "name" : "'Minor Shapes'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'Pixel Resolution'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcBmeInitializeINTEL", + "class" : "@exclude", + "opcode" : 5782, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Coord'" }, + { "kind" : "IdRef", "name" : "'Motion Vectors'" }, + { "kind" : "IdRef", "name" : "'Major Shapes'" }, + { "kind" : "IdRef", "name" : "'Minor Shapes'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'Pixel Resolution'" }, + { "kind" : "IdRef", "name" : "'Bidirectional Weight'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefConvertToMcePayloadINTEL", + "class" : "@exclude", + "opcode" : 5783, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL", + "class" : "@exclude", + "opcode" : 5784, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefSetBilinearFilterEnableINTEL", + "class" : "@exclude", + "opcode" : 5785, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL", + "class" : "@exclude", + "opcode" : 5786, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL", + "class" : "@exclude", + "opcode" : 5787, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL", + "class" : "@exclude", + "opcode" : 5788, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL", + "class" : "@exclude", + "opcode" : 5789, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Field Polarities'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefConvertToMceResultINTEL", + "class" : "@exclude", + "opcode" : 5790, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicInitializeINTEL", + "class" : "@exclude", + "opcode" : 5791, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Coord'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConfigureSkcINTEL", + "class" : "@exclude", + "opcode" : 5792, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Skip Block Partition Type'" }, + { "kind" : "IdRef", "name" : "'Skip Motion Vector Mask'" }, + { "kind" : "IdRef", "name" : "'Motion Vectors'" }, + { "kind" : "IdRef", "name" : "'Bidirectional Weight'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConfigureIpeLumaINTEL", + "class" : "@exclude", + "opcode" : 5793, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Luma Intra Partition Mask'" }, + { "kind" : "IdRef", "name" : "'Intra Neighbour Availabilty'" }, + { "kind" : "IdRef", "name" : "'Left Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Left Corner Luma Pixel'" }, + { "kind" : "IdRef", "name" : "'Upper Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Right Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL", + "class" : "@exclude", + "opcode" : 5794, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Luma Intra Partition Mask'" }, + { "kind" : "IdRef", "name" : "'Intra Neighbour Availabilty'" }, + { "kind" : "IdRef", "name" : "'Left Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Left Corner Luma Pixel'" }, + { "kind" : "IdRef", "name" : "'Upper Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Right Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Left Edge Chroma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Left Corner Chroma Pixel'" }, + { "kind" : "IdRef", "name" : "'Upper Edge Chroma Pixels'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationChromaINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetMotionVectorMaskINTEL", + "class" : "@exclude", + "opcode" : 5795, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Skip Block Partition Type'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConvertToMcePayloadINTEL", + "class" : "@exclude", + "opcode" : 5796, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5797, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Shape Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL", + "class" : "@exclude", + "opcode" : 5798, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Luma Mode Penalty'" }, + { "kind" : "IdRef", "name" : "'Luma Packed Neighbor Modes'" }, + { "kind" : "IdRef", "name" : "'Luma Packed Non Dc Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL", + "class" : "@exclude", + "opcode" : 5799, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Chroma Mode Base Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationChromaINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetBilinearFilterEnableINTEL", + "class" : "@exclude", + "opcode" : 5800, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL", + "class" : "@exclude", + "opcode" : 5801, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Sad Coefficients'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL", + "class" : "@exclude", + "opcode" : 5802, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Block Based Skip Type'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateIpeINTEL", + "class" : "@exclude", + "opcode" : 5803, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL", + "class" : "@exclude", + "opcode" : 5804, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL", + "class" : "@exclude", + "opcode" : 5805, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL", + "class" : "@exclude", + "opcode" : 5806, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL", + "class" : "@exclude", + "opcode" : 5807, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Field Polarities'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConvertToMceResultINTEL", + "class" : "@exclude", + "opcode" : 5808, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetIpeLumaShapeINTEL", + "class" : "@exclude", + "opcode" : 5809, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL", + "class" : "@exclude", + "opcode" : 5810, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL", + "class" : "@exclude", + "opcode" : 5811, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL", + "class" : "@exclude", + "opcode" : 5812, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetIpeChromaModeINTEL", + "class" : "@exclude", + "opcode" : 5813, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationChromaINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", + "class" : "@exclude", + "opcode" : 5814, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", + "class" : "@exclude", + "opcode" : 5815, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetInterRawSadsINTEL", + "class" : "@exclude", + "opcode" : 5816, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpVariableLengthArrayINTEL", + "class" : "@exclude", + "opcode" : 5818, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Lenght'" } + ], + "capabilities" : [ "VariableLengthArrayINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSaveMemoryINTEL", + "class" : "@exclude", + "opcode" : 5819, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "VariableLengthArrayINTEL" ], + "version" : "None" + }, + { + "opname" : "OpRestoreMemoryINTEL", + "class" : "@exclude", + "opcode" : 5820, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "VariableLengthArrayINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSinCosPiINTEL", + "class" : "@exclude", + "opcode" : 5840, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'FromSign'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCastINTEL", + "class" : "@exclude", + "opcode" : 5841, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCastFromIntINTEL", + "class" : "@exclude", + "opcode" : 5842, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'FromSign'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCastToIntINTEL", + "class" : "@exclude", + "opcode" : 5843, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatAddINTEL", + "class" : "@exclude", + "opcode" : 5846, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSubINTEL", + "class" : "@exclude", + "opcode" : 5847, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatMulINTEL", + "class" : "@exclude", + "opcode" : 5848, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatDivINTEL", + "class" : "@exclude", + "opcode" : 5849, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatGTINTEL", + "class" : "@exclude", + "opcode" : 5850, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatGEINTEL", + "class" : "@exclude", + "opcode" : 5851, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLTINTEL", + "class" : "@exclude", + "opcode" : 5852, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLEINTEL", + "class" : "@exclude", + "opcode" : 5853, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatEQINTEL", + "class" : "@exclude", + "opcode" : 5854, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatRecipINTEL", + "class" : "@exclude", + "opcode" : 5855, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatRSqrtINTEL", + "class" : "@exclude", + "opcode" : 5856, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCbrtINTEL", + "class" : "@exclude", + "opcode" : 5857, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatHypotINTEL", + "class" : "@exclude", + "opcode" : 5858, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSqrtINTEL", + "class" : "@exclude", + "opcode" : 5859, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLogINTEL", + "class" : "@exclude", + "opcode" : 5860, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLog2INTEL", + "class" : "@exclude", + "opcode" : 5861, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLog10INTEL", + "class" : "@exclude", + "opcode" : 5862, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLog1pINTEL", + "class" : "@exclude", + "opcode" : 5863, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatExpINTEL", + "class" : "@exclude", + "opcode" : 5864, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatExp2INTEL", + "class" : "@exclude", + "opcode" : 5865, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatExp10INTEL", + "class" : "@exclude", + "opcode" : 5866, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatExpm1INTEL", + "class" : "@exclude", + "opcode" : 5867, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSinINTEL", + "class" : "@exclude", + "opcode" : 5868, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCosINTEL", + "class" : "@exclude", + "opcode" : 5869, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSinCosINTEL", + "class" : "@exclude", + "opcode" : 5870, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSinPiINTEL", + "class" : "@exclude", + "opcode" : 5871, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCosPiINTEL", + "class" : "@exclude", + "opcode" : 5872, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatASinINTEL", + "class" : "@exclude", + "opcode" : 5873, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatASinPiINTEL", + "class" : "@exclude", + "opcode" : 5874, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatACosINTEL", + "class" : "@exclude", + "opcode" : 5875, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatACosPiINTEL", + "class" : "@exclude", + "opcode" : 5876, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatATanINTEL", + "class" : "@exclude", + "opcode" : 5877, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatATanPiINTEL", + "class" : "@exclude", + "opcode" : 5878, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatATan2INTEL", + "class" : "@exclude", + "opcode" : 5879, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatPowINTEL", + "class" : "@exclude", + "opcode" : 5880, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatPowRINTEL", + "class" : "@exclude", + "opcode" : 5881, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatPowNINTEL", + "class" : "@exclude", + "opcode" : 5882, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpLoopControlINTEL", + "class" : "Reserved", + "opcode" : 5887, + "operands" : [ + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Loop Control Parameters'" } + ], + "capabilities" : [ "UnstructuredLoopControlsINTEL" ], + "extensions" : [ "SPV_INTEL_unstructured_loop_controls" ], + "version" : "None" + }, + { + "opname" : "OpAliasDomainDeclINTEL", + "class" : "@exclude", + "opcode" : 5911, + "operands" : [ + { "kind" : "IdResult"}, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Name'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "opname" : "OpAliasScopeDeclINTEL", + "class" : "@exclude", + "opcode" : 5912, + "operands" : [ + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Alias Domain'"}, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Name'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "opname" : "OpAliasScopeListDeclINTEL", + "class" : "@exclude", + "opcode" : 5913, + "operands" : [ + { "kind" : "IdResult"}, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'AliasScope1, AliasScope2, ...'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "opname" : "OpFixedSqrtINTEL", + "class" : "@exclude", + "opcode" : 5923, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedRecipINTEL", + "class" : "@exclude", + "opcode" : 5924, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedRsqrtINTEL", + "class" : "@exclude", + "opcode" : 5925, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedSinINTEL", + "class" : "@exclude", + "opcode" : 5926, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedCosINTEL", + "class" : "@exclude", + "opcode" : 5927, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedSinCosINTEL", + "class" : "@exclude", + "opcode" : 5928, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedSinPiINTEL", + "class" : "@exclude", + "opcode" : 5929, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedCosPiINTEL", + "class" : "@exclude", + "opcode" : 5930, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedSinCosPiINTEL", + "class" : "@exclude", + "opcode" : 5931, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedLogINTEL", + "class" : "@exclude", + "opcode" : 5932, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedExpINTEL", + "class" : "@exclude", + "opcode" : 5933, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpPtrCastToCrossWorkgroupINTEL", + "class" : "@exclude", + "opcode" : 5934, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "USMStorageClassesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpCrossWorkgroupCastToPtrINTEL", + "class" : "@exclude", + "opcode" : 5938, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "USMStorageClassesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpReadPipeBlockingINTEL", + "class" : "Pipe", + "opcode" : 5946, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "BlockingPipesINTEL" ], + "extensions" : [ "SPV_INTEL_blocking_pipes" ], + "version" : "None" + }, + { + "opname" : "OpWritePipeBlockingINTEL", + "class" : "Pipe", + "opcode" : 5947, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "BlockingPipesINTEL" ], + "extensions" : [ "SPV_INTEL_blocking_pipes" ], + "version" : "None" + }, + { + "opname" : "OpFPGARegINTEL", + "class" : "Reserved", + "opcode" : 5949, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Result'" }, + { "kind" : "IdRef", "name" : "'Input'" } + ], + "capabilities" : [ "FPGARegINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_reg" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetRayTMinKHR", + "class" : "Reserved", + "opcode" : 6016, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetRayFlagsKHR", + "class" : "Reserved", + "opcode" : 6017, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionTKHR", + "class" : "Reserved", + "opcode" : 6018, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionInstanceCustomIndexKHR", + "class" : "Reserved", + "opcode" : 6019, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionInstanceIdKHR", + "class" : "Reserved", + "opcode" : 6020, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR", + "class" : "Reserved", + "opcode" : 6021, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionGeometryIndexKHR", + "class" : "Reserved", + "opcode" : 6022, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionPrimitiveIndexKHR", + "class" : "Reserved", + "opcode" : 6023, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionBarycentricsKHR", + "class" : "Reserved", + "opcode" : 6024, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionFrontFaceKHR", + "class" : "Reserved", + "opcode" : 6025, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR", + "class" : "Reserved", + "opcode" : 6026, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionObjectRayDirectionKHR", + "class" : "Reserved", + "opcode" : 6027, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionObjectRayOriginKHR", + "class" : "Reserved", + "opcode" : 6028, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetWorldRayDirectionKHR", + "class" : "Reserved", + "opcode" : 6029, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetWorldRayOriginKHR", + "class" : "Reserved", + "opcode" : 6030, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionObjectToWorldKHR", + "class" : "Reserved", + "opcode" : 6031, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionWorldToObjectKHR", + "class" : "Reserved", + "opcode" : 6032, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpAtomicFAddEXT", + "class" : "Atomic", + "opcode" : 6035, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "AtomicFloat16AddEXT", "AtomicFloat32AddEXT", "AtomicFloat64AddEXT", "AtomicFloat16VectorNV" ], + "extensions" : [ "SPV_EXT_shader_atomic_float_add" ], + "version" : "None" + }, + { + "opname" : "OpTypeBufferSurfaceINTEL", + "class" : "Type-Declaration", + "opcode" : 6086, + "operands" : [ + { "kind" : "IdResult" }, + { + "kind" : "AccessQualifier", + "name" : "'AccessQualifier'" + } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeStructContinuedINTEL", + "class" : "Type-Declaration", + "opcode" : 6090, + "operands" : [ + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ], + "capabilities" : [ "LongCompositesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpConstantCompositeContinuedINTEL", + "class" : "Constant-Creation", + "opcode" : 6091, + "operands" : [ + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "capabilities" : [ "LongCompositesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSpecConstantCompositeContinuedINTEL", + "class" : "Constant-Creation", + "opcode" : 6092, + "operands" : [ + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "capabilities" : [ "LongCompositesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpCompositeConstructContinuedINTEL", + "class" : "Composite", + "opcode" : 6096, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "capabilities" : [ "LongCompositesINTEL" ], + "version": "None" + }, + { + "opname" : "OpConvertFToBF16INTEL", + "class" : "Conversion", + "opcode" : 6116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ], + "capabilities" : [ "BFloat16ConversionINTEL" ], + "version" : "None" + }, + { + "opname" : "OpConvertBF16ToFINTEL", + "class" : "Conversion", + "opcode" : 6117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'BFloat16 Value'" } + ], + "capabilities" : [ "BFloat16ConversionINTEL" ], + "version" : "None" + }, + { + "opname" : "OpControlBarrierArriveINTEL", + "class" : "Barrier", + "opcode" : 6142, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "SplitBarrierINTEL" ], + "version" : "None" + }, + { + "opname" : "OpControlBarrierWaitINTEL", + "class" : "Barrier", + "opcode" : 6143, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "SplitBarrierINTEL" ], + "version" : "None" + }, + { + "opname" : "OpGroupIMulKHR", + "class" : "Group", + "opcode" : 6401, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupFMulKHR", + "class" : "Group", + "opcode" : 6402, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupBitwiseAndKHR", + "class" : "Group", + "opcode" : 6403, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupBitwiseOrKHR", + "class" : "Group", + "opcode" : 6404, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupBitwiseXorKHR", + "class" : "Group", + "opcode" : 6405, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupLogicalAndKHR", + "class" : "Group", + "opcode" : 6406, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupLogicalOrKHR", + "class" : "Group", + "opcode" : 6407, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupLogicalXorKHR", + "class" : "Group", + "opcode" : 6408, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpMaskedGatherINTEL", + "class" : "Memory", + "opcode" : 6428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'PtrVector'" }, + { "kind" : "LiteralInteger", "name" : "'Alignment'" }, + { "kind" : "IdRef", "name" : "'Mask'" }, + { "kind" : "IdRef", "name" : "'FillEmpty'" } + ], + "capabilities" : [ "MaskedGatherScatterINTEL" ], + "version" : "None" + }, + { + "opname" : "OpMaskedScatterINTEL", + "class" : "Memory", + "opcode" : 6429, + "operands" : [ + { "kind" : "IdRef", "name" : "'InputVector'" }, + { "kind" : "IdRef", "name" : "'PtrVector'" }, + { "kind" : "LiteralInteger", "name" : "'Alignment'" }, + { "kind" : "IdRef", "name" : "'Mask'" } + ], + "capabilities" : [ "MaskedGatherScatterINTEL" ], + "version" : "None" + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "ImageOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Bias", + "value" : "0x0001", + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "Lod", + "value" : "0x0002", + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "Grad", + "value" : "0x0004", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "ConstOffset", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "Offset", + "value" : "0x0010", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "ConstOffsets", + "value" : "0x0020", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "Sample", + "value" : "0x0040", + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "MinLod", + "value" : "0x0080", + "capabilities" : [ "MinLod" ], + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "MakeTexelAvailable", + "value" : "0x0100", + "capabilities" : [ "VulkanMemoryModel" ], + "parameters" : [ + { "kind" : "IdScope" } + ], + "version" : "1.5" + }, + { + "enumerant" : "MakeTexelAvailableKHR", + "value" : "0x0100", + "capabilities" : [ "VulkanMemoryModel" ], + "parameters" : [ + { "kind" : "IdScope" } + ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeTexelVisible", + "value" : "0x0200", + "capabilities" : [ "VulkanMemoryModel" ], + "parameters" : [ + { "kind" : "IdScope" } + ], + "version" : "1.5" + }, + { + "enumerant" : "MakeTexelVisibleKHR", + "value" : "0x0200", + "capabilities" : [ "VulkanMemoryModel" ], + "parameters" : [ + { "kind" : "IdScope" } + ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "NonPrivateTexel", + "value" : "0x0400", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "NonPrivateTexelKHR", + "value" : "0x0400", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "VolatileTexel", + "value" : "0x0800", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "VolatileTexelKHR", + "value" : "0x0800", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "SignExtend", + "value" : "0x1000", + "version" : "1.4" + }, + { + "enumerant" : "ZeroExtend", + "value" : "0x2000", + "version" : "1.4" + }, + { + "enumerant" : "Nontemporal", + "value" : "0x4000", + "version" : "1.6" + }, + { + "enumerant" : "Offsets", + "value" : "0x10000", + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FPFastMathMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "NotNaN", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "NotInf", + "value" : "0x0002", + "version" : "1.0" + }, + { + "enumerant" : "NSZ", + "value" : "0x0004", + "version" : "1.0" + }, + { + "enumerant" : "AllowRecip", + "value" : "0x0008", + "version" : "1.0" + }, + { + "enumerant" : "Fast", + "value" : "0x0010", + "version" : "1.0" + }, + { + "enumerant" : "AllowContract", + "value" : "0x10000", + "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AllowContractFastINTEL", + "value" : "0x10000", + "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AllowReassoc", + "value" : "0x20000", + "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AllowReassocINTEL", + "value" : "0x20000", + "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AllowTransform", + "value" : "0x40000", + "capabilities" : [ "FloatControls2" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "SelectionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Flatten", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "DontFlatten", + "value" : "0x0002", + "version" : "1.0" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "LoopControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Unroll", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "DontUnroll", + "value" : "0x0002", + "version" : "1.0" + }, + { + "enumerant" : "DependencyInfinite", + "value" : "0x0004", + "version" : "1.1" + }, + { + "enumerant" : "DependencyLength", + "value" : "0x0008", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.1" + }, + { + "enumerant" : "MinIterations", + "value" : "0x0010", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "MaxIterations", + "value" : "0x0020", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "IterationMultiple", + "value" : "0x0040", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "PeelCount", + "value" : "0x0080", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "PartialCount", + "value" : "0x0100", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "InitiationIntervalINTEL", + "value" : "0x10000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxConcurrencyINTEL", + "value" : "0x20000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "DependencyArrayINTEL", + "value" : "0x40000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "PipelineEnableINTEL", + "value" : "0x80000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "LoopCoalesceINTEL", + "value" : "0x100000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxInterleavingINTEL", + "value" : "0x200000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "SpeculatedIterationsINTEL", + "value" : "0x400000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "NoFusionINTEL", + "value" : "0x800000", + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "LoopCountINTEL", + "value" : "0x1000000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxReinvocationDelayINTEL", + "value" : "0x2000000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FunctionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Inline", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "DontInline", + "value" : "0x0002", + "version" : "1.0" + }, + { + "enumerant" : "Pure", + "value" : "0x0004", + "version" : "1.0" + }, + { + "enumerant" : "Const", + "value" : "0x0008", + "version" : "1.0" + }, + { + "enumerant" : "OptNoneINTEL", + "value" : "0x10000", + "capabilities" : [ "OptNoneINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemorySemantics", + "enumerants" : [ + { + "enumerant" : "Relaxed", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Acquire", + "value" : "0x0002", + "version" : "1.0" + }, + { + "enumerant" : "Release", + "value" : "0x0004", + "version" : "1.0" + }, + { + "enumerant" : "AcquireRelease", + "value" : "0x0008", + "version" : "1.0" + }, + { + "enumerant" : "SequentiallyConsistent", + "value" : "0x0010", + "version" : "1.0" + }, + { + "enumerant" : "UniformMemory", + "value" : "0x0040", + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupMemory", + "value" : "0x0080", + "version" : "1.0" + }, + { + "enumerant" : "WorkgroupMemory", + "value" : "0x0100", + "version" : "1.0" + }, + { + "enumerant" : "CrossWorkgroupMemory", + "value" : "0x0200", + "version" : "1.0" + }, + { + "enumerant" : "AtomicCounterMemory", + "value" : "0x0400", + "capabilities" : [ "AtomicStorage" ], + "version": "1.0" + }, + { + "enumerant" : "ImageMemory", + "value" : "0x0800", + "version" : "1.0" + }, + { + "enumerant" : "OutputMemory", + "value" : "0x1000", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "OutputMemoryKHR", + "value" : "0x1000", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeAvailable", + "value" : "0x2000", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeAvailableKHR", + "value" : "0x2000", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeVisible", + "value" : "0x4000", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeVisibleKHR", + "value" : "0x4000", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "Volatile", + "value" : "0x8000", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemoryAccess", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Volatile", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "Aligned", + "value" : "0x0002", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.0" + }, + { + "enumerant" : "Nontemporal", + "value" : "0x0004", + "version" : "1.0" + }, + { + "enumerant" : "MakePointerAvailable", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdScope" } + ], + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "MakePointerAvailableKHR", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdScope" } + ], + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "MakePointerVisible", + "value" : "0x0010", + "parameters" : [ + { "kind" : "IdScope" } + ], + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "MakePointerVisibleKHR", + "value" : "0x0010", + "parameters" : [ + { "kind" : "IdScope" } + ], + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "NonPrivatePointer", + "value" : "0x0020", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "NonPrivatePointerKHR", + "value" : "0x0020", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "AliasScopeINTELMask", + "value" : "0x10000", + "parameters" : [ + { "kind" : "IdRef" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "enumerant" : "NoAliasINTELMask", + "parameters" : [ + { "kind" : "IdRef" } + ], + "value" : "0x20000", + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "KernelProfilingInfo", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "CmdExecTime", + "value" : "0x0001", + "capabilities" : [ "Kernel" ], + "version": "1.0" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "RayFlags", + "enumerants" : [ + { + "enumerant" : "NoneKHR", + "value" : "0x0000", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "OpaqueKHR", + "value" : "0x0001", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "NoOpaqueKHR", + "value" : "0x0002", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "TerminateOnFirstHitKHR", + "value" : "0x0004", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "SkipClosestHitShaderKHR", + "value" : "0x0008", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CullBackFacingTrianglesKHR", + "value" : "0x0010", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CullFrontFacingTrianglesKHR", + "value" : "0x0020", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CullOpaqueKHR", + "value" : "0x0040", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CullNoOpaqueKHR", + "value" : "0x0080", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "SkipTrianglesKHR", + "value" : "0x0100", + "capabilities" : [ "RayTraversalPrimitiveCullingKHR" ], + "version" : "None" + }, + { + "enumerant" : "SkipAABBsKHR", + "value" : "0x0200", + "capabilities" : [ "RayTraversalPrimitiveCullingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ForceOpacityMicromap2StateEXT", + "value" : "0x0400", + "capabilities" : [ "RayTracingOpacityMicromapEXT" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FragmentShadingRate", + "enumerants" : [ + { + "enumerant" : "Vertical2Pixels", + "value" : "0x0001", + "capabilities" : [ "FragmentShadingRateKHR" ], + "version" : "None" + }, + { + "enumerant" : "Vertical4Pixels", + "value" : "0x0002", + "capabilities" : [ "FragmentShadingRateKHR" ], + "version" : "None" + }, + { + "enumerant" : "Horizontal2Pixels", + "value" : "0x0004", + "capabilities" : [ "FragmentShadingRateKHR" ], + "version" : "None" + }, + { + "enumerant" : "Horizontal4Pixels", + "value" : "0x0008", + "capabilities" : [ "FragmentShadingRateKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SourceLanguage", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "ESSL", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "GLSL", + "value" : 2, + "version" : "1.0" + }, + { + "enumerant" : "OpenCL_C", + "value" : 3, + "version" : "1.0" + }, + { + "enumerant" : "OpenCL_CPP", + "value" : 4, + "version" : "1.0" + }, + { + "enumerant" : "HLSL", + "value" : 5, + "version" : "1.0" + }, + { + "enumerant" : "CPP_for_OpenCL", + "value" : 6, + "version" : "1.0" + }, + { + "enumerant" : "SYCL", + "value" : 7, + "version" : "1.0" + }, + { + "enumerant" : "HERO_C", + "value" : 8, + "version" : "1.0" + }, + { + "enumerant" : "NZSL", + "value" : 9, + "version" : "1.0" + }, + { + "enumerant" : "WGSL", + "value" : 10, + "version" : "1.0" + }, + { + "enumerant" : "Slang", + "value" : 11, + "version" : "1.0" + }, + { + "enumerant" : "Zig", + "value" : 12, + "version" : "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionModel", + "enumerants" : [ + { + "enumerant" : "Vertex", + "value" : 0, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "TessellationControl", + "value" : 1, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "TessellationEvaluation", + "value" : 2, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Geometry", + "value" : 3, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "Fragment", + "value" : 4, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GLCompute", + "value" : 5, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Kernel", + "value" : 6, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "TaskNV", + "value" : 5267, + "capabilities" : [ "MeshShadingNV" ], + "version" : "None" + }, + { + "enumerant" : "MeshNV", + "value" : 5268, + "capabilities" : [ "MeshShadingNV" ], + "version" : "None" + }, + { + "enumerant" : "RayGenerationNV", + "value" : 5313, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayGenerationKHR", + "value" : 5313, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IntersectionNV", + "value" : 5314, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IntersectionKHR", + "value" : 5314, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "AnyHitNV", + "value" : 5315, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "AnyHitKHR", + "value" : 5315, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ClosestHitNV", + "value" : 5316, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ClosestHitKHR", + "value" : 5316, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "MissNV", + "value" : 5317, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "MissKHR", + "value" : 5317, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableNV", + "value" : 5318, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableKHR", + "value" : 5318, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "TaskEXT", + "value" : 5364, + "capabilities" : [ "MeshShadingEXT" ], + "version" : "None" + }, + { + "enumerant" : "MeshEXT", + "value" : 5365, + "capabilities" : [ "MeshShadingEXT" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AddressingModel", + "enumerants" : [ + { + "enumerant" : "Logical", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Physical32", + "value" : 1, + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "enumerant" : "Physical64", + "value" : 2, + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "enumerant" : "PhysicalStorageBuffer64", + "value" : 5348, + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "version" : "1.5" + }, + { + "enumerant" : "PhysicalStorageBuffer64EXT", + "value" : 5348, + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "version" : "1.5" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "MemoryModel", + "enumerants" : [ + { + "enumerant" : "Simple", + "value" : 0, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GLSL450", + "value" : 1, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "OpenCL", + "value" : 2, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Vulkan", + "value" : 3, + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "VulkanKHR", + "value" : 3, + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionMode", + "enumerants" : [ + { + "enumerant" : "Invocations", + "value" : 0, + "capabilities" : [ "Geometry" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of <>'" } + ], + "version": "1.0" + }, + { + "enumerant" : "SpacingEqual", + "value" : 1, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "SpacingFractionalEven", + "value" : 2, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "SpacingFractionalOdd", + "value" : 3, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "VertexOrderCw", + "value" : 4, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "VertexOrderCcw", + "value" : 5, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "PixelCenterInteger", + "value" : 6, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "OriginUpperLeft", + "value" : 7, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "OriginLowerLeft", + "value" : 8, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "EarlyFragmentTests", + "value" : 9, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "PointMode", + "value" : 10, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Xfb", + "value" : 11, + "capabilities" : [ "TransformFeedback" ], + "version": "1.0" + }, + { + "enumerant" : "DepthReplacing", + "value" : 12, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "DepthGreater", + "value" : 14, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "DepthLess", + "value" : 15, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "DepthUnchanged", + "value" : 16, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "LocalSize", + "value" : 17, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ], + "version": "1.0" + }, + { + "enumerant" : "LocalSizeHint", + "value" : 18, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ], + "version": "1.0" + }, + { + "enumerant" : "InputPoints", + "value" : 19, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "InputLines", + "value" : 20, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "InputLinesAdjacency", + "value" : 21, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "Triangles", + "value" : 22, + "capabilities" : [ "Geometry", "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "InputTrianglesAdjacency", + "value" : 23, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "Quads", + "value" : 24, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Isolines", + "value" : 25, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "OutputVertices", + "value" : 26, + "capabilities" : [ "Geometry", "Tessellation", "MeshShadingNV", "MeshShadingEXT" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vertex count'" } + ], + "version": "1.0" + }, + { + "enumerant" : "OutputPoints", + "value" : 27, + "capabilities" : [ "Geometry", "MeshShadingNV", "MeshShadingEXT" ], + "version": "1.0" + }, + { + "enumerant" : "OutputLineStrip", + "value" : 28, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "OutputTriangleStrip", + "value" : 29, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "VecTypeHint", + "value" : 30, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vector type'" } + ], + "version": "1.0" + }, + { + "enumerant" : "ContractionOff", + "value" : 31, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Initializer", + "value" : 33, + "capabilities" : [ "Kernel" ], + "version" : "1.1" + }, + { + "enumerant" : "Finalizer", + "value" : 34, + "capabilities" : [ "Kernel" ], + "version" : "1.1" + }, + { + "enumerant" : "SubgroupSize", + "value" : 35, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroup Size'" } + ], + "version" : "1.1" + }, + { + "enumerant" : "SubgroupsPerWorkgroup", + "value" : 36, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroups Per Workgroup'" } + ], + "version" : "1.1" + }, + { + "enumerant" : "SubgroupsPerWorkgroupId", + "value" : 37, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Subgroups Per Workgroup'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "LocalSizeId", + "value" : 38, + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size'" }, + { "kind" : "IdRef", "name" : "'y size'" }, + { "kind" : "IdRef", "name" : "'z size'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "LocalSizeHintId", + "value" : 39, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size hint'" }, + { "kind" : "IdRef", "name" : "'y size hint'" }, + { "kind" : "IdRef", "name" : "'z size hint'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "NonCoherentColorAttachmentReadEXT", + "value" : 4169, + "capabilities" : [ "TileImageColorReadAccessEXT" ], + "version" : "None" + }, + { + "enumerant" : "NonCoherentDepthAttachmentReadEXT", + "value" : 4170, + "capabilities" : [ "TileImageDepthReadAccessEXT" ], + "version" : "None" + }, + { + "enumerant" : "NonCoherentStencilAttachmentReadEXT", + "value" : 4171, + "capabilities" : [ "TileImageStencilReadAccessEXT" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupUniformControlFlowKHR", + "value" : 4421, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_subgroup_uniform_control_flow" ], + "version" : "None" + }, + { + "enumerant" : "PostDepthCoverage", + "value" : 4446, + "capabilities" : [ "SampleMaskPostDepthCoverage" ], + "extensions" : [ "SPV_KHR_post_depth_coverage" ], + "version" : "None" + }, + { + "enumerant" : "DenormPreserve", + "value" : 4459, + "capabilities" : [ "DenormPreserve" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "DenormFlushToZero", + "value" : 4460, + "capabilities" : [ "DenormFlushToZero" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "SignedZeroInfNanPreserve", + "value" : 4461, + "capabilities" : [ "SignedZeroInfNanPreserve" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "RoundingModeRTE", + "value" : 4462, + "capabilities" : [ "RoundingModeRTE" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "RoundingModeRTZ", + "value" : 4463, + "capabilities" : [ "RoundingModeRTZ" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant": "EarlyAndLateFragmentTestsAMD", + "value": 5017, + "capabilities": [ "Shader" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests" ], + "version": "None" + }, + { + "enumerant" : "StencilRefReplacingEXT", + "value" : 5027, + "capabilities" : [ "StencilExportEXT" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ], + "version" : "None" + }, + { + "enumerant" : "CoalescingAMDX", + "value" : 5069, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "MaxNodeRecursionAMDX", + "value" : 5071, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Number of recursions'" } + ], + "version" : "None" + }, + { + "enumerant" : "StaticNumWorkgroupsAMDX", + "value" : 5072, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size'" }, + { "kind" : "IdRef", "name" : "'y size'" }, + { "kind" : "IdRef", "name" : "'z size'" } + ], + "version" : "None" + }, + { + "enumerant" : "ShaderIndexAMDX", + "value" : 5073, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Shader Index'" } + ], + "version" : "None" + }, + { + "enumerant" : "MaxNumWorkgroupsAMDX", + "value" : 5077, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size'" }, + { "kind" : "IdRef", "name" : "'y size'" }, + { "kind" : "IdRef", "name" : "'z size'" } + ], + "version" : "None" + }, + { + "enumerant": "StencilRefUnchangedFrontAMD", + "value": 5079, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefGreaterFrontAMD", + "value": 5080, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefLessFrontAMD", + "value": 5081, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefUnchangedBackAMD", + "value": 5082, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefGreaterBackAMD", + "value": 5083, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefLessBackAMD", + "value": 5084, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "QuadDerivativesKHR", + "value": 5088, + "capabilities": [ "QuadControlKHR" ], + "version": "None" + }, + { + "enumerant" : "RequireFullQuadsKHR", + "value" : 5089, + "capabilities" : [ "QuadControlKHR" ], + "version" : "None" + }, + { + "enumerant" : "OutputLinesNV", + "value" : 5269, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputLinesEXT", + "value" : 5269, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputPrimitivesNV", + "value" : 5270, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Primitive count'" } + ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputPrimitivesEXT", + "value" : 5270, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Primitive count'" } + ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "DerivativeGroupQuadsNV", + "value" : 5289, + "capabilities" : [ "ComputeDerivativeGroupQuadsNV" ], + "extensions" : [ "SPV_NV_compute_shader_derivatives" ], + "version" : "None" + }, + { + "enumerant" : "DerivativeGroupLinearNV", + "value" : 5290, + "capabilities" : [ "ComputeDerivativeGroupLinearNV" ], + "extensions" : [ "SPV_NV_compute_shader_derivatives" ], + "version" : "None" + }, + { + "enumerant" : "OutputTrianglesNV", + "value" : 5298, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputTrianglesEXT", + "value" : 5298, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PixelInterlockOrderedEXT", + "value" : 5366, + "capabilities" : [ "FragmentShaderPixelInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "PixelInterlockUnorderedEXT", + "value" : 5367, + "capabilities" : [ "FragmentShaderPixelInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "SampleInterlockOrderedEXT", + "value" : 5368, + "capabilities" : [ "FragmentShaderSampleInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "SampleInterlockUnorderedEXT", + "value" : 5369, + "capabilities" : [ "FragmentShaderSampleInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "ShadingRateInterlockOrderedEXT", + "value" : 5370, + "capabilities" : [ "FragmentShaderShadingRateInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "ShadingRateInterlockUnorderedEXT", + "value" : 5371, + "capabilities" : [ "FragmentShaderShadingRateInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "SharedLocalMemorySizeINTEL", + "value" : 5618, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RoundingModeRTPINTEL", + "value" : 5620, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "capabilities" : [ "RoundToInfinityINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RoundingModeRTNINTEL", + "value" : 5621, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "capabilities" : [ "RoundToInfinityINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FloatingPointModeALTINTEL", + "value" : 5622, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "capabilities" : [ "RoundToInfinityINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FloatingPointModeIEEEINTEL", + "value" : 5623, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "capabilities" : [ "RoundToInfinityINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxWorkgroupSizeINTEL", + "value" : 5893, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'max_x_size'" }, + { "kind" : "LiteralInteger", "name" : "'max_y_size'" }, + { "kind" : "LiteralInteger", "name" : "'max_z_size'" } + ], + "capabilities" : [ "KernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MaxWorkDimINTEL", + "value" : 5894, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'max_dimensions'" } + ], + "capabilities" : [ "KernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "NoGlobalOffsetINTEL", + "value" : 5895, + "capabilities" : [ "KernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "NumSIMDWorkitemsINTEL", + "value" : 5896, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'vector_width'" } + ], + "capabilities" : [ "FPGAKernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "SchedulerTargetFmaxMhzINTEL", + "value" : 5903, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'target_fmax'" } + ], + "capabilities" : [ "FPGAKernelAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaximallyReconvergesKHR", + "value" : 6023, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_maximal_reconvergence" ], + "version" : "None" + }, + { + "enumerant" : "FPFastMathDefault", + "value" : 6028, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Target Type'" }, + { "kind" : "IdRef", "name" : "'Fast-Math Mode'" } + ], + "capabilities" : [ "FloatControls2" ], + "version" : "None" + }, + { + "enumerant" : "StreamingInterfaceINTEL", + "value" : 6154, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'StallFreeReturn'" } + ], + "capabilities" : [ "FPGAKernelAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RegisterMapInterfaceINTEL", + "value" : 6160, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'WaitForDoneWrite'" } + ], + "capabilities" : [ "FPGAKernelAttributesv2INTEL" ], + "version" : "None" + }, + { + "enumerant" : "NamedBarrierCountINTEL", + "value" : 6417, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Barrier Count'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaximumRegistersINTEL", + "value" : 6461, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaximumRegistersIdINTEL", + "value" : 6462, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "NamedMaximumRegistersINTEL", + "value" : 6463, + "parameters" : [ + { "kind" : "NamedMaximumNumberOfRegisters", "name" : "'Named Maximum Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StorageClass", + "enumerants" : [ + { + "enumerant" : "UniformConstant", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Input", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "Uniform", + "value" : 2, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Output", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Workgroup", + "value" : 4, + "version" : "1.0" + }, + { + "enumerant" : "CrossWorkgroup", + "value" : 5, + "version" : "1.0" + }, + { + "enumerant" : "Private", + "value" : 6, + "capabilities" : [ "Shader", "VectorComputeINTEL" ], + "version": "1.0" + }, + { + "enumerant" : "Function", + "value" : 7, + "version" : "1.0" + }, + { + "enumerant" : "Generic", + "value" : 8, + "capabilities" : [ "GenericPointer" ], + "version": "1.0" + }, + { + "enumerant" : "PushConstant", + "value" : 9, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "AtomicCounter", + "value" : 10, + "capabilities" : [ "AtomicStorage" ], + "version": "1.0" + }, + { + "enumerant" : "Image", + "value" : 11, + "version" : "1.0" + }, + { + "enumerant" : "StorageBuffer", + "value" : 12, + "extensions" : [ + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers" + ], + "capabilities" : [ "Shader" ], + "version" : "1.3" + }, + { + "enumerant" : "TileImageEXT", + "value" : 4172, + "capabilities" : [ "TileImageColorReadAccessEXT" ], + "version" : "None" + }, + { + "enumerant" : "NodePayloadAMDX", + "value" : 5068, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "NodeOutputPayloadAMDX", + "value" : 5076, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "CallableDataNV", + "value" : 5328, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableDataKHR", + "value" : 5328, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IncomingCallableDataNV", + "value" : 5329, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IncomingCallableDataKHR", + "value" : 5329, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayPayloadNV", + "value" : 5338, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayPayloadKHR", + "value" : 5338, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "HitAttributeNV", + "value" : 5339, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "HitAttributeKHR", + "value" : 5339, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayPayloadNV", + "value" : 5342, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayPayloadKHR", + "value" : 5342, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ShaderRecordBufferNV", + "value" : 5343, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ShaderRecordBufferKHR", + "value" : 5343, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "PhysicalStorageBuffer", + "value" : 5349, + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "version" : "1.5" + }, + { + "enumerant" : "PhysicalStorageBufferEXT", + "value" : 5349, + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "version" : "1.5" + }, + { + "enumerant" : "HitObjectAttributeNV", + "value" : 5385, + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "enumerant" : "TaskPayloadWorkgroupEXT", + "value" : 5402, + "extensions" : [ "SPV_EXT_mesh_shader" ], + "capabilities" : [ "MeshShadingEXT" ], + "version" : "1.4" + }, + { + "enumerant" : "CodeSectionINTEL", + "value" : 5605, + "extensions" : [ "SPV_INTEL_function_pointers" ], + "capabilities" : [ "FunctionPointersINTEL" ], + "version" : "None" + }, + { + "enumerant" : "DeviceOnlyINTEL", + "value" : 5936, + "extensions" : [ + "SPV_INTEL_usm_storage_classes" + ], + "capabilities" : [ "USMStorageClassesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "HostOnlyINTEL", + "value" : 5937, + "extensions" : [ + "SPV_INTEL_usm_storage_classes" + ], + "capabilities" : [ "USMStorageClassesINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Dim", + "enumerants" : [ + { + "enumerant" : "1D", + "value" : 0, + "capabilities" : [ "Sampled1D" ], + "version": "1.0" + }, + { + "enumerant" : "2D", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "3D", + "value" : 2, + "version" : "1.0" + }, + { + "enumerant" : "Cube", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rect", + "value" : 4, + "capabilities" : [ "SampledRect" ], + "version": "1.0" + }, + { + "enumerant" : "Buffer", + "value" : 5, + "capabilities" : [ "SampledBuffer" ], + "version": "1.0" + }, + { + "enumerant" : "SubpassData", + "value" : 6, + "capabilities" : [ "InputAttachment" ], + "version": "1.0" + }, + { + "enumerant" : "TileImageDataEXT", + "value" : 4173, + "capabilities" : [ "TileImageColorReadAccessEXT" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerAddressingMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : 0, + "version": "1.0" + }, + { + "enumerant" : "ClampToEdge", + "value" : 1, + "version": "1.0" + }, + { + "enumerant" : "Clamp", + "value" : 2, + "version": "1.0" + }, + { + "enumerant" : "Repeat", + "value" : 3, + "version": "1.0" + }, + { + "enumerant" : "RepeatMirrored", + "value" : 4, + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerFilterMode", + "enumerants" : [ + { + "enumerant" : "Nearest", + "value" : 0, + "version": "1.0" + }, + { + "enumerant" : "Linear", + "value" : 1, + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageFormat", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Rgba32f", + "value" : 1, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16f", + "value" : 2, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "R32f", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba8", + "value" : 4, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba8Snorm", + "value" : 5, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rg32f", + "value" : 6, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16f", + "value" : 7, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R11fG11fB10f", + "value" : 8, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16f", + "value" : 9, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16", + "value" : 10, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgb10A2", + "value" : 11, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16", + "value" : 12, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg8", + "value" : 13, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16", + "value" : 14, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R8", + "value" : 15, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16Snorm", + "value" : 16, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16Snorm", + "value" : 17, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg8Snorm", + "value" : 18, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16Snorm", + "value" : 19, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R8Snorm", + "value" : 20, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba32i", + "value" : 21, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16i", + "value" : 22, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba8i", + "value" : 23, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "R32i", + "value" : 24, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rg32i", + "value" : 25, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16i", + "value" : 26, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg8i", + "value" : 27, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16i", + "value" : 28, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R8i", + "value" : 29, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba32ui", + "value" : 30, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16ui", + "value" : 31, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba8ui", + "value" : 32, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "R32ui", + "value" : 33, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgb10a2ui", + "value" : 34, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg32ui", + "value" : 35, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16ui", + "value" : 36, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg8ui", + "value" : 37, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16ui", + "value" : 38, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R8ui", + "value" : 39, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R64ui", + "value" : 40, + "capabilities" : [ "Int64ImageEXT" ], + "version": "1.0" + }, + { + "enumerant" : "R64i", + "value" : 41, + "capabilities" : [ "Int64ImageEXT" ], + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelOrder", + "enumerants" : [ + { + "enumerant" : "R", + "value" : 0, + "version": "1.0" + }, + { + "enumerant" : "A", + "value" : 1, + "version": "1.0" + }, + { + "enumerant" : "RG", + "value" : 2, + "version": "1.0" + }, + { + "enumerant" : "RA", + "value" : 3, + "version": "1.0" + }, + { + "enumerant" : "RGB", + "value" : 4, + "version": "1.0" + }, + { + "enumerant" : "RGBA", + "value" : 5, + "version": "1.0" + }, + { + "enumerant" : "BGRA", + "value" : 6, + "version": "1.0" + }, + { + "enumerant" : "ARGB", + "value" : 7, + "version": "1.0" + }, + { + "enumerant" : "Intensity", + "value" : 8, + "version": "1.0" + }, + { + "enumerant" : "Luminance", + "value" : 9, + "version": "1.0" + }, + { + "enumerant" : "Rx", + "value" : 10, + "version": "1.0" + }, + { + "enumerant" : "RGx", + "value" : 11, + "version": "1.0" + }, + { + "enumerant" : "RGBx", + "value" : 12, + "version": "1.0" + }, + { + "enumerant" : "Depth", + "value" : 13, + "version": "1.0" + }, + { + "enumerant" : "DepthStencil", + "value" : 14, + "version": "1.0" + }, + { + "enumerant" : "sRGB", + "value" : 15, + "version": "1.0" + }, + { + "enumerant" : "sRGBx", + "value" : 16, + "version": "1.0" + }, + { + "enumerant" : "sRGBA", + "value" : 17, + "version": "1.0" + }, + { + "enumerant" : "sBGRA", + "value" : 18, + "version": "1.0" + }, + { + "enumerant" : "ABGR", + "value" : 19, + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelDataType", + "enumerants" : [ + { + "enumerant" : "SnormInt8", + "value" : 0, + "version": "1.0" + }, + { + "enumerant" : "SnormInt16", + "value" : 1, + "version": "1.0" + }, + { + "enumerant" : "UnormInt8", + "value" : 2, + "version": "1.0" + }, + { + "enumerant" : "UnormInt16", + "value" : 3, + "version": "1.0" + }, + { + "enumerant" : "UnormShort565", + "value" : 4, + "version": "1.0" + }, + { + "enumerant" : "UnormShort555", + "value" : 5, + "version": "1.0" + }, + { + "enumerant" : "UnormInt101010", + "value" : 6, + "version": "1.0" + }, + { + "enumerant" : "SignedInt8", + "value" : 7, + "version": "1.0" + }, + { + "enumerant" : "SignedInt16", + "value" : 8, + "version": "1.0" + }, + { + "enumerant" : "SignedInt32", + "value" : 9, + "version": "1.0" + }, + { + "enumerant" : "UnsignedInt8", + "value" : 10, + "version": "1.0" + }, + { + "enumerant" : "UnsignedInt16", + "value" : 11, + "version": "1.0" + }, + { + "enumerant" : "UnsignedInt32", + "value" : 12, + "version": "1.0" + }, + { + "enumerant" : "HalfFloat", + "value" : 13, + "version": "1.0" + }, + { + "enumerant" : "Float", + "value" : 14, + "version": "1.0" + }, + { + "enumerant" : "UnormInt24", + "value" : 15, + "version": "1.0" + }, + { + "enumerant" : "UnormInt101010_2", + "value" : 16, + "version": "1.0" + }, + { + "enumerant" : "UnsignedIntRaw10EXT", + "value" : 19, + "version": "1.0" + }, + { + "enumerant" : "UnsignedIntRaw12EXT", + "value" : 20, + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPRoundingMode", + "enumerants" : [ + { + "enumerant" : "RTE", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "RTZ", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "RTP", + "value" : 2, + "version" : "1.0" + }, + { + "enumerant" : "RTN", + "value" : 3, + "version" : "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPDenormMode", + "enumerants" : [ + { + "enumerant" : "Preserve", + "value" : 0, + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FlushToZero", + "value" : 1, + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "QuantizationModes", + "enumerants" : [ + { + "enumerant" : "TRN", + "value" : 0, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "TRN_ZERO", + "value" : 1, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND", + "value" : 2, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_ZERO", + "value" : 3, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_INF", + "value" : 4, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_MIN_INF", + "value" : 5, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_CONV", + "value" : 6, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_CONV_ODD", + "value" : 7, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPOperationMode", + "enumerants" : [ + { + "enumerant" : "IEEE", + "value" : 0, + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ALT", + "value" : 1, + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "OverflowModes", + "enumerants" : [ + { + "enumerant" : "WRAP", + "value" : 0, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "SAT", + "value" : 1, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "SAT_ZERO", + "value" : 2, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "SAT_SYM", + "value" : 3, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LinkageType", + "enumerants" : [ + { + "enumerant" : "Export", + "value" : 0, + "capabilities" : [ "Linkage" ], + "version": "1.0" + }, + { + "enumerant" : "Import", + "value" : 1, + "capabilities" : [ "Linkage" ], + "version": "1.0" + }, + { + "enumerant" : "LinkOnceODR", + "value" : 2, + "capabilities" : [ "Linkage" ], + "extensions" : [ "SPV_KHR_linkonce_odr" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AccessQualifier", + "enumerants" : [ + { + "enumerant" : "ReadOnly", + "value" : 0, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "WriteOnly", + "value" : 1, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "ReadWrite", + "value" : 2, + "capabilities" : [ "Kernel" ], + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "HostAccessQualifier", + "enumerants" : [ + { + "enumerant" : "NoneINTEL", + "value" : 0, + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ReadINTEL", + "value" : 1, + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + }, + { + "enumerant" : "WriteINTEL", + "value" : 2, + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ReadWriteINTEL", + "value" : 3, + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FunctionParameterAttribute", + "enumerants" : [ + { + "enumerant" : "Zext", + "value" : 0, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Sext", + "value" : 1, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "ByVal", + "value" : 2, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Sret", + "value" : 3, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NoAlias", + "value" : 4, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NoCapture", + "value" : 5, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NoWrite", + "value" : 6, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NoReadWrite", + "value" : 7, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "RuntimeAlignedINTEL", + "value" : 5940, + "capabilities" : [ "RuntimeAlignedAttributeINTEL" ], + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Decoration", + "enumerants" : [ + { + "enumerant" : "RelaxedPrecision", + "value" : 0, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SpecId", + "value" : 1, + "capabilities" : [ "Shader", "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Block", + "value" : 2, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "BufferBlock", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0", + "lastVersion" : "1.3" + }, + { + "enumerant" : "RowMajor", + "value" : 4, + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "enumerant" : "ColMajor", + "value" : 5, + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "enumerant" : "ArrayStride", + "value" : 6, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Array Stride'" } + ], + "version": "1.0" + }, + { + "enumerant" : "MatrixStride", + "value" : 7, + "capabilities" : [ "Matrix" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Matrix Stride'" } + ], + "version": "1.0" + }, + { + "enumerant" : "GLSLShared", + "value" : 8, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GLSLPacked", + "value" : 9, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "CPacked", + "value" : 10, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "BuiltIn", + "value" : 11, + "parameters" : [ + { "kind" : "BuiltIn" } + ], + "version": "1.0" + }, + { + "enumerant" : "NoPerspective", + "value" : 13, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Flat", + "value" : 14, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Patch", + "value" : 15, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Centroid", + "value" : 16, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Sample", + "value" : 17, + "capabilities" : [ "SampleRateShading" ], + "version": "1.0" + }, + { + "enumerant" : "Invariant", + "value" : 18, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Restrict", + "value" : 19, + "version" : "1.0" + }, + { + "enumerant" : "Aliased", + "value" : 20, + "version" : "1.0" + }, + { + "enumerant" : "Volatile", + "value" : 21, + "version" : "1.0" + }, + { + "enumerant" : "Constant", + "value" : 22, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Coherent", + "value" : 23, + "version": "1.0" + }, + { + "enumerant" : "NonWritable", + "value" : 24, + "version": "1.0" + }, + { + "enumerant" : "NonReadable", + "value" : 25, + "version": "1.0" + }, + { + "enumerant" : "Uniform", + "value" : 26, + "capabilities" : [ "Shader", "UniformDecoration" ], + "version": "1.0" + }, + { + "enumerant" : "UniformId", + "value" : 27, + "capabilities" : [ "Shader", "UniformDecoration" ], + "parameters" : [ + { "kind" : "IdScope", "name" : "'Execution'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "SaturatedConversion", + "value" : 28, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Stream", + "value" : 29, + "capabilities" : [ "GeometryStreams" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stream Number'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Location", + "value" : 30, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Location'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Component", + "value" : 31, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Component'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Index", + "value" : 32, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Index'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Binding", + "value" : 33, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Binding Point'" } + ], + "version": "1.0" + }, + { + "enumerant" : "DescriptorSet", + "value" : 34, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Descriptor Set'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Offset", + "value" : 35, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Byte Offset'" } + ], + "version": "1.0" + }, + { + "enumerant" : "XfbBuffer", + "value" : 36, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" } + ], + "version": "1.0" + }, + { + "enumerant" : "XfbStride", + "value" : 37, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Stride'" } + ], + "version": "1.0" + }, + { + "enumerant" : "FuncParamAttr", + "value" : 38, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" } + ], + "version": "1.0" + }, + { + "enumerant" : "FPRoundingMode", + "value" : 39, + "parameters" : [ + { "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" } + ], + "version": "1.0" + }, + { + "enumerant" : "FPFastMathMode", + "value" : 40, + "capabilities" : [ "Kernel", "FloatControls2" ], + "parameters" : [ + { "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" } + ], + "version": "1.0" + }, + { + "enumerant" : "LinkageAttributes", + "value" : 41, + "capabilities" : [ "Linkage" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "LinkageType", "name" : "'Linkage Type'" } + ], + "version": "1.0" + }, + { + "enumerant" : "NoContraction", + "value" : 42, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "InputAttachmentIndex", + "value" : 43, + "capabilities" : [ "InputAttachment" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Attachment Index'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Alignment", + "value" : 44, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Alignment'" } + ], + "version": "1.0" + }, + { + "enumerant" : "MaxByteOffset", + "value" : 45, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Max Byte Offset'" } + ], + "version" : "1.1" + }, + { + "enumerant" : "AlignmentId", + "value" : 46, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Alignment'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "MaxByteOffsetId", + "value" : 47, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Max Byte Offset'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "NoSignedWrap", + "value" : 4469, + "extensions" : [ "SPV_KHR_no_integer_wrap_decoration" ], + "version" : "1.4" + }, + { + "enumerant" : "NoUnsignedWrap", + "value" : 4470, + "extensions" : [ "SPV_KHR_no_integer_wrap_decoration" ], + "version" : "1.4" + }, + { + "enumerant" : "WeightTextureQCOM", + "value" : 4487, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "BlockMatchTextureQCOM", + "value" : 4488, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "BlockMatchSamplerQCOM", + "value" : 4499, + "extensions" : [ "SPV_QCOM_image_processing2" ], + "version" : "None" + }, + { + "enumerant" : "ExplicitInterpAMD", + "value" : 4999, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "NodeSharesPayloadLimitsWithAMDX", + "value" : 5019, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Payload Array'" } + ], + "version" : "None" + }, + { + "enumerant" : "NodeMaxPayloadsAMDX", + "value" : 5020, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Max number of payloads'" } + ], + "version" : "None" + }, + { + "enumerant" : "TrackFinishWritingAMDX", + "value" : 5078, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "PayloadNodeNameAMDX", + "value" : 5091, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Node Name'" } + ], + "version" : "None" + }, + { + "enumerant" : "OverrideCoverageNV", + "value" : 5248, + "capabilities" : [ "SampleMaskOverrideCoverageNV" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ], + "version" : "None" + }, + { + "enumerant" : "PassthroughNV", + "value" : 5250, + "capabilities" : [ "GeometryShaderPassthroughNV" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ], + "version" : "None" + }, + { + "enumerant" : "ViewportRelativeNV", + "value" : 5252, + "capabilities" : [ "ShaderViewportMaskNV" ], + "version" : "None" + }, + { + "enumerant" : "SecondaryViewportRelativeNV", + "value" : 5256, + "capabilities" : [ "ShaderStereoViewNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ], + "version" : "None", + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ] + }, + { + "enumerant" : "PerPrimitiveNV", + "value" : 5271, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerPrimitiveEXT", + "value" : 5271, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerViewNV", + "value" : 5272, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerTaskNV", + "value" : 5273, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerVertexKHR", + "value" : 5285, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "PerVertexNV", + "value" : 5285, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "NonUniform", + "value" : 5300, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "NonUniformEXT", + "value" : 5300, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "RestrictPointer", + "value" : 5355, + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "RestrictPointerEXT", + "value" : 5355, + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "AliasedPointer", + "value" : 5356, + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "AliasedPointerEXT", + "value" : 5356, + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "HitObjectShaderRecordBufferNV", + "value" : 5386, + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "enumerant" : "BindlessSamplerNV", + "value" : 5398, + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "enumerant" : "BindlessImageNV", + "value" : 5399, + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "enumerant" : "BoundSamplerNV", + "value" : 5400, + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "enumerant" : "BoundImageNV", + "value" : 5401, + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "enumerant" : "SIMTCallINTEL", + "value" : 5599, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'N'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ReferencedIndirectlyINTEL", + "value" : 5602, + "capabilities" : [ "IndirectReferencesINTEL" ], + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "enumerant" : "ClobberINTEL", + "value" : 5607, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Register'" } + ], + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "enumerant" : "SideEffectsINTEL", + "value" : 5608, + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "enumerant" : "VectorComputeVariableINTEL", + "value" : 5624, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FuncParamIOKindINTEL", + "value" : 5625, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Kind'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "VectorComputeFunctionINTEL", + "value" : 5626, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StackCallINTEL", + "value" : 5627, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "GlobalVariableOffsetINTEL", + "value" : 5628, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "CounterBuffer", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "HlslCounterBufferGOOGLE", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "None" + }, + { + "enumerant" : "UserSemantic", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "HlslSemanticGOOGLE", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "None" + }, + { + "enumerant" : "UserTypeGOOGLE", + "value" : 5636, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'User Type'" } + ], + "extensions" : [ "SPV_GOOGLE_user_type" ], + "version" : "None" + }, + { + "enumerant" : "FunctionRoundingModeINTEL", + "value" : 5822, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" }, + { "kind" : "FPRoundingMode", "name" : "'FP Rounding Mode'" } + ], + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FunctionDenormModeINTEL", + "value" : 5823, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" }, + { "kind" : "FPDenormMode", "name" : "'FP Denorm Mode'" } + ], + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RegisterINTEL", + "value" : 5825, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MemoryINTEL", + "value" : 5826, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Memory Type'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "NumbanksINTEL", + "value" : 5827, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Banks'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "BankwidthINTEL", + "value" : 5828, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Bank Width'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MaxPrivateCopiesINTEL", + "value" : 5829, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Maximum Copies'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "SinglepumpINTEL", + "value" : 5830, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "DoublepumpINTEL", + "value" : 5831, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MaxReplicatesINTEL", + "value" : 5832, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Maximum Replicates'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "SimpleDualPortINTEL", + "value" : 5833, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MergeINTEL", + "value" : 5834, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Merge Key'" }, + { "kind" : "LiteralString", "name" : "'Merge Type'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "BankBitsINTEL", + "value" : 5835, + "parameters" : [ + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Bank Bits'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "ForcePow2DepthINTEL", + "value" : 5836, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Force Key'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "StridesizeINTEL", + "value" : 5883, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stride Size'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "WordsizeINTEL", + "value" : 5884, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Word Size'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "TrueDualPortINTEL", + "value" : 5885, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "BurstCoalesceINTEL", + "value" : 5899, + "capabilities" : [ "FPGAMemoryAccessesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "CacheSizeINTEL", + "value" : 5900, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Cache Size in bytes'" } + ], + "capabilities" : [ "FPGAMemoryAccessesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "DontStaticallyCoalesceINTEL", + "value" : 5901, + "capabilities" : [ "FPGAMemoryAccessesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "PrefetchINTEL", + "value" : 5902, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Prefetcher Size in bytes'" } + ], + "capabilities" : [ "FPGAMemoryAccessesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StallEnableINTEL", + "value" : 5905, + "capabilities" : [ "FPGAClusterAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FuseLoopsInFunctionINTEL", + "value" : 5907, + "capabilities" : [ "LoopFuseINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MathOpDSPModeINTEL", + "value" : 5909, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Mode'" }, + { "kind" : "LiteralInteger", "name" : "'Propagate'" } + ], + "capabilities" : [ "FPGADSPControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AliasScopeINTEL", + "value" : 5914, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Aliasing Scopes List'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "version" : "None" + }, + { + "enumerant" : "NoAliasINTEL", + "value" : 5915, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Aliasing Scopes List'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "version" : "None" + }, + { + "enumerant" : "InitiationIntervalINTEL", + "value" : 5917, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Cycles'" } + ], + "capabilities" : [ "FPGAInvocationPipeliningAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxConcurrencyINTEL", + "value" : 5918, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Invocations'" } + ], + "capabilities" : [ "FPGAInvocationPipeliningAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "PipelineEnableINTEL", + "value" : 5919, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Enable'" } + ], + "capabilities" : [ "FPGAInvocationPipeliningAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "BufferLocationINTEL", + "value" : 5921, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Buffer Location ID'" } + ], + "capabilities" : [ "FPGABufferLocationINTEL" ], + "version" : "None" + }, + { + "enumerant" : "IOPipeStorageINTEL", + "value" : 5944, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'IO Pipe ID'" } + ], + "capabilities" : [ "IOPipesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FunctionFloatingPointModeINTEL", + "value" : 6080, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" }, + { "kind" : "FPOperationMode", "name" : "'FP Operation Mode'" } + ], + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "SingleElementVectorINTEL", + "value" : 6085, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "VectorComputeCallableFunctionINTEL", + "value" : 6087, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MediaBlockIOINTEL", + "value" : 6140, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StallFreeINTEL", + "value" : 6151, + "capabilities" : [ "FPGAClusterAttributesV2INTEL" ], + "version" : "None" + }, + { + "enumerant" : "FPMaxErrorDecorationINTEL", + "value" : 6170, + "parameters" : [ + { "kind" : "LiteralFloat", "name" : "'Max Error'" } + ], + "capabilities" : [ "FPMaxErrorINTEL" ], + "version" : "None" + }, + { + "enumerant" : "LatencyControlLabelINTEL", + "value" : 6172, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Latency Label'" } + ], + "capabilities" : [ "FPGALatencyControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "LatencyControlConstraintINTEL", + "value" : 6173, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Relative To'" }, + { "kind" : "LiteralInteger", "name" : "'Control Type'" }, + { "kind" : "LiteralInteger", "name" : "'Relative Cycle'" } + ], + "capabilities" : [ "FPGALatencyControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ConduitKernelArgumentINTEL", + "value" : 6175, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RegisterMapKernelArgumentINTEL", + "value" : 6176, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceAddressWidthINTEL", + "value" : 6177, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'AddressWidth'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceDataWidthINTEL", + "value" : 6178, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'DataWidth'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceLatencyINTEL", + "value" : 6179, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Latency'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceReadWriteModeINTEL", + "value" : 6180, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "AccessQualifier", "name" : "'ReadWriteMode'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceMaxBurstINTEL", + "value" : 6181, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'MaxBurstCount'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceWaitRequestINTEL", + "value" : 6182, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Waitrequest'" } + ], + "version" : "None" + }, + { + "enumerant" : "StableKernelArgumentINTEL", + "value" : 6183, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "HostAccessINTEL", + "value" : 6188, + "parameters": [ + { "kind" : "HostAccessQualifier", "name" : "'Access'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + }, + { + "enumerant" : "InitModeINTEL", + "value" : 6190, + "parameters": [ + { "kind" : "InitializationModeQualifier", "name" : "'Trigger'" } + ], + "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ImplementInRegisterMapINTEL", + "value" : 6191, + "parameters": [ + { "kind" : "LiteralInteger", "name" : "Value" } + ], + "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "CacheControlLoadINTEL", + "value" : 6442, + "capabilities" : [ "CacheControlsINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Cache Level'" }, + { "kind" : "LoadCacheControl", "name" : "'Cache Control'" } + ], + "version" : "None" + }, + { + "enumerant" : "CacheControlStoreINTEL", + "value" : 6443, + "capabilities" : [ "CacheControlsINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Cache Level'" }, + { "kind" : "StoreCacheControl", "name" : "'Cache Control'" } + ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "BuiltIn", + "enumerants" : [ + { + "enumerant" : "Position", + "value" : 0, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "PointSize", + "value" : 1, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ClipDistance", + "value" : 3, + "capabilities" : [ "ClipDistance" ], + "version": "1.0" + }, + { + "enumerant" : "CullDistance", + "value" : 4, + "capabilities" : [ "CullDistance" ], + "version": "1.0" + }, + { + "enumerant" : "VertexId", + "value" : 5, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "InstanceId", + "value" : 6, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "PrimitiveId", + "value" : 7, + "capabilities" : [ "Geometry", "Tessellation", "RayTracingNV", "RayTracingKHR", "MeshShadingNV", "MeshShadingEXT" ], + "version": "1.0" + }, + { + "enumerant" : "InvocationId", + "value" : 8, + "capabilities" : [ "Geometry", "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Layer", + "value" : 9, + "capabilities" : [ "Geometry", "ShaderLayer", "ShaderViewportIndexLayerEXT", "MeshShadingNV", "MeshShadingEXT" ], + "version": "1.0" + }, + { + "enumerant" : "ViewportIndex", + "value" : 10, + "capabilities" : [ "MultiViewport", "ShaderViewportIndex", "ShaderViewportIndexLayerEXT", "MeshShadingNV", "MeshShadingEXT" ], + "version": "1.0" + }, + { + "enumerant" : "TessLevelOuter", + "value" : 11, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "TessLevelInner", + "value" : 12, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "TessCoord", + "value" : 13, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "PatchVertices", + "value" : 14, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "FragCoord", + "value" : 15, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "PointCoord", + "value" : 16, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "FrontFacing", + "value" : 17, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SampleId", + "value" : 18, + "capabilities" : [ "SampleRateShading" ], + "version": "1.0" + }, + { + "enumerant" : "SamplePosition", + "value" : 19, + "capabilities" : [ "SampleRateShading" ], + "version": "1.0" + }, + { + "enumerant" : "SampleMask", + "value" : 20, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "FragDepth", + "value" : 22, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "HelperInvocation", + "value" : 23, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "NumWorkgroups", + "value" : 24, + "version" : "1.0" + }, + { + "enumerant" : "WorkgroupSize", + "value" : 25, + "version" : "1.0" + }, + { + "enumerant" : "WorkgroupId", + "value" : 26, + "version" : "1.0" + }, + { + "enumerant" : "LocalInvocationId", + "value" : 27, + "version" : "1.0" + }, + { + "enumerant" : "GlobalInvocationId", + "value" : 28, + "version" : "1.0" + }, + { + "enumerant" : "LocalInvocationIndex", + "value" : 29, + "version" : "1.0" + }, + { + "enumerant" : "WorkDim", + "value" : 30, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "GlobalSize", + "value" : 31, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "EnqueuedWorkgroupSize", + "value" : 32, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "GlobalOffset", + "value" : 33, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "GlobalLinearId", + "value" : 34, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupSize", + "value" : 36, + "capabilities" : [ "Kernel", "GroupNonUniform", "SubgroupBallotKHR" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupMaxSize", + "value" : 37, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NumSubgroups", + "value" : 38, + "capabilities" : [ "Kernel", "GroupNonUniform" ], + "version": "1.0" + }, + { + "enumerant" : "NumEnqueuedSubgroups", + "value" : 39, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupId", + "value" : 40, + "capabilities" : [ "Kernel", "GroupNonUniform" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupLocalInvocationId", + "value" : 41, + "capabilities" : [ "Kernel", "GroupNonUniform", "SubgroupBallotKHR" ], + "version": "1.0" + }, + { + "enumerant" : "VertexIndex", + "value" : 42, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "InstanceIndex", + "value" : 43, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "CoreIDARM", + "value" : 4160, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "CoreCountARM", + "value" : 4161, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "CoreMaxIDARM", + "value" : 4162, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "WarpIDARM", + "value" : 4163, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "WarpMaxIDARM", + "value" : 4164, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupEqMask", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupEqMaskKHR", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupGeMask", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupGeMaskKHR", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupGtMask", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupGtMaskKHR", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupLeMask", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupLeMaskKHR", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupLtMask", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupLtMaskKHR", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "BaseVertex", + "value" : 4424, + "capabilities" : [ "DrawParameters" ], + "extensions" : [ "SPV_KHR_shader_draw_parameters" ], + "version" : "1.3" + }, + { + "enumerant" : "BaseInstance", + "value" : 4425, + "capabilities" : [ "DrawParameters" ], + "extensions" : [ "SPV_KHR_shader_draw_parameters" ], + "version" : "1.3" + }, + { + "enumerant" : "DrawIndex", + "value" : 4426, + "capabilities" : [ "DrawParameters", "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_KHR_shader_draw_parameters", "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "1.3" + }, + { + "enumerant" : "PrimitiveShadingRateKHR", + "value" : 4432, + "capabilities" : [ "FragmentShadingRateKHR" ], + "extensions" : [ "SPV_KHR_fragment_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "DeviceIndex", + "value" : 4438, + "capabilities" : [ "DeviceGroup" ], + "extensions" : [ "SPV_KHR_device_group" ], + "version" : "1.3" + }, + { + "enumerant" : "ViewIndex", + "value" : 4440, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_KHR_multiview" ], + "version" : "1.3" + }, + { + "enumerant" : "ShadingRateKHR", + "value" : 4444, + "capabilities" : [ "FragmentShadingRateKHR" ], + "extensions" : [ "SPV_KHR_fragment_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspAMD", + "value" : 4992, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspCentroidAMD", + "value" : 4993, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspSampleAMD", + "value" : 4994, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordSmoothAMD", + "value" : 4995, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordSmoothCentroidAMD", + "value" : 4996, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordSmoothSampleAMD", + "value" : 4997, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordPullModelAMD", + "value" : 4998, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "FragStencilRefEXT", + "value" : 5014, + "capabilities" : [ "StencilExportEXT" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ], + "version" : "None" + }, + { + "enumerant" : "CoalescedInputCountAMDX", + "value" : 5021, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "ShaderIndexAMDX", + "value" : 5073, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "ViewportMaskNV", + "value" : 5253, + "capabilities" : [ "ShaderViewportMaskNV", "MeshShadingNV" ], + "extensions" : [ "SPV_NV_viewport_array2", "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "SecondaryPositionNV", + "value" : 5257, + "capabilities" : [ "ShaderStereoViewNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ], + "version" : "None" + }, + { + "enumerant" : "SecondaryViewportMaskNV", + "value" : 5258, + "capabilities" : [ "ShaderStereoViewNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ], + "version" : "None" + }, + { + "enumerant" : "PositionPerViewNV", + "value" : 5261, + "capabilities" : [ "PerViewAttributesNV", "MeshShadingNV" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes", "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "ViewportMaskPerViewNV", + "value" : 5262, + "capabilities" : [ "PerViewAttributesNV", "MeshShadingNV" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes", "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "FullyCoveredEXT", + "value" : 5264, + "capabilities" : [ "FragmentFullyCoveredEXT" ], + "extensions" : [ "SPV_EXT_fragment_fully_covered" ], + "version" : "None" + }, + { + "enumerant" : "TaskCountNV", + "value" : 5274, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PrimitiveCountNV", + "value" : 5275, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PrimitiveIndicesNV", + "value" : 5276, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "ClipDistancePerViewNV", + "value" : 5277, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "CullDistancePerViewNV", + "value" : 5278, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "LayerPerViewNV", + "value" : 5279, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "MeshViewCountNV", + "value" : 5280, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "MeshViewIndicesNV", + "value" : 5281, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordKHR", + "value" : 5286, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNV", + "value" : 5286, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspKHR", + "value" : 5287, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspNV", + "value" : 5287, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "FragSizeEXT", + "value" : 5292 , + "capabilities" : [ "FragmentDensityEXT", "ShadingRateNV" ], + "extensions" : [ "SPV_EXT_fragment_invocation_density", "SPV_NV_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "FragmentSizeNV", + "value" : 5292 , + "capabilities" : [ "ShadingRateNV", "FragmentDensityEXT" ], + "extensions" : [ "SPV_NV_shading_rate", "SPV_EXT_fragment_invocation_density" ], + "version" : "None" + }, + { + "enumerant" : "FragInvocationCountEXT", + "value" : 5293, + "capabilities" : [ "FragmentDensityEXT", "ShadingRateNV" ], + "extensions" : [ "SPV_EXT_fragment_invocation_density", "SPV_NV_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "InvocationsPerPixelNV", + "value" : 5293, + "capabilities" : [ "ShadingRateNV", "FragmentDensityEXT" ], + "extensions" : [ "SPV_NV_shading_rate", "SPV_EXT_fragment_invocation_density" ], + "version" : "None" + }, + { + "enumerant" : "PrimitivePointIndicesEXT", + "value" : 5294, + "capabilities" : [ "MeshShadingEXT" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PrimitiveLineIndicesEXT", + "value" : 5295, + "capabilities" : [ "MeshShadingEXT" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PrimitiveTriangleIndicesEXT", + "value" : 5296, + "capabilities" : [ "MeshShadingEXT" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "CullPrimitiveEXT", + "value" : 5299, + "capabilities" : [ "MeshShadingEXT" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "LaunchIdNV", + "value" : 5319, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "LaunchIdKHR", + "value" : 5319, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "LaunchSizeNV", + "value" : 5320, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "LaunchSizeKHR", + "value" : 5320, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldRayOriginNV", + "value" : 5321, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldRayOriginKHR", + "value" : 5321, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldRayDirectionNV", + "value" : 5322, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldRayDirectionKHR", + "value" : 5322, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectRayOriginNV", + "value" : 5323, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectRayOriginKHR", + "value" : 5323, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectRayDirectionNV", + "value" : 5324, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectRayDirectionKHR", + "value" : 5324, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTminNV", + "value" : 5325, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTminKHR", + "value" : 5325, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTmaxNV", + "value" : 5326, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTmaxKHR", + "value" : 5326, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "InstanceCustomIndexNV", + "value" : 5327, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "InstanceCustomIndexKHR", + "value" : 5327, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectToWorldNV", + "value" : 5330, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectToWorldKHR", + "value" : 5330, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldToObjectNV", + "value" : 5331, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldToObjectKHR", + "value" : 5331, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "HitTNV", + "value" : 5332, + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "HitKindNV", + "value" : 5333, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "HitKindKHR", + "value" : 5333, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "CurrentRayTimeNV", + "value" : 5334, + "capabilities" : [ "RayTracingMotionBlurNV" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, + { + "enumerant" : "HitTriangleVertexPositionsKHR", + "value" : 5335, + "capabilities" : [ "RayTracingPositionFetchKHR" ], + "version" : "None" + }, + { + "enumerant" : "HitMicroTriangleVertexPositionsNV", + "value" : 5337, + "capabilities" : [ "RayTracingDisplacementMicromapNV" ], + "version" : "None" + }, + { + "enumerant" : "HitMicroTriangleVertexBarycentricsNV", + "value" : 5344, + "capabilities" : [ "RayTracingDisplacementMicromapNV" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayFlagsNV", + "value" : 5351, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayFlagsKHR", + "value" : 5351, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayGeometryIndexKHR", + "value" : 5352, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WarpsPerSMNV", + "value" : 5374, + "capabilities" : [ "ShaderSMBuiltinsNV" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "SMCountNV", + "value" : 5375, + "capabilities" : [ "ShaderSMBuiltinsNV" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "WarpIDNV", + "value" : 5376, + "capabilities" : [ "ShaderSMBuiltinsNV" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "SMIDNV", + "value" : 5377, + "capabilities" : [ "ShaderSMBuiltinsNV" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "HitKindFrontFacingMicroTriangleNV", + "value" : 5405, + "capabilities" : [ "RayTracingDisplacementMicromapNV" ], + "version" : "None" + }, + { + "enumerant" : "HitKindBackFacingMicroTriangleNV", + "value" : 5406, + "capabilities" : [ "RayTracingDisplacementMicromapNV" ], + "version" : "None" + }, + { + "enumerant" : "CullMaskKHR", + "value" : 6021, + "capabilities" : [ "RayCullMaskKHR" ], + "extensions" : [ "SPV_KHR_ray_cull_mask" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Scope", + "enumerants" : [ + { + "enumerant" : "CrossDevice", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Device", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "Workgroup", + "value" : 2, + "version" : "1.0" + }, + { + "enumerant" : "Subgroup", + "value" : 3, + "version" : "1.0" + }, + { + "enumerant" : "Invocation", + "value" : 4, + "version" : "1.0" + }, + { + "enumerant" : "QueueFamily", + "value" : 5, + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "QueueFamilyKHR", + "value" : 5, + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "ShaderCallKHR", + "value" : 6, + "capabilities" : [ "RayTracingKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "GroupOperation", + "enumerants" : [ + { + "enumerant" : "Reduce", + "value" : 0, + "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ], + "version": "1.0" + }, + { + "enumerant" : "InclusiveScan", + "value" : 1, + "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ], + "version": "1.0" + }, + { + "enumerant" : "ExclusiveScan", + "value" : 2, + "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ], + "version": "1.0" + }, + { + "enumerant" : "ClusteredReduce", + "value" : 3, + "capabilities" : [ "GroupNonUniformClustered" ], + "version" : "1.3" + }, + { + "enumerant" : "PartitionedReduceNV", + "value" : 6, + "capabilities" : [ "GroupNonUniformPartitionedNV" ], + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + }, + { + "enumerant" : "PartitionedInclusiveScanNV", + "value" : 7, + "capabilities" : [ "GroupNonUniformPartitionedNV" ], + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + }, + { + "enumerant" : "PartitionedExclusiveScanNV", + "value" : 8, + "capabilities" : [ "GroupNonUniformPartitionedNV" ], + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "KernelEnqueueFlags", + "enumerants" : [ + { + "enumerant" : "NoWait", + "value" : 0, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "WaitKernel", + "value" : 1, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "WaitWorkGroup", + "value" : 2, + "capabilities" : [ "Kernel" ], + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Capability", + "enumerants" : [ + { + "enumerant" : "Matrix", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Shader", + "value" : 1, + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "enumerant" : "Geometry", + "value" : 2, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Tessellation", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Addresses", + "value" : 4, + "version" : "1.0" + }, + { + "enumerant" : "Linkage", + "value" : 5, + "version" : "1.0" + }, + { + "enumerant" : "Kernel", + "value" : 6, + "version" : "1.0" + }, + { + "enumerant" : "Vector16", + "value" : 7, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Float16Buffer", + "value" : 8, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Float16", + "value" : 9, + "version" : "1.0" + }, + { + "enumerant" : "Float64", + "value" : 10, + "version" : "1.0" + }, + { + "enumerant" : "Int64", + "value" : 11, + "version" : "1.0" + }, + { + "enumerant" : "Int64Atomics", + "value" : 12, + "capabilities" : [ "Int64" ], + "version": "1.0" + }, + { + "enumerant" : "ImageBasic", + "value" : 13, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "ImageReadWrite", + "value" : 14, + "capabilities" : [ "ImageBasic" ], + "version": "1.0" + }, + { + "enumerant" : "ImageMipmap", + "value" : 15, + "capabilities" : [ "ImageBasic" ], + "version": "1.0" + }, + { + "enumerant" : "Pipes", + "value" : 17, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Groups", + "value" : 18, + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version": "1.0" + }, + { + "enumerant" : "DeviceEnqueue", + "value" : 19, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "LiteralSampler", + "value" : 20, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "AtomicStorage", + "value" : 21, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Int16", + "value" : 22, + "version" : "1.0" + }, + { + "enumerant" : "TessellationPointSize", + "value" : 23, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "GeometryPointSize", + "value" : 24, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "ImageGatherExtended", + "value" : 25, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageMultisample", + "value" : 27, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "UniformBufferArrayDynamicIndexing", + "value" : 28, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SampledImageArrayDynamicIndexing", + "value" : 29, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageBufferArrayDynamicIndexing", + "value" : 30, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageArrayDynamicIndexing", + "value" : 31, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ClipDistance", + "value" : 32, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "CullDistance", + "value" : 33, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ImageCubeArray", + "value" : 34, + "capabilities" : [ "SampledCubeArray" ], + "version": "1.0" + }, + { + "enumerant" : "SampleRateShading", + "value" : 35, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ImageRect", + "value" : 36, + "capabilities" : [ "SampledRect" ], + "version": "1.0" + }, + { + "enumerant" : "SampledRect", + "value" : 37, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GenericPointer", + "value" : 38, + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "enumerant" : "Int8", + "value" : 39, + "version" : "1.0" + }, + { + "enumerant" : "InputAttachment", + "value" : 40, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SparseResidency", + "value" : 41, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "MinLod", + "value" : 42, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Sampled1D", + "value" : 43, + "version" : "1.0" + }, + { + "enumerant" : "Image1D", + "value" : 44, + "capabilities" : [ "Sampled1D" ], + "version": "1.0" + }, + { + "enumerant" : "SampledCubeArray", + "value" : 45, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SampledBuffer", + "value" : 46, + "version" : "1.0" + }, + { + "enumerant" : "ImageBuffer", + "value" : 47, + "capabilities" : [ "SampledBuffer" ], + "version": "1.0" + }, + { + "enumerant" : "ImageMSArray", + "value" : 48, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageExtendedFormats", + "value" : 49, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ImageQuery", + "value" : 50, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "DerivativeControl", + "value" : 51, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "InterpolationFunction", + "value" : 52, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "TransformFeedback", + "value" : 53, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GeometryStreams", + "value" : 54, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageReadWithoutFormat", + "value" : 55, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageWriteWithoutFormat", + "value" : 56, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "MultiViewport", + "value" : 57, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupDispatch", + "value" : 58, + "capabilities" : [ "DeviceEnqueue" ], + "version" : "1.1" + }, + { + "enumerant" : "NamedBarrier", + "value" : 59, + "capabilities" : [ "Kernel" ], + "version" : "1.1" + }, + { + "enumerant" : "PipeStorage", + "value" : 60, + "capabilities" : [ "Pipes" ], + "version" : "1.1" + }, + { + "enumerant" : "GroupNonUniform", + "value" : 61, + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformVote", + "value" : 62, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformArithmetic", + "value" : 63, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformBallot", + "value" : 64, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformShuffle", + "value" : 65, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformShuffleRelative", + "value" : 66, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformClustered", + "value" : 67, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformQuad", + "value" : 68, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "ShaderLayer", + "value" : 69, + "version" : "1.5" + }, + { + "enumerant" : "ShaderViewportIndex", + "value" : 70, + "version" : "1.5" + }, + { + "enumerant" : "UniformDecoration", + "value" : 71, + "version" : "1.6" + }, + { + "enumerant" : "CoreBuiltinsARM", + "value" : 4165, + "extensions" : [ "SPV_ARM_core_builtins" ], + "version": "None" + }, + { + "enumerant" : "TileImageColorReadAccessEXT", + "value" : 4166, + "extensions" : [ "SPV_EXT_shader_tile_image" ], + "version" : "None" + }, + { + "enumerant" : "TileImageDepthReadAccessEXT", + "value" : 4167, + "extensions" : [ "SPV_EXT_shader_tile_image" ], + "version" : "None" + }, + { + "enumerant" : "TileImageStencilReadAccessEXT", + "value" : 4168, + "extensions" : [ "SPV_EXT_shader_tile_image" ], + "version" : "None" + }, + { + "enumerant" : "FragmentShadingRateKHR", + "value" : 4422, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_fragment_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupBallotKHR", + "value" : 4423, + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "None" + }, + { + "enumerant" : "DrawParameters", + "value" : 4427, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_shader_draw_parameters" ], + "version" : "1.3" + }, + { + "enumerant" : "WorkgroupMemoryExplicitLayoutKHR", + "value" : 4428, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_workgroup_memory_explicit_layout" ], + "version" : "None" + }, + { + "enumerant" : "WorkgroupMemoryExplicitLayout8BitAccessKHR", + "value" : 4429, + "capabilities" : [ "WorkgroupMemoryExplicitLayoutKHR" ], + "extensions" : [ "SPV_KHR_workgroup_memory_explicit_layout" ], + "version" : "None" + }, + { + "enumerant" : "WorkgroupMemoryExplicitLayout16BitAccessKHR", + "value" : 4430, + "capabilities" : [ "WorkgroupMemoryExplicitLayoutKHR" ], + "extensions" : [ "SPV_KHR_workgroup_memory_explicit_layout" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupVoteKHR", + "value" : 4431, + "extensions" : [ "SPV_KHR_subgroup_vote" ], + "version" : "None" + }, + { + "enumerant" : "StorageBuffer16BitAccess", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "StorageUniformBufferBlock16", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "UniformAndStorageBuffer16BitAccess", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "StorageUniform16", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "StoragePushConstant16", + "value" : 4435, + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "StorageInputOutput16", + "value" : 4436, + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "DeviceGroup", + "value" : 4437, + "extensions" : [ "SPV_KHR_device_group" ], + "version" : "1.3" + }, + { + "enumerant" : "MultiView", + "value" : 4439, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_multiview" ], + "version" : "1.3" + }, + { + "enumerant" : "VariablePointersStorageBuffer", + "value" : 4441, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_variable_pointers" ], + "version" : "1.3" + }, + { + "enumerant" : "VariablePointers", + "value" : 4442, + "capabilities" : [ "VariablePointersStorageBuffer" ], + "extensions" : [ "SPV_KHR_variable_pointers" ], + "version" : "1.3" + }, + { + "enumerant" : "AtomicStorageOps", + "value" : 4445, + "extensions" : [ "SPV_KHR_shader_atomic_counter_ops" ], + "version" : "None" + }, + { + "enumerant" : "SampleMaskPostDepthCoverage", + "value" : 4447, + "extensions" : [ "SPV_KHR_post_depth_coverage" ], + "version" : "None" + }, + { + "enumerant" : "StorageBuffer8BitAccess", + "value" : 4448, + "extensions" : [ "SPV_KHR_8bit_storage" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformAndStorageBuffer8BitAccess", + "value" : 4449, + "capabilities" : [ "StorageBuffer8BitAccess" ], + "extensions" : [ "SPV_KHR_8bit_storage" ], + "version" : "1.5" + }, + { + "enumerant" : "StoragePushConstant8", + "value" : 4450, + "extensions" : [ "SPV_KHR_8bit_storage" ], + "version" : "1.5" + }, + { + "enumerant" : "DenormPreserve", + "value" : 4464, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "DenormFlushToZero", + "value" : 4465, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "SignedZeroInfNanPreserve", + "value" : 4466, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "RoundingModeRTE", + "value" : 4467, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "RoundingModeRTZ", + "value" : 4468, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "RayQueryProvisionalKHR", + "value" : 4471, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryKHR", + "value" : 4472, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "enumerant" : "RayTraversalPrimitiveCullingKHR", + "value" : 4478, + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_query","SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingKHR", + "value" : 4479, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "TextureSampleWeightedQCOM", + "value" : 4484, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "TextureBoxFilterQCOM", + "value" : 4485, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "TextureBlockMatchQCOM", + "value" : 4486, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "TextureBlockMatch2QCOM", + "value" : 4498, + "extensions" : [ "SPV_QCOM_image_processing2" ], + "version" : "None" + }, + { + "enumerant" : "Float16ImageAMD", + "value" : 5008, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_gpu_shader_half_float_fetch" ], + "version" : "None" + }, + { + "enumerant" : "ImageGatherBiasLodAMD", + "value" : 5009, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_texture_gather_bias_lod" ], + "version" : "None" + }, + { + "enumerant" : "FragmentMaskAMD", + "value" : 5010, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ], + "version" : "None" + }, + { + "enumerant" : "StencilExportEXT", + "value" : 5013, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ], + "version" : "None" + }, + { + "enumerant" : "ImageReadWriteLodAMD", + "value" : 5015, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_image_load_store_lod" ], + "version" : "None" + }, + { + "enumerant" : "Int64ImageEXT", + "value" : 5016, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_image_int64" ], + "version" : "None" + }, + { + "enumerant" : "ShaderClockKHR", + "value" : 5055, + "extensions" : [ "SPV_KHR_shader_clock" ], + "version" : "None" + }, + { + "enumerant" : "ShaderEnqueueAMDX", + "value" : 5067, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMDX_shader_enqueue" ], + "version" : "None" + }, + { + "enumerant" : "QuadControlKHR", + "value" : 5087, + "extensions" : [ "SPV_KHR_quad_control" ], + "version" : "None" + }, + { + "enumerant" : "SampleMaskOverrideCoverageNV", + "value" : 5249, + "capabilities" : [ "SampleRateShading" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ], + "version" : "None" + }, + { + "enumerant" : "GeometryShaderPassthroughNV", + "value" : 5251, + "capabilities" : [ "Geometry" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ], + "version" : "None" + }, + { + "enumerant" : "ShaderViewportIndexLayerEXT", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_EXT_shader_viewport_index_layer" ], + "version" : "None" + }, + { + "enumerant" : "ShaderViewportIndexLayerNV", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_NV_viewport_array2" ], + "version" : "None" + }, + { + "enumerant" : "ShaderViewportMaskNV", + "value" : 5255, + "capabilities" : [ "ShaderViewportIndexLayerNV" ], + "extensions" : [ "SPV_NV_viewport_array2" ], + "version" : "None" + }, + { + "enumerant" : "ShaderStereoViewNV", + "value" : 5259, + "capabilities" : [ "ShaderViewportMaskNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ], + "version" : "None" + }, + { + "enumerant" : "PerViewAttributesNV", + "value" : 5260, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FragmentFullyCoveredEXT", + "value" : 5265, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_fully_covered" ], + "version" : "None" + }, + { + "enumerant" : "MeshShadingNV", + "value" : 5266, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "ImageFootprintNV", + "value" : 5282, + "extensions" : [ "SPV_NV_shader_image_footprint" ], + "version" : "None" + }, + { + "enumerant" : "MeshShadingEXT", + "value" : 5283, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "FragmentBarycentricKHR", + "value" : 5284, + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "FragmentBarycentricNV", + "value" : 5284, + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "ComputeDerivativeGroupQuadsNV", + "value" : 5288, + "extensions" : [ "SPV_NV_compute_shader_derivatives" ], + "version" : "None" + }, + { + "enumerant" : "FragmentDensityEXT", + "value" : 5291, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_invocation_density", "SPV_NV_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "ShadingRateNV", + "value" : 5291, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_shading_rate", "SPV_EXT_fragment_invocation_density" ], + "version" : "None" + }, + { + "enumerant" : "GroupNonUniformPartitionedNV", + "value" : 5297, + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + }, + { + "enumerant" : "ShaderNonUniform", + "value" : 5301, + "capabilities" : [ "Shader" ], + "version" : "1.5" + }, + { + "enumerant" : "ShaderNonUniformEXT", + "value" : 5301, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "RuntimeDescriptorArray", + "value" : 5302, + "capabilities" : [ "Shader" ], + "version" : "1.5" + }, + { + "enumerant" : "RuntimeDescriptorArrayEXT", + "value" : 5302, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "InputAttachmentArrayDynamicIndexing", + "value" : 5303, + "capabilities" : [ "InputAttachment" ], + "version" : "1.5" + }, + { + "enumerant" : "InputAttachmentArrayDynamicIndexingEXT", + "value" : 5303, + "capabilities" : [ "InputAttachment" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformTexelBufferArrayDynamicIndexing", + "value" : 5304, + "capabilities" : [ "SampledBuffer" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformTexelBufferArrayDynamicIndexingEXT", + "value" : 5304, + "capabilities" : [ "SampledBuffer" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageTexelBufferArrayDynamicIndexing", + "value" : 5305, + "capabilities" : [ "ImageBuffer" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageTexelBufferArrayDynamicIndexingEXT", + "value" : 5305, + "capabilities" : [ "ImageBuffer" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformBufferArrayNonUniformIndexing", + "value" : 5306, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformBufferArrayNonUniformIndexingEXT", + "value" : 5306, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "SampledImageArrayNonUniformIndexing", + "value" : 5307, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "SampledImageArrayNonUniformIndexingEXT", + "value" : 5307, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageBufferArrayNonUniformIndexing", + "value" : 5308, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageBufferArrayNonUniformIndexingEXT", + "value" : 5308, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageImageArrayNonUniformIndexing", + "value" : 5309, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageImageArrayNonUniformIndexingEXT", + "value" : 5309, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "InputAttachmentArrayNonUniformIndexing", + "value" : 5310, + "capabilities" : [ "InputAttachment", "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "InputAttachmentArrayNonUniformIndexingEXT", + "value" : 5310, + "capabilities" : [ "InputAttachment", "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformTexelBufferArrayNonUniformIndexing", + "value" : 5311, + "capabilities" : [ "SampledBuffer", "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformTexelBufferArrayNonUniformIndexingEXT", + "value" : 5311, + "capabilities" : [ "SampledBuffer", "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageTexelBufferArrayNonUniformIndexing", + "value" : 5312, + "capabilities" : [ "ImageBuffer", "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageTexelBufferArrayNonUniformIndexingEXT", + "value" : 5312, + "capabilities" : [ "ImageBuffer", "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "RayTracingPositionFetchKHR", + "value" : 5336, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_tracing_position_fetch" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingNV", + "value" : 5340, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingMotionBlurNV", + "value" : 5341, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, + { + "enumerant" : "VulkanMemoryModel", + "value" : 5345, + "version" : "1.5" + }, + { + "enumerant" : "VulkanMemoryModelKHR", + "value" : 5345, + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "VulkanMemoryModelDeviceScope", + "value" : 5346, + "version" : "1.5" + }, + { + "enumerant" : "VulkanMemoryModelDeviceScopeKHR", + "value" : 5346, + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "PhysicalStorageBufferAddresses", + "value" : 5347, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "PhysicalStorageBufferAddressesEXT", + "value" : 5347, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "ComputeDerivativeGroupLinearNV", + "value" : 5350, + "extensions" : [ "SPV_NV_compute_shader_derivatives" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingProvisionalKHR", + "value" : 5353, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "CooperativeMatrixNV", + "value" : 5357, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "enumerant" : "FragmentShaderSampleInterlockEXT", + "value" : 5363, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "FragmentShaderShadingRateInterlockEXT", + "value" : 5372, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "ShaderSMBuiltinsNV", + "value" : 5373, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "FragmentShaderPixelInterlockEXT", + "value" : 5378, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "DemoteToHelperInvocation", + "value" : 5379, + "capabilities" : [ "Shader" ], + "version" : "1.6" + }, + { + "enumerant" : "DemoteToHelperInvocationEXT", + "value" : 5379, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_demote_to_helper_invocation" ], + "version" : "1.6" + }, + { + "enumerant" : "DisplacementMicromapNV", + "value" : 5380, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_displacement_micromap" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingOpacityMicromapEXT", + "value" : 5381, + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "extensions" : [ "SPV_EXT_opacity_micromap" ], + "version" : "None" + }, + { + "enumerant" : "ShaderInvocationReorderNV", + "value" : 5383, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_NV_shader_invocation_reorder" ], + "version" : "None" + }, + { + "enumerant" : "BindlessTextureNV", + "value" : 5390, + "extensions" : [ "SPV_NV_bindless_texture" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryPositionFetchKHR", + "value" : 5391, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_tracing_position_fetch" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat16VectorNV", + "value" : 5404, + "extensions" : [ "SPV_NV_shader_atomic_fp16_vector" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingDisplacementMicromapNV", + "value" : 5409, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_NV_displacement_micromap" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupShuffleINTEL", + "value" : 5568, + "extensions" : [ "SPV_INTEL_subgroups" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupBufferBlockIOINTEL", + "value" : 5569, + "extensions" : [ "SPV_INTEL_subgroups" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupImageBlockIOINTEL", + "value" : 5570, + "extensions" : [ "SPV_INTEL_subgroups" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupImageMediaBlockIOINTEL", + "value" : 5579, + "extensions" : [ "SPV_INTEL_media_block_io" ], + "version" : "None" + }, + { + "enumerant" : "RoundToInfinityINTEL", + "value" : 5582, + "extensions" : [ "SPV_INTEL_float_controls2" ], + "version" : "None" + }, + { + "enumerant" : "FloatingPointModeINTEL", + "value" : 5583, + "extensions" : [ "SPV_INTEL_float_controls2" ], + "version" : "None" + }, + { + "enumerant" : "IntegerFunctions2INTEL", + "value" : 5584, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_INTEL_shader_integer_functions2" ], + "version" : "None" + }, + { + "enumerant" : "FunctionPointersINTEL", + "value" : 5603, + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "enumerant" : "IndirectReferencesINTEL", + "value" : 5604, + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "enumerant" : "AsmINTEL", + "value" : 5606, + "extensions" : [ "SPV_INTEL_inline_assembly" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat32MinMaxEXT", + "value" : 5612, + "extensions" : [ "SPV_EXT_shader_atomic_float_min_max" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat64MinMaxEXT", + "value" : 5613, + "extensions" : [ "SPV_EXT_shader_atomic_float_min_max" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat16MinMaxEXT", + "value" : 5616, + "extensions" : [ "SPV_EXT_shader_atomic_float_min_max" ], + "version" : "None" + }, + { + "enumerant" : "VectorComputeINTEL", + "value" : 5617, + "capabilities" : [ "VectorAnyINTEL" ], + "extensions" : [ "SPV_INTEL_vector_compute" ], + "version" : "None" + }, + { + "enumerant" : "VectorAnyINTEL", + "value" : 5619, + "extensions" : [ "SPV_INTEL_vector_compute" ], + "version" : "None" + }, + { + "enumerant" : "ExpectAssumeKHR", + "value" : 5629, + "extensions" : [ "SPV_KHR_expect_assume" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupAvcMotionEstimationINTEL", + "value" : 5696, + "extensions" : [ "SPV_INTEL_device_side_avc_motion_estimation" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupAvcMotionEstimationIntraINTEL", + "value" : 5697, + "extensions" : [ "SPV_INTEL_device_side_avc_motion_estimation" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupAvcMotionEstimationChromaINTEL", + "value" : 5698, + "extensions" : [ "SPV_INTEL_device_side_avc_motion_estimation" ], + "version" : "None" + }, + { + "enumerant" : "VariableLengthArrayINTEL", + "value" : 5817, + "extensions" : [ "SPV_INTEL_variable_length_array" ], + "version" : "None" + }, + { + "enumerant" : "FunctionFloatControlINTEL", + "value" : 5821, + "extensions" : [ "SPV_INTEL_float_controls2" ], + "version" : "None" + }, + { + "enumerant" : "FPGAMemoryAttributesINTEL", + "value" : 5824, + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPFastMathModeINTEL", + "value" : 5837, + "capabilities" : [ "Kernel" ], + "extensions" : [ "SPV_INTEL_fp_fast_math_mode" ], + "version" : "None" + }, + { + "enumerant" : "ArbitraryPrecisionIntegersINTEL", + "value" : 5844, + "extensions" : [ "SPV_INTEL_arbitrary_precision_integers" ], + "version" : "None" + }, + { + "enumerant" : "ArbitraryPrecisionFloatingPointINTEL", + "value" : 5845, + "extensions" : [ "SPV_INTEL_arbitrary_precision_floating_point" ], + "version" : "None" + }, + { + "enumerant" : "UnstructuredLoopControlsINTEL", + "value" : 5886, + "extensions" : [ "SPV_INTEL_unstructured_loop_controls" ], + "version" : "None" + }, + { + "enumerant" : "FPGALoopControlsINTEL", + "value" : 5888, + "extensions" : [ "SPV_INTEL_fpga_loop_controls" ], + "version" : "None" + }, + { + "enumerant" : "KernelAttributesINTEL", + "value" : 5892, + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPGAKernelAttributesINTEL", + "value" : 5897, + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPGAMemoryAccessesINTEL", + "value" : 5898, + "extensions" : [ "SPV_INTEL_fpga_memory_accesses" ], + "version" : "None" + }, + { + "enumerant" : "FPGAClusterAttributesINTEL", + "value" : 5904, + "extensions" : [ "SPV_INTEL_fpga_cluster_attributes" ], + "version" : "None" + }, + { + "enumerant" : "LoopFuseINTEL", + "value" : 5906, + "extensions" : [ "SPV_INTEL_loop_fuse" ], + "version" : "None" + }, + { + "enumerant" : "FPGADSPControlINTEL", + "value" : 5908, + "extensions" : [ "SPV_INTEL_fpga_dsp_control" ], + "version" : "None" + }, + { + "enumerant" : "MemoryAccessAliasingINTEL", + "value" : 5910, + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "enumerant" : "FPGAInvocationPipeliningAttributesINTEL", + "value" : 5916, + "extensions" : [ "SPV_INTEL_fpga_invocation_pipelining_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPGABufferLocationINTEL", + "value" : 5920, + "extensions" : [ "SPV_INTEL_fpga_buffer_location" ], + "version" : "None" + }, + { + "enumerant" : "ArbitraryPrecisionFixedPointINTEL", + "value" : 5922, + "extensions" : [ "SPV_INTEL_arbitrary_precision_fixed_point" ], + "version" : "None" + }, + { + "enumerant" : "USMStorageClassesINTEL", + "value" : 5935, + "extensions" : [ "SPV_INTEL_usm_storage_classes" ], + "version" : "None" + }, + { + "enumerant" : "RuntimeAlignedAttributeINTEL", + "value" : 5939, + "extensions" : [ "SPV_INTEL_runtime_aligned" ], + "version" : "None" + }, + { + "enumerant" : "IOPipesINTEL", + "value" : 5943, + "extensions" : [ "SPV_INTEL_io_pipes" ], + "version" : "None" + }, + { + "enumerant" : "BlockingPipesINTEL", + "value" : 5945, + "extensions" : [ "SPV_INTEL_blocking_pipes" ], + "version" : "None" + }, + { + "enumerant" : "FPGARegINTEL", + "value" : 5948, + "extensions" : [ "SPV_INTEL_fpga_reg" ], + "version" : "None" + }, + { + "enumerant" : "DotProductInputAll", + "value" : 6016, + "version" : "1.6" + }, + { + "enumerant" : "DotProductInputAllKHR", + "value" : 6016, + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "enumerant" : "DotProductInput4x8Bit", + "value" : 6017, + "capabilities" : [ "Int8" ], + "version" : "1.6" + }, + { + "enumerant" : "DotProductInput4x8BitKHR", + "value" : 6017, + "capabilities" : [ "Int8" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "enumerant" : "DotProductInput4x8BitPacked", + "value" : 6018, + "version" : "1.6" + }, + { + "enumerant" : "DotProductInput4x8BitPackedKHR", + "value" : 6018, + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "enumerant" : "DotProduct", + "value" : 6019, + "version" : "1.6" + }, + { + "enumerant" : "DotProductKHR", + "value" : 6019, + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "enumerant" : "RayCullMaskKHR", + "value" : 6020, + "extensions" : [ "SPV_KHR_ray_cull_mask" ], + "version" : "None" + }, + { + "enumerant" : "CooperativeMatrixKHR", + "value" : 6022, + "extensions" : [ "SPV_KHR_cooperative_matrix" ], + "version" : "None" + }, + { + "enumerant" : "BitInstructions", + "value" : 6025, + "extensions" : [ "SPV_KHR_bit_instructions" ], + "version" : "None" + }, + { + "enumerant" : "GroupNonUniformRotateKHR", + "value" : 6026, + "capabilities" : [ "GroupNonUniform" ], + "extensions" : [ "SPV_KHR_subgroup_rotate" ], + "version" : "None" + }, + { + "enumerant" : "FloatControls2", + "value" : 6029, + "extensions" : [ "SPV_KHR_float_controls2" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat32AddEXT", + "value" : 6033, + "extensions" : [ "SPV_EXT_shader_atomic_float_add" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat64AddEXT", + "value" : 6034, + "extensions" : [ "SPV_EXT_shader_atomic_float_add" ], + "version" : "None" + }, + { + "enumerant" : "LongCompositesINTEL", + "value" : 6089, + "extensions" : [ "SPV_INTEL_long_composites" ], + "version" : "None" + }, + { + "enumerant" : "OptNoneINTEL", + "value" : 6094, + "extensions" : [ "SPV_INTEL_optnone" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat16AddEXT", + "value" : 6095, + "extensions" : [ "SPV_EXT_shader_atomic_float16_add" ], + "version" : "None" + }, + { + "enumerant" : "DebugInfoModuleINTEL", + "value" : 6114, + "extensions" : [ "SPV_INTEL_debug_module" ], + "version" : "None" + }, + { + "enumerant" : "BFloat16ConversionINTEL", + "value" : 6115, + "extensions" : [ "SPV_INTEL_bfloat16_conversion" ], + "version" : "None" + }, + { + "enumerant" : "SplitBarrierINTEL", + "value" : 6141, + "extensions" : [ "SPV_INTEL_split_barrier" ], + "version" : "None" + }, + { + "enumerant" : "FPGAClusterAttributesV2INTEL", + "value" : 6150, + "capabilities" : [ "FPGAClusterAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_cluster_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPGAKernelAttributesv2INTEL", + "value" : 6161, + "capabilities" : [ "FPGAKernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPMaxErrorINTEL", + "value" : 6169, + "extensions" : [ "SPV_INTEL_fp_max_error" ], + "version" : "None" + }, + { + "enumerant" : "FPGALatencyControlINTEL", + "value" : 6171, + "extensions" : [ "SPV_INTEL_fpga_latency_control" ], + "version" : "None" + }, + { + "enumerant" : "FPGAArgumentInterfacesINTEL", + "value" : 6174, + "extensions" : [ "SPV_INTEL_fpga_argument_interfaces" ], + "version" : "None" + }, + { + "enumerant" : "GlobalVariableHostAccessINTEL", + "value" : 6187, + "extensions": [ "SPV_INTEL_global_variable_host_access" ], + "version" : "None" + }, + { + "enumerant" : "GlobalVariableFPGADecorationsINTEL", + "value" : 6189, + "extensions": [ "SPV_INTEL_global_variable_fpga_decorations" ], + "version" : "None" + }, + { + "enumerant" : "GroupUniformArithmeticKHR", + "value" : 6400, + "extensions" : [ "SPV_KHR_uniform_group_instructions"], + "version" : "None" + }, + { + "enumerant" : "MaskedGatherScatterINTEL", + "value" : 6427, + "extensions" : [ "SPV_INTEL_masked_gather_scatter"], + "version" : "None" + }, + { + "enumerant" : "CacheControlsINTEL", + "value" : 6441, + "extensions" : [ "SPV_INTEL_cache_controls" ], + "version" : "None" + }, + { + "enumerant" : "RegisterLimitsINTEL", + "value" : 6460, + "extensions" : [ "SPV_INTEL_maximum_registers" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "RayQueryIntersection", + "enumerants" : [ + { + "enumerant" : "RayQueryCandidateIntersectionKHR", + "value" : 0, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryCommittedIntersectionKHR", + "value" : 1, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "RayQueryCommittedIntersectionType", + "enumerants" : [ + { + "enumerant" : "RayQueryCommittedIntersectionNoneKHR", + "value" : 0, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryCommittedIntersectionTriangleKHR", + "value" : 1, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryCommittedIntersectionGeneratedKHR", + "value" : 2, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "RayQueryCandidateIntersectionType", + "enumerants" : [ + { + "enumerant" : "RayQueryCandidateIntersectionTriangleKHR", + "value" : 0, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryCandidateIntersectionAABBKHR", + "value" : 1, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "PackedVectorFormat", + "enumerants" : [ + { + "enumerant" : "PackedVectorFormat4x8Bit", + "value" : 0, + "version" : "1.6" + }, + { + "enumerant" : "PackedVectorFormat4x8BitKHR", + "value" : 0, + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "CooperativeMatrixOperands", + "enumerants" : [ + { + "enumerant" : "NoneKHR", + "value" : "0x0000", + "version" : "None" + }, + { + "enumerant" : "MatrixASignedComponentsKHR", + "value" : "0x0001", + "version" : "None" + }, + { + "enumerant" : "MatrixBSignedComponentsKHR", + "value" : "0x0002", + "version" : "None" + }, + { + "enumerant" : "MatrixCSignedComponentsKHR", + "value" : "0x0004", + "version" : "None" + }, + { + "enumerant" : "MatrixResultSignedComponentsKHR", + "value" : "0x0008", + "version" : "None" + }, + { + "enumerant" : "SaturatingAccumulationKHR", + "value" : "0x0010", + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "CooperativeMatrixLayout", + "enumerants" : [ + { + "enumerant" : "RowMajorKHR", + "value" : 0, + "version" : "None" + }, + { + "enumerant" : "ColumnMajorKHR", + "value" : 1, + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "CooperativeMatrixUse", + "enumerants" : [ + { + "enumerant" : "MatrixAKHR", + "value" : 0, + "version" : "None" + }, + { + "enumerant" : "MatrixBKHR", + "value" : 1, + "version" : "None" + }, + { + "enumerant" : "MatrixAccumulatorKHR", + "value" : 2, + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "InitializationModeQualifier", + "enumerants" : [ + { + "enumerant" : "InitOnDeviceReprogramINTEL", + "value" : 0, + "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "InitOnDeviceResetINTEL", + "value" : 1, + "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LoadCacheControl", + "enumerants" : [ + { + "enumerant" : "UncachedINTEL", + "value" : 0, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "CachedINTEL", + "value" : 1, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StreamingINTEL", + "value" : 2, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "InvalidateAfterReadINTEL", + "value" : 3, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ConstCachedINTEL", + "value" : 4, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StoreCacheControl", + "enumerants" : [ + { + "enumerant" : "UncachedINTEL", + "value" : 0, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "WriteThroughINTEL", + "value" : 1, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "WriteBackINTEL", + "value" : 2, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StreamingINTEL", + "value" : 3, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "NamedMaximumNumberOfRegisters", + "enumerants" : [ + { + "enumerant" : "AutoINTEL", + "value" : 0, + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "Id", + "kind" : "IdResultType", + "doc" : "Reference to an representing the result's type of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdResult", + "doc" : "Definition of an representing the result of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdMemorySemantics", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the MemorySemantics operand kind" + }, + { + "category" : "Id", + "kind" : "IdScope", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the Scope operand kind" + }, + { + "category" : "Id", + "kind" : "IdRef", + "doc" : "Reference to an " + }, + { + "category" : "Literal", + "kind" : "LiteralInteger", + "doc" : "An integer consuming one or more words" + }, + { + "category" : "Literal", + "kind" : "LiteralString", + "doc" : "A null-terminated stream of characters consuming an integral number of words" + }, + { + "category" : "Literal", + "kind" : "LiteralFloat", + "doc" : "A float consuming one word" + }, + { + "category" : "Literal", + "kind" : "LiteralContextDependentNumber", + "doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction" + }, + { + "category" : "Literal", + "kind" : "LiteralExtInstInteger", + "doc" : "A 32-bit unsigned integer indicating which instruction to use and determining the layout of following operands (for OpExtInst)" + }, + { + "category" : "Literal", + "kind" : "LiteralSpecConstantOpInteger", + "doc" : "An opcode indicating the operation to be performed and determining the layout of following operands (for OpSpecConstantOp)" + }, + { + "category" : "Composite", + "kind" : "PairLiteralIntegerIdRef", + "bases" : [ "LiteralInteger", "IdRef" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefLiteralInteger", + "bases" : [ "IdRef", "LiteralInteger" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefIdRef", + "bases" : [ "IdRef", "IdRef" ] + } + ] +} diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.cs b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.cs new file mode 100644 index 000000000000..a91f4ff448a1 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.cs @@ -0,0 +1,2148 @@ +// Copyright (c) 2014-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + + public static class Specification + { + public const uint MagicNumber = 0x07230203; + public const uint Version = 0x00010600; + public const uint Revision = 1; + public const uint OpCodeMask = 0xffff; + public const uint WordCountShift = 16; + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + NodeOutputPayloadAMDX = 5076, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + } + + public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + } + + public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, + } + + public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + } + + public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + LinkOnceODR = 2, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + CoalescedInputCountAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + } + + public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + } + + public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, + } + + public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, + } + + public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, + } + + public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + } + + public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, + } + + public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + } + + public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + } + + public enum RayFlagsShift + { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + } + + public enum RayFlagsMask + { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, + } + + public enum RayQueryIntersection + { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + } + + public enum RayQueryCommittedIntersectionType + { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + } + + public enum RayQueryCandidateIntersectionType + { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + } + + public enum FragmentShadingRateShift + { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + } + + public enum FragmentShadingRateMask + { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, + } + + public enum FPDenormMode + { + Preserve = 0, + FlushToZero = 1, + } + + public enum FPOperationMode + { + IEEE = 0, + ALT = 1, + } + + public enum QuantizationModes + { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + } + + public enum OverflowModes + { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + } + + public enum PackedVectorFormat + { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + } + + public enum CooperativeMatrixOperandsShift + { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + } + + public enum CooperativeMatrixOperandsMask + { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, + } + + public enum CooperativeMatrixLayout + { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + } + + public enum CooperativeMatrixUse + { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + } + + public enum InitializationModeQualifier + { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + } + + public enum HostAccessQualifier + { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + } + + public enum LoadCacheControl + { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + } + + public enum StoreCacheControl + { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + } + + public enum NamedMaximumNumberOfRegisters + { + AutoINTEL = 0, + } + + public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + } + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.h b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.h new file mode 100644 index 000000000000..9276b301b850 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.h @@ -0,0 +1,2879 @@ +/* +** Copyright (c) 2014-2024 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python, C#, D, Beef +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** - C# will use enum classes in the Specification class located in the "Spv" namespace, +** e.g.: Spv.Specification.SourceLanguage.GLSL +** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +** - Beef will use enum classes in the Specification class located in the "Spv" namespace, +** e.g.: Spv.Specification.SourceLanguage.GLSL +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010600; +static const unsigned int SpvRevision = 1; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageCPP_for_OpenCL = 6, + SpvSourceLanguageSYCL = 7, + SpvSourceLanguageHERO_C = 8, + SpvSourceLanguageNZSL = 9, + SpvSourceLanguageWGSL = 10, + SpvSourceLanguageSlang = 11, + SpvSourceLanguageZig = 12, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelTaskNV = 5267, + SpvExecutionModelMeshNV = 5268, + SpvExecutionModelRayGenerationKHR = 5313, + SpvExecutionModelRayGenerationNV = 5313, + SpvExecutionModelIntersectionKHR = 5314, + SpvExecutionModelIntersectionNV = 5314, + SpvExecutionModelAnyHitKHR = 5315, + SpvExecutionModelAnyHitNV = 5315, + SpvExecutionModelClosestHitKHR = 5316, + SpvExecutionModelClosestHitNV = 5316, + SpvExecutionModelMissKHR = 5317, + SpvExecutionModelMissNV = 5317, + SpvExecutionModelCallableKHR = 5318, + SpvExecutionModelCallableNV = 5318, + SpvExecutionModelTaskEXT = 5364, + SpvExecutionModelMeshEXT = 5365, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelPhysicalStorageBuffer64 = 5348, + SpvAddressingModelPhysicalStorageBuffer64EXT = 5348, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelVulkan = 3, + SpvMemoryModelVulkanKHR = 3, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModeInitializer = 33, + SpvExecutionModeFinalizer = 34, + SpvExecutionModeSubgroupSize = 35, + SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModeSubgroupsPerWorkgroupId = 37, + SpvExecutionModeLocalSizeId = 38, + SpvExecutionModeLocalSizeHintId = 39, + SpvExecutionModeNonCoherentColorAttachmentReadEXT = 4169, + SpvExecutionModeNonCoherentDepthAttachmentReadEXT = 4170, + SpvExecutionModeNonCoherentStencilAttachmentReadEXT = 4171, + SpvExecutionModeSubgroupUniformControlFlowKHR = 4421, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeDenormPreserve = 4459, + SpvExecutionModeDenormFlushToZero = 4460, + SpvExecutionModeSignedZeroInfNanPreserve = 4461, + SpvExecutionModeRoundingModeRTE = 4462, + SpvExecutionModeRoundingModeRTZ = 4463, + SpvExecutionModeEarlyAndLateFragmentTestsAMD = 5017, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeCoalescingAMDX = 5069, + SpvExecutionModeMaxNodeRecursionAMDX = 5071, + SpvExecutionModeStaticNumWorkgroupsAMDX = 5072, + SpvExecutionModeShaderIndexAMDX = 5073, + SpvExecutionModeMaxNumWorkgroupsAMDX = 5077, + SpvExecutionModeStencilRefUnchangedFrontAMD = 5079, + SpvExecutionModeStencilRefGreaterFrontAMD = 5080, + SpvExecutionModeStencilRefLessFrontAMD = 5081, + SpvExecutionModeStencilRefUnchangedBackAMD = 5082, + SpvExecutionModeStencilRefGreaterBackAMD = 5083, + SpvExecutionModeStencilRefLessBackAMD = 5084, + SpvExecutionModeQuadDerivativesKHR = 5088, + SpvExecutionModeRequireFullQuadsKHR = 5089, + SpvExecutionModeOutputLinesEXT = 5269, + SpvExecutionModeOutputLinesNV = 5269, + SpvExecutionModeOutputPrimitivesEXT = 5270, + SpvExecutionModeOutputPrimitivesNV = 5270, + SpvExecutionModeDerivativeGroupQuadsNV = 5289, + SpvExecutionModeDerivativeGroupLinearNV = 5290, + SpvExecutionModeOutputTrianglesEXT = 5298, + SpvExecutionModeOutputTrianglesNV = 5298, + SpvExecutionModePixelInterlockOrderedEXT = 5366, + SpvExecutionModePixelInterlockUnorderedEXT = 5367, + SpvExecutionModeSampleInterlockOrderedEXT = 5368, + SpvExecutionModeSampleInterlockUnorderedEXT = 5369, + SpvExecutionModeShadingRateInterlockOrderedEXT = 5370, + SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371, + SpvExecutionModeSharedLocalMemorySizeINTEL = 5618, + SpvExecutionModeRoundingModeRTPINTEL = 5620, + SpvExecutionModeRoundingModeRTNINTEL = 5621, + SpvExecutionModeFloatingPointModeALTINTEL = 5622, + SpvExecutionModeFloatingPointModeIEEEINTEL = 5623, + SpvExecutionModeMaxWorkgroupSizeINTEL = 5893, + SpvExecutionModeMaxWorkDimINTEL = 5894, + SpvExecutionModeNoGlobalOffsetINTEL = 5895, + SpvExecutionModeNumSIMDWorkitemsINTEL = 5896, + SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + SpvExecutionModeMaximallyReconvergesKHR = 6023, + SpvExecutionModeFPFastMathDefault = 6028, + SpvExecutionModeStreamingInterfaceINTEL = 6154, + SpvExecutionModeRegisterMapInterfaceINTEL = 6160, + SpvExecutionModeNamedBarrierCountINTEL = 6417, + SpvExecutionModeMaximumRegistersINTEL = 6461, + SpvExecutionModeMaximumRegistersIdINTEL = 6462, + SpvExecutionModeNamedMaximumRegistersINTEL = 6463, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassTileImageEXT = 4172, + SpvStorageClassNodePayloadAMDX = 5068, + SpvStorageClassNodeOutputPayloadAMDX = 5076, + SpvStorageClassCallableDataKHR = 5328, + SpvStorageClassCallableDataNV = 5328, + SpvStorageClassIncomingCallableDataKHR = 5329, + SpvStorageClassIncomingCallableDataNV = 5329, + SpvStorageClassRayPayloadKHR = 5338, + SpvStorageClassRayPayloadNV = 5338, + SpvStorageClassHitAttributeKHR = 5339, + SpvStorageClassHitAttributeNV = 5339, + SpvStorageClassIncomingRayPayloadKHR = 5342, + SpvStorageClassIncomingRayPayloadNV = 5342, + SpvStorageClassShaderRecordBufferKHR = 5343, + SpvStorageClassShaderRecordBufferNV = 5343, + SpvStorageClassPhysicalStorageBuffer = 5349, + SpvStorageClassPhysicalStorageBufferEXT = 5349, + SpvStorageClassHitObjectAttributeNV = 5385, + SpvStorageClassTaskPayloadWorkgroupEXT = 5402, + SpvStorageClassCodeSectionINTEL = 5605, + SpvStorageClassDeviceOnlyINTEL = 5936, + SpvStorageClassHostOnlyINTEL = 5937, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimTileImageDataEXT = 4173, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatR64ui = 40, + SpvImageFormatR64i = 41, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeUnsignedIntRaw10EXT = 19, + SpvImageChannelDataTypeUnsignedIntRaw12EXT = 20, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMakeTexelAvailableShift = 8, + SpvImageOperandsMakeTexelAvailableKHRShift = 8, + SpvImageOperandsMakeTexelVisibleShift = 9, + SpvImageOperandsMakeTexelVisibleKHRShift = 9, + SpvImageOperandsNonPrivateTexelShift = 10, + SpvImageOperandsNonPrivateTexelKHRShift = 10, + SpvImageOperandsVolatileTexelShift = 11, + SpvImageOperandsVolatileTexelKHRShift = 11, + SpvImageOperandsSignExtendShift = 12, + SpvImageOperandsZeroExtendShift = 13, + SpvImageOperandsNontemporalShift = 14, + SpvImageOperandsOffsetsShift = 16, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, + SpvImageOperandsMakeTexelAvailableMask = 0x00000100, + SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + SpvImageOperandsMakeTexelVisibleMask = 0x00000200, + SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + SpvImageOperandsNonPrivateTexelMask = 0x00000400, + SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400, + SpvImageOperandsVolatileTexelMask = 0x00000800, + SpvImageOperandsVolatileTexelKHRMask = 0x00000800, + SpvImageOperandsSignExtendMask = 0x00001000, + SpvImageOperandsZeroExtendMask = 0x00002000, + SpvImageOperandsNontemporalMask = 0x00004000, + SpvImageOperandsOffsetsMask = 0x00010000, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeAllowContractShift = 16, + SpvFPFastMathModeAllowContractFastINTELShift = 16, + SpvFPFastMathModeAllowReassocShift = 17, + SpvFPFastMathModeAllowReassocINTELShift = 17, + SpvFPFastMathModeAllowTransformShift = 18, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, + SpvFPFastMathModeAllowContractMask = 0x00010000, + SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000, + SpvFPFastMathModeAllowReassocMask = 0x00020000, + SpvFPFastMathModeAllowReassocINTELMask = 0x00020000, + SpvFPFastMathModeAllowTransformMask = 0x00040000, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeLinkOnceODR = 2, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeRuntimeAlignedINTEL = 5940, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationUniformId = 27, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationMaxByteOffset = 45, + SpvDecorationAlignmentId = 46, + SpvDecorationMaxByteOffsetId = 47, + SpvDecorationNoSignedWrap = 4469, + SpvDecorationNoUnsignedWrap = 4470, + SpvDecorationWeightTextureQCOM = 4487, + SpvDecorationBlockMatchTextureQCOM = 4488, + SpvDecorationBlockMatchSamplerQCOM = 4499, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationNodeSharesPayloadLimitsWithAMDX = 5019, + SpvDecorationNodeMaxPayloadsAMDX = 5020, + SpvDecorationTrackFinishWritingAMDX = 5078, + SpvDecorationPayloadNodeNameAMDX = 5091, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationPerPrimitiveEXT = 5271, + SpvDecorationPerPrimitiveNV = 5271, + SpvDecorationPerViewNV = 5272, + SpvDecorationPerTaskNV = 5273, + SpvDecorationPerVertexKHR = 5285, + SpvDecorationPerVertexNV = 5285, + SpvDecorationNonUniform = 5300, + SpvDecorationNonUniformEXT = 5300, + SpvDecorationRestrictPointer = 5355, + SpvDecorationRestrictPointerEXT = 5355, + SpvDecorationAliasedPointer = 5356, + SpvDecorationAliasedPointerEXT = 5356, + SpvDecorationHitObjectShaderRecordBufferNV = 5386, + SpvDecorationBindlessSamplerNV = 5398, + SpvDecorationBindlessImageNV = 5399, + SpvDecorationBoundSamplerNV = 5400, + SpvDecorationBoundImageNV = 5401, + SpvDecorationSIMTCallINTEL = 5599, + SpvDecorationReferencedIndirectlyINTEL = 5602, + SpvDecorationClobberINTEL = 5607, + SpvDecorationSideEffectsINTEL = 5608, + SpvDecorationVectorComputeVariableINTEL = 5624, + SpvDecorationFuncParamIOKindINTEL = 5625, + SpvDecorationVectorComputeFunctionINTEL = 5626, + SpvDecorationStackCallINTEL = 5627, + SpvDecorationGlobalVariableOffsetINTEL = 5628, + SpvDecorationCounterBuffer = 5634, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationUserSemantic = 5635, + SpvDecorationUserTypeGOOGLE = 5636, + SpvDecorationFunctionRoundingModeINTEL = 5822, + SpvDecorationFunctionDenormModeINTEL = 5823, + SpvDecorationRegisterINTEL = 5825, + SpvDecorationMemoryINTEL = 5826, + SpvDecorationNumbanksINTEL = 5827, + SpvDecorationBankwidthINTEL = 5828, + SpvDecorationMaxPrivateCopiesINTEL = 5829, + SpvDecorationSinglepumpINTEL = 5830, + SpvDecorationDoublepumpINTEL = 5831, + SpvDecorationMaxReplicatesINTEL = 5832, + SpvDecorationSimpleDualPortINTEL = 5833, + SpvDecorationMergeINTEL = 5834, + SpvDecorationBankBitsINTEL = 5835, + SpvDecorationForcePow2DepthINTEL = 5836, + SpvDecorationStridesizeINTEL = 5883, + SpvDecorationWordsizeINTEL = 5884, + SpvDecorationTrueDualPortINTEL = 5885, + SpvDecorationBurstCoalesceINTEL = 5899, + SpvDecorationCacheSizeINTEL = 5900, + SpvDecorationDontStaticallyCoalesceINTEL = 5901, + SpvDecorationPrefetchINTEL = 5902, + SpvDecorationStallEnableINTEL = 5905, + SpvDecorationFuseLoopsInFunctionINTEL = 5907, + SpvDecorationMathOpDSPModeINTEL = 5909, + SpvDecorationAliasScopeINTEL = 5914, + SpvDecorationNoAliasINTEL = 5915, + SpvDecorationInitiationIntervalINTEL = 5917, + SpvDecorationMaxConcurrencyINTEL = 5918, + SpvDecorationPipelineEnableINTEL = 5919, + SpvDecorationBufferLocationINTEL = 5921, + SpvDecorationIOPipeStorageINTEL = 5944, + SpvDecorationFunctionFloatingPointModeINTEL = 6080, + SpvDecorationSingleElementVectorINTEL = 6085, + SpvDecorationVectorComputeCallableFunctionINTEL = 6087, + SpvDecorationMediaBlockIOINTEL = 6140, + SpvDecorationStallFreeINTEL = 6151, + SpvDecorationFPMaxErrorDecorationINTEL = 6170, + SpvDecorationLatencyControlLabelINTEL = 6172, + SpvDecorationLatencyControlConstraintINTEL = 6173, + SpvDecorationConduitKernelArgumentINTEL = 6175, + SpvDecorationRegisterMapKernelArgumentINTEL = 6176, + SpvDecorationMMHostInterfaceAddressWidthINTEL = 6177, + SpvDecorationMMHostInterfaceDataWidthINTEL = 6178, + SpvDecorationMMHostInterfaceLatencyINTEL = 6179, + SpvDecorationMMHostInterfaceReadWriteModeINTEL = 6180, + SpvDecorationMMHostInterfaceMaxBurstINTEL = 6181, + SpvDecorationMMHostInterfaceWaitRequestINTEL = 6182, + SpvDecorationStableKernelArgumentINTEL = 6183, + SpvDecorationHostAccessINTEL = 6188, + SpvDecorationInitModeINTEL = 6190, + SpvDecorationImplementInRegisterMapINTEL = 6191, + SpvDecorationCacheControlLoadINTEL = 6442, + SpvDecorationCacheControlStoreINTEL = 6443, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInCoreIDARM = 4160, + SpvBuiltInCoreCountARM = 4161, + SpvBuiltInCoreMaxIDARM = 4162, + SpvBuiltInWarpIDARM = 4163, + SpvBuiltInWarpMaxIDARM = 4164, + SpvBuiltInSubgroupEqMask = 4416, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMask = 4417, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMask = 4418, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMask = 4419, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMask = 4420, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInPrimitiveShadingRateKHR = 4432, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInShadingRateKHR = 4444, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInCoalescedInputCountAMDX = 5021, + SpvBuiltInShaderIndexAMDX = 5073, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInFullyCoveredEXT = 5264, + SpvBuiltInTaskCountNV = 5274, + SpvBuiltInPrimitiveCountNV = 5275, + SpvBuiltInPrimitiveIndicesNV = 5276, + SpvBuiltInClipDistancePerViewNV = 5277, + SpvBuiltInCullDistancePerViewNV = 5278, + SpvBuiltInLayerPerViewNV = 5279, + SpvBuiltInMeshViewCountNV = 5280, + SpvBuiltInMeshViewIndicesNV = 5281, + SpvBuiltInBaryCoordKHR = 5286, + SpvBuiltInBaryCoordNV = 5286, + SpvBuiltInBaryCoordNoPerspKHR = 5287, + SpvBuiltInBaryCoordNoPerspNV = 5287, + SpvBuiltInFragSizeEXT = 5292, + SpvBuiltInFragmentSizeNV = 5292, + SpvBuiltInFragInvocationCountEXT = 5293, + SpvBuiltInInvocationsPerPixelNV = 5293, + SpvBuiltInPrimitivePointIndicesEXT = 5294, + SpvBuiltInPrimitiveLineIndicesEXT = 5295, + SpvBuiltInPrimitiveTriangleIndicesEXT = 5296, + SpvBuiltInCullPrimitiveEXT = 5299, + SpvBuiltInLaunchIdKHR = 5319, + SpvBuiltInLaunchIdNV = 5319, + SpvBuiltInLaunchSizeKHR = 5320, + SpvBuiltInLaunchSizeNV = 5320, + SpvBuiltInWorldRayOriginKHR = 5321, + SpvBuiltInWorldRayOriginNV = 5321, + SpvBuiltInWorldRayDirectionKHR = 5322, + SpvBuiltInWorldRayDirectionNV = 5322, + SpvBuiltInObjectRayOriginKHR = 5323, + SpvBuiltInObjectRayOriginNV = 5323, + SpvBuiltInObjectRayDirectionKHR = 5324, + SpvBuiltInObjectRayDirectionNV = 5324, + SpvBuiltInRayTminKHR = 5325, + SpvBuiltInRayTminNV = 5325, + SpvBuiltInRayTmaxKHR = 5326, + SpvBuiltInRayTmaxNV = 5326, + SpvBuiltInInstanceCustomIndexKHR = 5327, + SpvBuiltInInstanceCustomIndexNV = 5327, + SpvBuiltInObjectToWorldKHR = 5330, + SpvBuiltInObjectToWorldNV = 5330, + SpvBuiltInWorldToObjectKHR = 5331, + SpvBuiltInWorldToObjectNV = 5331, + SpvBuiltInHitTNV = 5332, + SpvBuiltInHitKindKHR = 5333, + SpvBuiltInHitKindNV = 5333, + SpvBuiltInCurrentRayTimeNV = 5334, + SpvBuiltInHitTriangleVertexPositionsKHR = 5335, + SpvBuiltInHitMicroTriangleVertexPositionsNV = 5337, + SpvBuiltInHitMicroTriangleVertexBarycentricsNV = 5344, + SpvBuiltInIncomingRayFlagsKHR = 5351, + SpvBuiltInIncomingRayFlagsNV = 5351, + SpvBuiltInRayGeometryIndexKHR = 5352, + SpvBuiltInWarpsPerSMNV = 5374, + SpvBuiltInSMCountNV = 5375, + SpvBuiltInWarpIDNV = 5376, + SpvBuiltInSMIDNV = 5377, + SpvBuiltInHitKindFrontFacingMicroTriangleNV = 5405, + SpvBuiltInHitKindBackFacingMicroTriangleNV = 5406, + SpvBuiltInCullMaskKHR = 6021, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlDependencyInfiniteShift = 2, + SpvLoopControlDependencyLengthShift = 3, + SpvLoopControlMinIterationsShift = 4, + SpvLoopControlMaxIterationsShift = 5, + SpvLoopControlIterationMultipleShift = 6, + SpvLoopControlPeelCountShift = 7, + SpvLoopControlPartialCountShift = 8, + SpvLoopControlInitiationIntervalINTELShift = 16, + SpvLoopControlMaxConcurrencyINTELShift = 17, + SpvLoopControlDependencyArrayINTELShift = 18, + SpvLoopControlPipelineEnableINTELShift = 19, + SpvLoopControlLoopCoalesceINTELShift = 20, + SpvLoopControlMaxInterleavingINTELShift = 21, + SpvLoopControlSpeculatedIterationsINTELShift = 22, + SpvLoopControlNoFusionINTELShift = 23, + SpvLoopControlLoopCountINTELShift = 24, + SpvLoopControlMaxReinvocationDelayINTELShift = 25, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, + SpvLoopControlDependencyInfiniteMask = 0x00000004, + SpvLoopControlDependencyLengthMask = 0x00000008, + SpvLoopControlMinIterationsMask = 0x00000010, + SpvLoopControlMaxIterationsMask = 0x00000020, + SpvLoopControlIterationMultipleMask = 0x00000040, + SpvLoopControlPeelCountMask = 0x00000080, + SpvLoopControlPartialCountMask = 0x00000100, + SpvLoopControlInitiationIntervalINTELMask = 0x00010000, + SpvLoopControlMaxConcurrencyINTELMask = 0x00020000, + SpvLoopControlDependencyArrayINTELMask = 0x00040000, + SpvLoopControlPipelineEnableINTELMask = 0x00080000, + SpvLoopControlLoopCoalesceINTELMask = 0x00100000, + SpvLoopControlMaxInterleavingINTELMask = 0x00200000, + SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000, + SpvLoopControlNoFusionINTELMask = 0x00800000, + SpvLoopControlLoopCountINTELMask = 0x01000000, + SpvLoopControlMaxReinvocationDelayINTELMask = 0x02000000, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlOptNoneINTELShift = 16, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, + SpvFunctionControlOptNoneINTELMask = 0x00010000, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsOutputMemoryShift = 12, + SpvMemorySemanticsOutputMemoryKHRShift = 12, + SpvMemorySemanticsMakeAvailableShift = 13, + SpvMemorySemanticsMakeAvailableKHRShift = 13, + SpvMemorySemanticsMakeVisibleShift = 14, + SpvMemorySemanticsMakeVisibleKHRShift = 14, + SpvMemorySemanticsVolatileShift = 15, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, + SpvMemorySemanticsOutputMemoryMask = 0x00001000, + SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000, + SpvMemorySemanticsMakeAvailableMask = 0x00002000, + SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000, + SpvMemorySemanticsMakeVisibleMask = 0x00004000, + SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000, + SpvMemorySemanticsVolatileMask = 0x00008000, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMakePointerAvailableShift = 3, + SpvMemoryAccessMakePointerAvailableKHRShift = 3, + SpvMemoryAccessMakePointerVisibleShift = 4, + SpvMemoryAccessMakePointerVisibleKHRShift = 4, + SpvMemoryAccessNonPrivatePointerShift = 5, + SpvMemoryAccessNonPrivatePointerKHRShift = 5, + SpvMemoryAccessAliasScopeINTELMaskShift = 16, + SpvMemoryAccessNoAliasINTELMaskShift = 17, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, + SpvMemoryAccessMakePointerAvailableMask = 0x00000008, + SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008, + SpvMemoryAccessMakePointerVisibleMask = 0x00000010, + SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, + SpvMemoryAccessNonPrivatePointerMask = 0x00000020, + SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, + SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000, + SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeQueueFamily = 5, + SpvScopeQueueFamilyKHR = 5, + SpvScopeShaderCallKHR = 6, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationClusteredReduce = 3, + SpvGroupOperationPartitionedReduceNV = 6, + SpvGroupOperationPartitionedInclusiveScanNV = 7, + SpvGroupOperationPartitionedExclusiveScanNV = 8, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupDispatch = 58, + SpvCapabilityNamedBarrier = 59, + SpvCapabilityPipeStorage = 60, + SpvCapabilityGroupNonUniform = 61, + SpvCapabilityGroupNonUniformVote = 62, + SpvCapabilityGroupNonUniformArithmetic = 63, + SpvCapabilityGroupNonUniformBallot = 64, + SpvCapabilityGroupNonUniformShuffle = 65, + SpvCapabilityGroupNonUniformShuffleRelative = 66, + SpvCapabilityGroupNonUniformClustered = 67, + SpvCapabilityGroupNonUniformQuad = 68, + SpvCapabilityShaderLayer = 69, + SpvCapabilityShaderViewportIndex = 70, + SpvCapabilityUniformDecoration = 71, + SpvCapabilityCoreBuiltinsARM = 4165, + SpvCapabilityTileImageColorReadAccessEXT = 4166, + SpvCapabilityTileImageDepthReadAccessEXT = 4167, + SpvCapabilityTileImageStencilReadAccessEXT = 4168, + SpvCapabilityFragmentShadingRateKHR = 4422, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityStorageBuffer8BitAccess = 4448, + SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449, + SpvCapabilityStoragePushConstant8 = 4450, + SpvCapabilityDenormPreserve = 4464, + SpvCapabilityDenormFlushToZero = 4465, + SpvCapabilitySignedZeroInfNanPreserve = 4466, + SpvCapabilityRoundingModeRTE = 4467, + SpvCapabilityRoundingModeRTZ = 4468, + SpvCapabilityRayQueryProvisionalKHR = 4471, + SpvCapabilityRayQueryKHR = 4472, + SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478, + SpvCapabilityRayTracingKHR = 4479, + SpvCapabilityTextureSampleWeightedQCOM = 4484, + SpvCapabilityTextureBoxFilterQCOM = 4485, + SpvCapabilityTextureBlockMatchQCOM = 4486, + SpvCapabilityTextureBlockMatch2QCOM = 4498, + SpvCapabilityFloat16ImageAMD = 5008, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilityInt64ImageEXT = 5016, + SpvCapabilityShaderClockKHR = 5055, + SpvCapabilityShaderEnqueueAMDX = 5067, + SpvCapabilityQuadControlKHR = 5087, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilityFragmentFullyCoveredEXT = 5265, + SpvCapabilityMeshShadingNV = 5266, + SpvCapabilityImageFootprintNV = 5282, + SpvCapabilityMeshShadingEXT = 5283, + SpvCapabilityFragmentBarycentricKHR = 5284, + SpvCapabilityFragmentBarycentricNV = 5284, + SpvCapabilityComputeDerivativeGroupQuadsNV = 5288, + SpvCapabilityFragmentDensityEXT = 5291, + SpvCapabilityShadingRateNV = 5291, + SpvCapabilityGroupNonUniformPartitionedNV = 5297, + SpvCapabilityShaderNonUniform = 5301, + SpvCapabilityShaderNonUniformEXT = 5301, + SpvCapabilityRuntimeDescriptorArray = 5302, + SpvCapabilityRuntimeDescriptorArrayEXT = 5302, + SpvCapabilityInputAttachmentArrayDynamicIndexing = 5303, + SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + SpvCapabilityUniformTexelBufferArrayDynamicIndexing = 5304, + SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + SpvCapabilityStorageTexelBufferArrayDynamicIndexing = 5305, + SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + SpvCapabilityUniformBufferArrayNonUniformIndexing = 5306, + SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + SpvCapabilitySampledImageArrayNonUniformIndexing = 5307, + SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + SpvCapabilityStorageBufferArrayNonUniformIndexing = 5308, + SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + SpvCapabilityStorageImageArrayNonUniformIndexing = 5309, + SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + SpvCapabilityInputAttachmentArrayNonUniformIndexing = 5310, + SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + SpvCapabilityRayTracingPositionFetchKHR = 5336, + SpvCapabilityRayTracingNV = 5340, + SpvCapabilityRayTracingMotionBlurNV = 5341, + SpvCapabilityVulkanMemoryModel = 5345, + SpvCapabilityVulkanMemoryModelKHR = 5345, + SpvCapabilityVulkanMemoryModelDeviceScope = 5346, + SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + SpvCapabilityPhysicalStorageBufferAddresses = 5347, + SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347, + SpvCapabilityComputeDerivativeGroupLinearNV = 5350, + SpvCapabilityRayTracingProvisionalKHR = 5353, + SpvCapabilityCooperativeMatrixNV = 5357, + SpvCapabilityFragmentShaderSampleInterlockEXT = 5363, + SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372, + SpvCapabilityShaderSMBuiltinsNV = 5373, + SpvCapabilityFragmentShaderPixelInterlockEXT = 5378, + SpvCapabilityDemoteToHelperInvocation = 5379, + SpvCapabilityDemoteToHelperInvocationEXT = 5379, + SpvCapabilityDisplacementMicromapNV = 5380, + SpvCapabilityRayTracingOpacityMicromapEXT = 5381, + SpvCapabilityShaderInvocationReorderNV = 5383, + SpvCapabilityBindlessTextureNV = 5390, + SpvCapabilityRayQueryPositionFetchKHR = 5391, + SpvCapabilityAtomicFloat16VectorNV = 5404, + SpvCapabilityRayTracingDisplacementMicromapNV = 5409, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579, + SpvCapabilityRoundToInfinityINTEL = 5582, + SpvCapabilityFloatingPointModeINTEL = 5583, + SpvCapabilityIntegerFunctions2INTEL = 5584, + SpvCapabilityFunctionPointersINTEL = 5603, + SpvCapabilityIndirectReferencesINTEL = 5604, + SpvCapabilityAsmINTEL = 5606, + SpvCapabilityAtomicFloat32MinMaxEXT = 5612, + SpvCapabilityAtomicFloat64MinMaxEXT = 5613, + SpvCapabilityAtomicFloat16MinMaxEXT = 5616, + SpvCapabilityVectorComputeINTEL = 5617, + SpvCapabilityVectorAnyINTEL = 5619, + SpvCapabilityExpectAssumeKHR = 5629, + SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696, + SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + SpvCapabilityVariableLengthArrayINTEL = 5817, + SpvCapabilityFunctionFloatControlINTEL = 5821, + SpvCapabilityFPGAMemoryAttributesINTEL = 5824, + SpvCapabilityFPFastMathModeINTEL = 5837, + SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844, + SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845, + SpvCapabilityUnstructuredLoopControlsINTEL = 5886, + SpvCapabilityFPGALoopControlsINTEL = 5888, + SpvCapabilityKernelAttributesINTEL = 5892, + SpvCapabilityFPGAKernelAttributesINTEL = 5897, + SpvCapabilityFPGAMemoryAccessesINTEL = 5898, + SpvCapabilityFPGAClusterAttributesINTEL = 5904, + SpvCapabilityLoopFuseINTEL = 5906, + SpvCapabilityFPGADSPControlINTEL = 5908, + SpvCapabilityMemoryAccessAliasingINTEL = 5910, + SpvCapabilityFPGAInvocationPipeliningAttributesINTEL = 5916, + SpvCapabilityFPGABufferLocationINTEL = 5920, + SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922, + SpvCapabilityUSMStorageClassesINTEL = 5935, + SpvCapabilityRuntimeAlignedAttributeINTEL = 5939, + SpvCapabilityIOPipesINTEL = 5943, + SpvCapabilityBlockingPipesINTEL = 5945, + SpvCapabilityFPGARegINTEL = 5948, + SpvCapabilityDotProductInputAll = 6016, + SpvCapabilityDotProductInputAllKHR = 6016, + SpvCapabilityDotProductInput4x8Bit = 6017, + SpvCapabilityDotProductInput4x8BitKHR = 6017, + SpvCapabilityDotProductInput4x8BitPacked = 6018, + SpvCapabilityDotProductInput4x8BitPackedKHR = 6018, + SpvCapabilityDotProduct = 6019, + SpvCapabilityDotProductKHR = 6019, + SpvCapabilityRayCullMaskKHR = 6020, + SpvCapabilityCooperativeMatrixKHR = 6022, + SpvCapabilityBitInstructions = 6025, + SpvCapabilityGroupNonUniformRotateKHR = 6026, + SpvCapabilityFloatControls2 = 6029, + SpvCapabilityAtomicFloat32AddEXT = 6033, + SpvCapabilityAtomicFloat64AddEXT = 6034, + SpvCapabilityLongCompositesINTEL = 6089, + SpvCapabilityOptNoneINTEL = 6094, + SpvCapabilityAtomicFloat16AddEXT = 6095, + SpvCapabilityDebugInfoModuleINTEL = 6114, + SpvCapabilityBFloat16ConversionINTEL = 6115, + SpvCapabilitySplitBarrierINTEL = 6141, + SpvCapabilityFPGAClusterAttributesV2INTEL = 6150, + SpvCapabilityFPGAKernelAttributesv2INTEL = 6161, + SpvCapabilityFPMaxErrorINTEL = 6169, + SpvCapabilityFPGALatencyControlINTEL = 6171, + SpvCapabilityFPGAArgumentInterfacesINTEL = 6174, + SpvCapabilityGlobalVariableHostAccessINTEL = 6187, + SpvCapabilityGlobalVariableFPGADecorationsINTEL = 6189, + SpvCapabilityGroupUniformArithmeticKHR = 6400, + SpvCapabilityMaskedGatherScatterINTEL = 6427, + SpvCapabilityCacheControlsINTEL = 6441, + SpvCapabilityRegisterLimitsINTEL = 6460, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvRayFlagsShift_ { + SpvRayFlagsOpaqueKHRShift = 0, + SpvRayFlagsNoOpaqueKHRShift = 1, + SpvRayFlagsTerminateOnFirstHitKHRShift = 2, + SpvRayFlagsSkipClosestHitShaderKHRShift = 3, + SpvRayFlagsCullBackFacingTrianglesKHRShift = 4, + SpvRayFlagsCullFrontFacingTrianglesKHRShift = 5, + SpvRayFlagsCullOpaqueKHRShift = 6, + SpvRayFlagsCullNoOpaqueKHRShift = 7, + SpvRayFlagsSkipTrianglesKHRShift = 8, + SpvRayFlagsSkipAABBsKHRShift = 9, + SpvRayFlagsForceOpacityMicromap2StateEXTShift = 10, + SpvRayFlagsMax = 0x7fffffff, +} SpvRayFlagsShift; + +typedef enum SpvRayFlagsMask_ { + SpvRayFlagsMaskNone = 0, + SpvRayFlagsOpaqueKHRMask = 0x00000001, + SpvRayFlagsNoOpaqueKHRMask = 0x00000002, + SpvRayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + SpvRayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + SpvRayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + SpvRayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + SpvRayFlagsCullOpaqueKHRMask = 0x00000040, + SpvRayFlagsCullNoOpaqueKHRMask = 0x00000080, + SpvRayFlagsSkipTrianglesKHRMask = 0x00000100, + SpvRayFlagsSkipAABBsKHRMask = 0x00000200, + SpvRayFlagsForceOpacityMicromap2StateEXTMask = 0x00000400, +} SpvRayFlagsMask; + +typedef enum SpvRayQueryIntersection_ { + SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + SpvRayQueryIntersectionMax = 0x7fffffff, +} SpvRayQueryIntersection; + +typedef enum SpvRayQueryCommittedIntersectionType_ { + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + SpvRayQueryCommittedIntersectionTypeMax = 0x7fffffff, +} SpvRayQueryCommittedIntersectionType; + +typedef enum SpvRayQueryCandidateIntersectionType_ { + SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff, +} SpvRayQueryCandidateIntersectionType; + +typedef enum SpvFragmentShadingRateShift_ { + SpvFragmentShadingRateVertical2PixelsShift = 0, + SpvFragmentShadingRateVertical4PixelsShift = 1, + SpvFragmentShadingRateHorizontal2PixelsShift = 2, + SpvFragmentShadingRateHorizontal4PixelsShift = 3, + SpvFragmentShadingRateMax = 0x7fffffff, +} SpvFragmentShadingRateShift; + +typedef enum SpvFragmentShadingRateMask_ { + SpvFragmentShadingRateMaskNone = 0, + SpvFragmentShadingRateVertical2PixelsMask = 0x00000001, + SpvFragmentShadingRateVertical4PixelsMask = 0x00000002, + SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004, + SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008, +} SpvFragmentShadingRateMask; + +typedef enum SpvFPDenormMode_ { + SpvFPDenormModePreserve = 0, + SpvFPDenormModeFlushToZero = 1, + SpvFPDenormModeMax = 0x7fffffff, +} SpvFPDenormMode; + +typedef enum SpvFPOperationMode_ { + SpvFPOperationModeIEEE = 0, + SpvFPOperationModeALT = 1, + SpvFPOperationModeMax = 0x7fffffff, +} SpvFPOperationMode; + +typedef enum SpvQuantizationModes_ { + SpvQuantizationModesTRN = 0, + SpvQuantizationModesTRN_ZERO = 1, + SpvQuantizationModesRND = 2, + SpvQuantizationModesRND_ZERO = 3, + SpvQuantizationModesRND_INF = 4, + SpvQuantizationModesRND_MIN_INF = 5, + SpvQuantizationModesRND_CONV = 6, + SpvQuantizationModesRND_CONV_ODD = 7, + SpvQuantizationModesMax = 0x7fffffff, +} SpvQuantizationModes; + +typedef enum SpvOverflowModes_ { + SpvOverflowModesWRAP = 0, + SpvOverflowModesSAT = 1, + SpvOverflowModesSAT_ZERO = 2, + SpvOverflowModesSAT_SYM = 3, + SpvOverflowModesMax = 0x7fffffff, +} SpvOverflowModes; + +typedef enum SpvPackedVectorFormat_ { + SpvPackedVectorFormatPackedVectorFormat4x8Bit = 0, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + SpvPackedVectorFormatMax = 0x7fffffff, +} SpvPackedVectorFormat; + +typedef enum SpvCooperativeMatrixOperandsShift_ { + SpvCooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0, + SpvCooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1, + SpvCooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2, + SpvCooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3, + SpvCooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4, + SpvCooperativeMatrixOperandsMax = 0x7fffffff, +} SpvCooperativeMatrixOperandsShift; + +typedef enum SpvCooperativeMatrixOperandsMask_ { + SpvCooperativeMatrixOperandsMaskNone = 0, + SpvCooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001, + SpvCooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002, + SpvCooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004, + SpvCooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008, + SpvCooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010, +} SpvCooperativeMatrixOperandsMask; + +typedef enum SpvCooperativeMatrixLayout_ { + SpvCooperativeMatrixLayoutRowMajorKHR = 0, + SpvCooperativeMatrixLayoutColumnMajorKHR = 1, + SpvCooperativeMatrixLayoutMax = 0x7fffffff, +} SpvCooperativeMatrixLayout; + +typedef enum SpvCooperativeMatrixUse_ { + SpvCooperativeMatrixUseMatrixAKHR = 0, + SpvCooperativeMatrixUseMatrixBKHR = 1, + SpvCooperativeMatrixUseMatrixAccumulatorKHR = 2, + SpvCooperativeMatrixUseMax = 0x7fffffff, +} SpvCooperativeMatrixUse; + +typedef enum SpvInitializationModeQualifier_ { + SpvInitializationModeQualifierInitOnDeviceReprogramINTEL = 0, + SpvInitializationModeQualifierInitOnDeviceResetINTEL = 1, + SpvInitializationModeQualifierMax = 0x7fffffff, +} SpvInitializationModeQualifier; + +typedef enum SpvHostAccessQualifier_ { + SpvHostAccessQualifierNoneINTEL = 0, + SpvHostAccessQualifierReadINTEL = 1, + SpvHostAccessQualifierWriteINTEL = 2, + SpvHostAccessQualifierReadWriteINTEL = 3, + SpvHostAccessQualifierMax = 0x7fffffff, +} SpvHostAccessQualifier; + +typedef enum SpvLoadCacheControl_ { + SpvLoadCacheControlUncachedINTEL = 0, + SpvLoadCacheControlCachedINTEL = 1, + SpvLoadCacheControlStreamingINTEL = 2, + SpvLoadCacheControlInvalidateAfterReadINTEL = 3, + SpvLoadCacheControlConstCachedINTEL = 4, + SpvLoadCacheControlMax = 0x7fffffff, +} SpvLoadCacheControl; + +typedef enum SpvStoreCacheControl_ { + SpvStoreCacheControlUncachedINTEL = 0, + SpvStoreCacheControlWriteThroughINTEL = 1, + SpvStoreCacheControlWriteBackINTEL = 2, + SpvStoreCacheControlStreamingINTEL = 3, + SpvStoreCacheControlMax = 0x7fffffff, +} SpvStoreCacheControl; + +typedef enum SpvNamedMaximumNumberOfRegisters_ { + SpvNamedMaximumNumberOfRegistersAutoINTEL = 0, + SpvNamedMaximumNumberOfRegistersMax = 0x7fffffff, +} SpvNamedMaximumNumberOfRegisters; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpSizeOf = 321, + SpvOpTypePipeStorage = 322, + SpvOpConstantPipeStorage = 323, + SpvOpCreatePipeFromPipeStorage = 324, + SpvOpGetKernelLocalSizeForSubgroupCount = 325, + SpvOpGetKernelMaxNumSubgroups = 326, + SpvOpTypeNamedBarrier = 327, + SpvOpNamedBarrierInitialize = 328, + SpvOpMemoryNamedBarrier = 329, + SpvOpModuleProcessed = 330, + SpvOpExecutionModeId = 331, + SpvOpDecorateId = 332, + SpvOpGroupNonUniformElect = 333, + SpvOpGroupNonUniformAll = 334, + SpvOpGroupNonUniformAny = 335, + SpvOpGroupNonUniformAllEqual = 336, + SpvOpGroupNonUniformBroadcast = 337, + SpvOpGroupNonUniformBroadcastFirst = 338, + SpvOpGroupNonUniformBallot = 339, + SpvOpGroupNonUniformInverseBallot = 340, + SpvOpGroupNonUniformBallotBitExtract = 341, + SpvOpGroupNonUniformBallotBitCount = 342, + SpvOpGroupNonUniformBallotFindLSB = 343, + SpvOpGroupNonUniformBallotFindMSB = 344, + SpvOpGroupNonUniformShuffle = 345, + SpvOpGroupNonUniformShuffleXor = 346, + SpvOpGroupNonUniformShuffleUp = 347, + SpvOpGroupNonUniformShuffleDown = 348, + SpvOpGroupNonUniformIAdd = 349, + SpvOpGroupNonUniformFAdd = 350, + SpvOpGroupNonUniformIMul = 351, + SpvOpGroupNonUniformFMul = 352, + SpvOpGroupNonUniformSMin = 353, + SpvOpGroupNonUniformUMin = 354, + SpvOpGroupNonUniformFMin = 355, + SpvOpGroupNonUniformSMax = 356, + SpvOpGroupNonUniformUMax = 357, + SpvOpGroupNonUniformFMax = 358, + SpvOpGroupNonUniformBitwiseAnd = 359, + SpvOpGroupNonUniformBitwiseOr = 360, + SpvOpGroupNonUniformBitwiseXor = 361, + SpvOpGroupNonUniformLogicalAnd = 362, + SpvOpGroupNonUniformLogicalOr = 363, + SpvOpGroupNonUniformLogicalXor = 364, + SpvOpGroupNonUniformQuadBroadcast = 365, + SpvOpGroupNonUniformQuadSwap = 366, + SpvOpCopyLogical = 400, + SpvOpPtrEqual = 401, + SpvOpPtrNotEqual = 402, + SpvOpPtrDiff = 403, + SpvOpColorAttachmentReadEXT = 4160, + SpvOpDepthAttachmentReadEXT = 4161, + SpvOpStencilAttachmentReadEXT = 4162, + SpvOpTerminateInvocation = 4416, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpGroupNonUniformRotateKHR = 4431, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpTraceRayKHR = 4445, + SpvOpExecuteCallableKHR = 4446, + SpvOpConvertUToAccelerationStructureKHR = 4447, + SpvOpIgnoreIntersectionKHR = 4448, + SpvOpTerminateRayKHR = 4449, + SpvOpSDot = 4450, + SpvOpSDotKHR = 4450, + SpvOpUDot = 4451, + SpvOpUDotKHR = 4451, + SpvOpSUDot = 4452, + SpvOpSUDotKHR = 4452, + SpvOpSDotAccSat = 4453, + SpvOpSDotAccSatKHR = 4453, + SpvOpUDotAccSat = 4454, + SpvOpUDotAccSatKHR = 4454, + SpvOpSUDotAccSat = 4455, + SpvOpSUDotAccSatKHR = 4455, + SpvOpTypeCooperativeMatrixKHR = 4456, + SpvOpCooperativeMatrixLoadKHR = 4457, + SpvOpCooperativeMatrixStoreKHR = 4458, + SpvOpCooperativeMatrixMulAddKHR = 4459, + SpvOpCooperativeMatrixLengthKHR = 4460, + SpvOpTypeRayQueryKHR = 4472, + SpvOpRayQueryInitializeKHR = 4473, + SpvOpRayQueryTerminateKHR = 4474, + SpvOpRayQueryGenerateIntersectionKHR = 4475, + SpvOpRayQueryConfirmIntersectionKHR = 4476, + SpvOpRayQueryProceedKHR = 4477, + SpvOpRayQueryGetIntersectionTypeKHR = 4479, + SpvOpImageSampleWeightedQCOM = 4480, + SpvOpImageBoxFilterQCOM = 4481, + SpvOpImageBlockMatchSSDQCOM = 4482, + SpvOpImageBlockMatchSADQCOM = 4483, + SpvOpImageBlockMatchWindowSSDQCOM = 4500, + SpvOpImageBlockMatchWindowSADQCOM = 4501, + SpvOpImageBlockMatchGatherSSDQCOM = 4502, + SpvOpImageBlockMatchGatherSADQCOM = 4503, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpReadClockKHR = 5056, + SpvOpFinalizeNodePayloadsAMDX = 5075, + SpvOpFinishWritingNodePayloadAMDX = 5078, + SpvOpInitializeNodePayloadsAMDX = 5090, + SpvOpGroupNonUniformQuadAllKHR = 5110, + SpvOpGroupNonUniformQuadAnyKHR = 5111, + SpvOpHitObjectRecordHitMotionNV = 5249, + SpvOpHitObjectRecordHitWithIndexMotionNV = 5250, + SpvOpHitObjectRecordMissMotionNV = 5251, + SpvOpHitObjectGetWorldToObjectNV = 5252, + SpvOpHitObjectGetObjectToWorldNV = 5253, + SpvOpHitObjectGetObjectRayDirectionNV = 5254, + SpvOpHitObjectGetObjectRayOriginNV = 5255, + SpvOpHitObjectTraceRayMotionNV = 5256, + SpvOpHitObjectGetShaderRecordBufferHandleNV = 5257, + SpvOpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + SpvOpHitObjectRecordEmptyNV = 5259, + SpvOpHitObjectTraceRayNV = 5260, + SpvOpHitObjectRecordHitNV = 5261, + SpvOpHitObjectRecordHitWithIndexNV = 5262, + SpvOpHitObjectRecordMissNV = 5263, + SpvOpHitObjectExecuteShaderNV = 5264, + SpvOpHitObjectGetCurrentTimeNV = 5265, + SpvOpHitObjectGetAttributesNV = 5266, + SpvOpHitObjectGetHitKindNV = 5267, + SpvOpHitObjectGetPrimitiveIndexNV = 5268, + SpvOpHitObjectGetGeometryIndexNV = 5269, + SpvOpHitObjectGetInstanceIdNV = 5270, + SpvOpHitObjectGetInstanceCustomIndexNV = 5271, + SpvOpHitObjectGetWorldRayDirectionNV = 5272, + SpvOpHitObjectGetWorldRayOriginNV = 5273, + SpvOpHitObjectGetRayTMaxNV = 5274, + SpvOpHitObjectGetRayTMinNV = 5275, + SpvOpHitObjectIsEmptyNV = 5276, + SpvOpHitObjectIsHitNV = 5277, + SpvOpHitObjectIsMissNV = 5278, + SpvOpReorderThreadWithHitObjectNV = 5279, + SpvOpReorderThreadWithHintNV = 5280, + SpvOpTypeHitObjectNV = 5281, + SpvOpImageSampleFootprintNV = 5283, + SpvOpEmitMeshTasksEXT = 5294, + SpvOpSetMeshOutputsEXT = 5295, + SpvOpGroupNonUniformPartitionNV = 5296, + SpvOpWritePackedPrimitiveIndices4x8NV = 5299, + SpvOpFetchMicroTriangleVertexPositionNV = 5300, + SpvOpFetchMicroTriangleVertexBarycentricNV = 5301, + SpvOpReportIntersectionKHR = 5334, + SpvOpReportIntersectionNV = 5334, + SpvOpIgnoreIntersectionNV = 5335, + SpvOpTerminateRayNV = 5336, + SpvOpTraceNV = 5337, + SpvOpTraceMotionNV = 5338, + SpvOpTraceRayMotionNV = 5339, + SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + SpvOpTypeAccelerationStructureKHR = 5341, + SpvOpTypeAccelerationStructureNV = 5341, + SpvOpExecuteCallableNV = 5344, + SpvOpTypeCooperativeMatrixNV = 5358, + SpvOpCooperativeMatrixLoadNV = 5359, + SpvOpCooperativeMatrixStoreNV = 5360, + SpvOpCooperativeMatrixMulAddNV = 5361, + SpvOpCooperativeMatrixLengthNV = 5362, + SpvOpBeginInvocationInterlockEXT = 5364, + SpvOpEndInvocationInterlockEXT = 5365, + SpvOpDemoteToHelperInvocation = 5380, + SpvOpDemoteToHelperInvocationEXT = 5380, + SpvOpIsHelperInvocationEXT = 5381, + SpvOpConvertUToImageNV = 5391, + SpvOpConvertUToSamplerNV = 5392, + SpvOpConvertImageToUNV = 5393, + SpvOpConvertSamplerToUNV = 5394, + SpvOpConvertUToSampledImageNV = 5395, + SpvOpConvertSampledImageToUNV = 5396, + SpvOpSamplerImageAddressingModeNV = 5397, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpSubgroupImageMediaBlockReadINTEL = 5580, + SpvOpSubgroupImageMediaBlockWriteINTEL = 5581, + SpvOpUCountLeadingZerosINTEL = 5585, + SpvOpUCountTrailingZerosINTEL = 5586, + SpvOpAbsISubINTEL = 5587, + SpvOpAbsUSubINTEL = 5588, + SpvOpIAddSatINTEL = 5589, + SpvOpUAddSatINTEL = 5590, + SpvOpIAverageINTEL = 5591, + SpvOpUAverageINTEL = 5592, + SpvOpIAverageRoundedINTEL = 5593, + SpvOpUAverageRoundedINTEL = 5594, + SpvOpISubSatINTEL = 5595, + SpvOpUSubSatINTEL = 5596, + SpvOpIMul32x16INTEL = 5597, + SpvOpUMul32x16INTEL = 5598, + SpvOpConstantFunctionPointerINTEL = 5600, + SpvOpFunctionPointerCallINTEL = 5601, + SpvOpAsmTargetINTEL = 5609, + SpvOpAsmINTEL = 5610, + SpvOpAsmCallINTEL = 5611, + SpvOpAtomicFMinEXT = 5614, + SpvOpAtomicFMaxEXT = 5615, + SpvOpAssumeTrueKHR = 5630, + SpvOpExpectKHR = 5631, + SpvOpDecorateString = 5632, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateString = 5633, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpVmeImageINTEL = 5699, + SpvOpTypeVmeImageINTEL = 5700, + SpvOpTypeAvcImePayloadINTEL = 5701, + SpvOpTypeAvcRefPayloadINTEL = 5702, + SpvOpTypeAvcSicPayloadINTEL = 5703, + SpvOpTypeAvcMcePayloadINTEL = 5704, + SpvOpTypeAvcMceResultINTEL = 5705, + SpvOpTypeAvcImeResultINTEL = 5706, + SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + SpvOpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + SpvOpTypeAvcImeDualReferenceStreaminINTEL = 5710, + SpvOpTypeAvcRefResultINTEL = 5711, + SpvOpTypeAvcSicResultINTEL = 5712, + SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + SpvOpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + SpvOpSubgroupAvcMceConvertToImeResultINTEL = 5733, + SpvOpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + SpvOpSubgroupAvcMceConvertToRefResultINTEL = 5735, + SpvOpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + SpvOpSubgroupAvcMceConvertToSicResultINTEL = 5737, + SpvOpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + SpvOpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + SpvOpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + SpvOpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + SpvOpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + SpvOpSubgroupAvcImeInitializeINTEL = 5747, + SpvOpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + SpvOpSubgroupAvcImeSetDualReferenceINTEL = 5749, + SpvOpSubgroupAvcImeRefWindowSizeINTEL = 5750, + SpvOpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + SpvOpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + SpvOpSubgroupAvcImeSetWeightedSadINTEL = 5756, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + SpvOpSubgroupAvcImeConvertToMceResultINTEL = 5765, + SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + SpvOpSubgroupAvcImeGetBorderReachedINTEL = 5776, + SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + SpvOpSubgroupAvcFmeInitializeINTEL = 5781, + SpvOpSubgroupAvcBmeInitializeINTEL = 5782, + SpvOpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + SpvOpSubgroupAvcRefConvertToMceResultINTEL = 5790, + SpvOpSubgroupAvcSicInitializeINTEL = 5791, + SpvOpSubgroupAvcSicConfigureSkcINTEL = 5792, + SpvOpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + SpvOpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + SpvOpSubgroupAvcSicEvaluateIpeINTEL = 5803, + SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + SpvOpSubgroupAvcSicConvertToMceResultINTEL = 5808, + SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + SpvOpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + SpvOpVariableLengthArrayINTEL = 5818, + SpvOpSaveMemoryINTEL = 5819, + SpvOpRestoreMemoryINTEL = 5820, + SpvOpArbitraryFloatSinCosPiINTEL = 5840, + SpvOpArbitraryFloatCastINTEL = 5841, + SpvOpArbitraryFloatCastFromIntINTEL = 5842, + SpvOpArbitraryFloatCastToIntINTEL = 5843, + SpvOpArbitraryFloatAddINTEL = 5846, + SpvOpArbitraryFloatSubINTEL = 5847, + SpvOpArbitraryFloatMulINTEL = 5848, + SpvOpArbitraryFloatDivINTEL = 5849, + SpvOpArbitraryFloatGTINTEL = 5850, + SpvOpArbitraryFloatGEINTEL = 5851, + SpvOpArbitraryFloatLTINTEL = 5852, + SpvOpArbitraryFloatLEINTEL = 5853, + SpvOpArbitraryFloatEQINTEL = 5854, + SpvOpArbitraryFloatRecipINTEL = 5855, + SpvOpArbitraryFloatRSqrtINTEL = 5856, + SpvOpArbitraryFloatCbrtINTEL = 5857, + SpvOpArbitraryFloatHypotINTEL = 5858, + SpvOpArbitraryFloatSqrtINTEL = 5859, + SpvOpArbitraryFloatLogINTEL = 5860, + SpvOpArbitraryFloatLog2INTEL = 5861, + SpvOpArbitraryFloatLog10INTEL = 5862, + SpvOpArbitraryFloatLog1pINTEL = 5863, + SpvOpArbitraryFloatExpINTEL = 5864, + SpvOpArbitraryFloatExp2INTEL = 5865, + SpvOpArbitraryFloatExp10INTEL = 5866, + SpvOpArbitraryFloatExpm1INTEL = 5867, + SpvOpArbitraryFloatSinINTEL = 5868, + SpvOpArbitraryFloatCosINTEL = 5869, + SpvOpArbitraryFloatSinCosINTEL = 5870, + SpvOpArbitraryFloatSinPiINTEL = 5871, + SpvOpArbitraryFloatCosPiINTEL = 5872, + SpvOpArbitraryFloatASinINTEL = 5873, + SpvOpArbitraryFloatASinPiINTEL = 5874, + SpvOpArbitraryFloatACosINTEL = 5875, + SpvOpArbitraryFloatACosPiINTEL = 5876, + SpvOpArbitraryFloatATanINTEL = 5877, + SpvOpArbitraryFloatATanPiINTEL = 5878, + SpvOpArbitraryFloatATan2INTEL = 5879, + SpvOpArbitraryFloatPowINTEL = 5880, + SpvOpArbitraryFloatPowRINTEL = 5881, + SpvOpArbitraryFloatPowNINTEL = 5882, + SpvOpLoopControlINTEL = 5887, + SpvOpAliasDomainDeclINTEL = 5911, + SpvOpAliasScopeDeclINTEL = 5912, + SpvOpAliasScopeListDeclINTEL = 5913, + SpvOpFixedSqrtINTEL = 5923, + SpvOpFixedRecipINTEL = 5924, + SpvOpFixedRsqrtINTEL = 5925, + SpvOpFixedSinINTEL = 5926, + SpvOpFixedCosINTEL = 5927, + SpvOpFixedSinCosINTEL = 5928, + SpvOpFixedSinPiINTEL = 5929, + SpvOpFixedCosPiINTEL = 5930, + SpvOpFixedSinCosPiINTEL = 5931, + SpvOpFixedLogINTEL = 5932, + SpvOpFixedExpINTEL = 5933, + SpvOpPtrCastToCrossWorkgroupINTEL = 5934, + SpvOpCrossWorkgroupCastToPtrINTEL = 5938, + SpvOpReadPipeBlockingINTEL = 5946, + SpvOpWritePipeBlockingINTEL = 5947, + SpvOpFPGARegINTEL = 5949, + SpvOpRayQueryGetRayTMinKHR = 6016, + SpvOpRayQueryGetRayFlagsKHR = 6017, + SpvOpRayQueryGetIntersectionTKHR = 6018, + SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + SpvOpRayQueryGetIntersectionInstanceIdKHR = 6020, + SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + SpvOpRayQueryGetIntersectionGeometryIndexKHR = 6022, + SpvOpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + SpvOpRayQueryGetIntersectionBarycentricsKHR = 6024, + SpvOpRayQueryGetIntersectionFrontFaceKHR = 6025, + SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + SpvOpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + SpvOpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + SpvOpRayQueryGetWorldRayDirectionKHR = 6029, + SpvOpRayQueryGetWorldRayOriginKHR = 6030, + SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031, + SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032, + SpvOpAtomicFAddEXT = 6035, + SpvOpTypeBufferSurfaceINTEL = 6086, + SpvOpTypeStructContinuedINTEL = 6090, + SpvOpConstantCompositeContinuedINTEL = 6091, + SpvOpSpecConstantCompositeContinuedINTEL = 6092, + SpvOpCompositeConstructContinuedINTEL = 6096, + SpvOpConvertFToBF16INTEL = 6116, + SpvOpConvertBF16ToFINTEL = 6117, + SpvOpControlBarrierArriveINTEL = 6142, + SpvOpControlBarrierWaitINTEL = 6143, + SpvOpGroupIMulKHR = 6401, + SpvOpGroupFMulKHR = 6402, + SpvOpGroupBitwiseAndKHR = 6403, + SpvOpGroupBitwiseOrKHR = 6404, + SpvOpGroupBitwiseXorKHR = 6405, + SpvOpGroupLogicalAndKHR = 6406, + SpvOpGroupLogicalOrKHR = 6407, + SpvOpGroupLogicalXorKHR = 6408, + SpvOpMaskedGatherINTEL = 6428, + SpvOpMaskedScatterINTEL = 6429, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif +inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case SpvOpNop: *hasResult = false; *hasResultType = false; break; + case SpvOpUndef: *hasResult = true; *hasResultType = true; break; + case SpvOpSourceContinued: *hasResult = false; *hasResultType = false; break; + case SpvOpSource: *hasResult = false; *hasResultType = false; break; + case SpvOpSourceExtension: *hasResult = false; *hasResultType = false; break; + case SpvOpName: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberName: *hasResult = false; *hasResultType = false; break; + case SpvOpString: *hasResult = true; *hasResultType = false; break; + case SpvOpLine: *hasResult = false; *hasResultType = false; break; + case SpvOpExtension: *hasResult = false; *hasResultType = false; break; + case SpvOpExtInstImport: *hasResult = true; *hasResultType = false; break; + case SpvOpExtInst: *hasResult = true; *hasResultType = true; break; + case SpvOpMemoryModel: *hasResult = false; *hasResultType = false; break; + case SpvOpEntryPoint: *hasResult = false; *hasResultType = false; break; + case SpvOpExecutionMode: *hasResult = false; *hasResultType = false; break; + case SpvOpCapability: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeVoid: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeBool: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeInt: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeFloat: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeVector: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeImage: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeSampler: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeArray: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeStruct: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case SpvOpTypePointer: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeFunction: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeEvent: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeQueue: *hasResult = true; *hasResultType = false; break; + case SpvOpTypePipe: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case SpvOpConstantTrue: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantFalse: *hasResult = true; *hasResultType = true; break; + case SpvOpConstant: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantComposite: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantSampler: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantNull: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstant: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case SpvOpFunction: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case SpvOpFunctionCall: *hasResult = true; *hasResultType = true; break; + case SpvOpVariable: *hasResult = true; *hasResultType = true; break; + case SpvOpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case SpvOpLoad: *hasResult = true; *hasResultType = true; break; + case SpvOpStore: *hasResult = false; *hasResultType = false; break; + case SpvOpCopyMemory: *hasResult = false; *hasResultType = false; break; + case SpvOpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case SpvOpAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpArrayLength: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case SpvOpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case SpvOpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case SpvOpCopyObject: *hasResult = true; *hasResultType = true; break; + case SpvOpTranspose: *hasResult = true; *hasResultType = true; break; + case SpvOpSampledImage: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageFetch: *hasResult = true; *hasResultType = true; break; + case SpvOpImageGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageRead: *hasResult = true; *hasResultType = true; break; + case SpvOpImageWrite: *hasResult = false; *hasResultType = false; break; + case SpvOpImage: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToU: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToS: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSToF: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToF: *hasResult = true; *hasResultType = true; break; + case SpvOpUConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpSConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpFConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case SpvOpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case SpvOpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case SpvOpBitcast: *hasResult = true; *hasResultType = true; break; + case SpvOpSNegate: *hasResult = true; *hasResultType = true; break; + case SpvOpFNegate: *hasResult = true; *hasResultType = true; break; + case SpvOpIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpISub: *hasResult = true; *hasResultType = true; break; + case SpvOpFSub: *hasResult = true; *hasResultType = true; break; + case SpvOpIMul: *hasResult = true; *hasResultType = true; break; + case SpvOpFMul: *hasResult = true; *hasResultType = true; break; + case SpvOpUDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpSDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpFDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpUMod: *hasResult = true; *hasResultType = true; break; + case SpvOpSRem: *hasResult = true; *hasResultType = true; break; + case SpvOpSMod: *hasResult = true; *hasResultType = true; break; + case SpvOpFRem: *hasResult = true; *hasResultType = true; break; + case SpvOpFMod: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case SpvOpOuterProduct: *hasResult = true; *hasResultType = true; break; + case SpvOpDot: *hasResult = true; *hasResultType = true; break; + case SpvOpIAddCarry: *hasResult = true; *hasResultType = true; break; + case SpvOpISubBorrow: *hasResult = true; *hasResultType = true; break; + case SpvOpUMulExtended: *hasResult = true; *hasResultType = true; break; + case SpvOpSMulExtended: *hasResult = true; *hasResultType = true; break; + case SpvOpAny: *hasResult = true; *hasResultType = true; break; + case SpvOpAll: *hasResult = true; *hasResultType = true; break; + case SpvOpIsNan: *hasResult = true; *hasResultType = true; break; + case SpvOpIsInf: *hasResult = true; *hasResultType = true; break; + case SpvOpIsFinite: *hasResult = true; *hasResultType = true; break; + case SpvOpIsNormal: *hasResult = true; *hasResultType = true; break; + case SpvOpSignBitSet: *hasResult = true; *hasResultType = true; break; + case SpvOpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case SpvOpOrdered: *hasResult = true; *hasResultType = true; break; + case SpvOpUnordered: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalOr: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalNot: *hasResult = true; *hasResultType = true; break; + case SpvOpSelect: *hasResult = true; *hasResultType = true; break; + case SpvOpIEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpINotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpULessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpSLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpNot: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpBitReverse: *hasResult = true; *hasResultType = true; break; + case SpvOpBitCount: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdx: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdy: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidth: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdxFine: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdyFine: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidthFine: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpEmitVertex: *hasResult = false; *hasResultType = false; break; + case SpvOpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case SpvOpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case SpvOpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicStore: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicISub: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicOr: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicXor: *hasResult = true; *hasResultType = true; break; + case SpvOpPhi: *hasResult = true; *hasResultType = true; break; + case SpvOpLoopMerge: *hasResult = false; *hasResultType = false; break; + case SpvOpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case SpvOpLabel: *hasResult = true; *hasResultType = false; break; + case SpvOpBranch: *hasResult = false; *hasResultType = false; break; + case SpvOpBranchConditional: *hasResult = false; *hasResultType = false; break; + case SpvOpSwitch: *hasResult = false; *hasResultType = false; break; + case SpvOpKill: *hasResult = false; *hasResultType = false; break; + case SpvOpReturn: *hasResult = false; *hasResultType = false; break; + case SpvOpReturnValue: *hasResult = false; *hasResultType = false; break; + case SpvOpUnreachable: *hasResult = false; *hasResultType = false; break; + case SpvOpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case SpvOpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupAll: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupAny: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpReadPipe: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case SpvOpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case SpvOpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case SpvOpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case SpvOpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case SpvOpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case SpvOpRetainEvent: *hasResult = false; *hasResultType = false; break; + case SpvOpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case SpvOpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case SpvOpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case SpvOpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case SpvOpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case SpvOpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case SpvOpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case SpvOpNoLine: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case SpvOpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case SpvOpSizeOf: *hasResult = true; *hasResultType = true; break; + case SpvOpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case SpvOpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case SpvOpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case SpvOpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case SpvOpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case SpvOpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case SpvOpDecorateId: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break; + case SpvOpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpSDot: *hasResult = true; *hasResultType = true; break; + case SpvOpUDot: *hasResult = true; *hasResultType = true; break; + case SpvOpSUDot: *hasResult = true; *hasResultType = true; break; + case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break; + case SpvOpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleWeightedQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case SpvOpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break; + case SpvOpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectGetWorldToObjectNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetObjectToWorldNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetObjectRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetObjectRayOriginNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectGetShaderRecordBufferHandleNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetShaderBindingTableRecordIndexNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectRecordEmptyNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectTraceRayNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordHitNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordHitWithIndexNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordMissNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectExecuteShaderNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectGetCurrentTimeNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetAttributesNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectGetHitKindNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetPrimitiveIndexNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetGeometryIndexNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetInstanceIdNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetInstanceCustomIndexNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetWorldRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetWorldRayOriginNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetRayTMaxNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetRayTMinNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectIsEmptyNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectIsHitNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectIsMissNV: *hasResult = true; *hasResultType = true; break; + case SpvOpReorderThreadWithHitObjectNV: *hasResult = false; *hasResultType = false; break; + case SpvOpReorderThreadWithHintNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeHitObjectNV: *hasResult = true; *hasResultType = false; break; + case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case SpvOpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case SpvOpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; + case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case SpvOpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpExpectKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +#endif + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.hpp b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.hpp new file mode 100644 index 000000000000..327000af9a2d --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.hpp @@ -0,0 +1,2924 @@ +// Copyright (c) 2014-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010600; +static const unsigned int Revision = 1; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageCPP_for_OpenCL = 6, + SourceLanguageSYCL = 7, + SourceLanguageHERO_C = 8, + SourceLanguageNZSL = 9, + SourceLanguageWGSL = 10, + SourceLanguageSlang = 11, + SourceLanguageZig = 12, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelTaskNV = 5267, + ExecutionModelMeshNV = 5268, + ExecutionModelRayGenerationKHR = 5313, + ExecutionModelRayGenerationNV = 5313, + ExecutionModelIntersectionKHR = 5314, + ExecutionModelIntersectionNV = 5314, + ExecutionModelAnyHitKHR = 5315, + ExecutionModelAnyHitNV = 5315, + ExecutionModelClosestHitKHR = 5316, + ExecutionModelClosestHitNV = 5316, + ExecutionModelMissKHR = 5317, + ExecutionModelMissNV = 5317, + ExecutionModelCallableKHR = 5318, + ExecutionModelCallableNV = 5318, + ExecutionModelTaskEXT = 5364, + ExecutionModelMeshEXT = 5365, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelPhysicalStorageBuffer64 = 5348, + AddressingModelPhysicalStorageBuffer64EXT = 5348, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelVulkan = 3, + MemoryModelVulkanKHR = 3, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModeInitializer = 33, + ExecutionModeFinalizer = 34, + ExecutionModeSubgroupSize = 35, + ExecutionModeSubgroupsPerWorkgroup = 36, + ExecutionModeSubgroupsPerWorkgroupId = 37, + ExecutionModeLocalSizeId = 38, + ExecutionModeLocalSizeHintId = 39, + ExecutionModeNonCoherentColorAttachmentReadEXT = 4169, + ExecutionModeNonCoherentDepthAttachmentReadEXT = 4170, + ExecutionModeNonCoherentStencilAttachmentReadEXT = 4171, + ExecutionModeSubgroupUniformControlFlowKHR = 4421, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeDenormPreserve = 4459, + ExecutionModeDenormFlushToZero = 4460, + ExecutionModeSignedZeroInfNanPreserve = 4461, + ExecutionModeRoundingModeRTE = 4462, + ExecutionModeRoundingModeRTZ = 4463, + ExecutionModeEarlyAndLateFragmentTestsAMD = 5017, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeCoalescingAMDX = 5069, + ExecutionModeMaxNodeRecursionAMDX = 5071, + ExecutionModeStaticNumWorkgroupsAMDX = 5072, + ExecutionModeShaderIndexAMDX = 5073, + ExecutionModeMaxNumWorkgroupsAMDX = 5077, + ExecutionModeStencilRefUnchangedFrontAMD = 5079, + ExecutionModeStencilRefGreaterFrontAMD = 5080, + ExecutionModeStencilRefLessFrontAMD = 5081, + ExecutionModeStencilRefUnchangedBackAMD = 5082, + ExecutionModeStencilRefGreaterBackAMD = 5083, + ExecutionModeStencilRefLessBackAMD = 5084, + ExecutionModeQuadDerivativesKHR = 5088, + ExecutionModeRequireFullQuadsKHR = 5089, + ExecutionModeOutputLinesEXT = 5269, + ExecutionModeOutputLinesNV = 5269, + ExecutionModeOutputPrimitivesEXT = 5270, + ExecutionModeOutputPrimitivesNV = 5270, + ExecutionModeDerivativeGroupQuadsNV = 5289, + ExecutionModeDerivativeGroupLinearNV = 5290, + ExecutionModeOutputTrianglesEXT = 5298, + ExecutionModeOutputTrianglesNV = 5298, + ExecutionModePixelInterlockOrderedEXT = 5366, + ExecutionModePixelInterlockUnorderedEXT = 5367, + ExecutionModeSampleInterlockOrderedEXT = 5368, + ExecutionModeSampleInterlockUnorderedEXT = 5369, + ExecutionModeShadingRateInterlockOrderedEXT = 5370, + ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeSharedLocalMemorySizeINTEL = 5618, + ExecutionModeRoundingModeRTPINTEL = 5620, + ExecutionModeRoundingModeRTNINTEL = 5621, + ExecutionModeFloatingPointModeALTINTEL = 5622, + ExecutionModeFloatingPointModeIEEEINTEL = 5623, + ExecutionModeMaxWorkgroupSizeINTEL = 5893, + ExecutionModeMaxWorkDimINTEL = 5894, + ExecutionModeNoGlobalOffsetINTEL = 5895, + ExecutionModeNumSIMDWorkitemsINTEL = 5896, + ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + ExecutionModeMaximallyReconvergesKHR = 6023, + ExecutionModeFPFastMathDefault = 6028, + ExecutionModeStreamingInterfaceINTEL = 6154, + ExecutionModeRegisterMapInterfaceINTEL = 6160, + ExecutionModeNamedBarrierCountINTEL = 6417, + ExecutionModeMaximumRegistersINTEL = 6461, + ExecutionModeMaximumRegistersIdINTEL = 6462, + ExecutionModeNamedMaximumRegistersINTEL = 6463, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassTileImageEXT = 4172, + StorageClassNodePayloadAMDX = 5068, + StorageClassNodeOutputPayloadAMDX = 5076, + StorageClassCallableDataKHR = 5328, + StorageClassCallableDataNV = 5328, + StorageClassIncomingCallableDataKHR = 5329, + StorageClassIncomingCallableDataNV = 5329, + StorageClassRayPayloadKHR = 5338, + StorageClassRayPayloadNV = 5338, + StorageClassHitAttributeKHR = 5339, + StorageClassHitAttributeNV = 5339, + StorageClassIncomingRayPayloadKHR = 5342, + StorageClassIncomingRayPayloadNV = 5342, + StorageClassShaderRecordBufferKHR = 5343, + StorageClassShaderRecordBufferNV = 5343, + StorageClassPhysicalStorageBuffer = 5349, + StorageClassPhysicalStorageBufferEXT = 5349, + StorageClassHitObjectAttributeNV = 5385, + StorageClassTaskPayloadWorkgroupEXT = 5402, + StorageClassCodeSectionINTEL = 5605, + StorageClassDeviceOnlyINTEL = 5936, + StorageClassHostOnlyINTEL = 5937, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimTileImageDataEXT = 4173, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatR64ui = 40, + ImageFormatR64i = 41, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeUnsignedIntRaw10EXT = 19, + ImageChannelDataTypeUnsignedIntRaw12EXT = 20, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMakeTexelAvailableShift = 8, + ImageOperandsMakeTexelAvailableKHRShift = 8, + ImageOperandsMakeTexelVisibleShift = 9, + ImageOperandsMakeTexelVisibleKHRShift = 9, + ImageOperandsNonPrivateTexelShift = 10, + ImageOperandsNonPrivateTexelKHRShift = 10, + ImageOperandsVolatileTexelShift = 11, + ImageOperandsVolatileTexelKHRShift = 11, + ImageOperandsSignExtendShift = 12, + ImageOperandsZeroExtendShift = 13, + ImageOperandsNontemporalShift = 14, + ImageOperandsOffsetsShift = 16, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, + ImageOperandsMakeTexelAvailableMask = 0x00000100, + ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + ImageOperandsMakeTexelVisibleMask = 0x00000200, + ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + ImageOperandsNonPrivateTexelMask = 0x00000400, + ImageOperandsNonPrivateTexelKHRMask = 0x00000400, + ImageOperandsVolatileTexelMask = 0x00000800, + ImageOperandsVolatileTexelKHRMask = 0x00000800, + ImageOperandsSignExtendMask = 0x00001000, + ImageOperandsZeroExtendMask = 0x00002000, + ImageOperandsNontemporalMask = 0x00004000, + ImageOperandsOffsetsMask = 0x00010000, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeAllowContractShift = 16, + FPFastMathModeAllowContractFastINTELShift = 16, + FPFastMathModeAllowReassocShift = 17, + FPFastMathModeAllowReassocINTELShift = 17, + FPFastMathModeAllowTransformShift = 18, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, + FPFastMathModeAllowContractMask = 0x00010000, + FPFastMathModeAllowContractFastINTELMask = 0x00010000, + FPFastMathModeAllowReassocMask = 0x00020000, + FPFastMathModeAllowReassocINTELMask = 0x00020000, + FPFastMathModeAllowTransformMask = 0x00040000, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeLinkOnceODR = 2, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeRuntimeAlignedINTEL = 5940, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationUniformId = 27, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationMaxByteOffset = 45, + DecorationAlignmentId = 46, + DecorationMaxByteOffsetId = 47, + DecorationNoSignedWrap = 4469, + DecorationNoUnsignedWrap = 4470, + DecorationWeightTextureQCOM = 4487, + DecorationBlockMatchTextureQCOM = 4488, + DecorationBlockMatchSamplerQCOM = 4499, + DecorationExplicitInterpAMD = 4999, + DecorationNodeSharesPayloadLimitsWithAMDX = 5019, + DecorationNodeMaxPayloadsAMDX = 5020, + DecorationTrackFinishWritingAMDX = 5078, + DecorationPayloadNodeNameAMDX = 5091, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationPerPrimitiveEXT = 5271, + DecorationPerPrimitiveNV = 5271, + DecorationPerViewNV = 5272, + DecorationPerTaskNV = 5273, + DecorationPerVertexKHR = 5285, + DecorationPerVertexNV = 5285, + DecorationNonUniform = 5300, + DecorationNonUniformEXT = 5300, + DecorationRestrictPointer = 5355, + DecorationRestrictPointerEXT = 5355, + DecorationAliasedPointer = 5356, + DecorationAliasedPointerEXT = 5356, + DecorationHitObjectShaderRecordBufferNV = 5386, + DecorationBindlessSamplerNV = 5398, + DecorationBindlessImageNV = 5399, + DecorationBoundSamplerNV = 5400, + DecorationBoundImageNV = 5401, + DecorationSIMTCallINTEL = 5599, + DecorationReferencedIndirectlyINTEL = 5602, + DecorationClobberINTEL = 5607, + DecorationSideEffectsINTEL = 5608, + DecorationVectorComputeVariableINTEL = 5624, + DecorationFuncParamIOKindINTEL = 5625, + DecorationVectorComputeFunctionINTEL = 5626, + DecorationStackCallINTEL = 5627, + DecorationGlobalVariableOffsetINTEL = 5628, + DecorationCounterBuffer = 5634, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationUserSemantic = 5635, + DecorationUserTypeGOOGLE = 5636, + DecorationFunctionRoundingModeINTEL = 5822, + DecorationFunctionDenormModeINTEL = 5823, + DecorationRegisterINTEL = 5825, + DecorationMemoryINTEL = 5826, + DecorationNumbanksINTEL = 5827, + DecorationBankwidthINTEL = 5828, + DecorationMaxPrivateCopiesINTEL = 5829, + DecorationSinglepumpINTEL = 5830, + DecorationDoublepumpINTEL = 5831, + DecorationMaxReplicatesINTEL = 5832, + DecorationSimpleDualPortINTEL = 5833, + DecorationMergeINTEL = 5834, + DecorationBankBitsINTEL = 5835, + DecorationForcePow2DepthINTEL = 5836, + DecorationStridesizeINTEL = 5883, + DecorationWordsizeINTEL = 5884, + DecorationTrueDualPortINTEL = 5885, + DecorationBurstCoalesceINTEL = 5899, + DecorationCacheSizeINTEL = 5900, + DecorationDontStaticallyCoalesceINTEL = 5901, + DecorationPrefetchINTEL = 5902, + DecorationStallEnableINTEL = 5905, + DecorationFuseLoopsInFunctionINTEL = 5907, + DecorationMathOpDSPModeINTEL = 5909, + DecorationAliasScopeINTEL = 5914, + DecorationNoAliasINTEL = 5915, + DecorationInitiationIntervalINTEL = 5917, + DecorationMaxConcurrencyINTEL = 5918, + DecorationPipelineEnableINTEL = 5919, + DecorationBufferLocationINTEL = 5921, + DecorationIOPipeStorageINTEL = 5944, + DecorationFunctionFloatingPointModeINTEL = 6080, + DecorationSingleElementVectorINTEL = 6085, + DecorationVectorComputeCallableFunctionINTEL = 6087, + DecorationMediaBlockIOINTEL = 6140, + DecorationStallFreeINTEL = 6151, + DecorationFPMaxErrorDecorationINTEL = 6170, + DecorationLatencyControlLabelINTEL = 6172, + DecorationLatencyControlConstraintINTEL = 6173, + DecorationConduitKernelArgumentINTEL = 6175, + DecorationRegisterMapKernelArgumentINTEL = 6176, + DecorationMMHostInterfaceAddressWidthINTEL = 6177, + DecorationMMHostInterfaceDataWidthINTEL = 6178, + DecorationMMHostInterfaceLatencyINTEL = 6179, + DecorationMMHostInterfaceReadWriteModeINTEL = 6180, + DecorationMMHostInterfaceMaxBurstINTEL = 6181, + DecorationMMHostInterfaceWaitRequestINTEL = 6182, + DecorationStableKernelArgumentINTEL = 6183, + DecorationHostAccessINTEL = 6188, + DecorationInitModeINTEL = 6190, + DecorationImplementInRegisterMapINTEL = 6191, + DecorationCacheControlLoadINTEL = 6442, + DecorationCacheControlStoreINTEL = 6443, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInCoreIDARM = 4160, + BuiltInCoreCountARM = 4161, + BuiltInCoreMaxIDARM = 4162, + BuiltInWarpIDARM = 4163, + BuiltInWarpMaxIDARM = 4164, + BuiltInSubgroupEqMask = 4416, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMask = 4417, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMask = 4418, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMask = 4419, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMask = 4420, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInPrimitiveShadingRateKHR = 4432, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInShadingRateKHR = 4444, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInCoalescedInputCountAMDX = 5021, + BuiltInShaderIndexAMDX = 5073, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInFullyCoveredEXT = 5264, + BuiltInTaskCountNV = 5274, + BuiltInPrimitiveCountNV = 5275, + BuiltInPrimitiveIndicesNV = 5276, + BuiltInClipDistancePerViewNV = 5277, + BuiltInCullDistancePerViewNV = 5278, + BuiltInLayerPerViewNV = 5279, + BuiltInMeshViewCountNV = 5280, + BuiltInMeshViewIndicesNV = 5281, + BuiltInBaryCoordKHR = 5286, + BuiltInBaryCoordNV = 5286, + BuiltInBaryCoordNoPerspKHR = 5287, + BuiltInBaryCoordNoPerspNV = 5287, + BuiltInFragSizeEXT = 5292, + BuiltInFragmentSizeNV = 5292, + BuiltInFragInvocationCountEXT = 5293, + BuiltInInvocationsPerPixelNV = 5293, + BuiltInPrimitivePointIndicesEXT = 5294, + BuiltInPrimitiveLineIndicesEXT = 5295, + BuiltInPrimitiveTriangleIndicesEXT = 5296, + BuiltInCullPrimitiveEXT = 5299, + BuiltInLaunchIdKHR = 5319, + BuiltInLaunchIdNV = 5319, + BuiltInLaunchSizeKHR = 5320, + BuiltInLaunchSizeNV = 5320, + BuiltInWorldRayOriginKHR = 5321, + BuiltInWorldRayOriginNV = 5321, + BuiltInWorldRayDirectionKHR = 5322, + BuiltInWorldRayDirectionNV = 5322, + BuiltInObjectRayOriginKHR = 5323, + BuiltInObjectRayOriginNV = 5323, + BuiltInObjectRayDirectionKHR = 5324, + BuiltInObjectRayDirectionNV = 5324, + BuiltInRayTminKHR = 5325, + BuiltInRayTminNV = 5325, + BuiltInRayTmaxKHR = 5326, + BuiltInRayTmaxNV = 5326, + BuiltInInstanceCustomIndexKHR = 5327, + BuiltInInstanceCustomIndexNV = 5327, + BuiltInObjectToWorldKHR = 5330, + BuiltInObjectToWorldNV = 5330, + BuiltInWorldToObjectKHR = 5331, + BuiltInWorldToObjectNV = 5331, + BuiltInHitTNV = 5332, + BuiltInHitKindKHR = 5333, + BuiltInHitKindNV = 5333, + BuiltInCurrentRayTimeNV = 5334, + BuiltInHitTriangleVertexPositionsKHR = 5335, + BuiltInHitMicroTriangleVertexPositionsNV = 5337, + BuiltInHitMicroTriangleVertexBarycentricsNV = 5344, + BuiltInIncomingRayFlagsKHR = 5351, + BuiltInIncomingRayFlagsNV = 5351, + BuiltInRayGeometryIndexKHR = 5352, + BuiltInWarpsPerSMNV = 5374, + BuiltInSMCountNV = 5375, + BuiltInWarpIDNV = 5376, + BuiltInSMIDNV = 5377, + BuiltInHitKindFrontFacingMicroTriangleNV = 5405, + BuiltInHitKindBackFacingMicroTriangleNV = 5406, + BuiltInCullMaskKHR = 6021, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlDependencyInfiniteShift = 2, + LoopControlDependencyLengthShift = 3, + LoopControlMinIterationsShift = 4, + LoopControlMaxIterationsShift = 5, + LoopControlIterationMultipleShift = 6, + LoopControlPeelCountShift = 7, + LoopControlPartialCountShift = 8, + LoopControlInitiationIntervalINTELShift = 16, + LoopControlMaxConcurrencyINTELShift = 17, + LoopControlDependencyArrayINTELShift = 18, + LoopControlPipelineEnableINTELShift = 19, + LoopControlLoopCoalesceINTELShift = 20, + LoopControlMaxInterleavingINTELShift = 21, + LoopControlSpeculatedIterationsINTELShift = 22, + LoopControlNoFusionINTELShift = 23, + LoopControlLoopCountINTELShift = 24, + LoopControlMaxReinvocationDelayINTELShift = 25, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, + LoopControlDependencyInfiniteMask = 0x00000004, + LoopControlDependencyLengthMask = 0x00000008, + LoopControlMinIterationsMask = 0x00000010, + LoopControlMaxIterationsMask = 0x00000020, + LoopControlIterationMultipleMask = 0x00000040, + LoopControlPeelCountMask = 0x00000080, + LoopControlPartialCountMask = 0x00000100, + LoopControlInitiationIntervalINTELMask = 0x00010000, + LoopControlMaxConcurrencyINTELMask = 0x00020000, + LoopControlDependencyArrayINTELMask = 0x00040000, + LoopControlPipelineEnableINTELMask = 0x00080000, + LoopControlLoopCoalesceINTELMask = 0x00100000, + LoopControlMaxInterleavingINTELMask = 0x00200000, + LoopControlSpeculatedIterationsINTELMask = 0x00400000, + LoopControlNoFusionINTELMask = 0x00800000, + LoopControlLoopCountINTELMask = 0x01000000, + LoopControlMaxReinvocationDelayINTELMask = 0x02000000, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlOptNoneINTELShift = 16, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, + FunctionControlOptNoneINTELMask = 0x00010000, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsOutputMemoryShift = 12, + MemorySemanticsOutputMemoryKHRShift = 12, + MemorySemanticsMakeAvailableShift = 13, + MemorySemanticsMakeAvailableKHRShift = 13, + MemorySemanticsMakeVisibleShift = 14, + MemorySemanticsMakeVisibleKHRShift = 14, + MemorySemanticsVolatileShift = 15, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, + MemorySemanticsOutputMemoryMask = 0x00001000, + MemorySemanticsOutputMemoryKHRMask = 0x00001000, + MemorySemanticsMakeAvailableMask = 0x00002000, + MemorySemanticsMakeAvailableKHRMask = 0x00002000, + MemorySemanticsMakeVisibleMask = 0x00004000, + MemorySemanticsMakeVisibleKHRMask = 0x00004000, + MemorySemanticsVolatileMask = 0x00008000, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMakePointerAvailableShift = 3, + MemoryAccessMakePointerAvailableKHRShift = 3, + MemoryAccessMakePointerVisibleShift = 4, + MemoryAccessMakePointerVisibleKHRShift = 4, + MemoryAccessNonPrivatePointerShift = 5, + MemoryAccessNonPrivatePointerKHRShift = 5, + MemoryAccessAliasScopeINTELMaskShift = 16, + MemoryAccessNoAliasINTELMaskShift = 17, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, + MemoryAccessMakePointerAvailableMask = 0x00000008, + MemoryAccessMakePointerAvailableKHRMask = 0x00000008, + MemoryAccessMakePointerVisibleMask = 0x00000010, + MemoryAccessMakePointerVisibleKHRMask = 0x00000010, + MemoryAccessNonPrivatePointerMask = 0x00000020, + MemoryAccessNonPrivatePointerKHRMask = 0x00000020, + MemoryAccessAliasScopeINTELMaskMask = 0x00010000, + MemoryAccessNoAliasINTELMaskMask = 0x00020000, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeQueueFamily = 5, + ScopeQueueFamilyKHR = 5, + ScopeShaderCallKHR = 6, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationClusteredReduce = 3, + GroupOperationPartitionedReduceNV = 6, + GroupOperationPartitionedInclusiveScanNV = 7, + GroupOperationPartitionedExclusiveScanNV = 8, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupDispatch = 58, + CapabilityNamedBarrier = 59, + CapabilityPipeStorage = 60, + CapabilityGroupNonUniform = 61, + CapabilityGroupNonUniformVote = 62, + CapabilityGroupNonUniformArithmetic = 63, + CapabilityGroupNonUniformBallot = 64, + CapabilityGroupNonUniformShuffle = 65, + CapabilityGroupNonUniformShuffleRelative = 66, + CapabilityGroupNonUniformClustered = 67, + CapabilityGroupNonUniformQuad = 68, + CapabilityShaderLayer = 69, + CapabilityShaderViewportIndex = 70, + CapabilityUniformDecoration = 71, + CapabilityCoreBuiltinsARM = 4165, + CapabilityTileImageColorReadAccessEXT = 4166, + CapabilityTileImageDepthReadAccessEXT = 4167, + CapabilityTileImageStencilReadAccessEXT = 4168, + CapabilityFragmentShadingRateKHR = 4422, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityStorageBuffer8BitAccess = 4448, + CapabilityUniformAndStorageBuffer8BitAccess = 4449, + CapabilityStoragePushConstant8 = 4450, + CapabilityDenormPreserve = 4464, + CapabilityDenormFlushToZero = 4465, + CapabilitySignedZeroInfNanPreserve = 4466, + CapabilityRoundingModeRTE = 4467, + CapabilityRoundingModeRTZ = 4468, + CapabilityRayQueryProvisionalKHR = 4471, + CapabilityRayQueryKHR = 4472, + CapabilityRayTraversalPrimitiveCullingKHR = 4478, + CapabilityRayTracingKHR = 4479, + CapabilityTextureSampleWeightedQCOM = 4484, + CapabilityTextureBoxFilterQCOM = 4485, + CapabilityTextureBlockMatchQCOM = 4486, + CapabilityTextureBlockMatch2QCOM = 4498, + CapabilityFloat16ImageAMD = 5008, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilityInt64ImageEXT = 5016, + CapabilityShaderClockKHR = 5055, + CapabilityShaderEnqueueAMDX = 5067, + CapabilityQuadControlKHR = 5087, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilityFragmentFullyCoveredEXT = 5265, + CapabilityMeshShadingNV = 5266, + CapabilityImageFootprintNV = 5282, + CapabilityMeshShadingEXT = 5283, + CapabilityFragmentBarycentricKHR = 5284, + CapabilityFragmentBarycentricNV = 5284, + CapabilityComputeDerivativeGroupQuadsNV = 5288, + CapabilityFragmentDensityEXT = 5291, + CapabilityShadingRateNV = 5291, + CapabilityGroupNonUniformPartitionedNV = 5297, + CapabilityShaderNonUniform = 5301, + CapabilityShaderNonUniformEXT = 5301, + CapabilityRuntimeDescriptorArray = 5302, + CapabilityRuntimeDescriptorArrayEXT = 5302, + CapabilityInputAttachmentArrayDynamicIndexing = 5303, + CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, + CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, + CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + CapabilityUniformBufferArrayNonUniformIndexing = 5306, + CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + CapabilitySampledImageArrayNonUniformIndexing = 5307, + CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + CapabilityStorageBufferArrayNonUniformIndexing = 5308, + CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + CapabilityStorageImageArrayNonUniformIndexing = 5309, + CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + CapabilityInputAttachmentArrayNonUniformIndexing = 5310, + CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, + CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, + CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + CapabilityRayTracingPositionFetchKHR = 5336, + CapabilityRayTracingNV = 5340, + CapabilityRayTracingMotionBlurNV = 5341, + CapabilityVulkanMemoryModel = 5345, + CapabilityVulkanMemoryModelKHR = 5345, + CapabilityVulkanMemoryModelDeviceScope = 5346, + CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + CapabilityPhysicalStorageBufferAddresses = 5347, + CapabilityPhysicalStorageBufferAddressesEXT = 5347, + CapabilityComputeDerivativeGroupLinearNV = 5350, + CapabilityRayTracingProvisionalKHR = 5353, + CapabilityCooperativeMatrixNV = 5357, + CapabilityFragmentShaderSampleInterlockEXT = 5363, + CapabilityFragmentShaderShadingRateInterlockEXT = 5372, + CapabilityShaderSMBuiltinsNV = 5373, + CapabilityFragmentShaderPixelInterlockEXT = 5378, + CapabilityDemoteToHelperInvocation = 5379, + CapabilityDemoteToHelperInvocationEXT = 5379, + CapabilityDisplacementMicromapNV = 5380, + CapabilityRayTracingOpacityMicromapEXT = 5381, + CapabilityShaderInvocationReorderNV = 5383, + CapabilityBindlessTextureNV = 5390, + CapabilityRayQueryPositionFetchKHR = 5391, + CapabilityAtomicFloat16VectorNV = 5404, + CapabilityRayTracingDisplacementMicromapNV = 5409, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilitySubgroupImageMediaBlockIOINTEL = 5579, + CapabilityRoundToInfinityINTEL = 5582, + CapabilityFloatingPointModeINTEL = 5583, + CapabilityIntegerFunctions2INTEL = 5584, + CapabilityFunctionPointersINTEL = 5603, + CapabilityIndirectReferencesINTEL = 5604, + CapabilityAsmINTEL = 5606, + CapabilityAtomicFloat32MinMaxEXT = 5612, + CapabilityAtomicFloat64MinMaxEXT = 5613, + CapabilityAtomicFloat16MinMaxEXT = 5616, + CapabilityVectorComputeINTEL = 5617, + CapabilityVectorAnyINTEL = 5619, + CapabilityExpectAssumeKHR = 5629, + CapabilitySubgroupAvcMotionEstimationINTEL = 5696, + CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityVariableLengthArrayINTEL = 5817, + CapabilityFunctionFloatControlINTEL = 5821, + CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityFPFastMathModeINTEL = 5837, + CapabilityArbitraryPrecisionIntegersINTEL = 5844, + CapabilityArbitraryPrecisionFloatingPointINTEL = 5845, + CapabilityUnstructuredLoopControlsINTEL = 5886, + CapabilityFPGALoopControlsINTEL = 5888, + CapabilityKernelAttributesINTEL = 5892, + CapabilityFPGAKernelAttributesINTEL = 5897, + CapabilityFPGAMemoryAccessesINTEL = 5898, + CapabilityFPGAClusterAttributesINTEL = 5904, + CapabilityLoopFuseINTEL = 5906, + CapabilityFPGADSPControlINTEL = 5908, + CapabilityMemoryAccessAliasingINTEL = 5910, + CapabilityFPGAInvocationPipeliningAttributesINTEL = 5916, + CapabilityFPGABufferLocationINTEL = 5920, + CapabilityArbitraryPrecisionFixedPointINTEL = 5922, + CapabilityUSMStorageClassesINTEL = 5935, + CapabilityRuntimeAlignedAttributeINTEL = 5939, + CapabilityIOPipesINTEL = 5943, + CapabilityBlockingPipesINTEL = 5945, + CapabilityFPGARegINTEL = 5948, + CapabilityDotProductInputAll = 6016, + CapabilityDotProductInputAllKHR = 6016, + CapabilityDotProductInput4x8Bit = 6017, + CapabilityDotProductInput4x8BitKHR = 6017, + CapabilityDotProductInput4x8BitPacked = 6018, + CapabilityDotProductInput4x8BitPackedKHR = 6018, + CapabilityDotProduct = 6019, + CapabilityDotProductKHR = 6019, + CapabilityRayCullMaskKHR = 6020, + CapabilityCooperativeMatrixKHR = 6022, + CapabilityBitInstructions = 6025, + CapabilityGroupNonUniformRotateKHR = 6026, + CapabilityFloatControls2 = 6029, + CapabilityAtomicFloat32AddEXT = 6033, + CapabilityAtomicFloat64AddEXT = 6034, + CapabilityLongCompositesINTEL = 6089, + CapabilityOptNoneINTEL = 6094, + CapabilityAtomicFloat16AddEXT = 6095, + CapabilityDebugInfoModuleINTEL = 6114, + CapabilityBFloat16ConversionINTEL = 6115, + CapabilitySplitBarrierINTEL = 6141, + CapabilityFPGAClusterAttributesV2INTEL = 6150, + CapabilityFPGAKernelAttributesv2INTEL = 6161, + CapabilityFPMaxErrorINTEL = 6169, + CapabilityFPGALatencyControlINTEL = 6171, + CapabilityFPGAArgumentInterfacesINTEL = 6174, + CapabilityGlobalVariableHostAccessINTEL = 6187, + CapabilityGlobalVariableFPGADecorationsINTEL = 6189, + CapabilityGroupUniformArithmeticKHR = 6400, + CapabilityMaskedGatherScatterINTEL = 6427, + CapabilityCacheControlsINTEL = 6441, + CapabilityRegisterLimitsINTEL = 6460, + CapabilityMax = 0x7fffffff, +}; + +enum RayFlagsShift { + RayFlagsOpaqueKHRShift = 0, + RayFlagsNoOpaqueKHRShift = 1, + RayFlagsTerminateOnFirstHitKHRShift = 2, + RayFlagsSkipClosestHitShaderKHRShift = 3, + RayFlagsCullBackFacingTrianglesKHRShift = 4, + RayFlagsCullFrontFacingTrianglesKHRShift = 5, + RayFlagsCullOpaqueKHRShift = 6, + RayFlagsCullNoOpaqueKHRShift = 7, + RayFlagsSkipTrianglesKHRShift = 8, + RayFlagsSkipAABBsKHRShift = 9, + RayFlagsForceOpacityMicromap2StateEXTShift = 10, + RayFlagsMax = 0x7fffffff, +}; + +enum RayFlagsMask { + RayFlagsMaskNone = 0, + RayFlagsOpaqueKHRMask = 0x00000001, + RayFlagsNoOpaqueKHRMask = 0x00000002, + RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + RayFlagsCullOpaqueKHRMask = 0x00000040, + RayFlagsCullNoOpaqueKHRMask = 0x00000080, + RayFlagsSkipTrianglesKHRMask = 0x00000100, + RayFlagsSkipAABBsKHRMask = 0x00000200, + RayFlagsForceOpacityMicromap2StateEXTMask = 0x00000400, +}; + +enum RayQueryIntersection { + RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + RayQueryIntersectionMax = 0x7fffffff, +}; + +enum RayQueryCommittedIntersectionType { + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + RayQueryCommittedIntersectionTypeMax = 0x7fffffff, +}; + +enum RayQueryCandidateIntersectionType { + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + RayQueryCandidateIntersectionTypeMax = 0x7fffffff, +}; + +enum FragmentShadingRateShift { + FragmentShadingRateVertical2PixelsShift = 0, + FragmentShadingRateVertical4PixelsShift = 1, + FragmentShadingRateHorizontal2PixelsShift = 2, + FragmentShadingRateHorizontal4PixelsShift = 3, + FragmentShadingRateMax = 0x7fffffff, +}; + +enum FragmentShadingRateMask { + FragmentShadingRateMaskNone = 0, + FragmentShadingRateVertical2PixelsMask = 0x00000001, + FragmentShadingRateVertical4PixelsMask = 0x00000002, + FragmentShadingRateHorizontal2PixelsMask = 0x00000004, + FragmentShadingRateHorizontal4PixelsMask = 0x00000008, +}; + +enum FPDenormMode { + FPDenormModePreserve = 0, + FPDenormModeFlushToZero = 1, + FPDenormModeMax = 0x7fffffff, +}; + +enum FPOperationMode { + FPOperationModeIEEE = 0, + FPOperationModeALT = 1, + FPOperationModeMax = 0x7fffffff, +}; + +enum QuantizationModes { + QuantizationModesTRN = 0, + QuantizationModesTRN_ZERO = 1, + QuantizationModesRND = 2, + QuantizationModesRND_ZERO = 3, + QuantizationModesRND_INF = 4, + QuantizationModesRND_MIN_INF = 5, + QuantizationModesRND_CONV = 6, + QuantizationModesRND_CONV_ODD = 7, + QuantizationModesMax = 0x7fffffff, +}; + +enum OverflowModes { + OverflowModesWRAP = 0, + OverflowModesSAT = 1, + OverflowModesSAT_ZERO = 2, + OverflowModesSAT_SYM = 3, + OverflowModesMax = 0x7fffffff, +}; + +enum PackedVectorFormat { + PackedVectorFormatPackedVectorFormat4x8Bit = 0, + PackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + PackedVectorFormatMax = 0x7fffffff, +}; + +enum CooperativeMatrixOperandsShift { + CooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0, + CooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1, + CooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2, + CooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3, + CooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4, + CooperativeMatrixOperandsMax = 0x7fffffff, +}; + +enum CooperativeMatrixOperandsMask { + CooperativeMatrixOperandsMaskNone = 0, + CooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001, + CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002, + CooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004, + CooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008, + CooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010, +}; + +enum CooperativeMatrixLayout { + CooperativeMatrixLayoutRowMajorKHR = 0, + CooperativeMatrixLayoutColumnMajorKHR = 1, + CooperativeMatrixLayoutMax = 0x7fffffff, +}; + +enum CooperativeMatrixUse { + CooperativeMatrixUseMatrixAKHR = 0, + CooperativeMatrixUseMatrixBKHR = 1, + CooperativeMatrixUseMatrixAccumulatorKHR = 2, + CooperativeMatrixUseMax = 0x7fffffff, +}; + +enum InitializationModeQualifier { + InitializationModeQualifierInitOnDeviceReprogramINTEL = 0, + InitializationModeQualifierInitOnDeviceResetINTEL = 1, + InitializationModeQualifierMax = 0x7fffffff, +}; + +enum HostAccessQualifier { + HostAccessQualifierNoneINTEL = 0, + HostAccessQualifierReadINTEL = 1, + HostAccessQualifierWriteINTEL = 2, + HostAccessQualifierReadWriteINTEL = 3, + HostAccessQualifierMax = 0x7fffffff, +}; + +enum LoadCacheControl { + LoadCacheControlUncachedINTEL = 0, + LoadCacheControlCachedINTEL = 1, + LoadCacheControlStreamingINTEL = 2, + LoadCacheControlInvalidateAfterReadINTEL = 3, + LoadCacheControlConstCachedINTEL = 4, + LoadCacheControlMax = 0x7fffffff, +}; + +enum StoreCacheControl { + StoreCacheControlUncachedINTEL = 0, + StoreCacheControlWriteThroughINTEL = 1, + StoreCacheControlWriteBackINTEL = 2, + StoreCacheControlStreamingINTEL = 3, + StoreCacheControlMax = 0x7fffffff, +}; + +enum NamedMaximumNumberOfRegisters { + NamedMaximumNumberOfRegistersAutoINTEL = 0, + NamedMaximumNumberOfRegistersMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + OpMax = 0x7fffffff, +}; + +#ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif +inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case OpNop: *hasResult = false; *hasResultType = false; break; + case OpUndef: *hasResult = true; *hasResultType = true; break; + case OpSourceContinued: *hasResult = false; *hasResultType = false; break; + case OpSource: *hasResult = false; *hasResultType = false; break; + case OpSourceExtension: *hasResult = false; *hasResultType = false; break; + case OpName: *hasResult = false; *hasResultType = false; break; + case OpMemberName: *hasResult = false; *hasResultType = false; break; + case OpString: *hasResult = true; *hasResultType = false; break; + case OpLine: *hasResult = false; *hasResultType = false; break; + case OpExtension: *hasResult = false; *hasResultType = false; break; + case OpExtInstImport: *hasResult = true; *hasResultType = false; break; + case OpExtInst: *hasResult = true; *hasResultType = true; break; + case OpMemoryModel: *hasResult = false; *hasResultType = false; break; + case OpEntryPoint: *hasResult = false; *hasResultType = false; break; + case OpExecutionMode: *hasResult = false; *hasResultType = false; break; + case OpCapability: *hasResult = false; *hasResultType = false; break; + case OpTypeVoid: *hasResult = true; *hasResultType = false; break; + case OpTypeBool: *hasResult = true; *hasResultType = false; break; + case OpTypeInt: *hasResult = true; *hasResultType = false; break; + case OpTypeFloat: *hasResult = true; *hasResultType = false; break; + case OpTypeVector: *hasResult = true; *hasResultType = false; break; + case OpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case OpTypeImage: *hasResult = true; *hasResultType = false; break; + case OpTypeSampler: *hasResult = true; *hasResultType = false; break; + case OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case OpTypeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeStruct: *hasResult = true; *hasResultType = false; break; + case OpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case OpTypePointer: *hasResult = true; *hasResultType = false; break; + case OpTypeFunction: *hasResult = true; *hasResultType = false; break; + case OpTypeEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case OpTypeQueue: *hasResult = true; *hasResultType = false; break; + case OpTypePipe: *hasResult = true; *hasResultType = false; break; + case OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case OpConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpConstant: *hasResult = true; *hasResultType = true; break; + case OpConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpConstantSampler: *hasResult = true; *hasResultType = true; break; + case OpConstantNull: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpSpecConstant: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case OpFunction: *hasResult = true; *hasResultType = true; break; + case OpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case OpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case OpFunctionCall: *hasResult = true; *hasResultType = true; break; + case OpVariable: *hasResult = true; *hasResultType = true; break; + case OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case OpLoad: *hasResult = true; *hasResultType = true; break; + case OpStore: *hasResult = false; *hasResultType = false; break; + case OpCopyMemory: *hasResult = false; *hasResultType = false; break; + case OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case OpAccessChain: *hasResult = true; *hasResultType = true; break; + case OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpArrayLength: *hasResult = true; *hasResultType = true; break; + case OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpDecorate: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case OpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case OpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case OpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case OpCopyObject: *hasResult = true; *hasResultType = true; break; + case OpTranspose: *hasResult = true; *hasResultType = true; break; + case OpSampledImage: *hasResult = true; *hasResultType = true; break; + case OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageFetch: *hasResult = true; *hasResultType = true; break; + case OpImageGather: *hasResult = true; *hasResultType = true; break; + case OpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageRead: *hasResult = true; *hasResultType = true; break; + case OpImageWrite: *hasResult = false; *hasResultType = false; break; + case OpImage: *hasResult = true; *hasResultType = true; break; + case OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case OpConvertFToU: *hasResult = true; *hasResultType = true; break; + case OpConvertFToS: *hasResult = true; *hasResultType = true; break; + case OpConvertSToF: *hasResult = true; *hasResultType = true; break; + case OpConvertUToF: *hasResult = true; *hasResultType = true; break; + case OpUConvert: *hasResult = true; *hasResultType = true; break; + case OpSConvert: *hasResult = true; *hasResultType = true; break; + case OpFConvert: *hasResult = true; *hasResultType = true; break; + case OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case OpBitcast: *hasResult = true; *hasResultType = true; break; + case OpSNegate: *hasResult = true; *hasResultType = true; break; + case OpFNegate: *hasResult = true; *hasResultType = true; break; + case OpIAdd: *hasResult = true; *hasResultType = true; break; + case OpFAdd: *hasResult = true; *hasResultType = true; break; + case OpISub: *hasResult = true; *hasResultType = true; break; + case OpFSub: *hasResult = true; *hasResultType = true; break; + case OpIMul: *hasResult = true; *hasResultType = true; break; + case OpFMul: *hasResult = true; *hasResultType = true; break; + case OpUDiv: *hasResult = true; *hasResultType = true; break; + case OpSDiv: *hasResult = true; *hasResultType = true; break; + case OpFDiv: *hasResult = true; *hasResultType = true; break; + case OpUMod: *hasResult = true; *hasResultType = true; break; + case OpSRem: *hasResult = true; *hasResultType = true; break; + case OpSMod: *hasResult = true; *hasResultType = true; break; + case OpFRem: *hasResult = true; *hasResultType = true; break; + case OpFMod: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpOuterProduct: *hasResult = true; *hasResultType = true; break; + case OpDot: *hasResult = true; *hasResultType = true; break; + case OpIAddCarry: *hasResult = true; *hasResultType = true; break; + case OpISubBorrow: *hasResult = true; *hasResultType = true; break; + case OpUMulExtended: *hasResult = true; *hasResultType = true; break; + case OpSMulExtended: *hasResult = true; *hasResultType = true; break; + case OpAny: *hasResult = true; *hasResultType = true; break; + case OpAll: *hasResult = true; *hasResultType = true; break; + case OpIsNan: *hasResult = true; *hasResultType = true; break; + case OpIsInf: *hasResult = true; *hasResultType = true; break; + case OpIsFinite: *hasResult = true; *hasResultType = true; break; + case OpIsNormal: *hasResult = true; *hasResultType = true; break; + case OpSignBitSet: *hasResult = true; *hasResultType = true; break; + case OpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case OpOrdered: *hasResult = true; *hasResultType = true; break; + case OpUnordered: *hasResult = true; *hasResultType = true; break; + case OpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpLogicalNot: *hasResult = true; *hasResultType = true; break; + case OpSelect: *hasResult = true; *hasResultType = true; break; + case OpIEqual: *hasResult = true; *hasResultType = true; break; + case OpINotEqual: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpULessThan: *hasResult = true; *hasResultType = true; break; + case OpSLessThan: *hasResult = true; *hasResultType = true; break; + case OpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case OpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpNot: *hasResult = true; *hasResultType = true; break; + case OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case OpBitReverse: *hasResult = true; *hasResultType = true; break; + case OpBitCount: *hasResult = true; *hasResultType = true; break; + case OpDPdx: *hasResult = true; *hasResultType = true; break; + case OpDPdy: *hasResult = true; *hasResultType = true; break; + case OpFwidth: *hasResult = true; *hasResultType = true; break; + case OpDPdxFine: *hasResult = true; *hasResultType = true; break; + case OpDPdyFine: *hasResult = true; *hasResultType = true; break; + case OpFwidthFine: *hasResult = true; *hasResultType = true; break; + case OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case OpEmitVertex: *hasResult = false; *hasResultType = false; break; + case OpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case OpControlBarrier: *hasResult = false; *hasResultType = false; break; + case OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case OpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case OpAtomicStore: *hasResult = false; *hasResultType = false; break; + case OpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case OpAtomicISub: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case OpAtomicOr: *hasResult = true; *hasResultType = true; break; + case OpAtomicXor: *hasResult = true; *hasResultType = true; break; + case OpPhi: *hasResult = true; *hasResultType = true; break; + case OpLoopMerge: *hasResult = false; *hasResultType = false; break; + case OpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case OpLabel: *hasResult = true; *hasResultType = false; break; + case OpBranch: *hasResult = false; *hasResultType = false; break; + case OpBranchConditional: *hasResult = false; *hasResultType = false; break; + case OpSwitch: *hasResult = false; *hasResultType = false; break; + case OpKill: *hasResult = false; *hasResultType = false; break; + case OpReturn: *hasResult = false; *hasResultType = false; break; + case OpReturnValue: *hasResult = false; *hasResultType = false; break; + case OpUnreachable: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case OpGroupAll: *hasResult = true; *hasResultType = true; break; + case OpGroupAny: *hasResult = true; *hasResultType = true; break; + case OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupSMax: *hasResult = true; *hasResultType = true; break; + case OpReadPipe: *hasResult = true; *hasResultType = true; break; + case OpWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case OpRetainEvent: *hasResult = false; *hasResultType = false; break; + case OpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case OpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case OpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case OpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case OpNoLine: *hasResult = false; *hasResultType = false; break; + case OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case OpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case OpSizeOf: *hasResult = true; *hasResultType = true; break; + case OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case OpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case OpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case OpDecorateId: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case OpCopyLogical: *hasResult = true; *hasResultType = true; break; + case OpPtrEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case OpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case OpSDot: *hasResult = true; *hasResultType = true; break; + case OpUDot: *hasResult = true; *hasResultType = true; break; + case OpSUDot: *hasResult = true; *hasResultType = true; break; + case OpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break; + case OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; + case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case OpImageSampleWeightedQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case OpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case OpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break; + case OpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; + case OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetWorldToObjectNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectToWorldNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectRayOriginNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetShaderRecordBufferHandleNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetShaderBindingTableRecordIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectRecordEmptyNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectTraceRayNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitWithIndexNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordMissNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectExecuteShaderNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetCurrentTimeNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetAttributesNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetHitKindNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetPrimitiveIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetGeometryIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetInstanceIdNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetInstanceCustomIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetWorldRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetWorldRayOriginNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetRayTMaxNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetRayTMinNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsEmptyNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsHitNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsMissNV: *hasResult = true; *hasResultType = true; break; + case OpReorderThreadWithHitObjectNV: *hasResult = false; *hasResultType = false; break; + case OpReorderThreadWithHintNV: *hasResult = false; *hasResultType = false; break; + case OpTypeHitObjectNV: *hasResult = true; *hasResultType = false; break; + case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case OpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case OpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; + case OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; + case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case OpTraceNV: *hasResult = false; *hasResultType = false; break; + case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; + case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case OpExpectKHR: *hasResult = true; *hasResultType = true; break; + case OpDecorateString: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break; + case OpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break; + case OpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break; + case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; + case OpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break; + case OpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +// Overload bitwise operators for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline ImageOperandsMask operator&(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) & unsigned(b)); } +inline ImageOperandsMask operator^(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) ^ unsigned(b)); } +inline ImageOperandsMask operator~(ImageOperandsMask a) { return ImageOperandsMask(~unsigned(a)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator&(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) & unsigned(b)); } +inline FPFastMathModeMask operator^(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) ^ unsigned(b)); } +inline FPFastMathModeMask operator~(FPFastMathModeMask a) { return FPFastMathModeMask(~unsigned(a)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator&(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) & unsigned(b)); } +inline SelectionControlMask operator^(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) ^ unsigned(b)); } +inline SelectionControlMask operator~(SelectionControlMask a) { return SelectionControlMask(~unsigned(a)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator&(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) & unsigned(b)); } +inline LoopControlMask operator^(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) ^ unsigned(b)); } +inline LoopControlMask operator~(LoopControlMask a) { return LoopControlMask(~unsigned(a)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator&(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) & unsigned(b)); } +inline FunctionControlMask operator^(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) ^ unsigned(b)); } +inline FunctionControlMask operator~(FunctionControlMask a) { return FunctionControlMask(~unsigned(a)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator&(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) & unsigned(b)); } +inline MemorySemanticsMask operator^(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) ^ unsigned(b)); } +inline MemorySemanticsMask operator~(MemorySemanticsMask a) { return MemorySemanticsMask(~unsigned(a)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator&(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) & unsigned(b)); } +inline MemoryAccessMask operator^(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) ^ unsigned(b)); } +inline MemoryAccessMask operator~(MemoryAccessMask a) { return MemoryAccessMask(~unsigned(a)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator&(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) & unsigned(b)); } +inline KernelProfilingInfoMask operator^(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) ^ unsigned(b)); } +inline KernelProfilingInfoMask operator~(KernelProfilingInfoMask a) { return KernelProfilingInfoMask(~unsigned(a)); } +inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } +inline RayFlagsMask operator&(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) & unsigned(b)); } +inline RayFlagsMask operator^(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) ^ unsigned(b)); } +inline RayFlagsMask operator~(RayFlagsMask a) { return RayFlagsMask(~unsigned(a)); } +inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } +inline FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); } +inline FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); } +inline FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); } +inline CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) | unsigned(b)); } +inline CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); } +inline CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); } +inline CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.hpp11 b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.hpp11 new file mode 100644 index 000000000000..79307fd451d8 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.hpp11 @@ -0,0 +1,2924 @@ +// Copyright (c) 2014-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010600; +static const unsigned int Revision = 1; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + NodeOutputPayloadAMDX = 5076, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + LinkOnceODR = 2, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + CoalescedInputCountAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + Max = 0x7fffffff, +}; + +enum class RayFlagsShift : unsigned { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + Max = 0x7fffffff, +}; + +enum class RayFlagsMask : unsigned { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, +}; + +enum class RayQueryIntersection : unsigned { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + Max = 0x7fffffff, +}; + +enum class RayQueryCommittedIntersectionType : unsigned { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + Max = 0x7fffffff, +}; + +enum class RayQueryCandidateIntersectionType : unsigned { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + Max = 0x7fffffff, +}; + +enum class FragmentShadingRateShift : unsigned { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + Max = 0x7fffffff, +}; + +enum class FragmentShadingRateMask : unsigned { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, +}; + +enum class FPDenormMode : unsigned { + Preserve = 0, + FlushToZero = 1, + Max = 0x7fffffff, +}; + +enum class FPOperationMode : unsigned { + IEEE = 0, + ALT = 1, + Max = 0x7fffffff, +}; + +enum class QuantizationModes : unsigned { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + Max = 0x7fffffff, +}; + +enum class OverflowModes : unsigned { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + Max = 0x7fffffff, +}; + +enum class PackedVectorFormat : unsigned { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixOperandsShift : unsigned { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixOperandsMask : unsigned { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, +}; + +enum class CooperativeMatrixLayout : unsigned { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixUse : unsigned { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + Max = 0x7fffffff, +}; + +enum class InitializationModeQualifier : unsigned { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + Max = 0x7fffffff, +}; + +enum class HostAccessQualifier : unsigned { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + Max = 0x7fffffff, +}; + +enum class LoadCacheControl : unsigned { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + Max = 0x7fffffff, +}; + +enum class StoreCacheControl : unsigned { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + Max = 0x7fffffff, +}; + +enum class NamedMaximumNumberOfRegisters : unsigned { + AutoINTEL = 0, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + Max = 0x7fffffff, +}; + +#ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif +inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case Op::OpNop: *hasResult = false; *hasResultType = false; break; + case Op::OpUndef: *hasResult = true; *hasResultType = true; break; + case Op::OpSourceContinued: *hasResult = false; *hasResultType = false; break; + case Op::OpSource: *hasResult = false; *hasResultType = false; break; + case Op::OpSourceExtension: *hasResult = false; *hasResultType = false; break; + case Op::OpName: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberName: *hasResult = false; *hasResultType = false; break; + case Op::OpString: *hasResult = true; *hasResultType = false; break; + case Op::OpLine: *hasResult = false; *hasResultType = false; break; + case Op::OpExtension: *hasResult = false; *hasResultType = false; break; + case Op::OpExtInstImport: *hasResult = true; *hasResultType = false; break; + case Op::OpExtInst: *hasResult = true; *hasResultType = true; break; + case Op::OpMemoryModel: *hasResult = false; *hasResultType = false; break; + case Op::OpEntryPoint: *hasResult = false; *hasResultType = false; break; + case Op::OpExecutionMode: *hasResult = false; *hasResultType = false; break; + case Op::OpCapability: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeVoid: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeBool: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeInt: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeFloat: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeVector: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeImage: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeSampler: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeArray: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeStruct: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case Op::OpTypePointer: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeFunction: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeEvent: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeQueue: *hasResult = true; *hasResultType = false; break; + case Op::OpTypePipe: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case Op::OpConstantTrue: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantFalse: *hasResult = true; *hasResultType = true; break; + case Op::OpConstant: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantComposite: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantSampler: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantNull: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstant: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case Op::OpFunction: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case Op::OpFunctionCall: *hasResult = true; *hasResultType = true; break; + case Op::OpVariable: *hasResult = true; *hasResultType = true; break; + case Op::OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case Op::OpLoad: *hasResult = true; *hasResultType = true; break; + case Op::OpStore: *hasResult = false; *hasResultType = false; break; + case Op::OpCopyMemory: *hasResult = false; *hasResultType = false; break; + case Op::OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case Op::OpAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpArrayLength: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case Op::OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case Op::OpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case Op::OpCopyObject: *hasResult = true; *hasResultType = true; break; + case Op::OpTranspose: *hasResult = true; *hasResultType = true; break; + case Op::OpSampledImage: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageFetch: *hasResult = true; *hasResultType = true; break; + case Op::OpImageGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageRead: *hasResult = true; *hasResultType = true; break; + case Op::OpImageWrite: *hasResult = false; *hasResultType = false; break; + case Op::OpImage: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToU: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToS: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSToF: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToF: *hasResult = true; *hasResultType = true; break; + case Op::OpUConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpSConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpFConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case Op::OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case Op::OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case Op::OpBitcast: *hasResult = true; *hasResultType = true; break; + case Op::OpSNegate: *hasResult = true; *hasResultType = true; break; + case Op::OpFNegate: *hasResult = true; *hasResultType = true; break; + case Op::OpIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpISub: *hasResult = true; *hasResultType = true; break; + case Op::OpFSub: *hasResult = true; *hasResultType = true; break; + case Op::OpIMul: *hasResult = true; *hasResultType = true; break; + case Op::OpFMul: *hasResult = true; *hasResultType = true; break; + case Op::OpUDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpSDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpFDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpUMod: *hasResult = true; *hasResultType = true; break; + case Op::OpSRem: *hasResult = true; *hasResultType = true; break; + case Op::OpSMod: *hasResult = true; *hasResultType = true; break; + case Op::OpFRem: *hasResult = true; *hasResultType = true; break; + case Op::OpFMod: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case Op::OpOuterProduct: *hasResult = true; *hasResultType = true; break; + case Op::OpDot: *hasResult = true; *hasResultType = true; break; + case Op::OpIAddCarry: *hasResult = true; *hasResultType = true; break; + case Op::OpISubBorrow: *hasResult = true; *hasResultType = true; break; + case Op::OpUMulExtended: *hasResult = true; *hasResultType = true; break; + case Op::OpSMulExtended: *hasResult = true; *hasResultType = true; break; + case Op::OpAny: *hasResult = true; *hasResultType = true; break; + case Op::OpAll: *hasResult = true; *hasResultType = true; break; + case Op::OpIsNan: *hasResult = true; *hasResultType = true; break; + case Op::OpIsInf: *hasResult = true; *hasResultType = true; break; + case Op::OpIsFinite: *hasResult = true; *hasResultType = true; break; + case Op::OpIsNormal: *hasResult = true; *hasResultType = true; break; + case Op::OpSignBitSet: *hasResult = true; *hasResultType = true; break; + case Op::OpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case Op::OpOrdered: *hasResult = true; *hasResultType = true; break; + case Op::OpUnordered: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalOr: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalNot: *hasResult = true; *hasResultType = true; break; + case Op::OpSelect: *hasResult = true; *hasResultType = true; break; + case Op::OpIEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpINotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpULessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpSLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpNot: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpBitReverse: *hasResult = true; *hasResultType = true; break; + case Op::OpBitCount: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdx: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdy: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidth: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdxFine: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdyFine: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidthFine: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpEmitVertex: *hasResult = false; *hasResultType = false; break; + case Op::OpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case Op::OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case Op::OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case Op::OpControlBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicStore: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicISub: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicOr: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicXor: *hasResult = true; *hasResultType = true; break; + case Op::OpPhi: *hasResult = true; *hasResultType = true; break; + case Op::OpLoopMerge: *hasResult = false; *hasResultType = false; break; + case Op::OpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case Op::OpLabel: *hasResult = true; *hasResultType = false; break; + case Op::OpBranch: *hasResult = false; *hasResultType = false; break; + case Op::OpBranchConditional: *hasResult = false; *hasResultType = false; break; + case Op::OpSwitch: *hasResult = false; *hasResultType = false; break; + case Op::OpKill: *hasResult = false; *hasResultType = false; break; + case Op::OpReturn: *hasResult = false; *hasResultType = false; break; + case Op::OpReturnValue: *hasResult = false; *hasResultType = false; break; + case Op::OpUnreachable: *hasResult = false; *hasResultType = false; break; + case Op::OpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case Op::OpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupAll: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupAny: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpReadPipe: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case Op::OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case Op::OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case Op::OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case Op::OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case Op::OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case Op::OpRetainEvent: *hasResult = false; *hasResultType = false; break; + case Op::OpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case Op::OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case Op::OpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case Op::OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case Op::OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case Op::OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case Op::OpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case Op::OpNoLine: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case Op::OpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case Op::OpSizeOf: *hasResult = true; *hasResultType = true; break; + case Op::OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case Op::OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case Op::OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case Op::OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case Op::OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case Op::OpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case Op::OpDecorateId: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case Op::OpCopyLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case Op::OpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpSDot: *hasResult = true; *hasResultType = true; break; + case Op::OpUDot: *hasResult = true; *hasResultType = true; break; + case Op::OpSUDot: *hasResult = true; *hasResultType = true; break; + case Op::OpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break; + case Op::OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case Op::OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleWeightedQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case Op::OpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break; + case Op::OpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetWorldToObjectNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectToWorldNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectRayOriginNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetShaderRecordBufferHandleNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetShaderBindingTableRecordIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectRecordEmptyNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectTraceRayNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitWithIndexNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordMissNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectExecuteShaderNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetCurrentTimeNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetAttributesNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetHitKindNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetPrimitiveIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetGeometryIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetInstanceIdNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetInstanceCustomIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetWorldRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetWorldRayOriginNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetRayTMaxNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetRayTMinNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsEmptyNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsHitNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsMissNV: *hasResult = true; *hasResultType = true; break; + case Op::OpReorderThreadWithHitObjectNV: *hasResult = false; *hasResultType = false; break; + case Op::OpReorderThreadWithHintNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeHitObjectNV: *hasResult = true; *hasResultType = false; break; + case Op::OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case Op::OpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case Op::OpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; + case Op::OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case Op::OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case Op::OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case Op::OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case Op::OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpExpectKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpDecorateString: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case Op::OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +// Overload bitwise operators for mask bit combining + +constexpr ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +constexpr ImageOperandsMask operator&(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) & unsigned(b)); } +constexpr ImageOperandsMask operator^(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr ImageOperandsMask operator~(ImageOperandsMask a) { return ImageOperandsMask(~unsigned(a)); } +constexpr FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +constexpr FPFastMathModeMask operator&(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) & unsigned(b)); } +constexpr FPFastMathModeMask operator^(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) ^ unsigned(b)); } +constexpr FPFastMathModeMask operator~(FPFastMathModeMask a) { return FPFastMathModeMask(~unsigned(a)); } +constexpr SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +constexpr SelectionControlMask operator&(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) & unsigned(b)); } +constexpr SelectionControlMask operator^(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) ^ unsigned(b)); } +constexpr SelectionControlMask operator~(SelectionControlMask a) { return SelectionControlMask(~unsigned(a)); } +constexpr LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +constexpr LoopControlMask operator&(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) & unsigned(b)); } +constexpr LoopControlMask operator^(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) ^ unsigned(b)); } +constexpr LoopControlMask operator~(LoopControlMask a) { return LoopControlMask(~unsigned(a)); } +constexpr FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +constexpr FunctionControlMask operator&(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) & unsigned(b)); } +constexpr FunctionControlMask operator^(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) ^ unsigned(b)); } +constexpr FunctionControlMask operator~(FunctionControlMask a) { return FunctionControlMask(~unsigned(a)); } +constexpr MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +constexpr MemorySemanticsMask operator&(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) & unsigned(b)); } +constexpr MemorySemanticsMask operator^(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) ^ unsigned(b)); } +constexpr MemorySemanticsMask operator~(MemorySemanticsMask a) { return MemorySemanticsMask(~unsigned(a)); } +constexpr MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +constexpr MemoryAccessMask operator&(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) & unsigned(b)); } +constexpr MemoryAccessMask operator^(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) ^ unsigned(b)); } +constexpr MemoryAccessMask operator~(MemoryAccessMask a) { return MemoryAccessMask(~unsigned(a)); } +constexpr KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +constexpr KernelProfilingInfoMask operator&(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) & unsigned(b)); } +constexpr KernelProfilingInfoMask operator^(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) ^ unsigned(b)); } +constexpr KernelProfilingInfoMask operator~(KernelProfilingInfoMask a) { return KernelProfilingInfoMask(~unsigned(a)); } +constexpr RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } +constexpr RayFlagsMask operator&(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) & unsigned(b)); } +constexpr RayFlagsMask operator^(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) ^ unsigned(b)); } +constexpr RayFlagsMask operator~(RayFlagsMask a) { return RayFlagsMask(~unsigned(a)); } +constexpr FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } +constexpr FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); } +constexpr FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); } +constexpr FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); } +constexpr CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) | unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.json b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.json new file mode 100644 index 000000000000..c329090aa238 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.json @@ -0,0 +1,2145 @@ +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python, C#, D, Beef", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "- C# will use enum classes in the Specification class located in the \"Spv\" namespace,", + " e.g.: Spv.Specification.SourceLanguage.GLSL", + "- D will have tokens under the \"spv\" module, e.g: spv.SourceLanguage.GLSL", + "- Beef will use enum classes in the Specification class located in the \"Spv\" namespace,", + " e.g.: Spv.Specification.SourceLanguage.GLSL", + "", + "Some tokens act like mask values, which can be OR'd together,", + "while others are mutually exclusive. The mask-like ones have", + "\"Mask\" in their name, and a parallel enum that has the shift", + "amount (1 << x) for each corresponding enumerant." + ] + ], + "MagicNumber": 119734787, + "Version": 67072, + "Revision": 1, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5, + "CPP_for_OpenCL": 6, + "SYCL": 7, + "HERO_C": 8, + "NZSL": 9, + "WGSL": 10, + "Slang": 11, + "Zig": 12 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6, + "TaskNV": 5267, + "MeshNV": 5268, + "RayGenerationKHR": 5313, + "RayGenerationNV": 5313, + "IntersectionKHR": 5314, + "IntersectionNV": 5314, + "AnyHitKHR": 5315, + "AnyHitNV": 5315, + "ClosestHitKHR": 5316, + "ClosestHitNV": 5316, + "MissKHR": 5317, + "MissNV": 5317, + "CallableKHR": 5318, + "CallableNV": 5318, + "TaskEXT": 5364, + "MeshEXT": 5365 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2, + "PhysicalStorageBuffer64": 5348, + "PhysicalStorageBuffer64EXT": 5348 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2, + "Vulkan": 3, + "VulkanKHR": 3 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "Initializer": 33, + "Finalizer": 34, + "SubgroupSize": 35, + "SubgroupsPerWorkgroup": 36, + "SubgroupsPerWorkgroupId": 37, + "LocalSizeId": 38, + "LocalSizeHintId": 39, + "NonCoherentColorAttachmentReadEXT": 4169, + "NonCoherentDepthAttachmentReadEXT": 4170, + "NonCoherentStencilAttachmentReadEXT": 4171, + "SubgroupUniformControlFlowKHR": 4421, + "PostDepthCoverage": 4446, + "DenormPreserve": 4459, + "DenormFlushToZero": 4460, + "SignedZeroInfNanPreserve": 4461, + "RoundingModeRTE": 4462, + "RoundingModeRTZ": 4463, + "EarlyAndLateFragmentTestsAMD": 5017, + "StencilRefReplacingEXT": 5027, + "CoalescingAMDX": 5069, + "MaxNodeRecursionAMDX": 5071, + "StaticNumWorkgroupsAMDX": 5072, + "ShaderIndexAMDX": 5073, + "MaxNumWorkgroupsAMDX": 5077, + "StencilRefUnchangedFrontAMD": 5079, + "StencilRefGreaterFrontAMD": 5080, + "StencilRefLessFrontAMD": 5081, + "StencilRefUnchangedBackAMD": 5082, + "StencilRefGreaterBackAMD": 5083, + "StencilRefLessBackAMD": 5084, + "QuadDerivativesKHR": 5088, + "RequireFullQuadsKHR": 5089, + "OutputLinesEXT": 5269, + "OutputLinesNV": 5269, + "OutputPrimitivesEXT": 5270, + "OutputPrimitivesNV": 5270, + "DerivativeGroupQuadsNV": 5289, + "DerivativeGroupLinearNV": 5290, + "OutputTrianglesEXT": 5298, + "OutputTrianglesNV": 5298, + "PixelInterlockOrderedEXT": 5366, + "PixelInterlockUnorderedEXT": 5367, + "SampleInterlockOrderedEXT": 5368, + "SampleInterlockUnorderedEXT": 5369, + "ShadingRateInterlockOrderedEXT": 5370, + "ShadingRateInterlockUnorderedEXT": 5371, + "SharedLocalMemorySizeINTEL": 5618, + "RoundingModeRTPINTEL": 5620, + "RoundingModeRTNINTEL": 5621, + "FloatingPointModeALTINTEL": 5622, + "FloatingPointModeIEEEINTEL": 5623, + "MaxWorkgroupSizeINTEL": 5893, + "MaxWorkDimINTEL": 5894, + "NoGlobalOffsetINTEL": 5895, + "NumSIMDWorkitemsINTEL": 5896, + "SchedulerTargetFmaxMhzINTEL": 5903, + "MaximallyReconvergesKHR": 6023, + "FPFastMathDefault": 6028, + "StreamingInterfaceINTEL": 6154, + "RegisterMapInterfaceINTEL": 6160, + "NamedBarrierCountINTEL": 6417, + "MaximumRegistersINTEL": 6461, + "MaximumRegistersIdINTEL": 6462, + "NamedMaximumRegistersINTEL": 6463 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12, + "TileImageEXT": 4172, + "NodePayloadAMDX": 5068, + "NodeOutputPayloadAMDX": 5076, + "CallableDataKHR": 5328, + "CallableDataNV": 5328, + "IncomingCallableDataKHR": 5329, + "IncomingCallableDataNV": 5329, + "RayPayloadKHR": 5338, + "RayPayloadNV": 5338, + "HitAttributeKHR": 5339, + "HitAttributeNV": 5339, + "IncomingRayPayloadKHR": 5342, + "IncomingRayPayloadNV": 5342, + "ShaderRecordBufferKHR": 5343, + "ShaderRecordBufferNV": 5343, + "PhysicalStorageBuffer": 5349, + "PhysicalStorageBufferEXT": 5349, + "HitObjectAttributeNV": 5385, + "TaskPayloadWorkgroupEXT": 5402, + "CodeSectionINTEL": 5605, + "DeviceOnlyINTEL": 5936, + "HostOnlyINTEL": 5937 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6, + "TileImageDataEXT": 4173 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39, + "R64ui": 40, + "R64i": 41 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16, + "UnsignedIntRaw10EXT": 19, + "UnsignedIntRaw12EXT": 20 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7, + "MakeTexelAvailable": 8, + "MakeTexelAvailableKHR": 8, + "MakeTexelVisible": 9, + "MakeTexelVisibleKHR": 9, + "NonPrivateTexel": 10, + "NonPrivateTexelKHR": 10, + "VolatileTexel": 11, + "VolatileTexelKHR": 11, + "SignExtend": 12, + "ZeroExtend": 13, + "Nontemporal": 14, + "Offsets": 16 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4, + "AllowContract": 16, + "AllowContractFastINTEL": 16, + "AllowReassoc": 17, + "AllowReassocINTEL": 17, + "AllowTransform": 18 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1, + "LinkOnceODR": 2 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7, + "RuntimeAlignedINTEL": 5940 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "UniformId": 27, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "MaxByteOffset": 45, + "AlignmentId": 46, + "MaxByteOffsetId": 47, + "NoSignedWrap": 4469, + "NoUnsignedWrap": 4470, + "WeightTextureQCOM": 4487, + "BlockMatchTextureQCOM": 4488, + "BlockMatchSamplerQCOM": 4499, + "ExplicitInterpAMD": 4999, + "NodeSharesPayloadLimitsWithAMDX": 5019, + "NodeMaxPayloadsAMDX": 5020, + "TrackFinishWritingAMDX": 5078, + "PayloadNodeNameAMDX": 5091, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256, + "PerPrimitiveEXT": 5271, + "PerPrimitiveNV": 5271, + "PerViewNV": 5272, + "PerTaskNV": 5273, + "PerVertexKHR": 5285, + "PerVertexNV": 5285, + "NonUniform": 5300, + "NonUniformEXT": 5300, + "RestrictPointer": 5355, + "RestrictPointerEXT": 5355, + "AliasedPointer": 5356, + "AliasedPointerEXT": 5356, + "HitObjectShaderRecordBufferNV": 5386, + "BindlessSamplerNV": 5398, + "BindlessImageNV": 5399, + "BoundSamplerNV": 5400, + "BoundImageNV": 5401, + "SIMTCallINTEL": 5599, + "ReferencedIndirectlyINTEL": 5602, + "ClobberINTEL": 5607, + "SideEffectsINTEL": 5608, + "VectorComputeVariableINTEL": 5624, + "FuncParamIOKindINTEL": 5625, + "VectorComputeFunctionINTEL": 5626, + "StackCallINTEL": 5627, + "GlobalVariableOffsetINTEL": 5628, + "CounterBuffer": 5634, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635, + "UserSemantic": 5635, + "UserTypeGOOGLE": 5636, + "FunctionRoundingModeINTEL": 5822, + "FunctionDenormModeINTEL": 5823, + "RegisterINTEL": 5825, + "MemoryINTEL": 5826, + "NumbanksINTEL": 5827, + "BankwidthINTEL": 5828, + "MaxPrivateCopiesINTEL": 5829, + "SinglepumpINTEL": 5830, + "DoublepumpINTEL": 5831, + "MaxReplicatesINTEL": 5832, + "SimpleDualPortINTEL": 5833, + "MergeINTEL": 5834, + "BankBitsINTEL": 5835, + "ForcePow2DepthINTEL": 5836, + "StridesizeINTEL": 5883, + "WordsizeINTEL": 5884, + "TrueDualPortINTEL": 5885, + "BurstCoalesceINTEL": 5899, + "CacheSizeINTEL": 5900, + "DontStaticallyCoalesceINTEL": 5901, + "PrefetchINTEL": 5902, + "StallEnableINTEL": 5905, + "FuseLoopsInFunctionINTEL": 5907, + "MathOpDSPModeINTEL": 5909, + "AliasScopeINTEL": 5914, + "NoAliasINTEL": 5915, + "InitiationIntervalINTEL": 5917, + "MaxConcurrencyINTEL": 5918, + "PipelineEnableINTEL": 5919, + "BufferLocationINTEL": 5921, + "IOPipeStorageINTEL": 5944, + "FunctionFloatingPointModeINTEL": 6080, + "SingleElementVectorINTEL": 6085, + "VectorComputeCallableFunctionINTEL": 6087, + "MediaBlockIOINTEL": 6140, + "StallFreeINTEL": 6151, + "FPMaxErrorDecorationINTEL": 6170, + "LatencyControlLabelINTEL": 6172, + "LatencyControlConstraintINTEL": 6173, + "ConduitKernelArgumentINTEL": 6175, + "RegisterMapKernelArgumentINTEL": 6176, + "MMHostInterfaceAddressWidthINTEL": 6177, + "MMHostInterfaceDataWidthINTEL": 6178, + "MMHostInterfaceLatencyINTEL": 6179, + "MMHostInterfaceReadWriteModeINTEL": 6180, + "MMHostInterfaceMaxBurstINTEL": 6181, + "MMHostInterfaceWaitRequestINTEL": 6182, + "StableKernelArgumentINTEL": 6183, + "HostAccessINTEL": 6188, + "InitModeINTEL": 6190, + "ImplementInRegisterMapINTEL": 6191, + "CacheControlLoadINTEL": 6442, + "CacheControlStoreINTEL": 6443 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "CoreIDARM": 4160, + "CoreCountARM": 4161, + "CoreMaxIDARM": 4162, + "WarpIDARM": 4163, + "WarpMaxIDARM": 4164, + "SubgroupEqMask": 4416, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMask": 4417, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMask": 4418, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMask": 4419, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMask": 4420, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "PrimitiveShadingRateKHR": 4432, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "ShadingRateKHR": 4444, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "CoalescedInputCountAMDX": 5021, + "ShaderIndexAMDX": 5073, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262, + "FullyCoveredEXT": 5264, + "TaskCountNV": 5274, + "PrimitiveCountNV": 5275, + "PrimitiveIndicesNV": 5276, + "ClipDistancePerViewNV": 5277, + "CullDistancePerViewNV": 5278, + "LayerPerViewNV": 5279, + "MeshViewCountNV": 5280, + "MeshViewIndicesNV": 5281, + "BaryCoordKHR": 5286, + "BaryCoordNV": 5286, + "BaryCoordNoPerspKHR": 5287, + "BaryCoordNoPerspNV": 5287, + "FragSizeEXT": 5292, + "FragmentSizeNV": 5292, + "FragInvocationCountEXT": 5293, + "InvocationsPerPixelNV": 5293, + "PrimitivePointIndicesEXT": 5294, + "PrimitiveLineIndicesEXT": 5295, + "PrimitiveTriangleIndicesEXT": 5296, + "CullPrimitiveEXT": 5299, + "LaunchIdKHR": 5319, + "LaunchIdNV": 5319, + "LaunchSizeKHR": 5320, + "LaunchSizeNV": 5320, + "WorldRayOriginKHR": 5321, + "WorldRayOriginNV": 5321, + "WorldRayDirectionKHR": 5322, + "WorldRayDirectionNV": 5322, + "ObjectRayOriginKHR": 5323, + "ObjectRayOriginNV": 5323, + "ObjectRayDirectionKHR": 5324, + "ObjectRayDirectionNV": 5324, + "RayTminKHR": 5325, + "RayTminNV": 5325, + "RayTmaxKHR": 5326, + "RayTmaxNV": 5326, + "InstanceCustomIndexKHR": 5327, + "InstanceCustomIndexNV": 5327, + "ObjectToWorldKHR": 5330, + "ObjectToWorldNV": 5330, + "WorldToObjectKHR": 5331, + "WorldToObjectNV": 5331, + "HitTNV": 5332, + "HitKindKHR": 5333, + "HitKindNV": 5333, + "CurrentRayTimeNV": 5334, + "HitTriangleVertexPositionsKHR": 5335, + "HitMicroTriangleVertexPositionsNV": 5337, + "HitMicroTriangleVertexBarycentricsNV": 5344, + "IncomingRayFlagsKHR": 5351, + "IncomingRayFlagsNV": 5351, + "RayGeometryIndexKHR": 5352, + "WarpsPerSMNV": 5374, + "SMCountNV": 5375, + "WarpIDNV": 5376, + "SMIDNV": 5377, + "HitKindFrontFacingMicroTriangleNV": 5405, + "HitKindBackFacingMicroTriangleNV": 5406, + "CullMaskKHR": 6021 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1, + "DependencyInfinite": 2, + "DependencyLength": 3, + "MinIterations": 4, + "MaxIterations": 5, + "IterationMultiple": 6, + "PeelCount": 7, + "PartialCount": 8, + "InitiationIntervalINTEL": 16, + "MaxConcurrencyINTEL": 17, + "DependencyArrayINTEL": 18, + "PipelineEnableINTEL": 19, + "LoopCoalesceINTEL": 20, + "MaxInterleavingINTEL": 21, + "SpeculatedIterationsINTEL": 22, + "NoFusionINTEL": 23, + "LoopCountINTEL": 24, + "MaxReinvocationDelayINTEL": 25 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3, + "OptNoneINTEL": 16 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11, + "OutputMemory": 12, + "OutputMemoryKHR": 12, + "MakeAvailable": 13, + "MakeAvailableKHR": 13, + "MakeVisible": 14, + "MakeVisibleKHR": 14, + "Volatile": 15 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2, + "MakePointerAvailable": 3, + "MakePointerAvailableKHR": 3, + "MakePointerVisible": 4, + "MakePointerVisibleKHR": 4, + "NonPrivatePointer": 5, + "NonPrivatePointerKHR": 5, + "AliasScopeINTELMask": 16, + "NoAliasINTELMask": 17 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4, + "QueueFamily": 5, + "QueueFamilyKHR": 5, + "ShaderCallKHR": 6 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2, + "ClusteredReduce": 3, + "PartitionedReduceNV": 6, + "PartitionedInclusiveScanNV": 7, + "PartitionedExclusiveScanNV": 8 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupDispatch": 58, + "NamedBarrier": 59, + "PipeStorage": 60, + "GroupNonUniform": 61, + "GroupNonUniformVote": 62, + "GroupNonUniformArithmetic": 63, + "GroupNonUniformBallot": 64, + "GroupNonUniformShuffle": 65, + "GroupNonUniformShuffleRelative": 66, + "GroupNonUniformClustered": 67, + "GroupNonUniformQuad": 68, + "ShaderLayer": 69, + "ShaderViewportIndex": 70, + "UniformDecoration": 71, + "CoreBuiltinsARM": 4165, + "TileImageColorReadAccessEXT": 4166, + "TileImageDepthReadAccessEXT": 4167, + "TileImageStencilReadAccessEXT": 4168, + "FragmentShadingRateKHR": 4422, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "WorkgroupMemoryExplicitLayoutKHR": 4428, + "WorkgroupMemoryExplicitLayout8BitAccessKHR": 4429, + "WorkgroupMemoryExplicitLayout16BitAccessKHR": 4430, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "StorageBuffer8BitAccess": 4448, + "UniformAndStorageBuffer8BitAccess": 4449, + "StoragePushConstant8": 4450, + "DenormPreserve": 4464, + "DenormFlushToZero": 4465, + "SignedZeroInfNanPreserve": 4466, + "RoundingModeRTE": 4467, + "RoundingModeRTZ": 4468, + "RayQueryProvisionalKHR": 4471, + "RayQueryKHR": 4472, + "RayTraversalPrimitiveCullingKHR": 4478, + "RayTracingKHR": 4479, + "TextureSampleWeightedQCOM": 4484, + "TextureBoxFilterQCOM": 4485, + "TextureBlockMatchQCOM": 4486, + "TextureBlockMatch2QCOM": 4498, + "Float16ImageAMD": 5008, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "Int64ImageEXT": 5016, + "ShaderClockKHR": 5055, + "ShaderEnqueueAMDX": 5067, + "QuadControlKHR": 5087, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "FragmentFullyCoveredEXT": 5265, + "MeshShadingNV": 5266, + "ImageFootprintNV": 5282, + "MeshShadingEXT": 5283, + "FragmentBarycentricKHR": 5284, + "FragmentBarycentricNV": 5284, + "ComputeDerivativeGroupQuadsNV": 5288, + "FragmentDensityEXT": 5291, + "ShadingRateNV": 5291, + "GroupNonUniformPartitionedNV": 5297, + "ShaderNonUniform": 5301, + "ShaderNonUniformEXT": 5301, + "RuntimeDescriptorArray": 5302, + "RuntimeDescriptorArrayEXT": 5302, + "InputAttachmentArrayDynamicIndexing": 5303, + "InputAttachmentArrayDynamicIndexingEXT": 5303, + "UniformTexelBufferArrayDynamicIndexing": 5304, + "UniformTexelBufferArrayDynamicIndexingEXT": 5304, + "StorageTexelBufferArrayDynamicIndexing": 5305, + "StorageTexelBufferArrayDynamicIndexingEXT": 5305, + "UniformBufferArrayNonUniformIndexing": 5306, + "UniformBufferArrayNonUniformIndexingEXT": 5306, + "SampledImageArrayNonUniformIndexing": 5307, + "SampledImageArrayNonUniformIndexingEXT": 5307, + "StorageBufferArrayNonUniformIndexing": 5308, + "StorageBufferArrayNonUniformIndexingEXT": 5308, + "StorageImageArrayNonUniformIndexing": 5309, + "StorageImageArrayNonUniformIndexingEXT": 5309, + "InputAttachmentArrayNonUniformIndexing": 5310, + "InputAttachmentArrayNonUniformIndexingEXT": 5310, + "UniformTexelBufferArrayNonUniformIndexing": 5311, + "UniformTexelBufferArrayNonUniformIndexingEXT": 5311, + "StorageTexelBufferArrayNonUniformIndexing": 5312, + "StorageTexelBufferArrayNonUniformIndexingEXT": 5312, + "RayTracingPositionFetchKHR": 5336, + "RayTracingNV": 5340, + "RayTracingMotionBlurNV": 5341, + "VulkanMemoryModel": 5345, + "VulkanMemoryModelKHR": 5345, + "VulkanMemoryModelDeviceScope": 5346, + "VulkanMemoryModelDeviceScopeKHR": 5346, + "PhysicalStorageBufferAddresses": 5347, + "PhysicalStorageBufferAddressesEXT": 5347, + "ComputeDerivativeGroupLinearNV": 5350, + "RayTracingProvisionalKHR": 5353, + "CooperativeMatrixNV": 5357, + "FragmentShaderSampleInterlockEXT": 5363, + "FragmentShaderShadingRateInterlockEXT": 5372, + "ShaderSMBuiltinsNV": 5373, + "FragmentShaderPixelInterlockEXT": 5378, + "DemoteToHelperInvocation": 5379, + "DemoteToHelperInvocationEXT": 5379, + "DisplacementMicromapNV": 5380, + "RayTracingOpacityMicromapEXT": 5381, + "ShaderInvocationReorderNV": 5383, + "BindlessTextureNV": 5390, + "RayQueryPositionFetchKHR": 5391, + "AtomicFloat16VectorNV": 5404, + "RayTracingDisplacementMicromapNV": 5409, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570, + "SubgroupImageMediaBlockIOINTEL": 5579, + "RoundToInfinityINTEL": 5582, + "FloatingPointModeINTEL": 5583, + "IntegerFunctions2INTEL": 5584, + "FunctionPointersINTEL": 5603, + "IndirectReferencesINTEL": 5604, + "AsmINTEL": 5606, + "AtomicFloat32MinMaxEXT": 5612, + "AtomicFloat64MinMaxEXT": 5613, + "AtomicFloat16MinMaxEXT": 5616, + "VectorComputeINTEL": 5617, + "VectorAnyINTEL": 5619, + "ExpectAssumeKHR": 5629, + "SubgroupAvcMotionEstimationINTEL": 5696, + "SubgroupAvcMotionEstimationIntraINTEL": 5697, + "SubgroupAvcMotionEstimationChromaINTEL": 5698, + "VariableLengthArrayINTEL": 5817, + "FunctionFloatControlINTEL": 5821, + "FPGAMemoryAttributesINTEL": 5824, + "FPFastMathModeINTEL": 5837, + "ArbitraryPrecisionIntegersINTEL": 5844, + "ArbitraryPrecisionFloatingPointINTEL": 5845, + "UnstructuredLoopControlsINTEL": 5886, + "FPGALoopControlsINTEL": 5888, + "KernelAttributesINTEL": 5892, + "FPGAKernelAttributesINTEL": 5897, + "FPGAMemoryAccessesINTEL": 5898, + "FPGAClusterAttributesINTEL": 5904, + "LoopFuseINTEL": 5906, + "FPGADSPControlINTEL": 5908, + "MemoryAccessAliasingINTEL": 5910, + "FPGAInvocationPipeliningAttributesINTEL": 5916, + "FPGABufferLocationINTEL": 5920, + "ArbitraryPrecisionFixedPointINTEL": 5922, + "USMStorageClassesINTEL": 5935, + "RuntimeAlignedAttributeINTEL": 5939, + "IOPipesINTEL": 5943, + "BlockingPipesINTEL": 5945, + "FPGARegINTEL": 5948, + "DotProductInputAll": 6016, + "DotProductInputAllKHR": 6016, + "DotProductInput4x8Bit": 6017, + "DotProductInput4x8BitKHR": 6017, + "DotProductInput4x8BitPacked": 6018, + "DotProductInput4x8BitPackedKHR": 6018, + "DotProduct": 6019, + "DotProductKHR": 6019, + "RayCullMaskKHR": 6020, + "CooperativeMatrixKHR": 6022, + "BitInstructions": 6025, + "GroupNonUniformRotateKHR": 6026, + "FloatControls2": 6029, + "AtomicFloat32AddEXT": 6033, + "AtomicFloat64AddEXT": 6034, + "LongCompositesINTEL": 6089, + "OptNoneINTEL": 6094, + "AtomicFloat16AddEXT": 6095, + "DebugInfoModuleINTEL": 6114, + "BFloat16ConversionINTEL": 6115, + "SplitBarrierINTEL": 6141, + "FPGAClusterAttributesV2INTEL": 6150, + "FPGAKernelAttributesv2INTEL": 6161, + "FPMaxErrorINTEL": 6169, + "FPGALatencyControlINTEL": 6171, + "FPGAArgumentInterfacesINTEL": 6174, + "GlobalVariableHostAccessINTEL": 6187, + "GlobalVariableFPGADecorationsINTEL": 6189, + "GroupUniformArithmeticKHR": 6400, + "MaskedGatherScatterINTEL": 6427, + "CacheControlsINTEL": 6441, + "RegisterLimitsINTEL": 6460 + } + }, + { + "Name": "RayFlags", + "Type": "Bit", + "Values": + { + "OpaqueKHR": 0, + "NoOpaqueKHR": 1, + "TerminateOnFirstHitKHR": 2, + "SkipClosestHitShaderKHR": 3, + "CullBackFacingTrianglesKHR": 4, + "CullFrontFacingTrianglesKHR": 5, + "CullOpaqueKHR": 6, + "CullNoOpaqueKHR": 7, + "SkipTrianglesKHR": 8, + "SkipAABBsKHR": 9, + "ForceOpacityMicromap2StateEXT": 10 + } + }, + { + "Name": "RayQueryIntersection", + "Type": "Value", + "Values": + { + "RayQueryCandidateIntersectionKHR": 0, + "RayQueryCommittedIntersectionKHR": 1 + } + }, + { + "Name": "RayQueryCommittedIntersectionType", + "Type": "Value", + "Values": + { + "RayQueryCommittedIntersectionNoneKHR": 0, + "RayQueryCommittedIntersectionTriangleKHR": 1, + "RayQueryCommittedIntersectionGeneratedKHR": 2 + } + }, + { + "Name": "RayQueryCandidateIntersectionType", + "Type": "Value", + "Values": + { + "RayQueryCandidateIntersectionTriangleKHR": 0, + "RayQueryCandidateIntersectionAABBKHR": 1 + } + }, + { + "Name": "FragmentShadingRate", + "Type": "Bit", + "Values": + { + "Vertical2Pixels": 0, + "Vertical4Pixels": 1, + "Horizontal2Pixels": 2, + "Horizontal4Pixels": 3 + } + }, + { + "Name": "FPDenormMode", + "Type": "Value", + "Values": + { + "Preserve": 0, + "FlushToZero": 1 + } + }, + { + "Name": "FPOperationMode", + "Type": "Value", + "Values": + { + "IEEE": 0, + "ALT": 1 + } + }, + { + "Name": "QuantizationModes", + "Type": "Value", + "Values": + { + "TRN": 0, + "TRN_ZERO": 1, + "RND": 2, + "RND_ZERO": 3, + "RND_INF": 4, + "RND_MIN_INF": 5, + "RND_CONV": 6, + "RND_CONV_ODD": 7 + } + }, + { + "Name": "OverflowModes", + "Type": "Value", + "Values": + { + "WRAP": 0, + "SAT": 1, + "SAT_ZERO": 2, + "SAT_SYM": 3 + } + }, + { + "Name": "PackedVectorFormat", + "Type": "Value", + "Values": + { + "PackedVectorFormat4x8Bit": 0, + "PackedVectorFormat4x8BitKHR": 0 + } + }, + { + "Name": "CooperativeMatrixOperands", + "Type": "Bit", + "Values": + { + "MatrixASignedComponentsKHR": 0, + "MatrixBSignedComponentsKHR": 1, + "MatrixCSignedComponentsKHR": 2, + "MatrixResultSignedComponentsKHR": 3, + "SaturatingAccumulationKHR": 4 + } + }, + { + "Name": "CooperativeMatrixLayout", + "Type": "Value", + "Values": + { + "RowMajorKHR": 0, + "ColumnMajorKHR": 1 + } + }, + { + "Name": "CooperativeMatrixUse", + "Type": "Value", + "Values": + { + "MatrixAKHR": 0, + "MatrixBKHR": 1, + "MatrixAccumulatorKHR": 2 + } + }, + { + "Name": "InitializationModeQualifier", + "Type": "Value", + "Values": + { + "InitOnDeviceReprogramINTEL": 0, + "InitOnDeviceResetINTEL": 1 + } + }, + { + "Name": "HostAccessQualifier", + "Type": "Value", + "Values": + { + "NoneINTEL": 0, + "ReadINTEL": 1, + "WriteINTEL": 2, + "ReadWriteINTEL": 3 + } + }, + { + "Name": "LoadCacheControl", + "Type": "Value", + "Values": + { + "UncachedINTEL": 0, + "CachedINTEL": 1, + "StreamingINTEL": 2, + "InvalidateAfterReadINTEL": 3, + "ConstCachedINTEL": 4 + } + }, + { + "Name": "StoreCacheControl", + "Type": "Value", + "Values": + { + "UncachedINTEL": 0, + "WriteThroughINTEL": 1, + "WriteBackINTEL": 2, + "StreamingINTEL": 3 + } + }, + { + "Name": "NamedMaximumNumberOfRegisters", + "Type": "Value", + "Values": + { + "AutoINTEL": 0 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpSizeOf": 321, + "OpTypePipeStorage": 322, + "OpConstantPipeStorage": 323, + "OpCreatePipeFromPipeStorage": 324, + "OpGetKernelLocalSizeForSubgroupCount": 325, + "OpGetKernelMaxNumSubgroups": 326, + "OpTypeNamedBarrier": 327, + "OpNamedBarrierInitialize": 328, + "OpMemoryNamedBarrier": 329, + "OpModuleProcessed": 330, + "OpExecutionModeId": 331, + "OpDecorateId": 332, + "OpGroupNonUniformElect": 333, + "OpGroupNonUniformAll": 334, + "OpGroupNonUniformAny": 335, + "OpGroupNonUniformAllEqual": 336, + "OpGroupNonUniformBroadcast": 337, + "OpGroupNonUniformBroadcastFirst": 338, + "OpGroupNonUniformBallot": 339, + "OpGroupNonUniformInverseBallot": 340, + "OpGroupNonUniformBallotBitExtract": 341, + "OpGroupNonUniformBallotBitCount": 342, + "OpGroupNonUniformBallotFindLSB": 343, + "OpGroupNonUniformBallotFindMSB": 344, + "OpGroupNonUniformShuffle": 345, + "OpGroupNonUniformShuffleXor": 346, + "OpGroupNonUniformShuffleUp": 347, + "OpGroupNonUniformShuffleDown": 348, + "OpGroupNonUniformIAdd": 349, + "OpGroupNonUniformFAdd": 350, + "OpGroupNonUniformIMul": 351, + "OpGroupNonUniformFMul": 352, + "OpGroupNonUniformSMin": 353, + "OpGroupNonUniformUMin": 354, + "OpGroupNonUniformFMin": 355, + "OpGroupNonUniformSMax": 356, + "OpGroupNonUniformUMax": 357, + "OpGroupNonUniformFMax": 358, + "OpGroupNonUniformBitwiseAnd": 359, + "OpGroupNonUniformBitwiseOr": 360, + "OpGroupNonUniformBitwiseXor": 361, + "OpGroupNonUniformLogicalAnd": 362, + "OpGroupNonUniformLogicalOr": 363, + "OpGroupNonUniformLogicalXor": 364, + "OpGroupNonUniformQuadBroadcast": 365, + "OpGroupNonUniformQuadSwap": 366, + "OpCopyLogical": 400, + "OpPtrEqual": 401, + "OpPtrNotEqual": 402, + "OpPtrDiff": 403, + "OpColorAttachmentReadEXT": 4160, + "OpDepthAttachmentReadEXT": 4161, + "OpStencilAttachmentReadEXT": 4162, + "OpTerminateInvocation": 4416, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpGroupNonUniformRotateKHR": 4431, + "OpSubgroupReadInvocationKHR": 4432, + "OpTraceRayKHR": 4445, + "OpExecuteCallableKHR": 4446, + "OpConvertUToAccelerationStructureKHR": 4447, + "OpIgnoreIntersectionKHR": 4448, + "OpTerminateRayKHR": 4449, + "OpSDot": 4450, + "OpSDotKHR": 4450, + "OpUDot": 4451, + "OpUDotKHR": 4451, + "OpSUDot": 4452, + "OpSUDotKHR": 4452, + "OpSDotAccSat": 4453, + "OpSDotAccSatKHR": 4453, + "OpUDotAccSat": 4454, + "OpUDotAccSatKHR": 4454, + "OpSUDotAccSat": 4455, + "OpSUDotAccSatKHR": 4455, + "OpTypeCooperativeMatrixKHR": 4456, + "OpCooperativeMatrixLoadKHR": 4457, + "OpCooperativeMatrixStoreKHR": 4458, + "OpCooperativeMatrixMulAddKHR": 4459, + "OpCooperativeMatrixLengthKHR": 4460, + "OpTypeRayQueryKHR": 4472, + "OpRayQueryInitializeKHR": 4473, + "OpRayQueryTerminateKHR": 4474, + "OpRayQueryGenerateIntersectionKHR": 4475, + "OpRayQueryConfirmIntersectionKHR": 4476, + "OpRayQueryProceedKHR": 4477, + "OpRayQueryGetIntersectionTypeKHR": 4479, + "OpImageSampleWeightedQCOM": 4480, + "OpImageBoxFilterQCOM": 4481, + "OpImageBlockMatchSSDQCOM": 4482, + "OpImageBlockMatchSADQCOM": 4483, + "OpImageBlockMatchWindowSSDQCOM": 4500, + "OpImageBlockMatchWindowSADQCOM": 4501, + "OpImageBlockMatchGatherSSDQCOM": 4502, + "OpImageBlockMatchGatherSADQCOM": 4503, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpReadClockKHR": 5056, + "OpFinalizeNodePayloadsAMDX": 5075, + "OpFinishWritingNodePayloadAMDX": 5078, + "OpInitializeNodePayloadsAMDX": 5090, + "OpGroupNonUniformQuadAllKHR": 5110, + "OpGroupNonUniformQuadAnyKHR": 5111, + "OpHitObjectRecordHitMotionNV": 5249, + "OpHitObjectRecordHitWithIndexMotionNV": 5250, + "OpHitObjectRecordMissMotionNV": 5251, + "OpHitObjectGetWorldToObjectNV": 5252, + "OpHitObjectGetObjectToWorldNV": 5253, + "OpHitObjectGetObjectRayDirectionNV": 5254, + "OpHitObjectGetObjectRayOriginNV": 5255, + "OpHitObjectTraceRayMotionNV": 5256, + "OpHitObjectGetShaderRecordBufferHandleNV": 5257, + "OpHitObjectGetShaderBindingTableRecordIndexNV": 5258, + "OpHitObjectRecordEmptyNV": 5259, + "OpHitObjectTraceRayNV": 5260, + "OpHitObjectRecordHitNV": 5261, + "OpHitObjectRecordHitWithIndexNV": 5262, + "OpHitObjectRecordMissNV": 5263, + "OpHitObjectExecuteShaderNV": 5264, + "OpHitObjectGetCurrentTimeNV": 5265, + "OpHitObjectGetAttributesNV": 5266, + "OpHitObjectGetHitKindNV": 5267, + "OpHitObjectGetPrimitiveIndexNV": 5268, + "OpHitObjectGetGeometryIndexNV": 5269, + "OpHitObjectGetInstanceIdNV": 5270, + "OpHitObjectGetInstanceCustomIndexNV": 5271, + "OpHitObjectGetWorldRayDirectionNV": 5272, + "OpHitObjectGetWorldRayOriginNV": 5273, + "OpHitObjectGetRayTMaxNV": 5274, + "OpHitObjectGetRayTMinNV": 5275, + "OpHitObjectIsEmptyNV": 5276, + "OpHitObjectIsHitNV": 5277, + "OpHitObjectIsMissNV": 5278, + "OpReorderThreadWithHitObjectNV": 5279, + "OpReorderThreadWithHintNV": 5280, + "OpTypeHitObjectNV": 5281, + "OpImageSampleFootprintNV": 5283, + "OpEmitMeshTasksEXT": 5294, + "OpSetMeshOutputsEXT": 5295, + "OpGroupNonUniformPartitionNV": 5296, + "OpWritePackedPrimitiveIndices4x8NV": 5299, + "OpFetchMicroTriangleVertexPositionNV": 5300, + "OpFetchMicroTriangleVertexBarycentricNV": 5301, + "OpReportIntersectionKHR": 5334, + "OpReportIntersectionNV": 5334, + "OpIgnoreIntersectionNV": 5335, + "OpTerminateRayNV": 5336, + "OpTraceNV": 5337, + "OpTraceMotionNV": 5338, + "OpTraceRayMotionNV": 5339, + "OpRayQueryGetIntersectionTriangleVertexPositionsKHR": 5340, + "OpTypeAccelerationStructureKHR": 5341, + "OpTypeAccelerationStructureNV": 5341, + "OpExecuteCallableNV": 5344, + "OpTypeCooperativeMatrixNV": 5358, + "OpCooperativeMatrixLoadNV": 5359, + "OpCooperativeMatrixStoreNV": 5360, + "OpCooperativeMatrixMulAddNV": 5361, + "OpCooperativeMatrixLengthNV": 5362, + "OpBeginInvocationInterlockEXT": 5364, + "OpEndInvocationInterlockEXT": 5365, + "OpDemoteToHelperInvocation": 5380, + "OpDemoteToHelperInvocationEXT": 5380, + "OpIsHelperInvocationEXT": 5381, + "OpConvertUToImageNV": 5391, + "OpConvertUToSamplerNV": 5392, + "OpConvertImageToUNV": 5393, + "OpConvertSamplerToUNV": 5394, + "OpConvertUToSampledImageNV": 5395, + "OpConvertSampledImageToUNV": 5396, + "OpSamplerImageAddressingModeNV": 5397, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpSubgroupImageMediaBlockReadINTEL": 5580, + "OpSubgroupImageMediaBlockWriteINTEL": 5581, + "OpUCountLeadingZerosINTEL": 5585, + "OpUCountTrailingZerosINTEL": 5586, + "OpAbsISubINTEL": 5587, + "OpAbsUSubINTEL": 5588, + "OpIAddSatINTEL": 5589, + "OpUAddSatINTEL": 5590, + "OpIAverageINTEL": 5591, + "OpUAverageINTEL": 5592, + "OpIAverageRoundedINTEL": 5593, + "OpUAverageRoundedINTEL": 5594, + "OpISubSatINTEL": 5595, + "OpUSubSatINTEL": 5596, + "OpIMul32x16INTEL": 5597, + "OpUMul32x16INTEL": 5598, + "OpConstantFunctionPointerINTEL": 5600, + "OpFunctionPointerCallINTEL": 5601, + "OpAsmTargetINTEL": 5609, + "OpAsmINTEL": 5610, + "OpAsmCallINTEL": 5611, + "OpAtomicFMinEXT": 5614, + "OpAtomicFMaxEXT": 5615, + "OpAssumeTrueKHR": 5630, + "OpExpectKHR": 5631, + "OpDecorateString": 5632, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateString": 5633, + "OpMemberDecorateStringGOOGLE": 5633, + "OpVmeImageINTEL": 5699, + "OpTypeVmeImageINTEL": 5700, + "OpTypeAvcImePayloadINTEL": 5701, + "OpTypeAvcRefPayloadINTEL": 5702, + "OpTypeAvcSicPayloadINTEL": 5703, + "OpTypeAvcMcePayloadINTEL": 5704, + "OpTypeAvcMceResultINTEL": 5705, + "OpTypeAvcImeResultINTEL": 5706, + "OpTypeAvcImeResultSingleReferenceStreamoutINTEL": 5707, + "OpTypeAvcImeResultDualReferenceStreamoutINTEL": 5708, + "OpTypeAvcImeSingleReferenceStreaminINTEL": 5709, + "OpTypeAvcImeDualReferenceStreaminINTEL": 5710, + "OpTypeAvcRefResultINTEL": 5711, + "OpTypeAvcSicResultINTEL": 5712, + "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL": 5713, + "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL": 5714, + "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL": 5715, + "OpSubgroupAvcMceSetInterShapePenaltyINTEL": 5716, + "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL": 5717, + "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL": 5718, + "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL": 5719, + "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL": 5720, + "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL": 5721, + "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL": 5722, + "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL": 5723, + "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL": 5724, + "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL": 5725, + "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL": 5726, + "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL": 5727, + "OpSubgroupAvcMceSetAcOnlyHaarINTEL": 5728, + "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL": 5729, + "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL": 5730, + "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL": 5731, + "OpSubgroupAvcMceConvertToImePayloadINTEL": 5732, + "OpSubgroupAvcMceConvertToImeResultINTEL": 5733, + "OpSubgroupAvcMceConvertToRefPayloadINTEL": 5734, + "OpSubgroupAvcMceConvertToRefResultINTEL": 5735, + "OpSubgroupAvcMceConvertToSicPayloadINTEL": 5736, + "OpSubgroupAvcMceConvertToSicResultINTEL": 5737, + "OpSubgroupAvcMceGetMotionVectorsINTEL": 5738, + "OpSubgroupAvcMceGetInterDistortionsINTEL": 5739, + "OpSubgroupAvcMceGetBestInterDistortionsINTEL": 5740, + "OpSubgroupAvcMceGetInterMajorShapeINTEL": 5741, + "OpSubgroupAvcMceGetInterMinorShapeINTEL": 5742, + "OpSubgroupAvcMceGetInterDirectionsINTEL": 5743, + "OpSubgroupAvcMceGetInterMotionVectorCountINTEL": 5744, + "OpSubgroupAvcMceGetInterReferenceIdsINTEL": 5745, + "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL": 5746, + "OpSubgroupAvcImeInitializeINTEL": 5747, + "OpSubgroupAvcImeSetSingleReferenceINTEL": 5748, + "OpSubgroupAvcImeSetDualReferenceINTEL": 5749, + "OpSubgroupAvcImeRefWindowSizeINTEL": 5750, + "OpSubgroupAvcImeAdjustRefOffsetINTEL": 5751, + "OpSubgroupAvcImeConvertToMcePayloadINTEL": 5752, + "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL": 5753, + "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL": 5754, + "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL": 5755, + "OpSubgroupAvcImeSetWeightedSadINTEL": 5756, + "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL": 5757, + "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL": 5758, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL": 5759, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL": 5760, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL": 5761, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL": 5762, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL": 5763, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL": 5764, + "OpSubgroupAvcImeConvertToMceResultINTEL": 5765, + "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL": 5766, + "OpSubgroupAvcImeGetDualReferenceStreaminINTEL": 5767, + "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL": 5768, + "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL": 5769, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL": 5770, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL": 5771, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL": 5772, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL": 5773, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL": 5774, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL": 5775, + "OpSubgroupAvcImeGetBorderReachedINTEL": 5776, + "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL": 5777, + "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL": 5778, + "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL": 5779, + "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL": 5780, + "OpSubgroupAvcFmeInitializeINTEL": 5781, + "OpSubgroupAvcBmeInitializeINTEL": 5782, + "OpSubgroupAvcRefConvertToMcePayloadINTEL": 5783, + "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL": 5784, + "OpSubgroupAvcRefSetBilinearFilterEnableINTEL": 5785, + "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL": 5786, + "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL": 5787, + "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL": 5788, + "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL": 5789, + "OpSubgroupAvcRefConvertToMceResultINTEL": 5790, + "OpSubgroupAvcSicInitializeINTEL": 5791, + "OpSubgroupAvcSicConfigureSkcINTEL": 5792, + "OpSubgroupAvcSicConfigureIpeLumaINTEL": 5793, + "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL": 5794, + "OpSubgroupAvcSicGetMotionVectorMaskINTEL": 5795, + "OpSubgroupAvcSicConvertToMcePayloadINTEL": 5796, + "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL": 5797, + "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL": 5798, + "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL": 5799, + "OpSubgroupAvcSicSetBilinearFilterEnableINTEL": 5800, + "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL": 5801, + "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL": 5802, + "OpSubgroupAvcSicEvaluateIpeINTEL": 5803, + "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL": 5804, + "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL": 5805, + "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL": 5806, + "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL": 5807, + "OpSubgroupAvcSicConvertToMceResultINTEL": 5808, + "OpSubgroupAvcSicGetIpeLumaShapeINTEL": 5809, + "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL": 5810, + "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL": 5811, + "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL": 5812, + "OpSubgroupAvcSicGetIpeChromaModeINTEL": 5813, + "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL": 5814, + "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL": 5815, + "OpSubgroupAvcSicGetInterRawSadsINTEL": 5816, + "OpVariableLengthArrayINTEL": 5818, + "OpSaveMemoryINTEL": 5819, + "OpRestoreMemoryINTEL": 5820, + "OpArbitraryFloatSinCosPiINTEL": 5840, + "OpArbitraryFloatCastINTEL": 5841, + "OpArbitraryFloatCastFromIntINTEL": 5842, + "OpArbitraryFloatCastToIntINTEL": 5843, + "OpArbitraryFloatAddINTEL": 5846, + "OpArbitraryFloatSubINTEL": 5847, + "OpArbitraryFloatMulINTEL": 5848, + "OpArbitraryFloatDivINTEL": 5849, + "OpArbitraryFloatGTINTEL": 5850, + "OpArbitraryFloatGEINTEL": 5851, + "OpArbitraryFloatLTINTEL": 5852, + "OpArbitraryFloatLEINTEL": 5853, + "OpArbitraryFloatEQINTEL": 5854, + "OpArbitraryFloatRecipINTEL": 5855, + "OpArbitraryFloatRSqrtINTEL": 5856, + "OpArbitraryFloatCbrtINTEL": 5857, + "OpArbitraryFloatHypotINTEL": 5858, + "OpArbitraryFloatSqrtINTEL": 5859, + "OpArbitraryFloatLogINTEL": 5860, + "OpArbitraryFloatLog2INTEL": 5861, + "OpArbitraryFloatLog10INTEL": 5862, + "OpArbitraryFloatLog1pINTEL": 5863, + "OpArbitraryFloatExpINTEL": 5864, + "OpArbitraryFloatExp2INTEL": 5865, + "OpArbitraryFloatExp10INTEL": 5866, + "OpArbitraryFloatExpm1INTEL": 5867, + "OpArbitraryFloatSinINTEL": 5868, + "OpArbitraryFloatCosINTEL": 5869, + "OpArbitraryFloatSinCosINTEL": 5870, + "OpArbitraryFloatSinPiINTEL": 5871, + "OpArbitraryFloatCosPiINTEL": 5872, + "OpArbitraryFloatASinINTEL": 5873, + "OpArbitraryFloatASinPiINTEL": 5874, + "OpArbitraryFloatACosINTEL": 5875, + "OpArbitraryFloatACosPiINTEL": 5876, + "OpArbitraryFloatATanINTEL": 5877, + "OpArbitraryFloatATanPiINTEL": 5878, + "OpArbitraryFloatATan2INTEL": 5879, + "OpArbitraryFloatPowINTEL": 5880, + "OpArbitraryFloatPowRINTEL": 5881, + "OpArbitraryFloatPowNINTEL": 5882, + "OpLoopControlINTEL": 5887, + "OpAliasDomainDeclINTEL": 5911, + "OpAliasScopeDeclINTEL": 5912, + "OpAliasScopeListDeclINTEL": 5913, + "OpFixedSqrtINTEL": 5923, + "OpFixedRecipINTEL": 5924, + "OpFixedRsqrtINTEL": 5925, + "OpFixedSinINTEL": 5926, + "OpFixedCosINTEL": 5927, + "OpFixedSinCosINTEL": 5928, + "OpFixedSinPiINTEL": 5929, + "OpFixedCosPiINTEL": 5930, + "OpFixedSinCosPiINTEL": 5931, + "OpFixedLogINTEL": 5932, + "OpFixedExpINTEL": 5933, + "OpPtrCastToCrossWorkgroupINTEL": 5934, + "OpCrossWorkgroupCastToPtrINTEL": 5938, + "OpReadPipeBlockingINTEL": 5946, + "OpWritePipeBlockingINTEL": 5947, + "OpFPGARegINTEL": 5949, + "OpRayQueryGetRayTMinKHR": 6016, + "OpRayQueryGetRayFlagsKHR": 6017, + "OpRayQueryGetIntersectionTKHR": 6018, + "OpRayQueryGetIntersectionInstanceCustomIndexKHR": 6019, + "OpRayQueryGetIntersectionInstanceIdKHR": 6020, + "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR": 6021, + "OpRayQueryGetIntersectionGeometryIndexKHR": 6022, + "OpRayQueryGetIntersectionPrimitiveIndexKHR": 6023, + "OpRayQueryGetIntersectionBarycentricsKHR": 6024, + "OpRayQueryGetIntersectionFrontFaceKHR": 6025, + "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR": 6026, + "OpRayQueryGetIntersectionObjectRayDirectionKHR": 6027, + "OpRayQueryGetIntersectionObjectRayOriginKHR": 6028, + "OpRayQueryGetWorldRayDirectionKHR": 6029, + "OpRayQueryGetWorldRayOriginKHR": 6030, + "OpRayQueryGetIntersectionObjectToWorldKHR": 6031, + "OpRayQueryGetIntersectionWorldToObjectKHR": 6032, + "OpAtomicFAddEXT": 6035, + "OpTypeBufferSurfaceINTEL": 6086, + "OpTypeStructContinuedINTEL": 6090, + "OpConstantCompositeContinuedINTEL": 6091, + "OpSpecConstantCompositeContinuedINTEL": 6092, + "OpCompositeConstructContinuedINTEL": 6096, + "OpConvertFToBF16INTEL": 6116, + "OpConvertBF16ToFINTEL": 6117, + "OpControlBarrierArriveINTEL": 6142, + "OpControlBarrierWaitINTEL": 6143, + "OpGroupIMulKHR": 6401, + "OpGroupFMulKHR": 6402, + "OpGroupBitwiseAndKHR": 6403, + "OpGroupBitwiseOrKHR": 6404, + "OpGroupBitwiseXorKHR": 6405, + "OpGroupLogicalAndKHR": 6406, + "OpGroupLogicalOrKHR": 6407, + "OpGroupLogicalXorKHR": 6408, + "OpMaskedGatherINTEL": 6428, + "OpMaskedScatterINTEL": 6429 + } + } + ] + } +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.lua b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.lua new file mode 100644 index 000000000000..0be8e9119bf8 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.lua @@ -0,0 +1,2084 @@ +-- Copyright (c) 2014-2024 The Khronos Group Inc. +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and/or associated documentation files (the "Materials"), +-- to deal in the Materials without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Materials, and to permit persons to whom the +-- Materials are furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Materials. +-- +-- MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +-- STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +-- HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +-- +-- THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +-- IN THE MATERIALS. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python, C#, D, Beef +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- - C# will use enum classes in the Specification class located in the "Spv" namespace, +-- e.g.: Spv.Specification.SourceLanguage.GLSL +-- - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +-- - Beef will use enum classes in the Specification class located in the "Spv" namespace, +-- e.g.: Spv.Specification.SourceLanguage.GLSL +-- +-- Some tokens act like mask values, which can be OR'd together, +-- while others are mutually exclusive. The mask-like ones have +-- "Mask" in their name, and a parallel enum that has the shift +-- amount (1 << x) for each corresponding enumerant. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010600, + Revision = 1, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + NodeOutputPayloadAMDX = 5076, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + LinkOnceODR = 2, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + CoalescedInputCountAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + }, + + RayFlagsShift = { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + }, + + RayFlagsMask = { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, + }, + + RayQueryIntersection = { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + }, + + RayQueryCommittedIntersectionType = { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + }, + + RayQueryCandidateIntersectionType = { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + }, + + FragmentShadingRateShift = { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + }, + + FragmentShadingRateMask = { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, + }, + + FPDenormMode = { + Preserve = 0, + FlushToZero = 1, + }, + + FPOperationMode = { + IEEE = 0, + ALT = 1, + }, + + QuantizationModes = { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + }, + + OverflowModes = { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + }, + + PackedVectorFormat = { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + }, + + CooperativeMatrixOperandsShift = { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + }, + + CooperativeMatrixOperandsMask = { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, + }, + + CooperativeMatrixLayout = { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + }, + + CooperativeMatrixUse = { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + }, + + InitializationModeQualifier = { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + }, + + HostAccessQualifier = { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + }, + + LoadCacheControl = { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + }, + + StoreCacheControl = { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + }, + + NamedMaximumNumberOfRegisters = { + AutoINTEL = 0, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + }, + +} + diff --git a/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.py b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.py new file mode 100644 index 000000000000..a507f19e9b37 --- /dev/null +++ b/thirdparty/glslang/SPIRV-Headers/spirv/unified1/spirv.py @@ -0,0 +1,2084 @@ +# Copyright (c) 2014-2024 The Khronos Group Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and/or associated documentation files (the "Materials"), +# to deal in the Materials without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Materials, and to permit persons to whom the +# Materials are furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Materials. +# +# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +# STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +# HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +# +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +# IN THE MATERIALS. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python, C#, D, Beef +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# - C# will use enum classes in the Specification class located in the "Spv" namespace, +# e.g.: Spv.Specification.SourceLanguage.GLSL +# - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +# - Beef will use enum classes in the Specification class located in the "Spv" namespace, +# e.g.: Spv.Specification.SourceLanguage.GLSL +# +# Some tokens act like mask values, which can be OR'd together, +# while others are mutually exclusive. The mask-like ones have +# "Mask" in their name, and a parallel enum that has the shift +# amount (1 << x) for each corresponding enumerant. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010600, + 'Revision' : 1, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + 'CPP_for_OpenCL' : 6, + 'SYCL' : 7, + 'HERO_C' : 8, + 'NZSL' : 9, + 'WGSL' : 10, + 'Slang' : 11, + 'Zig' : 12, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + 'TaskNV' : 5267, + 'MeshNV' : 5268, + 'RayGenerationKHR' : 5313, + 'RayGenerationNV' : 5313, + 'IntersectionKHR' : 5314, + 'IntersectionNV' : 5314, + 'AnyHitKHR' : 5315, + 'AnyHitNV' : 5315, + 'ClosestHitKHR' : 5316, + 'ClosestHitNV' : 5316, + 'MissKHR' : 5317, + 'MissNV' : 5317, + 'CallableKHR' : 5318, + 'CallableNV' : 5318, + 'TaskEXT' : 5364, + 'MeshEXT' : 5365, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + 'PhysicalStorageBuffer64' : 5348, + 'PhysicalStorageBuffer64EXT' : 5348, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + 'Vulkan' : 3, + 'VulkanKHR' : 3, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'Initializer' : 33, + 'Finalizer' : 34, + 'SubgroupSize' : 35, + 'SubgroupsPerWorkgroup' : 36, + 'SubgroupsPerWorkgroupId' : 37, + 'LocalSizeId' : 38, + 'LocalSizeHintId' : 39, + 'NonCoherentColorAttachmentReadEXT' : 4169, + 'NonCoherentDepthAttachmentReadEXT' : 4170, + 'NonCoherentStencilAttachmentReadEXT' : 4171, + 'SubgroupUniformControlFlowKHR' : 4421, + 'PostDepthCoverage' : 4446, + 'DenormPreserve' : 4459, + 'DenormFlushToZero' : 4460, + 'SignedZeroInfNanPreserve' : 4461, + 'RoundingModeRTE' : 4462, + 'RoundingModeRTZ' : 4463, + 'EarlyAndLateFragmentTestsAMD' : 5017, + 'StencilRefReplacingEXT' : 5027, + 'CoalescingAMDX' : 5069, + 'MaxNodeRecursionAMDX' : 5071, + 'StaticNumWorkgroupsAMDX' : 5072, + 'ShaderIndexAMDX' : 5073, + 'MaxNumWorkgroupsAMDX' : 5077, + 'StencilRefUnchangedFrontAMD' : 5079, + 'StencilRefGreaterFrontAMD' : 5080, + 'StencilRefLessFrontAMD' : 5081, + 'StencilRefUnchangedBackAMD' : 5082, + 'StencilRefGreaterBackAMD' : 5083, + 'StencilRefLessBackAMD' : 5084, + 'QuadDerivativesKHR' : 5088, + 'RequireFullQuadsKHR' : 5089, + 'OutputLinesEXT' : 5269, + 'OutputLinesNV' : 5269, + 'OutputPrimitivesEXT' : 5270, + 'OutputPrimitivesNV' : 5270, + 'DerivativeGroupQuadsNV' : 5289, + 'DerivativeGroupLinearNV' : 5290, + 'OutputTrianglesEXT' : 5298, + 'OutputTrianglesNV' : 5298, + 'PixelInterlockOrderedEXT' : 5366, + 'PixelInterlockUnorderedEXT' : 5367, + 'SampleInterlockOrderedEXT' : 5368, + 'SampleInterlockUnorderedEXT' : 5369, + 'ShadingRateInterlockOrderedEXT' : 5370, + 'ShadingRateInterlockUnorderedEXT' : 5371, + 'SharedLocalMemorySizeINTEL' : 5618, + 'RoundingModeRTPINTEL' : 5620, + 'RoundingModeRTNINTEL' : 5621, + 'FloatingPointModeALTINTEL' : 5622, + 'FloatingPointModeIEEEINTEL' : 5623, + 'MaxWorkgroupSizeINTEL' : 5893, + 'MaxWorkDimINTEL' : 5894, + 'NoGlobalOffsetINTEL' : 5895, + 'NumSIMDWorkitemsINTEL' : 5896, + 'SchedulerTargetFmaxMhzINTEL' : 5903, + 'MaximallyReconvergesKHR' : 6023, + 'FPFastMathDefault' : 6028, + 'StreamingInterfaceINTEL' : 6154, + 'RegisterMapInterfaceINTEL' : 6160, + 'NamedBarrierCountINTEL' : 6417, + 'MaximumRegistersINTEL' : 6461, + 'MaximumRegistersIdINTEL' : 6462, + 'NamedMaximumRegistersINTEL' : 6463, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + 'TileImageEXT' : 4172, + 'NodePayloadAMDX' : 5068, + 'NodeOutputPayloadAMDX' : 5076, + 'CallableDataKHR' : 5328, + 'CallableDataNV' : 5328, + 'IncomingCallableDataKHR' : 5329, + 'IncomingCallableDataNV' : 5329, + 'RayPayloadKHR' : 5338, + 'RayPayloadNV' : 5338, + 'HitAttributeKHR' : 5339, + 'HitAttributeNV' : 5339, + 'IncomingRayPayloadKHR' : 5342, + 'IncomingRayPayloadNV' : 5342, + 'ShaderRecordBufferKHR' : 5343, + 'ShaderRecordBufferNV' : 5343, + 'PhysicalStorageBuffer' : 5349, + 'PhysicalStorageBufferEXT' : 5349, + 'HitObjectAttributeNV' : 5385, + 'TaskPayloadWorkgroupEXT' : 5402, + 'CodeSectionINTEL' : 5605, + 'DeviceOnlyINTEL' : 5936, + 'HostOnlyINTEL' : 5937, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + 'TileImageDataEXT' : 4173, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + 'R64ui' : 40, + 'R64i' : 41, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + 'UnsignedIntRaw10EXT' : 19, + 'UnsignedIntRaw12EXT' : 20, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + 'MakeTexelAvailable' : 8, + 'MakeTexelAvailableKHR' : 8, + 'MakeTexelVisible' : 9, + 'MakeTexelVisibleKHR' : 9, + 'NonPrivateTexel' : 10, + 'NonPrivateTexelKHR' : 10, + 'VolatileTexel' : 11, + 'VolatileTexelKHR' : 11, + 'SignExtend' : 12, + 'ZeroExtend' : 13, + 'Nontemporal' : 14, + 'Offsets' : 16, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + 'MakeTexelAvailable' : 0x00000100, + 'MakeTexelAvailableKHR' : 0x00000100, + 'MakeTexelVisible' : 0x00000200, + 'MakeTexelVisibleKHR' : 0x00000200, + 'NonPrivateTexel' : 0x00000400, + 'NonPrivateTexelKHR' : 0x00000400, + 'VolatileTexel' : 0x00000800, + 'VolatileTexelKHR' : 0x00000800, + 'SignExtend' : 0x00001000, + 'ZeroExtend' : 0x00002000, + 'Nontemporal' : 0x00004000, + 'Offsets' : 0x00010000, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + 'AllowContract' : 16, + 'AllowContractFastINTEL' : 16, + 'AllowReassoc' : 17, + 'AllowReassocINTEL' : 17, + 'AllowTransform' : 18, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + 'AllowContract' : 0x00010000, + 'AllowContractFastINTEL' : 0x00010000, + 'AllowReassoc' : 0x00020000, + 'AllowReassocINTEL' : 0x00020000, + 'AllowTransform' : 0x00040000, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + 'LinkOnceODR' : 2, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + 'RuntimeAlignedINTEL' : 5940, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'UniformId' : 27, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'MaxByteOffset' : 45, + 'AlignmentId' : 46, + 'MaxByteOffsetId' : 47, + 'NoSignedWrap' : 4469, + 'NoUnsignedWrap' : 4470, + 'WeightTextureQCOM' : 4487, + 'BlockMatchTextureQCOM' : 4488, + 'BlockMatchSamplerQCOM' : 4499, + 'ExplicitInterpAMD' : 4999, + 'NodeSharesPayloadLimitsWithAMDX' : 5019, + 'NodeMaxPayloadsAMDX' : 5020, + 'TrackFinishWritingAMDX' : 5078, + 'PayloadNodeNameAMDX' : 5091, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + 'PerPrimitiveEXT' : 5271, + 'PerPrimitiveNV' : 5271, + 'PerViewNV' : 5272, + 'PerTaskNV' : 5273, + 'PerVertexKHR' : 5285, + 'PerVertexNV' : 5285, + 'NonUniform' : 5300, + 'NonUniformEXT' : 5300, + 'RestrictPointer' : 5355, + 'RestrictPointerEXT' : 5355, + 'AliasedPointer' : 5356, + 'AliasedPointerEXT' : 5356, + 'HitObjectShaderRecordBufferNV' : 5386, + 'BindlessSamplerNV' : 5398, + 'BindlessImageNV' : 5399, + 'BoundSamplerNV' : 5400, + 'BoundImageNV' : 5401, + 'SIMTCallINTEL' : 5599, + 'ReferencedIndirectlyINTEL' : 5602, + 'ClobberINTEL' : 5607, + 'SideEffectsINTEL' : 5608, + 'VectorComputeVariableINTEL' : 5624, + 'FuncParamIOKindINTEL' : 5625, + 'VectorComputeFunctionINTEL' : 5626, + 'StackCallINTEL' : 5627, + 'GlobalVariableOffsetINTEL' : 5628, + 'CounterBuffer' : 5634, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, + 'UserSemantic' : 5635, + 'UserTypeGOOGLE' : 5636, + 'FunctionRoundingModeINTEL' : 5822, + 'FunctionDenormModeINTEL' : 5823, + 'RegisterINTEL' : 5825, + 'MemoryINTEL' : 5826, + 'NumbanksINTEL' : 5827, + 'BankwidthINTEL' : 5828, + 'MaxPrivateCopiesINTEL' : 5829, + 'SinglepumpINTEL' : 5830, + 'DoublepumpINTEL' : 5831, + 'MaxReplicatesINTEL' : 5832, + 'SimpleDualPortINTEL' : 5833, + 'MergeINTEL' : 5834, + 'BankBitsINTEL' : 5835, + 'ForcePow2DepthINTEL' : 5836, + 'StridesizeINTEL' : 5883, + 'WordsizeINTEL' : 5884, + 'TrueDualPortINTEL' : 5885, + 'BurstCoalesceINTEL' : 5899, + 'CacheSizeINTEL' : 5900, + 'DontStaticallyCoalesceINTEL' : 5901, + 'PrefetchINTEL' : 5902, + 'StallEnableINTEL' : 5905, + 'FuseLoopsInFunctionINTEL' : 5907, + 'MathOpDSPModeINTEL' : 5909, + 'AliasScopeINTEL' : 5914, + 'NoAliasINTEL' : 5915, + 'InitiationIntervalINTEL' : 5917, + 'MaxConcurrencyINTEL' : 5918, + 'PipelineEnableINTEL' : 5919, + 'BufferLocationINTEL' : 5921, + 'IOPipeStorageINTEL' : 5944, + 'FunctionFloatingPointModeINTEL' : 6080, + 'SingleElementVectorINTEL' : 6085, + 'VectorComputeCallableFunctionINTEL' : 6087, + 'MediaBlockIOINTEL' : 6140, + 'StallFreeINTEL' : 6151, + 'FPMaxErrorDecorationINTEL' : 6170, + 'LatencyControlLabelINTEL' : 6172, + 'LatencyControlConstraintINTEL' : 6173, + 'ConduitKernelArgumentINTEL' : 6175, + 'RegisterMapKernelArgumentINTEL' : 6176, + 'MMHostInterfaceAddressWidthINTEL' : 6177, + 'MMHostInterfaceDataWidthINTEL' : 6178, + 'MMHostInterfaceLatencyINTEL' : 6179, + 'MMHostInterfaceReadWriteModeINTEL' : 6180, + 'MMHostInterfaceMaxBurstINTEL' : 6181, + 'MMHostInterfaceWaitRequestINTEL' : 6182, + 'StableKernelArgumentINTEL' : 6183, + 'HostAccessINTEL' : 6188, + 'InitModeINTEL' : 6190, + 'ImplementInRegisterMapINTEL' : 6191, + 'CacheControlLoadINTEL' : 6442, + 'CacheControlStoreINTEL' : 6443, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'CoreIDARM' : 4160, + 'CoreCountARM' : 4161, + 'CoreMaxIDARM' : 4162, + 'WarpIDARM' : 4163, + 'WarpMaxIDARM' : 4164, + 'SubgroupEqMask' : 4416, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMask' : 4417, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMask' : 4418, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMask' : 4419, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMask' : 4420, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'PrimitiveShadingRateKHR' : 4432, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'ShadingRateKHR' : 4444, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'CoalescedInputCountAMDX' : 5021, + 'ShaderIndexAMDX' : 5073, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + 'FullyCoveredEXT' : 5264, + 'TaskCountNV' : 5274, + 'PrimitiveCountNV' : 5275, + 'PrimitiveIndicesNV' : 5276, + 'ClipDistancePerViewNV' : 5277, + 'CullDistancePerViewNV' : 5278, + 'LayerPerViewNV' : 5279, + 'MeshViewCountNV' : 5280, + 'MeshViewIndicesNV' : 5281, + 'BaryCoordKHR' : 5286, + 'BaryCoordNV' : 5286, + 'BaryCoordNoPerspKHR' : 5287, + 'BaryCoordNoPerspNV' : 5287, + 'FragSizeEXT' : 5292, + 'FragmentSizeNV' : 5292, + 'FragInvocationCountEXT' : 5293, + 'InvocationsPerPixelNV' : 5293, + 'PrimitivePointIndicesEXT' : 5294, + 'PrimitiveLineIndicesEXT' : 5295, + 'PrimitiveTriangleIndicesEXT' : 5296, + 'CullPrimitiveEXT' : 5299, + 'LaunchIdKHR' : 5319, + 'LaunchIdNV' : 5319, + 'LaunchSizeKHR' : 5320, + 'LaunchSizeNV' : 5320, + 'WorldRayOriginKHR' : 5321, + 'WorldRayOriginNV' : 5321, + 'WorldRayDirectionKHR' : 5322, + 'WorldRayDirectionNV' : 5322, + 'ObjectRayOriginKHR' : 5323, + 'ObjectRayOriginNV' : 5323, + 'ObjectRayDirectionKHR' : 5324, + 'ObjectRayDirectionNV' : 5324, + 'RayTminKHR' : 5325, + 'RayTminNV' : 5325, + 'RayTmaxKHR' : 5326, + 'RayTmaxNV' : 5326, + 'InstanceCustomIndexKHR' : 5327, + 'InstanceCustomIndexNV' : 5327, + 'ObjectToWorldKHR' : 5330, + 'ObjectToWorldNV' : 5330, + 'WorldToObjectKHR' : 5331, + 'WorldToObjectNV' : 5331, + 'HitTNV' : 5332, + 'HitKindKHR' : 5333, + 'HitKindNV' : 5333, + 'CurrentRayTimeNV' : 5334, + 'HitTriangleVertexPositionsKHR' : 5335, + 'HitMicroTriangleVertexPositionsNV' : 5337, + 'HitMicroTriangleVertexBarycentricsNV' : 5344, + 'IncomingRayFlagsKHR' : 5351, + 'IncomingRayFlagsNV' : 5351, + 'RayGeometryIndexKHR' : 5352, + 'WarpsPerSMNV' : 5374, + 'SMCountNV' : 5375, + 'WarpIDNV' : 5376, + 'SMIDNV' : 5377, + 'HitKindFrontFacingMicroTriangleNV' : 5405, + 'HitKindBackFacingMicroTriangleNV' : 5406, + 'CullMaskKHR' : 6021, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + 'DependencyInfinite' : 2, + 'DependencyLength' : 3, + 'MinIterations' : 4, + 'MaxIterations' : 5, + 'IterationMultiple' : 6, + 'PeelCount' : 7, + 'PartialCount' : 8, + 'InitiationIntervalINTEL' : 16, + 'MaxConcurrencyINTEL' : 17, + 'DependencyArrayINTEL' : 18, + 'PipelineEnableINTEL' : 19, + 'LoopCoalesceINTEL' : 20, + 'MaxInterleavingINTEL' : 21, + 'SpeculatedIterationsINTEL' : 22, + 'NoFusionINTEL' : 23, + 'LoopCountINTEL' : 24, + 'MaxReinvocationDelayINTEL' : 25, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + 'DependencyInfinite' : 0x00000004, + 'DependencyLength' : 0x00000008, + 'MinIterations' : 0x00000010, + 'MaxIterations' : 0x00000020, + 'IterationMultiple' : 0x00000040, + 'PeelCount' : 0x00000080, + 'PartialCount' : 0x00000100, + 'InitiationIntervalINTEL' : 0x00010000, + 'MaxConcurrencyINTEL' : 0x00020000, + 'DependencyArrayINTEL' : 0x00040000, + 'PipelineEnableINTEL' : 0x00080000, + 'LoopCoalesceINTEL' : 0x00100000, + 'MaxInterleavingINTEL' : 0x00200000, + 'SpeculatedIterationsINTEL' : 0x00400000, + 'NoFusionINTEL' : 0x00800000, + 'LoopCountINTEL' : 0x01000000, + 'MaxReinvocationDelayINTEL' : 0x02000000, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + 'OptNoneINTEL' : 16, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + 'OptNoneINTEL' : 0x00010000, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + 'OutputMemory' : 12, + 'OutputMemoryKHR' : 12, + 'MakeAvailable' : 13, + 'MakeAvailableKHR' : 13, + 'MakeVisible' : 14, + 'MakeVisibleKHR' : 14, + 'Volatile' : 15, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + 'OutputMemory' : 0x00001000, + 'OutputMemoryKHR' : 0x00001000, + 'MakeAvailable' : 0x00002000, + 'MakeAvailableKHR' : 0x00002000, + 'MakeVisible' : 0x00004000, + 'MakeVisibleKHR' : 0x00004000, + 'Volatile' : 0x00008000, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + 'MakePointerAvailable' : 3, + 'MakePointerAvailableKHR' : 3, + 'MakePointerVisible' : 4, + 'MakePointerVisibleKHR' : 4, + 'NonPrivatePointer' : 5, + 'NonPrivatePointerKHR' : 5, + 'AliasScopeINTELMask' : 16, + 'NoAliasINTELMask' : 17, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + 'MakePointerAvailable' : 0x00000008, + 'MakePointerAvailableKHR' : 0x00000008, + 'MakePointerVisible' : 0x00000010, + 'MakePointerVisibleKHR' : 0x00000010, + 'NonPrivatePointer' : 0x00000020, + 'NonPrivatePointerKHR' : 0x00000020, + 'AliasScopeINTELMask' : 0x00010000, + 'NoAliasINTELMask' : 0x00020000, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + 'QueueFamily' : 5, + 'QueueFamilyKHR' : 5, + 'ShaderCallKHR' : 6, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + 'ClusteredReduce' : 3, + 'PartitionedReduceNV' : 6, + 'PartitionedInclusiveScanNV' : 7, + 'PartitionedExclusiveScanNV' : 8, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupDispatch' : 58, + 'NamedBarrier' : 59, + 'PipeStorage' : 60, + 'GroupNonUniform' : 61, + 'GroupNonUniformVote' : 62, + 'GroupNonUniformArithmetic' : 63, + 'GroupNonUniformBallot' : 64, + 'GroupNonUniformShuffle' : 65, + 'GroupNonUniformShuffleRelative' : 66, + 'GroupNonUniformClustered' : 67, + 'GroupNonUniformQuad' : 68, + 'ShaderLayer' : 69, + 'ShaderViewportIndex' : 70, + 'UniformDecoration' : 71, + 'CoreBuiltinsARM' : 4165, + 'TileImageColorReadAccessEXT' : 4166, + 'TileImageDepthReadAccessEXT' : 4167, + 'TileImageStencilReadAccessEXT' : 4168, + 'FragmentShadingRateKHR' : 4422, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'WorkgroupMemoryExplicitLayoutKHR' : 4428, + 'WorkgroupMemoryExplicitLayout8BitAccessKHR' : 4429, + 'WorkgroupMemoryExplicitLayout16BitAccessKHR' : 4430, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'StorageBuffer8BitAccess' : 4448, + 'UniformAndStorageBuffer8BitAccess' : 4449, + 'StoragePushConstant8' : 4450, + 'DenormPreserve' : 4464, + 'DenormFlushToZero' : 4465, + 'SignedZeroInfNanPreserve' : 4466, + 'RoundingModeRTE' : 4467, + 'RoundingModeRTZ' : 4468, + 'RayQueryProvisionalKHR' : 4471, + 'RayQueryKHR' : 4472, + 'RayTraversalPrimitiveCullingKHR' : 4478, + 'RayTracingKHR' : 4479, + 'TextureSampleWeightedQCOM' : 4484, + 'TextureBoxFilterQCOM' : 4485, + 'TextureBlockMatchQCOM' : 4486, + 'TextureBlockMatch2QCOM' : 4498, + 'Float16ImageAMD' : 5008, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'Int64ImageEXT' : 5016, + 'ShaderClockKHR' : 5055, + 'ShaderEnqueueAMDX' : 5067, + 'QuadControlKHR' : 5087, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'FragmentFullyCoveredEXT' : 5265, + 'MeshShadingNV' : 5266, + 'ImageFootprintNV' : 5282, + 'MeshShadingEXT' : 5283, + 'FragmentBarycentricKHR' : 5284, + 'FragmentBarycentricNV' : 5284, + 'ComputeDerivativeGroupQuadsNV' : 5288, + 'FragmentDensityEXT' : 5291, + 'ShadingRateNV' : 5291, + 'GroupNonUniformPartitionedNV' : 5297, + 'ShaderNonUniform' : 5301, + 'ShaderNonUniformEXT' : 5301, + 'RuntimeDescriptorArray' : 5302, + 'RuntimeDescriptorArrayEXT' : 5302, + 'InputAttachmentArrayDynamicIndexing' : 5303, + 'InputAttachmentArrayDynamicIndexingEXT' : 5303, + 'UniformTexelBufferArrayDynamicIndexing' : 5304, + 'UniformTexelBufferArrayDynamicIndexingEXT' : 5304, + 'StorageTexelBufferArrayDynamicIndexing' : 5305, + 'StorageTexelBufferArrayDynamicIndexingEXT' : 5305, + 'UniformBufferArrayNonUniformIndexing' : 5306, + 'UniformBufferArrayNonUniformIndexingEXT' : 5306, + 'SampledImageArrayNonUniformIndexing' : 5307, + 'SampledImageArrayNonUniformIndexingEXT' : 5307, + 'StorageBufferArrayNonUniformIndexing' : 5308, + 'StorageBufferArrayNonUniformIndexingEXT' : 5308, + 'StorageImageArrayNonUniformIndexing' : 5309, + 'StorageImageArrayNonUniformIndexingEXT' : 5309, + 'InputAttachmentArrayNonUniformIndexing' : 5310, + 'InputAttachmentArrayNonUniformIndexingEXT' : 5310, + 'UniformTexelBufferArrayNonUniformIndexing' : 5311, + 'UniformTexelBufferArrayNonUniformIndexingEXT' : 5311, + 'StorageTexelBufferArrayNonUniformIndexing' : 5312, + 'StorageTexelBufferArrayNonUniformIndexingEXT' : 5312, + 'RayTracingPositionFetchKHR' : 5336, + 'RayTracingNV' : 5340, + 'RayTracingMotionBlurNV' : 5341, + 'VulkanMemoryModel' : 5345, + 'VulkanMemoryModelKHR' : 5345, + 'VulkanMemoryModelDeviceScope' : 5346, + 'VulkanMemoryModelDeviceScopeKHR' : 5346, + 'PhysicalStorageBufferAddresses' : 5347, + 'PhysicalStorageBufferAddressesEXT' : 5347, + 'ComputeDerivativeGroupLinearNV' : 5350, + 'RayTracingProvisionalKHR' : 5353, + 'CooperativeMatrixNV' : 5357, + 'FragmentShaderSampleInterlockEXT' : 5363, + 'FragmentShaderShadingRateInterlockEXT' : 5372, + 'ShaderSMBuiltinsNV' : 5373, + 'FragmentShaderPixelInterlockEXT' : 5378, + 'DemoteToHelperInvocation' : 5379, + 'DemoteToHelperInvocationEXT' : 5379, + 'DisplacementMicromapNV' : 5380, + 'RayTracingOpacityMicromapEXT' : 5381, + 'ShaderInvocationReorderNV' : 5383, + 'BindlessTextureNV' : 5390, + 'RayQueryPositionFetchKHR' : 5391, + 'AtomicFloat16VectorNV' : 5404, + 'RayTracingDisplacementMicromapNV' : 5409, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + 'SubgroupImageMediaBlockIOINTEL' : 5579, + 'RoundToInfinityINTEL' : 5582, + 'FloatingPointModeINTEL' : 5583, + 'IntegerFunctions2INTEL' : 5584, + 'FunctionPointersINTEL' : 5603, + 'IndirectReferencesINTEL' : 5604, + 'AsmINTEL' : 5606, + 'AtomicFloat32MinMaxEXT' : 5612, + 'AtomicFloat64MinMaxEXT' : 5613, + 'AtomicFloat16MinMaxEXT' : 5616, + 'VectorComputeINTEL' : 5617, + 'VectorAnyINTEL' : 5619, + 'ExpectAssumeKHR' : 5629, + 'SubgroupAvcMotionEstimationINTEL' : 5696, + 'SubgroupAvcMotionEstimationIntraINTEL' : 5697, + 'SubgroupAvcMotionEstimationChromaINTEL' : 5698, + 'VariableLengthArrayINTEL' : 5817, + 'FunctionFloatControlINTEL' : 5821, + 'FPGAMemoryAttributesINTEL' : 5824, + 'FPFastMathModeINTEL' : 5837, + 'ArbitraryPrecisionIntegersINTEL' : 5844, + 'ArbitraryPrecisionFloatingPointINTEL' : 5845, + 'UnstructuredLoopControlsINTEL' : 5886, + 'FPGALoopControlsINTEL' : 5888, + 'KernelAttributesINTEL' : 5892, + 'FPGAKernelAttributesINTEL' : 5897, + 'FPGAMemoryAccessesINTEL' : 5898, + 'FPGAClusterAttributesINTEL' : 5904, + 'LoopFuseINTEL' : 5906, + 'FPGADSPControlINTEL' : 5908, + 'MemoryAccessAliasingINTEL' : 5910, + 'FPGAInvocationPipeliningAttributesINTEL' : 5916, + 'FPGABufferLocationINTEL' : 5920, + 'ArbitraryPrecisionFixedPointINTEL' : 5922, + 'USMStorageClassesINTEL' : 5935, + 'RuntimeAlignedAttributeINTEL' : 5939, + 'IOPipesINTEL' : 5943, + 'BlockingPipesINTEL' : 5945, + 'FPGARegINTEL' : 5948, + 'DotProductInputAll' : 6016, + 'DotProductInputAllKHR' : 6016, + 'DotProductInput4x8Bit' : 6017, + 'DotProductInput4x8BitKHR' : 6017, + 'DotProductInput4x8BitPacked' : 6018, + 'DotProductInput4x8BitPackedKHR' : 6018, + 'DotProduct' : 6019, + 'DotProductKHR' : 6019, + 'RayCullMaskKHR' : 6020, + 'CooperativeMatrixKHR' : 6022, + 'BitInstructions' : 6025, + 'GroupNonUniformRotateKHR' : 6026, + 'FloatControls2' : 6029, + 'AtomicFloat32AddEXT' : 6033, + 'AtomicFloat64AddEXT' : 6034, + 'LongCompositesINTEL' : 6089, + 'OptNoneINTEL' : 6094, + 'AtomicFloat16AddEXT' : 6095, + 'DebugInfoModuleINTEL' : 6114, + 'BFloat16ConversionINTEL' : 6115, + 'SplitBarrierINTEL' : 6141, + 'FPGAClusterAttributesV2INTEL' : 6150, + 'FPGAKernelAttributesv2INTEL' : 6161, + 'FPMaxErrorINTEL' : 6169, + 'FPGALatencyControlINTEL' : 6171, + 'FPGAArgumentInterfacesINTEL' : 6174, + 'GlobalVariableHostAccessINTEL' : 6187, + 'GlobalVariableFPGADecorationsINTEL' : 6189, + 'GroupUniformArithmeticKHR' : 6400, + 'MaskedGatherScatterINTEL' : 6427, + 'CacheControlsINTEL' : 6441, + 'RegisterLimitsINTEL' : 6460, + }, + + 'RayFlagsShift' : { + 'OpaqueKHR' : 0, + 'NoOpaqueKHR' : 1, + 'TerminateOnFirstHitKHR' : 2, + 'SkipClosestHitShaderKHR' : 3, + 'CullBackFacingTrianglesKHR' : 4, + 'CullFrontFacingTrianglesKHR' : 5, + 'CullOpaqueKHR' : 6, + 'CullNoOpaqueKHR' : 7, + 'SkipTrianglesKHR' : 8, + 'SkipAABBsKHR' : 9, + 'ForceOpacityMicromap2StateEXT' : 10, + }, + + 'RayFlagsMask' : { + 'MaskNone' : 0, + 'OpaqueKHR' : 0x00000001, + 'NoOpaqueKHR' : 0x00000002, + 'TerminateOnFirstHitKHR' : 0x00000004, + 'SkipClosestHitShaderKHR' : 0x00000008, + 'CullBackFacingTrianglesKHR' : 0x00000010, + 'CullFrontFacingTrianglesKHR' : 0x00000020, + 'CullOpaqueKHR' : 0x00000040, + 'CullNoOpaqueKHR' : 0x00000080, + 'SkipTrianglesKHR' : 0x00000100, + 'SkipAABBsKHR' : 0x00000200, + 'ForceOpacityMicromap2StateEXT' : 0x00000400, + }, + + 'RayQueryIntersection' : { + 'RayQueryCandidateIntersectionKHR' : 0, + 'RayQueryCommittedIntersectionKHR' : 1, + }, + + 'RayQueryCommittedIntersectionType' : { + 'RayQueryCommittedIntersectionNoneKHR' : 0, + 'RayQueryCommittedIntersectionTriangleKHR' : 1, + 'RayQueryCommittedIntersectionGeneratedKHR' : 2, + }, + + 'RayQueryCandidateIntersectionType' : { + 'RayQueryCandidateIntersectionTriangleKHR' : 0, + 'RayQueryCandidateIntersectionAABBKHR' : 1, + }, + + 'FragmentShadingRateShift' : { + 'Vertical2Pixels' : 0, + 'Vertical4Pixels' : 1, + 'Horizontal2Pixels' : 2, + 'Horizontal4Pixels' : 3, + }, + + 'FragmentShadingRateMask' : { + 'MaskNone' : 0, + 'Vertical2Pixels' : 0x00000001, + 'Vertical4Pixels' : 0x00000002, + 'Horizontal2Pixels' : 0x00000004, + 'Horizontal4Pixels' : 0x00000008, + }, + + 'FPDenormMode' : { + 'Preserve' : 0, + 'FlushToZero' : 1, + }, + + 'FPOperationMode' : { + 'IEEE' : 0, + 'ALT' : 1, + }, + + 'QuantizationModes' : { + 'TRN' : 0, + 'TRN_ZERO' : 1, + 'RND' : 2, + 'RND_ZERO' : 3, + 'RND_INF' : 4, + 'RND_MIN_INF' : 5, + 'RND_CONV' : 6, + 'RND_CONV_ODD' : 7, + }, + + 'OverflowModes' : { + 'WRAP' : 0, + 'SAT' : 1, + 'SAT_ZERO' : 2, + 'SAT_SYM' : 3, + }, + + 'PackedVectorFormat' : { + 'PackedVectorFormat4x8Bit' : 0, + 'PackedVectorFormat4x8BitKHR' : 0, + }, + + 'CooperativeMatrixOperandsShift' : { + 'MatrixASignedComponentsKHR' : 0, + 'MatrixBSignedComponentsKHR' : 1, + 'MatrixCSignedComponentsKHR' : 2, + 'MatrixResultSignedComponentsKHR' : 3, + 'SaturatingAccumulationKHR' : 4, + }, + + 'CooperativeMatrixOperandsMask' : { + 'MaskNone' : 0, + 'MatrixASignedComponentsKHR' : 0x00000001, + 'MatrixBSignedComponentsKHR' : 0x00000002, + 'MatrixCSignedComponentsKHR' : 0x00000004, + 'MatrixResultSignedComponentsKHR' : 0x00000008, + 'SaturatingAccumulationKHR' : 0x00000010, + }, + + 'CooperativeMatrixLayout' : { + 'RowMajorKHR' : 0, + 'ColumnMajorKHR' : 1, + }, + + 'CooperativeMatrixUse' : { + 'MatrixAKHR' : 0, + 'MatrixBKHR' : 1, + 'MatrixAccumulatorKHR' : 2, + }, + + 'InitializationModeQualifier' : { + 'InitOnDeviceReprogramINTEL' : 0, + 'InitOnDeviceResetINTEL' : 1, + }, + + 'HostAccessQualifier' : { + 'NoneINTEL' : 0, + 'ReadINTEL' : 1, + 'WriteINTEL' : 2, + 'ReadWriteINTEL' : 3, + }, + + 'LoadCacheControl' : { + 'UncachedINTEL' : 0, + 'CachedINTEL' : 1, + 'StreamingINTEL' : 2, + 'InvalidateAfterReadINTEL' : 3, + 'ConstCachedINTEL' : 4, + }, + + 'StoreCacheControl' : { + 'UncachedINTEL' : 0, + 'WriteThroughINTEL' : 1, + 'WriteBackINTEL' : 2, + 'StreamingINTEL' : 3, + }, + + 'NamedMaximumNumberOfRegisters' : { + 'AutoINTEL' : 0, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpSizeOf' : 321, + 'OpTypePipeStorage' : 322, + 'OpConstantPipeStorage' : 323, + 'OpCreatePipeFromPipeStorage' : 324, + 'OpGetKernelLocalSizeForSubgroupCount' : 325, + 'OpGetKernelMaxNumSubgroups' : 326, + 'OpTypeNamedBarrier' : 327, + 'OpNamedBarrierInitialize' : 328, + 'OpMemoryNamedBarrier' : 329, + 'OpModuleProcessed' : 330, + 'OpExecutionModeId' : 331, + 'OpDecorateId' : 332, + 'OpGroupNonUniformElect' : 333, + 'OpGroupNonUniformAll' : 334, + 'OpGroupNonUniformAny' : 335, + 'OpGroupNonUniformAllEqual' : 336, + 'OpGroupNonUniformBroadcast' : 337, + 'OpGroupNonUniformBroadcastFirst' : 338, + 'OpGroupNonUniformBallot' : 339, + 'OpGroupNonUniformInverseBallot' : 340, + 'OpGroupNonUniformBallotBitExtract' : 341, + 'OpGroupNonUniformBallotBitCount' : 342, + 'OpGroupNonUniformBallotFindLSB' : 343, + 'OpGroupNonUniformBallotFindMSB' : 344, + 'OpGroupNonUniformShuffle' : 345, + 'OpGroupNonUniformShuffleXor' : 346, + 'OpGroupNonUniformShuffleUp' : 347, + 'OpGroupNonUniformShuffleDown' : 348, + 'OpGroupNonUniformIAdd' : 349, + 'OpGroupNonUniformFAdd' : 350, + 'OpGroupNonUniformIMul' : 351, + 'OpGroupNonUniformFMul' : 352, + 'OpGroupNonUniformSMin' : 353, + 'OpGroupNonUniformUMin' : 354, + 'OpGroupNonUniformFMin' : 355, + 'OpGroupNonUniformSMax' : 356, + 'OpGroupNonUniformUMax' : 357, + 'OpGroupNonUniformFMax' : 358, + 'OpGroupNonUniformBitwiseAnd' : 359, + 'OpGroupNonUniformBitwiseOr' : 360, + 'OpGroupNonUniformBitwiseXor' : 361, + 'OpGroupNonUniformLogicalAnd' : 362, + 'OpGroupNonUniformLogicalOr' : 363, + 'OpGroupNonUniformLogicalXor' : 364, + 'OpGroupNonUniformQuadBroadcast' : 365, + 'OpGroupNonUniformQuadSwap' : 366, + 'OpCopyLogical' : 400, + 'OpPtrEqual' : 401, + 'OpPtrNotEqual' : 402, + 'OpPtrDiff' : 403, + 'OpColorAttachmentReadEXT' : 4160, + 'OpDepthAttachmentReadEXT' : 4161, + 'OpStencilAttachmentReadEXT' : 4162, + 'OpTerminateInvocation' : 4416, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpGroupNonUniformRotateKHR' : 4431, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpTraceRayKHR' : 4445, + 'OpExecuteCallableKHR' : 4446, + 'OpConvertUToAccelerationStructureKHR' : 4447, + 'OpIgnoreIntersectionKHR' : 4448, + 'OpTerminateRayKHR' : 4449, + 'OpSDot' : 4450, + 'OpSDotKHR' : 4450, + 'OpUDot' : 4451, + 'OpUDotKHR' : 4451, + 'OpSUDot' : 4452, + 'OpSUDotKHR' : 4452, + 'OpSDotAccSat' : 4453, + 'OpSDotAccSatKHR' : 4453, + 'OpUDotAccSat' : 4454, + 'OpUDotAccSatKHR' : 4454, + 'OpSUDotAccSat' : 4455, + 'OpSUDotAccSatKHR' : 4455, + 'OpTypeCooperativeMatrixKHR' : 4456, + 'OpCooperativeMatrixLoadKHR' : 4457, + 'OpCooperativeMatrixStoreKHR' : 4458, + 'OpCooperativeMatrixMulAddKHR' : 4459, + 'OpCooperativeMatrixLengthKHR' : 4460, + 'OpTypeRayQueryKHR' : 4472, + 'OpRayQueryInitializeKHR' : 4473, + 'OpRayQueryTerminateKHR' : 4474, + 'OpRayQueryGenerateIntersectionKHR' : 4475, + 'OpRayQueryConfirmIntersectionKHR' : 4476, + 'OpRayQueryProceedKHR' : 4477, + 'OpRayQueryGetIntersectionTypeKHR' : 4479, + 'OpImageSampleWeightedQCOM' : 4480, + 'OpImageBoxFilterQCOM' : 4481, + 'OpImageBlockMatchSSDQCOM' : 4482, + 'OpImageBlockMatchSADQCOM' : 4483, + 'OpImageBlockMatchWindowSSDQCOM' : 4500, + 'OpImageBlockMatchWindowSADQCOM' : 4501, + 'OpImageBlockMatchGatherSSDQCOM' : 4502, + 'OpImageBlockMatchGatherSADQCOM' : 4503, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpReadClockKHR' : 5056, + 'OpFinalizeNodePayloadsAMDX' : 5075, + 'OpFinishWritingNodePayloadAMDX' : 5078, + 'OpInitializeNodePayloadsAMDX' : 5090, + 'OpGroupNonUniformQuadAllKHR' : 5110, + 'OpGroupNonUniformQuadAnyKHR' : 5111, + 'OpHitObjectRecordHitMotionNV' : 5249, + 'OpHitObjectRecordHitWithIndexMotionNV' : 5250, + 'OpHitObjectRecordMissMotionNV' : 5251, + 'OpHitObjectGetWorldToObjectNV' : 5252, + 'OpHitObjectGetObjectToWorldNV' : 5253, + 'OpHitObjectGetObjectRayDirectionNV' : 5254, + 'OpHitObjectGetObjectRayOriginNV' : 5255, + 'OpHitObjectTraceRayMotionNV' : 5256, + 'OpHitObjectGetShaderRecordBufferHandleNV' : 5257, + 'OpHitObjectGetShaderBindingTableRecordIndexNV' : 5258, + 'OpHitObjectRecordEmptyNV' : 5259, + 'OpHitObjectTraceRayNV' : 5260, + 'OpHitObjectRecordHitNV' : 5261, + 'OpHitObjectRecordHitWithIndexNV' : 5262, + 'OpHitObjectRecordMissNV' : 5263, + 'OpHitObjectExecuteShaderNV' : 5264, + 'OpHitObjectGetCurrentTimeNV' : 5265, + 'OpHitObjectGetAttributesNV' : 5266, + 'OpHitObjectGetHitKindNV' : 5267, + 'OpHitObjectGetPrimitiveIndexNV' : 5268, + 'OpHitObjectGetGeometryIndexNV' : 5269, + 'OpHitObjectGetInstanceIdNV' : 5270, + 'OpHitObjectGetInstanceCustomIndexNV' : 5271, + 'OpHitObjectGetWorldRayDirectionNV' : 5272, + 'OpHitObjectGetWorldRayOriginNV' : 5273, + 'OpHitObjectGetRayTMaxNV' : 5274, + 'OpHitObjectGetRayTMinNV' : 5275, + 'OpHitObjectIsEmptyNV' : 5276, + 'OpHitObjectIsHitNV' : 5277, + 'OpHitObjectIsMissNV' : 5278, + 'OpReorderThreadWithHitObjectNV' : 5279, + 'OpReorderThreadWithHintNV' : 5280, + 'OpTypeHitObjectNV' : 5281, + 'OpImageSampleFootprintNV' : 5283, + 'OpEmitMeshTasksEXT' : 5294, + 'OpSetMeshOutputsEXT' : 5295, + 'OpGroupNonUniformPartitionNV' : 5296, + 'OpWritePackedPrimitiveIndices4x8NV' : 5299, + 'OpFetchMicroTriangleVertexPositionNV' : 5300, + 'OpFetchMicroTriangleVertexBarycentricNV' : 5301, + 'OpReportIntersectionKHR' : 5334, + 'OpReportIntersectionNV' : 5334, + 'OpIgnoreIntersectionNV' : 5335, + 'OpTerminateRayNV' : 5336, + 'OpTraceNV' : 5337, + 'OpTraceMotionNV' : 5338, + 'OpTraceRayMotionNV' : 5339, + 'OpRayQueryGetIntersectionTriangleVertexPositionsKHR' : 5340, + 'OpTypeAccelerationStructureKHR' : 5341, + 'OpTypeAccelerationStructureNV' : 5341, + 'OpExecuteCallableNV' : 5344, + 'OpTypeCooperativeMatrixNV' : 5358, + 'OpCooperativeMatrixLoadNV' : 5359, + 'OpCooperativeMatrixStoreNV' : 5360, + 'OpCooperativeMatrixMulAddNV' : 5361, + 'OpCooperativeMatrixLengthNV' : 5362, + 'OpBeginInvocationInterlockEXT' : 5364, + 'OpEndInvocationInterlockEXT' : 5365, + 'OpDemoteToHelperInvocation' : 5380, + 'OpDemoteToHelperInvocationEXT' : 5380, + 'OpIsHelperInvocationEXT' : 5381, + 'OpConvertUToImageNV' : 5391, + 'OpConvertUToSamplerNV' : 5392, + 'OpConvertImageToUNV' : 5393, + 'OpConvertSamplerToUNV' : 5394, + 'OpConvertUToSampledImageNV' : 5395, + 'OpConvertSampledImageToUNV' : 5396, + 'OpSamplerImageAddressingModeNV' : 5397, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpSubgroupImageMediaBlockReadINTEL' : 5580, + 'OpSubgroupImageMediaBlockWriteINTEL' : 5581, + 'OpUCountLeadingZerosINTEL' : 5585, + 'OpUCountTrailingZerosINTEL' : 5586, + 'OpAbsISubINTEL' : 5587, + 'OpAbsUSubINTEL' : 5588, + 'OpIAddSatINTEL' : 5589, + 'OpUAddSatINTEL' : 5590, + 'OpIAverageINTEL' : 5591, + 'OpUAverageINTEL' : 5592, + 'OpIAverageRoundedINTEL' : 5593, + 'OpUAverageRoundedINTEL' : 5594, + 'OpISubSatINTEL' : 5595, + 'OpUSubSatINTEL' : 5596, + 'OpIMul32x16INTEL' : 5597, + 'OpUMul32x16INTEL' : 5598, + 'OpConstantFunctionPointerINTEL' : 5600, + 'OpFunctionPointerCallINTEL' : 5601, + 'OpAsmTargetINTEL' : 5609, + 'OpAsmINTEL' : 5610, + 'OpAsmCallINTEL' : 5611, + 'OpAtomicFMinEXT' : 5614, + 'OpAtomicFMaxEXT' : 5615, + 'OpAssumeTrueKHR' : 5630, + 'OpExpectKHR' : 5631, + 'OpDecorateString' : 5632, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateString' : 5633, + 'OpMemberDecorateStringGOOGLE' : 5633, + 'OpVmeImageINTEL' : 5699, + 'OpTypeVmeImageINTEL' : 5700, + 'OpTypeAvcImePayloadINTEL' : 5701, + 'OpTypeAvcRefPayloadINTEL' : 5702, + 'OpTypeAvcSicPayloadINTEL' : 5703, + 'OpTypeAvcMcePayloadINTEL' : 5704, + 'OpTypeAvcMceResultINTEL' : 5705, + 'OpTypeAvcImeResultINTEL' : 5706, + 'OpTypeAvcImeResultSingleReferenceStreamoutINTEL' : 5707, + 'OpTypeAvcImeResultDualReferenceStreamoutINTEL' : 5708, + 'OpTypeAvcImeSingleReferenceStreaminINTEL' : 5709, + 'OpTypeAvcImeDualReferenceStreaminINTEL' : 5710, + 'OpTypeAvcRefResultINTEL' : 5711, + 'OpTypeAvcSicResultINTEL' : 5712, + 'OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL' : 5713, + 'OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL' : 5714, + 'OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL' : 5715, + 'OpSubgroupAvcMceSetInterShapePenaltyINTEL' : 5716, + 'OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL' : 5717, + 'OpSubgroupAvcMceSetInterDirectionPenaltyINTEL' : 5718, + 'OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL' : 5719, + 'OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL' : 5720, + 'OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL' : 5721, + 'OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL' : 5722, + 'OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL' : 5723, + 'OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL' : 5724, + 'OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL' : 5725, + 'OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL' : 5726, + 'OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL' : 5727, + 'OpSubgroupAvcMceSetAcOnlyHaarINTEL' : 5728, + 'OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL' : 5729, + 'OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL' : 5730, + 'OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL' : 5731, + 'OpSubgroupAvcMceConvertToImePayloadINTEL' : 5732, + 'OpSubgroupAvcMceConvertToImeResultINTEL' : 5733, + 'OpSubgroupAvcMceConvertToRefPayloadINTEL' : 5734, + 'OpSubgroupAvcMceConvertToRefResultINTEL' : 5735, + 'OpSubgroupAvcMceConvertToSicPayloadINTEL' : 5736, + 'OpSubgroupAvcMceConvertToSicResultINTEL' : 5737, + 'OpSubgroupAvcMceGetMotionVectorsINTEL' : 5738, + 'OpSubgroupAvcMceGetInterDistortionsINTEL' : 5739, + 'OpSubgroupAvcMceGetBestInterDistortionsINTEL' : 5740, + 'OpSubgroupAvcMceGetInterMajorShapeINTEL' : 5741, + 'OpSubgroupAvcMceGetInterMinorShapeINTEL' : 5742, + 'OpSubgroupAvcMceGetInterDirectionsINTEL' : 5743, + 'OpSubgroupAvcMceGetInterMotionVectorCountINTEL' : 5744, + 'OpSubgroupAvcMceGetInterReferenceIdsINTEL' : 5745, + 'OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL' : 5746, + 'OpSubgroupAvcImeInitializeINTEL' : 5747, + 'OpSubgroupAvcImeSetSingleReferenceINTEL' : 5748, + 'OpSubgroupAvcImeSetDualReferenceINTEL' : 5749, + 'OpSubgroupAvcImeRefWindowSizeINTEL' : 5750, + 'OpSubgroupAvcImeAdjustRefOffsetINTEL' : 5751, + 'OpSubgroupAvcImeConvertToMcePayloadINTEL' : 5752, + 'OpSubgroupAvcImeSetMaxMotionVectorCountINTEL' : 5753, + 'OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL' : 5754, + 'OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL' : 5755, + 'OpSubgroupAvcImeSetWeightedSadINTEL' : 5756, + 'OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL' : 5757, + 'OpSubgroupAvcImeEvaluateWithDualReferenceINTEL' : 5758, + 'OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL' : 5759, + 'OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL' : 5760, + 'OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL' : 5761, + 'OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL' : 5762, + 'OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL' : 5763, + 'OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL' : 5764, + 'OpSubgroupAvcImeConvertToMceResultINTEL' : 5765, + 'OpSubgroupAvcImeGetSingleReferenceStreaminINTEL' : 5766, + 'OpSubgroupAvcImeGetDualReferenceStreaminINTEL' : 5767, + 'OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL' : 5768, + 'OpSubgroupAvcImeStripDualReferenceStreamoutINTEL' : 5769, + 'OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL' : 5770, + 'OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL' : 5771, + 'OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL' : 5772, + 'OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL' : 5773, + 'OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL' : 5774, + 'OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL' : 5775, + 'OpSubgroupAvcImeGetBorderReachedINTEL' : 5776, + 'OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL' : 5777, + 'OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL' : 5778, + 'OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL' : 5779, + 'OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL' : 5780, + 'OpSubgroupAvcFmeInitializeINTEL' : 5781, + 'OpSubgroupAvcBmeInitializeINTEL' : 5782, + 'OpSubgroupAvcRefConvertToMcePayloadINTEL' : 5783, + 'OpSubgroupAvcRefSetBidirectionalMixDisableINTEL' : 5784, + 'OpSubgroupAvcRefSetBilinearFilterEnableINTEL' : 5785, + 'OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL' : 5786, + 'OpSubgroupAvcRefEvaluateWithDualReferenceINTEL' : 5787, + 'OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL' : 5788, + 'OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL' : 5789, + 'OpSubgroupAvcRefConvertToMceResultINTEL' : 5790, + 'OpSubgroupAvcSicInitializeINTEL' : 5791, + 'OpSubgroupAvcSicConfigureSkcINTEL' : 5792, + 'OpSubgroupAvcSicConfigureIpeLumaINTEL' : 5793, + 'OpSubgroupAvcSicConfigureIpeLumaChromaINTEL' : 5794, + 'OpSubgroupAvcSicGetMotionVectorMaskINTEL' : 5795, + 'OpSubgroupAvcSicConvertToMcePayloadINTEL' : 5796, + 'OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL' : 5797, + 'OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL' : 5798, + 'OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL' : 5799, + 'OpSubgroupAvcSicSetBilinearFilterEnableINTEL' : 5800, + 'OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL' : 5801, + 'OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL' : 5802, + 'OpSubgroupAvcSicEvaluateIpeINTEL' : 5803, + 'OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL' : 5804, + 'OpSubgroupAvcSicEvaluateWithDualReferenceINTEL' : 5805, + 'OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL' : 5806, + 'OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL' : 5807, + 'OpSubgroupAvcSicConvertToMceResultINTEL' : 5808, + 'OpSubgroupAvcSicGetIpeLumaShapeINTEL' : 5809, + 'OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL' : 5810, + 'OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL' : 5811, + 'OpSubgroupAvcSicGetPackedIpeLumaModesINTEL' : 5812, + 'OpSubgroupAvcSicGetIpeChromaModeINTEL' : 5813, + 'OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL' : 5814, + 'OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL' : 5815, + 'OpSubgroupAvcSicGetInterRawSadsINTEL' : 5816, + 'OpVariableLengthArrayINTEL' : 5818, + 'OpSaveMemoryINTEL' : 5819, + 'OpRestoreMemoryINTEL' : 5820, + 'OpArbitraryFloatSinCosPiINTEL' : 5840, + 'OpArbitraryFloatCastINTEL' : 5841, + 'OpArbitraryFloatCastFromIntINTEL' : 5842, + 'OpArbitraryFloatCastToIntINTEL' : 5843, + 'OpArbitraryFloatAddINTEL' : 5846, + 'OpArbitraryFloatSubINTEL' : 5847, + 'OpArbitraryFloatMulINTEL' : 5848, + 'OpArbitraryFloatDivINTEL' : 5849, + 'OpArbitraryFloatGTINTEL' : 5850, + 'OpArbitraryFloatGEINTEL' : 5851, + 'OpArbitraryFloatLTINTEL' : 5852, + 'OpArbitraryFloatLEINTEL' : 5853, + 'OpArbitraryFloatEQINTEL' : 5854, + 'OpArbitraryFloatRecipINTEL' : 5855, + 'OpArbitraryFloatRSqrtINTEL' : 5856, + 'OpArbitraryFloatCbrtINTEL' : 5857, + 'OpArbitraryFloatHypotINTEL' : 5858, + 'OpArbitraryFloatSqrtINTEL' : 5859, + 'OpArbitraryFloatLogINTEL' : 5860, + 'OpArbitraryFloatLog2INTEL' : 5861, + 'OpArbitraryFloatLog10INTEL' : 5862, + 'OpArbitraryFloatLog1pINTEL' : 5863, + 'OpArbitraryFloatExpINTEL' : 5864, + 'OpArbitraryFloatExp2INTEL' : 5865, + 'OpArbitraryFloatExp10INTEL' : 5866, + 'OpArbitraryFloatExpm1INTEL' : 5867, + 'OpArbitraryFloatSinINTEL' : 5868, + 'OpArbitraryFloatCosINTEL' : 5869, + 'OpArbitraryFloatSinCosINTEL' : 5870, + 'OpArbitraryFloatSinPiINTEL' : 5871, + 'OpArbitraryFloatCosPiINTEL' : 5872, + 'OpArbitraryFloatASinINTEL' : 5873, + 'OpArbitraryFloatASinPiINTEL' : 5874, + 'OpArbitraryFloatACosINTEL' : 5875, + 'OpArbitraryFloatACosPiINTEL' : 5876, + 'OpArbitraryFloatATanINTEL' : 5877, + 'OpArbitraryFloatATanPiINTEL' : 5878, + 'OpArbitraryFloatATan2INTEL' : 5879, + 'OpArbitraryFloatPowINTEL' : 5880, + 'OpArbitraryFloatPowRINTEL' : 5881, + 'OpArbitraryFloatPowNINTEL' : 5882, + 'OpLoopControlINTEL' : 5887, + 'OpAliasDomainDeclINTEL' : 5911, + 'OpAliasScopeDeclINTEL' : 5912, + 'OpAliasScopeListDeclINTEL' : 5913, + 'OpFixedSqrtINTEL' : 5923, + 'OpFixedRecipINTEL' : 5924, + 'OpFixedRsqrtINTEL' : 5925, + 'OpFixedSinINTEL' : 5926, + 'OpFixedCosINTEL' : 5927, + 'OpFixedSinCosINTEL' : 5928, + 'OpFixedSinPiINTEL' : 5929, + 'OpFixedCosPiINTEL' : 5930, + 'OpFixedSinCosPiINTEL' : 5931, + 'OpFixedLogINTEL' : 5932, + 'OpFixedExpINTEL' : 5933, + 'OpPtrCastToCrossWorkgroupINTEL' : 5934, + 'OpCrossWorkgroupCastToPtrINTEL' : 5938, + 'OpReadPipeBlockingINTEL' : 5946, + 'OpWritePipeBlockingINTEL' : 5947, + 'OpFPGARegINTEL' : 5949, + 'OpRayQueryGetRayTMinKHR' : 6016, + 'OpRayQueryGetRayFlagsKHR' : 6017, + 'OpRayQueryGetIntersectionTKHR' : 6018, + 'OpRayQueryGetIntersectionInstanceCustomIndexKHR' : 6019, + 'OpRayQueryGetIntersectionInstanceIdKHR' : 6020, + 'OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR' : 6021, + 'OpRayQueryGetIntersectionGeometryIndexKHR' : 6022, + 'OpRayQueryGetIntersectionPrimitiveIndexKHR' : 6023, + 'OpRayQueryGetIntersectionBarycentricsKHR' : 6024, + 'OpRayQueryGetIntersectionFrontFaceKHR' : 6025, + 'OpRayQueryGetIntersectionCandidateAABBOpaqueKHR' : 6026, + 'OpRayQueryGetIntersectionObjectRayDirectionKHR' : 6027, + 'OpRayQueryGetIntersectionObjectRayOriginKHR' : 6028, + 'OpRayQueryGetWorldRayDirectionKHR' : 6029, + 'OpRayQueryGetWorldRayOriginKHR' : 6030, + 'OpRayQueryGetIntersectionObjectToWorldKHR' : 6031, + 'OpRayQueryGetIntersectionWorldToObjectKHR' : 6032, + 'OpAtomicFAddEXT' : 6035, + 'OpTypeBufferSurfaceINTEL' : 6086, + 'OpTypeStructContinuedINTEL' : 6090, + 'OpConstantCompositeContinuedINTEL' : 6091, + 'OpSpecConstantCompositeContinuedINTEL' : 6092, + 'OpCompositeConstructContinuedINTEL' : 6096, + 'OpConvertFToBF16INTEL' : 6116, + 'OpConvertBF16ToFINTEL' : 6117, + 'OpControlBarrierArriveINTEL' : 6142, + 'OpControlBarrierWaitINTEL' : 6143, + 'OpGroupIMulKHR' : 6401, + 'OpGroupFMulKHR' : 6402, + 'OpGroupBitwiseAndKHR' : 6403, + 'OpGroupBitwiseOrKHR' : 6404, + 'OpGroupBitwiseXorKHR' : 6405, + 'OpGroupLogicalAndKHR' : 6406, + 'OpGroupLogicalOrKHR' : 6407, + 'OpGroupLogicalXorKHR' : 6408, + 'OpMaskedGatherINTEL' : 6428, + 'OpMaskedScatterINTEL' : 6429, + }, + +} + diff --git a/thirdparty/glslang/SPIRV/SpvTools.cpp b/thirdparty/glslang/SPIRV/SpvTools.cpp index ff04f4f96771..e56f532ce34a 100644 --- a/thirdparty/glslang/SPIRV/SpvTools.cpp +++ b/thirdparty/glslang/SPIRV/SpvTools.cpp @@ -219,6 +219,8 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector spvtools::OptimizerOptions spvOptOptions; optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); + spvOptOptions.set_preserve_bindings(true); + spvOptOptions.set_preserve_spec_constants(true); spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); } diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/GLSL.std.450.h b/thirdparty/glslang/glslang/Include/spirv/1.0/GLSL.std.450.h new file mode 100644 index 000000000000..54cc00e9a888 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/GLSL.std.450.h @@ -0,0 +1,131 @@ +/* +** Copyright (c) 2014-2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLstd450_H +#define GLSLstd450_H + +static const int GLSLstd450Version = 100; +static const int GLSLstd450Revision = 3; + +enum GLSLstd450 { + GLSLstd450Bad = 0, // Don't use + + GLSLstd450Round = 1, + GLSLstd450RoundEven = 2, + GLSLstd450Trunc = 3, + GLSLstd450FAbs = 4, + GLSLstd450SAbs = 5, + GLSLstd450FSign = 6, + GLSLstd450SSign = 7, + GLSLstd450Floor = 8, + GLSLstd450Ceil = 9, + GLSLstd450Fract = 10, + + GLSLstd450Radians = 11, + GLSLstd450Degrees = 12, + GLSLstd450Sin = 13, + GLSLstd450Cos = 14, + GLSLstd450Tan = 15, + GLSLstd450Asin = 16, + GLSLstd450Acos = 17, + GLSLstd450Atan = 18, + GLSLstd450Sinh = 19, + GLSLstd450Cosh = 20, + GLSLstd450Tanh = 21, + GLSLstd450Asinh = 22, + GLSLstd450Acosh = 23, + GLSLstd450Atanh = 24, + GLSLstd450Atan2 = 25, + + GLSLstd450Pow = 26, + GLSLstd450Exp = 27, + GLSLstd450Log = 28, + GLSLstd450Exp2 = 29, + GLSLstd450Log2 = 30, + GLSLstd450Sqrt = 31, + GLSLstd450InverseSqrt = 32, + + GLSLstd450Determinant = 33, + GLSLstd450MatrixInverse = 34, + + GLSLstd450Modf = 35, // second operand needs an OpVariable to write to + GLSLstd450ModfStruct = 36, // no OpVariable operand + GLSLstd450FMin = 37, + GLSLstd450UMin = 38, + GLSLstd450SMin = 39, + GLSLstd450FMax = 40, + GLSLstd450UMax = 41, + GLSLstd450SMax = 42, + GLSLstd450FClamp = 43, + GLSLstd450UClamp = 44, + GLSLstd450SClamp = 45, + GLSLstd450FMix = 46, + GLSLstd450IMix = 47, // Reserved + GLSLstd450Step = 48, + GLSLstd450SmoothStep = 49, + + GLSLstd450Fma = 50, + GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to + GLSLstd450FrexpStruct = 52, // no OpVariable operand + GLSLstd450Ldexp = 53, + + GLSLstd450PackSnorm4x8 = 54, + GLSLstd450PackUnorm4x8 = 55, + GLSLstd450PackSnorm2x16 = 56, + GLSLstd450PackUnorm2x16 = 57, + GLSLstd450PackHalf2x16 = 58, + GLSLstd450PackDouble2x32 = 59, + GLSLstd450UnpackSnorm2x16 = 60, + GLSLstd450UnpackUnorm2x16 = 61, + GLSLstd450UnpackHalf2x16 = 62, + GLSLstd450UnpackSnorm4x8 = 63, + GLSLstd450UnpackUnorm4x8 = 64, + GLSLstd450UnpackDouble2x32 = 65, + + GLSLstd450Length = 66, + GLSLstd450Distance = 67, + GLSLstd450Cross = 68, + GLSLstd450Normalize = 69, + GLSLstd450FaceForward = 70, + GLSLstd450Reflect = 71, + GLSLstd450Refract = 72, + + GLSLstd450FindILsb = 73, + GLSLstd450FindSMsb = 74, + GLSLstd450FindUMsb = 75, + + GLSLstd450InterpolateAtCentroid = 76, + GLSLstd450InterpolateAtSample = 77, + GLSLstd450InterpolateAtOffset = 78, + + GLSLstd450NMin = 79, + GLSLstd450NMax = 80, + GLSLstd450NClamp = 81, + + GLSLstd450Count +}; + +#endif // #ifndef GLSLstd450_H diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/OpenCL.std.h b/thirdparty/glslang/glslang/Include/spirv/1.0/OpenCL.std.h new file mode 100644 index 000000000000..19a6688490c7 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/OpenCL.std.h @@ -0,0 +1,210 @@ +/* +** Copyright (c) 2015-2017 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +namespace OpenCLLIB { + +enum Entrypoints { + + // Section 2.1: Math extended instructions + Acos = 0, + Acosh = 1, + Acospi = 2, + Asin = 3, + Asinh = 4, + Asinpi = 5, + Atan = 6, + Atan2 = 7, + Atanh = 8, + Atanpi = 9, + Atan2pi = 10, + Cbrt = 11, + Ceil = 12, + Copysign = 13, + Cos = 14, + Cosh = 15, + Cospi = 16, + Erfc = 17, + Erf = 18, + Exp = 19, + Exp2 = 20, + Exp10 = 21, + Expm1 = 22, + Fabs = 23, + Fdim = 24, + Floor = 25, + Fma = 26, + Fmax = 27, + Fmin = 28, + Fmod = 29, + Fract = 30, + Frexp = 31, + Hypot = 32, + Ilogb = 33, + Ldexp = 34, + Lgamma = 35, + Lgamma_r = 36, + Log = 37, + Log2 = 38, + Log10 = 39, + Log1p = 40, + Logb = 41, + Mad = 42, + Maxmag = 43, + Minmag = 44, + Modf = 45, + Nan = 46, + Nextafter = 47, + Pow = 48, + Pown = 49, + Powr = 50, + Remainder = 51, + Remquo = 52, + Rint = 53, + Rootn = 54, + Round = 55, + Rsqrt = 56, + Sin = 57, + Sincos = 58, + Sinh = 59, + Sinpi = 60, + Sqrt = 61, + Tan = 62, + Tanh = 63, + Tanpi = 64, + Tgamma = 65, + Trunc = 66, + Half_cos = 67, + Half_divide = 68, + Half_exp = 69, + Half_exp2 = 70, + Half_exp10 = 71, + Half_log = 72, + Half_log2 = 73, + Half_log10 = 74, + Half_powr = 75, + Half_recip = 76, + Half_rsqrt = 77, + Half_sin = 78, + Half_sqrt = 79, + Half_tan = 80, + Native_cos = 81, + Native_divide = 82, + Native_exp = 83, + Native_exp2 = 84, + Native_exp10 = 85, + Native_log = 86, + Native_log2 = 87, + Native_log10 = 88, + Native_powr = 89, + Native_recip = 90, + Native_rsqrt = 91, + Native_sin = 92, + Native_sqrt = 93, + Native_tan = 94, + + // Section 2.2: Integer instructions + SAbs = 141, + SAbs_diff = 142, + SAdd_sat = 143, + UAdd_sat = 144, + SHadd = 145, + UHadd = 146, + SRhadd = 147, + URhadd = 148, + SClamp = 149, + UClamp = 150, + Clz = 151, + Ctz = 152, + SMad_hi = 153, + UMad_sat = 154, + SMad_sat = 155, + SMax = 156, + UMax = 157, + SMin = 158, + UMin = 159, + SMul_hi = 160, + Rotate = 161, + SSub_sat = 162, + USub_sat = 163, + U_Upsample = 164, + S_Upsample = 165, + Popcount = 166, + SMad24 = 167, + UMad24 = 168, + SMul24 = 169, + UMul24 = 170, + UAbs = 201, + UAbs_diff = 202, + UMul_hi = 203, + UMad_hi = 204, + + // Section 2.3: Common instructions + FClamp = 95, + Degrees = 96, + FMax_common = 97, + FMin_common = 98, + Mix = 99, + Radians = 100, + Step = 101, + Smoothstep = 102, + Sign = 103, + + // Section 2.4: Geometric instructions + Cross = 104, + Distance = 105, + Length = 106, + Normalize = 107, + Fast_distance = 108, + Fast_length = 109, + Fast_normalize = 110, + + // Section 2.5: Relational instructions + Bitselect = 186, + Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + Vloadn = 171, + Vstoren = 172, + Vload_half = 173, + Vload_halfn = 174, + Vstore_half = 175, + Vstore_half_r = 176, + Vstore_halfn = 177, + Vstore_halfn_r = 178, + Vloada_halfn = 179, + Vstorea_halfn = 180, + Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + Shuffle = 182, + Shuffle2 = 183, + + // Section 2.8: Misc instructions + Printf = 184, + Prefetch = 185, +}; + +} // end namespace OpenCLLIB diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/extinst.glsl.std.450.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.0/extinst.glsl.std.450.grammar.json new file mode 100644 index 000000000000..3d9f39e76c9c --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/extinst.glsl.std.450.grammar.json @@ -0,0 +1,642 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "Round", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "RoundEven", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Trunc", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FAbs", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SAbs", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FSign", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SSign", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Floor", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ceil", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fract", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Radians", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "Degrees", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "Sin", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tan", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asin", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acos", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'y_over_x'" } + ] + }, + { + "opname" : "Sinh", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cosh", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tanh", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asinh", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acosh", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atanh", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan2", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Pow", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Exp", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Exp2", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log2", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Sqrt", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "InverseSqrt", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Determinant", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "MatrixInverse", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Modf", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "ModfStruct", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FMin", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMin", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMin", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FMax", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMax", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMax", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FClamp", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "UClamp", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "SClamp", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "FMix", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "IMix", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "Step", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SmoothStep", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fma", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "Frexp", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "FrexpStruct", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ldexp", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "PackSnorm4x8", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm4x8", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackSnorm2x16", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm2x16", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackHalf2x16", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackDouble2x32", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "UnpackSnorm2x16", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm2x16", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackHalf2x16", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "UnpackSnorm4x8", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm4x8", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackDouble2x32", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "Length", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Distance", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "Cross", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Normalize", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FaceForward", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'Nref'" } + ] + }, + { + "opname" : "Reflect", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" } + ] + }, + { + "opname" : "Refract", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'eta'" } + ] + }, + { + "opname" : "FindILsb", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindSMsb", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindUMsb", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "InterpolateAtCentroid", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtSample", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'sample'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtOffset", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "NMin", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NMax", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NClamp", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/extinst.opencl.std.100.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.0/extinst.opencl.std.100.grammar.json new file mode 100644 index 000000000000..4fe45060bb98 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/extinst.opencl.std.100.grammar.json @@ -0,0 +1,1279 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "acos", + "opcode" : 0, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acosh", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acospi", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asin", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinh", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinpi", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanh", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanpi", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2pi", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cbrt", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ceil", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "copysign", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cosh", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cospi", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erfc", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erf", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp2", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp10", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "expm1", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fabs", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fdim", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "floor", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fma", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fmax", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmod", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fract", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'ptr'" } + ] + }, + { + "opname" : "frexp", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "hypot", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "ilogb", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ldexp", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'k'" } + ] + }, + { + "opname" : "lgamma", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "lgamma_r", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'signp'" } + ] + }, + { + "opname" : "log", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log2", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log10", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log1p", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "logb", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "mad", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "maxmag", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "minmag", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "modf", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'iptr'" } + ] + }, + { + "opname" : "nan", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'nancode'" } + ] + }, + { + "opname" : "nextafter", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "pow", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y" } + ] + }, + { + "opname" : "pown", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "powr", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remainder", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remquo", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'quo'" } + ] + }, + { + "opname" : "rint", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rootn", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "round", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rsqrt", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sin", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sincos", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'cosval'" } + ] + }, + { + "opname" : "sinh", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sinpi", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sqrt", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tan", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanh", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanpi", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tgamma", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "trunc", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_cos", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_divide", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_exp", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp2", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp10", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log2", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log10", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_powr", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_recip", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_rsqrt", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sin", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sqrt", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_tan", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_cos", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_divide", + "opcode" : 82, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_exp", + "opcode" : 83, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp2", + "opcode" : 84, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp10", + "opcode" : 85, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log", + "opcode" : 86, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log2", + "opcode" : 87, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log10", + "opcode" : 88, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_powr", + "opcode" : 89, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_recip", + "opcode" : 90, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_rsqrt", + "opcode" : 91, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sin", + "opcode" : 92, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sqrt", + "opcode" : 93, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_tan", + "opcode" : 94, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs", + "opcode" : 141, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs_diff", + "opcode" : 142, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_add_sat", + "opcode" : 143, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_add_sat", + "opcode" : 144, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_hadd", + "opcode" : 145, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_hadd", + "opcode" : 146, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_rhadd", + "opcode" : 147, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_rhadd", + "opcode" : 148, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_clamp", + "opcode" : 149, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "u_clamp", + "opcode" : 150, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "clz", + "opcode" : 151, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ctz", + "opcode" : 152, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad_hi", + "opcode" : 153, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "u_mad_sat", + "opcode" : 154, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mad_sat", + "opcode" : 155, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_max", + "opcode" : 156, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_max", + "opcode" : 157, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_min", + "opcode" : 158, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_min", + "opcode" : 159, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_mul_hi", + "opcode" : 160, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "rotate", + "opcode" : 161, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "s_sub_sat", + "opcode" : 162, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_sub_sat", + "opcode" : 163, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_upsample", + "opcode" : 164, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "s_upsample", + "opcode" : 165, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "popcount", + "opcode" : 166, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad24", + "opcode" : 167, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "u_mad24", + "opcode" : 168, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mul24", + "opcode" : 169, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul24", + "opcode" : 170, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_abs", + "opcode" : 201, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "u_abs_diff", + "opcode" : 202, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul_hi", + "opcode" : 203, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mad_hi", + "opcode" : 204, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fclamp", + "opcode" : 95, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "degrees", + "opcode" :96, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "fmax_common", + "opcode" : 97, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin_common", + "opcode" : 98, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "mix", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "radians", + "opcode" : 100, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "step", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "smoothstep", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sign", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cross", + "opcode" : 104, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "distance", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "length", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "normalize", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_distance", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "fast_length", + "opcode" : 109, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_normalize", + "opcode" : 110, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "bitselect", + "opcode" : 186, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "select", + "opcode" : 187, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "vloadn", + "opcode" : 171, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstoren", + "opcode" : 172, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_half", + "opcode" : 173, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_halfn", + "opcode" : 174, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstore_half", + "opcode" : 175, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_half_r", + "opcode" : 176, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vstore_halfn", + "opcode" : 177, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_halfn_r", + "opcode" : 178, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vloada_halfn", + "opcode" : 179, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstorea_halfn", + "opcode" : 180, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstorea_halfn_r", + "opcode" : 181, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "shuffle", + "opcode" : 182, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "shuffle2", + "opcode" : 183, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "printf", + "opcode" : 184, + "operands" : [ + { "kind" : "IdRef", "name" : "'format'" }, + { "kind" : "IdRef", "name" : "'additional arguments'", "quantifier" : "*" } + ] + }, + { + "opname" : "prefetch", + "opcode" : 185, + "operands" : [ + { "kind" : "IdRef", "name" : "'ptr'" }, + { "kind" : "IdRef", "name" : "'num elements'" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.core.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.core.grammar.json new file mode 100644 index 000000000000..f3cfc4c299bf --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.core.grammar.json @@ -0,0 +1,5775 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "magic_number" : "0x07230203", + "major_version" : 1, + "minor_version" : 0, + "revision" : 12, + "instructions" : [ + { + "opname" : "OpNop", + "opcode" : 0 + }, + { + "opname" : "OpUndef", + "opcode" : 1, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSourceContinued", + "opcode" : 2, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Continued Source'" } + ] + }, + { + "opname" : "OpSource", + "opcode" : 3, + "operands" : [ + { "kind" : "SourceLanguage" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" }, + { "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" } + ] + }, + { + "opname" : "OpSourceExtension", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Extension'" } + ] + }, + { + "opname" : "OpName", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpMemberName", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpString", + "opcode" : 7, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'String'" } + ] + }, + { + "opname" : "OpLine", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "OpExtension", + "opcode" : 10, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInstImport", + "opcode" : 11, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInst", + "opcode" : 12, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ] + }, + { + "opname" : "OpMemoryModel", + "opcode" : 14, + "operands" : [ + { "kind" : "AddressingModel" }, + { "kind" : "MemoryModel" } + ] + }, + { + "opname" : "OpEntryPoint", + "opcode" : 15, + "operands" : [ + { "kind" : "ExecutionModel" }, + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } + ] + }, + { + "opname" : "OpExecutionMode", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ] + }, + { + "opname" : "OpCapability", + "opcode" : 17, + "operands" : [ + { "kind" : "Capability", "name" : "'Capability'" } + ] + }, + { + "opname" : "OpTypeVoid", + "opcode" : 19, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeBool", + "opcode" : 20, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeInt", + "opcode" : 21, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" }, + { "kind" : "LiteralInteger", "name" : "'Signedness'" } + ] + }, + { + "opname" : "OpTypeFloat", + "opcode" : 22, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" } + ] + }, + { + "opname" : "OpTypeVector", + "opcode" : 23, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "OpTypeMatrix", + "opcode" : 24, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Column Type'" }, + { "kind" : "LiteralInteger", "name" : "'Column Count'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpTypeImage", + "opcode" : 25, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Type'" }, + { "kind" : "Dim" }, + { "kind" : "LiteralInteger", "name" : "'Depth'" }, + { "kind" : "LiteralInteger", "name" : "'Arrayed'" }, + { "kind" : "LiteralInteger", "name" : "'MS'" }, + { "kind" : "LiteralInteger", "name" : "'Sampled'" }, + { "kind" : "ImageFormat" }, + { "kind" : "AccessQualifier", "quantifier" : "?" } + ] + }, + { + "opname" : "OpTypeSampler", + "opcode" : 26, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeSampledImage", + "opcode" : 27, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ] + }, + { + "opname" : "OpTypeArray", + "opcode" : 28, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" }, + { "kind" : "IdRef", "name" : "'Length'" } + ] + }, + { + "opname" : "OpTypeRuntimeArray", + "opcode" : 29, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpTypeStruct", + "opcode" : 30, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ] + }, + { + "opname" : "OpTypeOpaque", + "opcode" : 31, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "The name of the opaque type." } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypePointer", + "opcode" : 32, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "name" : "'Type'" } + ] + }, + { + "opname" : "OpTypeFunction", + "opcode" : 33, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." } + ] + }, + { + "opname" : "OpTypeEvent", + "opcode" : 34, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypeDeviceEvent", + "opcode" : 35, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypeReserveId", + "opcode" : 36, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeQueue", + "opcode" : 37, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypePipe", + "opcode" : 38, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "AccessQualifier", "name" : "'Qualifier'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeForwardPointer", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer Type'" }, + { "kind" : "StorageClass" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpConstantTrue", + "opcode" : 41, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstantFalse", + "opcode" : 42, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstant", + "opcode" : 43, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConstantComposite", + "opcode" : 44, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpConstantSampler", + "opcode" : 45, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "SamplerAddressingMode" }, + { "kind" : "LiteralInteger", "name" : "'Param'" }, + { "kind" : "SamplerFilterMode" } + ], + "capabilities" : [ "LiteralSampler" ] + }, + { + "opname" : "OpConstantNull", + "opcode" : 46, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantTrue", + "opcode" : 48, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantFalse", + "opcode" : 49, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstant", + "opcode" : 50, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpSpecConstantComposite", + "opcode" : 51, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpSpecConstantOp", + "opcode" : 52, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" } + ] + }, + { + "opname" : "OpFunction", + "opcode" : 54, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "FunctionControl" }, + { "kind" : "IdRef", "name" : "'Function Type'" } + ] + }, + { + "opname" : "OpFunctionParameter", + "opcode" : 55, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpFunctionEnd", + "opcode" : 56 + }, + { + "opname" : "OpFunctionCall", + "opcode" : 57, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." } + ] + }, + { + "opname" : "OpVariable", + "opcode" : 59, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" } + ] + }, + { + "opname" : "OpImageTexelPointer", + "opcode" : 60, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Sample'" } + ] + }, + { + "opname" : "OpLoad", + "opcode" : 61, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpStore", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemory", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemorySized", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpAccessChain", + "opcode" : 65, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpInBoundsAccessChain", + "opcode" : 66, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpPtrAccessChain", + "opcode" : 67, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ + "Addresses", + "VariablePointers", + "VariablePointersStorageBuffer" + ] + }, + { + "opname" : "OpArrayLength", + "opcode" : 68, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Structure'" }, + { "kind" : "LiteralInteger", "name" : "'Array member'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpGenericPtrMemSemantics", + "opcode" : 69, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpInBoundsPtrAccessChain", + "opcode" : 70, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpDecorate", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpMemberDecorate", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'Structure Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpDecorationGroup", + "opcode" : 73, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpGroupDecorate", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpGroupMemberDecorate", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpVectorExtractDynamic", + "opcode" : 77, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorInsertDynamic", + "opcode" : 78, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorShuffle", + "opcode" : 79, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" } + ] + }, + { + "opname" : "OpCompositeConstruct", + "opcode" : 80, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpCompositeExtract", + "opcode" : 81, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCompositeInsert", + "opcode" : 82, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCopyObject", + "opcode" : 83, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpTranspose", + "opcode" : 84, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpSampledImage", + "opcode" : 86, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ] + }, + { + "opname" : "OpImageSampleImplicitLod", + "opcode" : 87, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleExplicitLod", + "opcode" : 88, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ] + }, + { + "opname" : "OpImageSampleDrefImplicitLod", + "opcode" : 89, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleDrefExplicitLod", + "opcode" : 90, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjImplicitLod", + "opcode" : 91, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjExplicitLod", + "opcode" : 92, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefImplicitLod", + "opcode" : 93, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefExplicitLod", + "opcode" : 94, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageFetch", + "opcode" : 95, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageGather", + "opcode" : 96, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageDrefGather", + "opcode" : 97, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageRead", + "opcode" : 98, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageWrite", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Texel'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImage", + "opcode" : 100, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" } + ] + }, + { + "opname" : "OpImageQueryFormat", + "opcode" : 101, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQueryOrder", + "opcode" : 102, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQuerySizeLod", + "opcode" : 103, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Level of Detail'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySize", + "opcode" : 104, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLod", + "opcode" : 105, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLevels", + "opcode" : 106, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySamples", + "opcode" : 107, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpConvertFToU", + "opcode" : 109, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertFToS", + "opcode" : 110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertSToF", + "opcode" : 111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpConvertUToF", + "opcode" : 112, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpUConvert", + "opcode" : 113, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpSConvert", + "opcode" : 114, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpFConvert", + "opcode" : 115, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpQuantizeToF16", + "opcode" : 116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConvertPtrToU", + "opcode" : 117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpSatConvertSToU", + "opcode" : 118, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSatConvertUToS", + "opcode" : 119, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpConvertUToPtr", + "opcode" : 120, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Integer Value'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpPtrCastToGeneric", + "opcode" : 121, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtr", + "opcode" : 122, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtrExplicit", + "opcode" : 123, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "StorageClass", "name" : "'Storage'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpBitcast", + "opcode" : 124, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSNegate", + "opcode" : 126, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpFNegate", + "opcode" : 127, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpIAdd", + "opcode" : 128, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFAdd", + "opcode" : 129, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISub", + "opcode" : 130, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFSub", + "opcode" : 131, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpIMul", + "opcode" : 132, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMul", + "opcode" : 133, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUDiv", + "opcode" : 134, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSDiv", + "opcode" : 135, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFDiv", + "opcode" : 136, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMod", + "opcode" : 137, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSRem", + "opcode" : 138, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMod", + "opcode" : 139, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFRem", + "opcode" : 140, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMod", + "opcode" : 141, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpVectorTimesScalar", + "opcode" : 142, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ] + }, + { + "opname" : "OpMatrixTimesScalar", + "opcode" : 143, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpVectorTimesMatrix", + "opcode" : 144, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesVector", + "opcode" : 145, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesMatrix", + "opcode" : 146, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'LeftMatrix'" }, + { "kind" : "IdRef", "name" : "'RightMatrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpOuterProduct", + "opcode" : 147, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpDot", + "opcode" : 148, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ] + }, + { + "opname" : "OpIAddCarry", + "opcode" : 149, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISubBorrow", + "opcode" : 150, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMulExtended", + "opcode" : 151, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMulExtended", + "opcode" : 152, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpAny", + "opcode" : 154, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpAll", + "opcode" : 155, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpIsNan", + "opcode" : 156, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsInf", + "opcode" : 157, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsFinite", + "opcode" : 158, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpIsNormal", + "opcode" : 159, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSignBitSet", + "opcode" : 160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLessOrGreater", + "opcode" : 161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpOrdered", + "opcode" : 162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpUnordered", + "opcode" : 163, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLogicalEqual", + "opcode" : 164, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNotEqual", + "opcode" : 165, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalOr", + "opcode" : 166, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalAnd", + "opcode" : 167, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNot", + "opcode" : 168, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSelect", + "opcode" : 169, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'Object 1'" }, + { "kind" : "IdRef", "name" : "'Object 2'" } + ] + }, + { + "opname" : "OpIEqual", + "opcode" : 170, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpINotEqual", + "opcode" : 171, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThan", + "opcode" : 172, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThan", + "opcode" : 173, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThanEqual", + "opcode" : 174, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThanEqual", + "opcode" : 175, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThan", + "opcode" : 176, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThan", + "opcode" : 177, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThanEqual", + "opcode" : 178, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThanEqual", + "opcode" : 179, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdEqual", + "opcode" : 180, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordEqual", + "opcode" : 181, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdNotEqual", + "opcode" : 182, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordNotEqual", + "opcode" : 183, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThan", + "opcode" : 184, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThan", + "opcode" : 185, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThan", + "opcode" : 186, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThan", + "opcode" : 187, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThanEqual", + "opcode" : 188, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThanEqual", + "opcode" : 189, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThanEqual", + "opcode" : 190, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThanEqual", + "opcode" : 191, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpShiftRightLogical", + "opcode" : 194, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftRightArithmetic", + "opcode" : 195, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftLeftLogical", + "opcode" : 196, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpBitwiseOr", + "opcode" : 197, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseXor", + "opcode" : 198, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseAnd", + "opcode" : 199, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpNot", + "opcode" : 200, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpBitFieldInsert", + "opcode" : 201, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Insert'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldSExtract", + "opcode" : 202, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldUExtract", + "opcode" : 203, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitReverse", + "opcode" : 204, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitCount", + "opcode" : 205, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ] + }, + { + "opname" : "OpDPdx", + "opcode" : 207, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdy", + "opcode" : 208, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpFwidth", + "opcode" : 209, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdxFine", + "opcode" : 210, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyFine", + "opcode" : 211, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthFine", + "opcode" : 212, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdxCoarse", + "opcode" : 213, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyCoarse", + "opcode" : 214, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthCoarse", + "opcode" : 215, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpEmitVertex", + "opcode" : 218, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEndPrimitive", + "opcode" : 219, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEmitStreamVertex", + "opcode" : 220, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpEndStreamPrimitive", + "opcode" : 221, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpControlBarrier", + "opcode" : 224, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpMemoryBarrier", + "opcode" : 225, + "operands" : [ + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicLoad", + "opcode" : 227, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicStore", + "opcode" : 228, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicExchange", + "opcode" : 229, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicCompareExchange", + "opcode" : 230, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ] + }, + { + "opname" : "OpAtomicCompareExchangeWeak", + "opcode" : 231, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicIIncrement", + "opcode" : 232, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIDecrement", + "opcode" : 233, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIAdd", + "opcode" : 234, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicISub", + "opcode" : 235, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMin", + "opcode" : 236, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMin", + "opcode" : 237, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMax", + "opcode" : 238, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMax", + "opcode" : 239, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicAnd", + "opcode" : 240, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicOr", + "opcode" : 241, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicXor", + "opcode" : 242, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpPhi", + "opcode" : 245, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" } + ] + }, + { + "opname" : "OpLoopMerge", + "opcode" : 246, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "IdRef", "name" : "'Continue Target'" }, + { "kind" : "LoopControl" } + ] + }, + { + "opname" : "OpSelectionMerge", + "opcode" : 247, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "SelectionControl" } + ] + }, + { + "opname" : "OpLabel", + "opcode" : 248, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpBranch", + "opcode" : 249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target Label'" } + ] + }, + { + "opname" : "OpBranchConditional", + "opcode" : 250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'True Label'" }, + { "kind" : "IdRef", "name" : "'False Label'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" } + ] + }, + { + "opname" : "OpSwitch", + "opcode" : 251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Selector'" }, + { "kind" : "IdRef", "name" : "'Default'" }, + { "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" } + ] + }, + { + "opname" : "OpKill", + "opcode" : 252, + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpReturn", + "opcode" : 253 + }, + { + "opname" : "OpReturnValue", + "opcode" : 254, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpUnreachable", + "opcode" : 255 + }, + { + "opname" : "OpLifetimeStart", + "opcode" : 256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLifetimeStop", + "opcode" : 257, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAsyncCopy", + "opcode" : 259, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Destination'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Num Elements'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupWaitEvents", + "opcode" : 260, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Events List'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAll", + "opcode" : 261, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupAny", + "opcode" : 262, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupBroadcast", + "opcode" : 263, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'LocalId'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupIAdd", + "opcode" : 264, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAdd", + "opcode" : 265, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMin", + "opcode" : 266, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMin", + "opcode" : 267, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMin", + "opcode" : 268, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMax", + "opcode" : 269, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMax", + "opcode" : 270, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMax", + "opcode" : 271, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpReadPipe", + "opcode" : 274, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpWritePipe", + "opcode" : 275, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedReadPipe", + "opcode" : 276, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedWritePipe", + "opcode" : 277, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveReadPipePackets", + "opcode" : 278, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveWritePipePackets", + "opcode" : 279, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitReadPipe", + "opcode" : 280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitWritePipe", + "opcode" : 281, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpIsValidReserveId", + "opcode" : 282, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetNumPipePackets", + "opcode" : 283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetMaxPipePackets", + "opcode" : 284, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveReadPipePackets", + "opcode" : 285, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveWritePipePackets", + "opcode" : 286, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitReadPipe", + "opcode" : 287, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitWritePipe", + "opcode" : 288, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpEnqueueMarker", + "opcode" : 291, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpEnqueueKernel", + "opcode" : 292, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeSubGroupCount", + "opcode" : 293, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeMaxSubGroupSize", + "opcode" : 294, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelWorkGroupSize", + "opcode" : 295, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelPreferredWorkGroupSizeMultiple", + "opcode" : 296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpRetainEvent", + "opcode" : 297, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpReleaseEvent", + "opcode" : 298, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCreateUserEvent", + "opcode" : 299, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpIsValidEvent", + "opcode" : 300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpSetUserEventStatus", + "opcode" : 301, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Status'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCaptureEventProfilingInfo", + "opcode" : 302, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Profiling Info'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetDefaultQueue", + "opcode" : 303, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpBuildNDRange", + "opcode" : 304, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'GlobalWorkSize'" }, + { "kind" : "IdRef", "name" : "'LocalWorkSize'" }, + { "kind" : "IdRef", "name" : "'GlobalWorkOffset'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpImageSparseSampleImplicitLod", + "opcode" : 305, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleExplicitLod", + "opcode" : 306, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefImplicitLod", + "opcode" : 307, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefExplicitLod", + "opcode" : 308, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjImplicitLod", + "opcode" : 309, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjExplicitLod", + "opcode" : 310, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefImplicitLod", + "opcode" : 311, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefExplicitLod", + "opcode" : 312, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseFetch", + "opcode" : 313, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseGather", + "opcode" : 314, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseDrefGather", + "opcode" : 315, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseTexelsResident", + "opcode" : 316, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Resident Code'" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpNoLine", + "opcode" : 317 + }, + { + "opname" : "OpAtomicFlagTestAndSet", + "opcode" : 318, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicFlagClear", + "opcode" : 319, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageSparseRead", + "opcode" : 320, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpDecorateId", + "opcode" : 332, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "opname" : "OpSubgroupBallotKHR", + "opcode" : 4421, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupFirstInvocationKHR", + "opcode" : 4422, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupAllKHR", + "opcode" : 4428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAnyKHR", + "opcode" : 4429, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAllEqualKHR", + "opcode" : 4430, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupReadInvocationKHR", + "opcode" : 4432, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpGroupIAddNonUniformAMD", + "opcode" : 5000, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAddNonUniformAMD", + "opcode" : 5001, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMinNonUniformAMD", + "opcode" : 5002, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMinNonUniformAMD", + "opcode" : 5003, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMinNonUniformAMD", + "opcode" : 5004, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMaxNonUniformAMD", + "opcode" : 5005, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMaxNonUniformAMD", + "opcode" : 5006, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMaxNonUniformAMD", + "opcode" : 5007, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpFragmentMaskFetchAMD", + "opcode" : 5011, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpFragmentFetchAMD", + "opcode" : 5012, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Fragment Index'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpSubgroupShuffleINTEL", + "opcode" : 5571, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'InvocationId'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleDownINTEL", + "opcode" : 5572, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Next'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleUpINTEL", + "opcode" : 5573, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Previous'" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleXorINTEL", + "opcode" : 5574, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupBlockReadINTEL", + "opcode" : 5575, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupBlockWriteINTEL", + "opcode" : 5576, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockReadINTEL", + "opcode" : 5577, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockWriteINTEL", + "opcode" : 5578, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpDecorateStringGOOGLE", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + }, + { + "opname" : "OpMemberDecorateStringGOOGLE", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "ImageOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Bias", + "value" : "0x0001", + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Lod", + "value" : "0x0002", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Grad", + "value" : "0x0004", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffset", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Offset", + "value" : "0x0010", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffsets", + "value" : "0x0020", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Sample", + "value" : "0x0040", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "MinLod", + "value" : "0x0080", + "capabilities" : [ "MinLod" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FPFastMathMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "NotNaN", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NotInf", + "value" : "0x0002", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NSZ", + "value" : "0x0004", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AllowRecip", + "value" : "0x0008", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Fast", + "value" : "0x0010", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "SelectionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Flatten", + "value" : "0x0001" + }, + { + "enumerant" : "DontFlatten", + "value" : "0x0002" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "LoopControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Unroll", + "value" : "0x0001" + }, + { + "enumerant" : "DontUnroll", + "value" : "0x0002" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FunctionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Inline", + "value" : "0x0001" + }, + { + "enumerant" : "DontInline", + "value" : "0x0002" + }, + { + "enumerant" : "Pure", + "value" : "0x0004" + }, + { + "enumerant" : "Const", + "value" : "0x0008" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemorySemantics", + "enumerants" : [ + { + "enumerant" : "Relaxed", + "value" : "0x0000" + }, + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Acquire", + "value" : "0x0002" + }, + { + "enumerant" : "Release", + "value" : "0x0004" + }, + { + "enumerant" : "AcquireRelease", + "value" : "0x0008" + }, + { + "enumerant" : "SequentiallyConsistent", + "value" : "0x0010" + }, + { + "enumerant" : "UniformMemory", + "value" : "0x0040", + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupMemory", + "value" : "0x0080" + }, + { + "enumerant" : "WorkgroupMemory", + "value" : "0x0100" + }, + { + "enumerant" : "CrossWorkgroupMemory", + "value" : "0x0200" + }, + { + "enumerant" : "AtomicCounterMemory", + "value" : "0x0400", + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "ImageMemory", + "value" : "0x0800" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemoryAccess", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Volatile", + "value" : "0x0001" + }, + { + "enumerant" : "Aligned", + "value" : "0x0002", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Nontemporal", + "value" : "0x0004" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "KernelProfilingInfo", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "CmdExecTime", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SourceLanguage", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "ESSL", + "value" : 1 + }, + { + "enumerant" : "GLSL", + "value" : 2 + }, + { + "enumerant" : "OpenCL_C", + "value" : 3 + }, + { + "enumerant" : "OpenCL_CPP", + "value" : 4 + }, + { + "enumerant" : "HLSL", + "value" : 5 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionModel", + "enumerants" : [ + { + "enumerant" : "Vertex", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TessellationControl", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessellationEvaluation", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Geometry", + "value" : 3, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Fragment", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLCompute", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Kernel", + "value" : 6, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AddressingModel", + "enumerants" : [ + { + "enumerant" : "Logical", + "value" : 0 + }, + { + "enumerant" : "Physical32", + "value" : 1, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Physical64", + "value" : 2, + "capabilities" : [ "Addresses" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "MemoryModel", + "enumerants" : [ + { + "enumerant" : "Simple", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSL450", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OpenCL", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionMode", + "enumerants" : [ + { + "enumerant" : "Invocations", + "value" : 0, + "capabilities" : [ "Geometry" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of <>'" } + ] + }, + { + "enumerant" : "SpacingEqual", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalEven", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalOdd", + "value" : 3, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCw", + "value" : 4, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCcw", + "value" : 5, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PixelCenterInteger", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginUpperLeft", + "value" : 7, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginLowerLeft", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "EarlyFragmentTests", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointMode", + "value" : 10, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Xfb", + "value" : 11, + "capabilities" : [ "TransformFeedback" ] + }, + { + "enumerant" : "DepthReplacing", + "value" : 12, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthGreater", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthLess", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthUnchanged", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "LocalSize", + "value" : 17, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "LocalSizeHint", + "value" : 18, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "InputPoints", + "value" : 19, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLines", + "value" : 20, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLinesAdjacency", + "value" : 21, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Triangles", + "value" : 22, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InputTrianglesAdjacency", + "value" : 23, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Quads", + "value" : 24, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Isolines", + "value" : 25, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "OutputVertices", + "value" : 26, + "capabilities" : [ "Geometry", "Tessellation" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vertex count'" } + ] + }, + { + "enumerant" : "OutputPoints", + "value" : 27, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputLineStrip", + "value" : 28, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputTriangleStrip", + "value" : 29, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "VecTypeHint", + "value" : 30, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vector type'" } + ] + }, + { + "enumerant" : "ContractionOff", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "PostDepthCoverage", + "value" : 4446, + "capabilities" : [ "SampleMaskPostDepthCoverage" ] + }, + { + "enumerant" : "StencilRefReplacingEXT", + "value" : 5027, + "capabilities" : [ "StencilExportEXT" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StorageClass", + "enumerants" : [ + { + "enumerant" : "UniformConstant", + "value" : 0 + }, + { + "enumerant" : "Input", + "value" : 1 + }, + { + "enumerant" : "Uniform", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Output", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Workgroup", + "value" : 4 + }, + { + "enumerant" : "CrossWorkgroup", + "value" : 5 + }, + { + "enumerant" : "Private", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Function", + "value" : 7 + }, + { + "enumerant" : "Generic", + "value" : 8, + "capabilities" : [ "GenericPointer" ] + }, + { + "enumerant" : "PushConstant", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "AtomicCounter", + "value" : 10, + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "Image", + "value" : 11 + }, + { + "enumerant" : "StorageBuffer", + "value" : 12, + "extensions" : [ + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers" + ], + "capabilities" : [ "Shader" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Dim", + "enumerants" : [ + { + "enumerant" : "1D", + "value" : 0, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "2D", + "value" : 1 + }, + { + "enumerant" : "3D", + "value" : 2 + }, + { + "enumerant" : "Cube", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rect", + "value" : 4, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "Buffer", + "value" : 5, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "SubpassData", + "value" : 6, + "capabilities" : [ "InputAttachment" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerAddressingMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ClampToEdge", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Clamp", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Repeat", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RepeatMirrored", + "value" : 4, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerFilterMode", + "enumerants" : [ + { + "enumerant" : "Nearest", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Linear", + "value" : 1, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageFormat", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "Rgba32f", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16f", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32f", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8Snorm", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32f", + "value" : 6, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16f", + "value" : 7, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R11fG11fB10f", + "value" : 8, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16f", + "value" : 9, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16", + "value" : 10, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgb10A2", + "value" : 11, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16", + "value" : 12, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8", + "value" : 13, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16", + "value" : 14, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8", + "value" : 15, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16Snorm", + "value" : 16, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16Snorm", + "value" : 17, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8Snorm", + "value" : 18, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16Snorm", + "value" : 19, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8Snorm", + "value" : 20, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32i", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16i", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8i", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32i", + "value" : 24, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32i", + "value" : 25, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16i", + "value" : 26, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8i", + "value" : 27, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16i", + "value" : 28, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8i", + "value" : 29, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32ui", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16ui", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8ui", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32ui", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgb10a2ui", + "value" : 34, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg32ui", + "value" : 35, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16ui", + "value" : 36, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8ui", + "value" : 37, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16ui", + "value" : 38, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8ui", + "value" : 39, + "capabilities" : [ "StorageImageExtendedFormats" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelOrder", + "enumerants" : [ + { + "enumerant" : "R", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "A", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RG", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RA", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGB", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBA", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BGRA", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ARGB", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Intensity", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Luminance", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Rx", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGx", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBx", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Depth", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "DepthStencil", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGB", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBx", + "value" : 16, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBA", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sBGRA", + "value" : 18, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ABGR", + "value" : 19, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelDataType", + "enumerants" : [ + { + "enumerant" : "SnormInt8", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SnormInt16", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt8", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt16", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort565", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort555", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt8", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt16", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt32", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt8", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt16", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt32", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "HalfFloat", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt24", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010_2", + "value" : 16, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPRoundingMode", + "enumerants" : [ + { + "enumerant" : "RTE", + "value" : 0, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTZ", + "value" : 1, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTP", + "value" : 2, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTN", + "value" : 3, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LinkageType", + "enumerants" : [ + { + "enumerant" : "Export", + "value" : 0, + "capabilities" : [ "Linkage" ] + }, + { + "enumerant" : "Import", + "value" : 1, + "capabilities" : [ "Linkage" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AccessQualifier", + "enumerants" : [ + { + "enumerant" : "ReadOnly", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WriteOnly", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ReadWrite", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FunctionParameterAttribute", + "enumerants" : [ + { + "enumerant" : "Zext", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sext", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ByVal", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sret", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoAlias", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoCapture", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoWrite", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoReadWrite", + "value" : 7, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Decoration", + "enumerants" : [ + { + "enumerant" : "RelaxedPrecision", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SpecId", + "value" : 1, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" } + ] + }, + { + "enumerant" : "Block", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "BufferBlock", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "RowMajor", + "value" : 4, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ColMajor", + "value" : 5, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ArrayStride", + "value" : 6, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Array Stride'" } + ] + }, + { + "enumerant" : "MatrixStride", + "value" : 7, + "capabilities" : [ "Matrix" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Matrix Stride'" } + ] + }, + { + "enumerant" : "GLSLShared", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSLPacked", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CPacked", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BuiltIn", + "value" : 11, + "parameters" : [ + { "kind" : "BuiltIn" } + ] + }, + { + "enumerant" : "NoPerspective", + "value" : 13, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Flat", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Patch", + "value" : 15, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Centroid", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sample", + "value" : 17, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "Invariant", + "value" : 18, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Restrict", + "value" : 19 + }, + { + "enumerant" : "Aliased", + "value" : 20 + }, + { + "enumerant" : "Volatile", + "value" : 21 + }, + { + "enumerant" : "Constant", + "value" : 22, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Coherent", + "value" : 23 + }, + { + "enumerant" : "NonWritable", + "value" : 24 + }, + { + "enumerant" : "NonReadable", + "value" : 25 + }, + { + "enumerant" : "Uniform", + "value" : 26, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SaturatedConversion", + "value" : 28, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Stream", + "value" : 29, + "capabilities" : [ "GeometryStreams" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stream Number'" } + ] + }, + { + "enumerant" : "Location", + "value" : 30, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Location'" } + ] + }, + { + "enumerant" : "Component", + "value" : 31, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Component'" } + ] + }, + { + "enumerant" : "Index", + "value" : 32, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Index'" } + ] + }, + { + "enumerant" : "Binding", + "value" : 33, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Binding Point'" } + ] + }, + { + "enumerant" : "DescriptorSet", + "value" : 34, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Descriptor Set'" } + ] + }, + { + "enumerant" : "Offset", + "value" : 35, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Byte Offset'" } + ] + }, + { + "enumerant" : "XfbBuffer", + "value" : 36, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" } + ] + }, + { + "enumerant" : "XfbStride", + "value" : 37, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Stride'" } + ] + }, + { + "enumerant" : "FuncParamAttr", + "value" : 38, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" } + ] + }, + { + "enumerant" : "FPRoundingMode", + "value" : 39, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ], + "parameters" : [ + { "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" } + ] + }, + { + "enumerant" : "FPFastMathMode", + "value" : 40, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" } + ] + }, + { + "enumerant" : "LinkageAttributes", + "value" : 41, + "capabilities" : [ "Linkage" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "LinkageType", "name" : "'Linkage Type'" } + ] + }, + { + "enumerant" : "NoContraction", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InputAttachmentIndex", + "value" : 43, + "capabilities" : [ "InputAttachment" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Attachment Index'" } + ] + }, + { + "enumerant" : "Alignment", + "value" : 44, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Alignment'" } + ] + }, + { + "enumerant" : "ExplicitInterpAMD", + "value" : 4999 + }, + { + "enumerant" : "OverrideCoverageNV", + "value" : 5248, + "capabilities" : [ "SampleMaskOverrideCoverageNV" ] + }, + { + "enumerant" : "PassthroughNV", + "value" : 5250, + "capabilities" : [ "GeometryShaderPassthroughNV" ] + }, + { + "enumerant" : "ViewportRelativeNV", + "value" : 5252, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryViewportRelativeNV", + "value" : 5256, + "capabilities" : [ "ShaderStereoViewNV" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ] + }, + { + "enumerant" : "HlslCounterBufferGOOGLE", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "enumerant" : "HlslSemanticGOOGLE", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "BuiltIn", + "enumerants" : [ + { + "enumerant" : "Position", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointSize", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 3, + "capabilities" : [ "ClipDistance" ] + }, + { + "enumerant" : "CullDistance", + "value" : 4, + "capabilities" : [ "CullDistance" ] + }, + { + "enumerant" : "VertexId", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceId", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PrimitiveId", + "value" : 7, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InvocationId", + "value" : 8, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "Layer", + "value" : 9, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ViewportIndex", + "value" : 10, + "capabilities" : [ "MultiViewport" ] + }, + { + "enumerant" : "TessLevelOuter", + "value" : 11, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessLevelInner", + "value" : 12, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessCoord", + "value" : 13, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PatchVertices", + "value" : 14, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "FragCoord", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointCoord", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FrontFacing", + "value" : 17, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampleId", + "value" : 18, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SamplePosition", + "value" : 19, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SampleMask", + "value" : 20, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FragDepth", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "HelperInvocation", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "NumWorkgroups", + "value" : 24 + }, + { + "enumerant" : "WorkgroupSize", + "value" : 25 + }, + { + "enumerant" : "WorkgroupId", + "value" : 26 + }, + { + "enumerant" : "LocalInvocationId", + "value" : 27 + }, + { + "enumerant" : "GlobalInvocationId", + "value" : 28 + }, + { + "enumerant" : "LocalInvocationIndex", + "value" : 29 + }, + { + "enumerant" : "WorkDim", + "value" : 30, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalSize", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "EnqueuedWorkgroupSize", + "value" : 32, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalOffset", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalLinearId", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 36, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupMaxSize", + "value" : 37, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumSubgroups", + "value" : 38, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumEnqueuedSubgroups", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupId", + "value" : 40, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupLocalInvocationId", + "value" : 41, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "VertexIndex", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceIndex", + "value" : 43, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupEqMaskKHR", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGeMaskKHR", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGtMaskKHR", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLeMaskKHR", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLtMaskKHR", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "BaseVertex", + "value" : 4424, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "BaseInstance", + "value" : 4425, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DrawIndex", + "value" : 4426, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DeviceIndex", + "value" : 4438, + "capabilities" : [ "DeviceGroup" ] + }, + { + "enumerant" : "ViewIndex", + "value" : 4440, + "capabilities" : [ "MultiView" ] + }, + { + "enumerant" : "BaryCoordNoPerspAMD", + "value" : 4992 + }, + { + "enumerant" : "BaryCoordNoPerspCentroidAMD", + "value" : 4993 + }, + { + "enumerant" : "BaryCoordNoPerspSampleAMD", + "value" : 4994 + }, + { + "enumerant" : "BaryCoordSmoothAMD", + "value" : 4995 + }, + { + "enumerant" : "BaryCoordSmoothCentroidAMD", + "value" : 4996 + }, + { + "enumerant" : "BaryCoordSmoothSampleAMD", + "value" : 4997 + }, + { + "enumerant" : "BaryCoordPullModelAMD", + "value" : 4998 + }, + { + "enumerant" : "FragStencilRefEXT", + "value" : 5014, + "capabilities" : [ "StencilExportEXT" ] + }, + { + "enumerant" : "ViewportMaskNV", + "value" : 5253, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryPositionNV", + "value" : 5257, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "SecondaryViewportMaskNV", + "value" : 5258, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "PositionPerViewNV", + "value" : 5261, + "capabilities" : [ "PerViewAttributesNV" ] + }, + { + "enumerant" : "ViewportMaskPerViewNV", + "value" : 5262, + "capabilities" : [ "PerViewAttributesNV" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Scope", + "enumerants" : [ + { + "enumerant" : "CrossDevice", + "value" : 0 + }, + { + "enumerant" : "Device", + "value" : 1 + }, + { + "enumerant" : "Workgroup", + "value" : 2 + }, + { + "enumerant" : "Subgroup", + "value" : 3 + }, + { + "enumerant" : "Invocation", + "value" : 4 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "GroupOperation", + "enumerants" : [ + { + "enumerant" : "Reduce", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InclusiveScan", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ExclusiveScan", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "KernelEnqueueFlags", + "enumerants" : [ + { + "enumerant" : "NoWait", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitKernel", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitWorkGroup", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Capability", + "enumerants" : [ + { + "enumerant" : "Matrix", + "value" : 0 + }, + { + "enumerant" : "Shader", + "value" : 1, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "Geometry", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Tessellation", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Addresses", + "value" : 4 + }, + { + "enumerant" : "Linkage", + "value" : 5 + }, + { + "enumerant" : "Kernel", + "value" : 6 + }, + { + "enumerant" : "Vector16", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16Buffer", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16", + "value" : 9 + }, + { + "enumerant" : "Float64", + "value" : 10 + }, + { + "enumerant" : "Int64", + "value" : 11 + }, + { + "enumerant" : "Int64Atomics", + "value" : 12, + "capabilities" : [ "Int64" ] + }, + { + "enumerant" : "ImageBasic", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ImageReadWrite", + "value" : 14, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "ImageMipmap", + "value" : 15, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "Pipes", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Groups", + "value" : 18 + }, + { + "enumerant" : "DeviceEnqueue", + "value" : 19, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "LiteralSampler", + "value" : 20, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AtomicStorage", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Int16", + "value" : 22 + }, + { + "enumerant" : "TessellationPointSize", + "value" : 23, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "GeometryPointSize", + "value" : 24, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ImageGatherExtended", + "value" : 25, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageMultisample", + "value" : 27, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "UniformBufferArrayDynamicIndexing", + "value" : 28, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledImageArrayDynamicIndexing", + "value" : 29, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageBufferArrayDynamicIndexing", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageArrayDynamicIndexing", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CullDistance", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageCubeArray", + "value" : 34, + "capabilities" : [ "SampledCubeArray" ] + }, + { + "enumerant" : "SampleRateShading", + "value" : 35, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageRect", + "value" : 36, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "SampledRect", + "value" : 37, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GenericPointer", + "value" : 38, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Int8", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InputAttachment", + "value" : 40, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SparseResidency", + "value" : 41, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MinLod", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sampled1D", + "value" : 43 + }, + { + "enumerant" : "Image1D", + "value" : 44, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "SampledCubeArray", + "value" : 45, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledBuffer", + "value" : 46 + }, + { + "enumerant" : "ImageBuffer", + "value" : 47, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "ImageMSArray", + "value" : 48, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageExtendedFormats", + "value" : 49, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageQuery", + "value" : 50, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DerivativeControl", + "value" : 51, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InterpolationFunction", + "value" : 52, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TransformFeedback", + "value" : 53, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GeometryStreams", + "value" : 54, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "StorageImageReadWithoutFormat", + "value" : 55, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageWriteWithoutFormat", + "value" : 56, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MultiViewport", + "value" : 57, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "SubgroupBallotKHR", + "value" : 4423, + "extensions" : [ "SPV_KHR_shader_ballot" ] + }, + { + "enumerant" : "DrawParameters", + "value" : 4427, + "extensions" : [ "SPV_KHR_shader_draw_parameters" ] + }, + { + "enumerant" : "SubgroupVoteKHR", + "value" : 4431, + "extensions" : [ "SPV_KHR_subgroup_vote" ] + }, + { + "enumerant" : "StorageBuffer16BitAccess", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniformBufferBlock16", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "UniformAndStorageBuffer16BitAccess", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniform16", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StoragePushConstant16", + "value" : 4435, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageInputOutput16", + "value" : 4436, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "DeviceGroup", + "value" : 4437, + "extensions" : [ "SPV_KHR_device_group" ] + }, + { + "enumerant" : "MultiView", + "value" : 4439, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_multiview" ] + }, + { + "enumerant" : "VariablePointersStorageBuffer", + "value" : 4441, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant" : "VariablePointers", + "value" : 4442, + "capabilities" : [ "VariablePointersStorageBuffer" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant": "AtomicStorageOps", + "value": 4445, + "extensions": [ "SPV_KHR_shader_atomic_counter_ops" ] + }, + { + "enumerant" : "SampleMaskPostDepthCoverage", + "value" : 4447, + "extensions" : [ "SPV_KHR_post_depth_coverage" ] + }, + { + "enumerant" : "ImageGatherBiasLodAMD", + "value" : 5009, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_texture_gather_bias_lod" ] + }, + { + "enumerant" : "FragmentMaskAMD", + "value" : 5010, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ] + }, + { + "enumerant" : "StencilExportEXT", + "value" : 5013, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ] + }, + { + "enumerant" : "ImageReadWriteLodAMD", + "value" : 5015, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_image_load_store_lod" ] + }, + { + "enumerant" : "SampleMaskOverrideCoverageNV", + "value" : 5249, + "capabilities" : [ "SampleRateShading" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ] + }, + { + "enumerant" : "GeometryShaderPassthroughNV", + "value" : 5251, + "capabilities" : [ "Geometry" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerEXT", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_EXT_shader_viewport_index_layer" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerNV", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderViewportMaskNV", + "value" : 5255, + "capabilities" : [ "ShaderViewportIndexLayerNV" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderStereoViewNV", + "value" : 5259, + "capabilities" : [ "ShaderViewportMaskNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ] + }, + { + "enumerant" : "PerViewAttributesNV", + "value" : 5260, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes" ] + }, + { + "enumerant" : "SubgroupShuffleINTEL", + "value" : 5568, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupBufferBlockIOINTEL", + "value" : 5569, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupImageBlockIOINTEL", + "value" : 5570, + "extensions" : [ "SPV_INTEL_subgroups" ] + } + ] + }, + { + "category" : "Id", + "kind" : "IdResultType", + "doc" : "Reference to an representing the result's type of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdResult", + "doc" : "Definition of an representing the result of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdMemorySemantics", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the MemorySemantics operand kind" + }, + { + "category" : "Id", + "kind" : "IdScope", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the Scope operand kind" + }, + { + "category" : "Id", + "kind" : "IdRef", + "doc" : "Reference to an " + }, + { + "category" : "Literal", + "kind" : "LiteralInteger", + "doc" : "An integer consuming one or more words" + }, + { + "category" : "Literal", + "kind" : "LiteralString", + "doc" : "A null-terminated stream of characters consuming an integral number of words" + }, + { + "category" : "Literal", + "kind" : "LiteralContextDependentNumber", + "doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction" + }, + { + "category" : "Literal", + "kind" : "LiteralExtInstInteger", + "doc" : "A 32-bit unsigned integer indicating which instruction to use and determining the layout of following operands (for OpExtInst)" + }, + { + "category" : "Literal", + "kind" : "LiteralSpecConstantOpInteger", + "doc" : "An opcode indicating the operation to be performed and determining the layout of following operands (for OpSpecConstantOp)" + }, + { + "category" : "Composite", + "kind" : "PairLiteralIntegerIdRef", + "bases" : [ "LiteralInteger", "IdRef" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefLiteralInteger", + "bases" : [ "IdRef", "LiteralInteger" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefIdRef", + "bases" : [ "IdRef", "IdRef" ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.cs b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.cs new file mode 100644 index 000000000000..de325cc4aad5 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.cs @@ -0,0 +1,993 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C# +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + + public static class Specification + { + public const uint MagicNumber = 0x07230203; + public const uint Version = 0x00010000; + public const uint Revision = 12; + public const uint OpCodeMask = 0xffff; + public const uint WordCountShift = 16; + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + } + + public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + } + + public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + } + + public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + } + + public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + } + + public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + } + + public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + } + + public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + } + + public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + } + + public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + } + + public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + } + + public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + } + + public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + } + + public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + } + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.h b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.h new file mode 100644 index 000000000000..bd5a9b9593aa --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.h @@ -0,0 +1,993 @@ +/* +** Copyright (c) 2014-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10000 +#define SPV_REVISION 12 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010000; +static const unsigned int SpvRevision = 12; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpDecorateId = 332, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#endif // #ifndef spirv_H + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.hpp b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.hpp new file mode 100644 index 000000000000..e98a89cee74b --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.hpp @@ -0,0 +1,1002 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10000 +#define SPV_REVISION 12 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010000; +static const unsigned int Revision = 12; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationExplicitInterpAMD = 4999, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilityMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + OpMax = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.hpp11 b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.hpp11 new file mode 100644 index 000000000000..8896e81b7c40 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.hpp11 @@ -0,0 +1,1002 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10000 +#define SPV_REVISION 12 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010000; +static const unsigned int Revision = 12; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + Max = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.json b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.json new file mode 100644 index 000000000000..9b0a8f3de284 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.json @@ -0,0 +1,1020 @@ +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2018 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "", + "Some tokens act like mask values, which can be OR'd together,", + "while others are mutually exclusive. The mask-like ones have", + "\"Mask\" in their name, and a parallel enum that has the shift", + "amount (1 << x) for each corresponding enumerant." + ] + ], + "MagicNumber": 119734787, + "Version": 65536, + "Revision": 12, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "PostDepthCoverage": 4446, + "StencilRefReplacingEXT": 5027 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "ExplicitInterpAMD": 4999, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpDecorateId": 332, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpSubgroupReadInvocationKHR": 4432, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateStringGOOGLE": 5633 + } + } + ] + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.lua b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.lua new file mode 100644 index 000000000000..2bd33ba082b7 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.lua @@ -0,0 +1,949 @@ +-- Copyright (c) 2014-2018 The Khronos Group Inc. +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and/or associated documentation files (the "Materials"), +-- to deal in the Materials without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Materials, and to permit persons to whom the +-- Materials are furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Materials. +-- +-- MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +-- STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +-- HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +-- +-- THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +-- IN THE MATERIALS. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- +-- Some tokens act like mask values, which can be OR'd together, +-- while others are mutually exclusive. The mask-like ones have +-- "Mask" in their name, and a parallel enum that has the shift +-- amount (1 << x) for each corresponding enumerant. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010000, + Revision = 12, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + }, + +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.py b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.py new file mode 100644 index 000000000000..8a200e7655f8 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.0/spirv.py @@ -0,0 +1,949 @@ +# Copyright (c) 2014-2018 The Khronos Group Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and/or associated documentation files (the "Materials"), +# to deal in the Materials without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Materials, and to permit persons to whom the +# Materials are furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Materials. +# +# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +# STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +# HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +# +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +# IN THE MATERIALS. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# +# Some tokens act like mask values, which can be OR'd together, +# while others are mutually exclusive. The mask-like ones have +# "Mask" in their name, and a parallel enum that has the shift +# amount (1 << x) for each corresponding enumerant. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010000, + 'Revision' : 12, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'PostDepthCoverage' : 4446, + 'StencilRefReplacingEXT' : 5027, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'ExplicitInterpAMD' : 4999, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpDecorateId' : 332, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateStringGOOGLE' : 5633, + }, + +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/GLSL.std.450.h b/thirdparty/glslang/glslang/Include/spirv/1.1/GLSL.std.450.h new file mode 100644 index 000000000000..54cc00e9a888 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/GLSL.std.450.h @@ -0,0 +1,131 @@ +/* +** Copyright (c) 2014-2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLstd450_H +#define GLSLstd450_H + +static const int GLSLstd450Version = 100; +static const int GLSLstd450Revision = 3; + +enum GLSLstd450 { + GLSLstd450Bad = 0, // Don't use + + GLSLstd450Round = 1, + GLSLstd450RoundEven = 2, + GLSLstd450Trunc = 3, + GLSLstd450FAbs = 4, + GLSLstd450SAbs = 5, + GLSLstd450FSign = 6, + GLSLstd450SSign = 7, + GLSLstd450Floor = 8, + GLSLstd450Ceil = 9, + GLSLstd450Fract = 10, + + GLSLstd450Radians = 11, + GLSLstd450Degrees = 12, + GLSLstd450Sin = 13, + GLSLstd450Cos = 14, + GLSLstd450Tan = 15, + GLSLstd450Asin = 16, + GLSLstd450Acos = 17, + GLSLstd450Atan = 18, + GLSLstd450Sinh = 19, + GLSLstd450Cosh = 20, + GLSLstd450Tanh = 21, + GLSLstd450Asinh = 22, + GLSLstd450Acosh = 23, + GLSLstd450Atanh = 24, + GLSLstd450Atan2 = 25, + + GLSLstd450Pow = 26, + GLSLstd450Exp = 27, + GLSLstd450Log = 28, + GLSLstd450Exp2 = 29, + GLSLstd450Log2 = 30, + GLSLstd450Sqrt = 31, + GLSLstd450InverseSqrt = 32, + + GLSLstd450Determinant = 33, + GLSLstd450MatrixInverse = 34, + + GLSLstd450Modf = 35, // second operand needs an OpVariable to write to + GLSLstd450ModfStruct = 36, // no OpVariable operand + GLSLstd450FMin = 37, + GLSLstd450UMin = 38, + GLSLstd450SMin = 39, + GLSLstd450FMax = 40, + GLSLstd450UMax = 41, + GLSLstd450SMax = 42, + GLSLstd450FClamp = 43, + GLSLstd450UClamp = 44, + GLSLstd450SClamp = 45, + GLSLstd450FMix = 46, + GLSLstd450IMix = 47, // Reserved + GLSLstd450Step = 48, + GLSLstd450SmoothStep = 49, + + GLSLstd450Fma = 50, + GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to + GLSLstd450FrexpStruct = 52, // no OpVariable operand + GLSLstd450Ldexp = 53, + + GLSLstd450PackSnorm4x8 = 54, + GLSLstd450PackUnorm4x8 = 55, + GLSLstd450PackSnorm2x16 = 56, + GLSLstd450PackUnorm2x16 = 57, + GLSLstd450PackHalf2x16 = 58, + GLSLstd450PackDouble2x32 = 59, + GLSLstd450UnpackSnorm2x16 = 60, + GLSLstd450UnpackUnorm2x16 = 61, + GLSLstd450UnpackHalf2x16 = 62, + GLSLstd450UnpackSnorm4x8 = 63, + GLSLstd450UnpackUnorm4x8 = 64, + GLSLstd450UnpackDouble2x32 = 65, + + GLSLstd450Length = 66, + GLSLstd450Distance = 67, + GLSLstd450Cross = 68, + GLSLstd450Normalize = 69, + GLSLstd450FaceForward = 70, + GLSLstd450Reflect = 71, + GLSLstd450Refract = 72, + + GLSLstd450FindILsb = 73, + GLSLstd450FindSMsb = 74, + GLSLstd450FindUMsb = 75, + + GLSLstd450InterpolateAtCentroid = 76, + GLSLstd450InterpolateAtSample = 77, + GLSLstd450InterpolateAtOffset = 78, + + GLSLstd450NMin = 79, + GLSLstd450NMax = 80, + GLSLstd450NClamp = 81, + + GLSLstd450Count +}; + +#endif // #ifndef GLSLstd450_H diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/OpenCL.std.h b/thirdparty/glslang/glslang/Include/spirv/1.1/OpenCL.std.h new file mode 100644 index 000000000000..19a6688490c7 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/OpenCL.std.h @@ -0,0 +1,210 @@ +/* +** Copyright (c) 2015-2017 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +namespace OpenCLLIB { + +enum Entrypoints { + + // Section 2.1: Math extended instructions + Acos = 0, + Acosh = 1, + Acospi = 2, + Asin = 3, + Asinh = 4, + Asinpi = 5, + Atan = 6, + Atan2 = 7, + Atanh = 8, + Atanpi = 9, + Atan2pi = 10, + Cbrt = 11, + Ceil = 12, + Copysign = 13, + Cos = 14, + Cosh = 15, + Cospi = 16, + Erfc = 17, + Erf = 18, + Exp = 19, + Exp2 = 20, + Exp10 = 21, + Expm1 = 22, + Fabs = 23, + Fdim = 24, + Floor = 25, + Fma = 26, + Fmax = 27, + Fmin = 28, + Fmod = 29, + Fract = 30, + Frexp = 31, + Hypot = 32, + Ilogb = 33, + Ldexp = 34, + Lgamma = 35, + Lgamma_r = 36, + Log = 37, + Log2 = 38, + Log10 = 39, + Log1p = 40, + Logb = 41, + Mad = 42, + Maxmag = 43, + Minmag = 44, + Modf = 45, + Nan = 46, + Nextafter = 47, + Pow = 48, + Pown = 49, + Powr = 50, + Remainder = 51, + Remquo = 52, + Rint = 53, + Rootn = 54, + Round = 55, + Rsqrt = 56, + Sin = 57, + Sincos = 58, + Sinh = 59, + Sinpi = 60, + Sqrt = 61, + Tan = 62, + Tanh = 63, + Tanpi = 64, + Tgamma = 65, + Trunc = 66, + Half_cos = 67, + Half_divide = 68, + Half_exp = 69, + Half_exp2 = 70, + Half_exp10 = 71, + Half_log = 72, + Half_log2 = 73, + Half_log10 = 74, + Half_powr = 75, + Half_recip = 76, + Half_rsqrt = 77, + Half_sin = 78, + Half_sqrt = 79, + Half_tan = 80, + Native_cos = 81, + Native_divide = 82, + Native_exp = 83, + Native_exp2 = 84, + Native_exp10 = 85, + Native_log = 86, + Native_log2 = 87, + Native_log10 = 88, + Native_powr = 89, + Native_recip = 90, + Native_rsqrt = 91, + Native_sin = 92, + Native_sqrt = 93, + Native_tan = 94, + + // Section 2.2: Integer instructions + SAbs = 141, + SAbs_diff = 142, + SAdd_sat = 143, + UAdd_sat = 144, + SHadd = 145, + UHadd = 146, + SRhadd = 147, + URhadd = 148, + SClamp = 149, + UClamp = 150, + Clz = 151, + Ctz = 152, + SMad_hi = 153, + UMad_sat = 154, + SMad_sat = 155, + SMax = 156, + UMax = 157, + SMin = 158, + UMin = 159, + SMul_hi = 160, + Rotate = 161, + SSub_sat = 162, + USub_sat = 163, + U_Upsample = 164, + S_Upsample = 165, + Popcount = 166, + SMad24 = 167, + UMad24 = 168, + SMul24 = 169, + UMul24 = 170, + UAbs = 201, + UAbs_diff = 202, + UMul_hi = 203, + UMad_hi = 204, + + // Section 2.3: Common instructions + FClamp = 95, + Degrees = 96, + FMax_common = 97, + FMin_common = 98, + Mix = 99, + Radians = 100, + Step = 101, + Smoothstep = 102, + Sign = 103, + + // Section 2.4: Geometric instructions + Cross = 104, + Distance = 105, + Length = 106, + Normalize = 107, + Fast_distance = 108, + Fast_length = 109, + Fast_normalize = 110, + + // Section 2.5: Relational instructions + Bitselect = 186, + Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + Vloadn = 171, + Vstoren = 172, + Vload_half = 173, + Vload_halfn = 174, + Vstore_half = 175, + Vstore_half_r = 176, + Vstore_halfn = 177, + Vstore_halfn_r = 178, + Vloada_halfn = 179, + Vstorea_halfn = 180, + Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + Shuffle = 182, + Shuffle2 = 183, + + // Section 2.8: Misc instructions + Printf = 184, + Prefetch = 185, +}; + +} // end namespace OpenCLLIB diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/extinst.glsl.std.450.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.1/extinst.glsl.std.450.grammar.json new file mode 100644 index 000000000000..3d9f39e76c9c --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/extinst.glsl.std.450.grammar.json @@ -0,0 +1,642 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "Round", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "RoundEven", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Trunc", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FAbs", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SAbs", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FSign", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SSign", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Floor", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ceil", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fract", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Radians", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "Degrees", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "Sin", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tan", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asin", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acos", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'y_over_x'" } + ] + }, + { + "opname" : "Sinh", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cosh", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tanh", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asinh", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acosh", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atanh", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan2", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Pow", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Exp", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Exp2", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log2", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Sqrt", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "InverseSqrt", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Determinant", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "MatrixInverse", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Modf", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "ModfStruct", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FMin", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMin", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMin", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FMax", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMax", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMax", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FClamp", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "UClamp", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "SClamp", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "FMix", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "IMix", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "Step", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SmoothStep", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fma", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "Frexp", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "FrexpStruct", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ldexp", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "PackSnorm4x8", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm4x8", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackSnorm2x16", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm2x16", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackHalf2x16", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackDouble2x32", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "UnpackSnorm2x16", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm2x16", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackHalf2x16", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "UnpackSnorm4x8", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm4x8", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackDouble2x32", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "Length", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Distance", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "Cross", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Normalize", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FaceForward", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'Nref'" } + ] + }, + { + "opname" : "Reflect", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" } + ] + }, + { + "opname" : "Refract", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'eta'" } + ] + }, + { + "opname" : "FindILsb", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindSMsb", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindUMsb", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "InterpolateAtCentroid", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtSample", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'sample'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtOffset", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "NMin", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NMax", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NClamp", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/extinst.opencl.std.100.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.1/extinst.opencl.std.100.grammar.json new file mode 100644 index 000000000000..4fe45060bb98 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/extinst.opencl.std.100.grammar.json @@ -0,0 +1,1279 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "acos", + "opcode" : 0, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acosh", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acospi", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asin", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinh", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinpi", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanh", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanpi", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2pi", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cbrt", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ceil", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "copysign", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cosh", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cospi", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erfc", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erf", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp2", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp10", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "expm1", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fabs", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fdim", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "floor", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fma", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fmax", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmod", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fract", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'ptr'" } + ] + }, + { + "opname" : "frexp", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "hypot", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "ilogb", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ldexp", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'k'" } + ] + }, + { + "opname" : "lgamma", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "lgamma_r", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'signp'" } + ] + }, + { + "opname" : "log", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log2", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log10", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log1p", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "logb", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "mad", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "maxmag", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "minmag", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "modf", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'iptr'" } + ] + }, + { + "opname" : "nan", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'nancode'" } + ] + }, + { + "opname" : "nextafter", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "pow", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y" } + ] + }, + { + "opname" : "pown", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "powr", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remainder", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remquo", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'quo'" } + ] + }, + { + "opname" : "rint", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rootn", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "round", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rsqrt", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sin", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sincos", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'cosval'" } + ] + }, + { + "opname" : "sinh", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sinpi", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sqrt", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tan", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanh", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanpi", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tgamma", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "trunc", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_cos", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_divide", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_exp", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp2", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp10", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log2", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log10", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_powr", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_recip", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_rsqrt", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sin", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sqrt", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_tan", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_cos", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_divide", + "opcode" : 82, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_exp", + "opcode" : 83, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp2", + "opcode" : 84, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp10", + "opcode" : 85, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log", + "opcode" : 86, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log2", + "opcode" : 87, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log10", + "opcode" : 88, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_powr", + "opcode" : 89, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_recip", + "opcode" : 90, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_rsqrt", + "opcode" : 91, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sin", + "opcode" : 92, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sqrt", + "opcode" : 93, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_tan", + "opcode" : 94, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs", + "opcode" : 141, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs_diff", + "opcode" : 142, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_add_sat", + "opcode" : 143, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_add_sat", + "opcode" : 144, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_hadd", + "opcode" : 145, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_hadd", + "opcode" : 146, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_rhadd", + "opcode" : 147, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_rhadd", + "opcode" : 148, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_clamp", + "opcode" : 149, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "u_clamp", + "opcode" : 150, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "clz", + "opcode" : 151, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ctz", + "opcode" : 152, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad_hi", + "opcode" : 153, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "u_mad_sat", + "opcode" : 154, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mad_sat", + "opcode" : 155, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_max", + "opcode" : 156, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_max", + "opcode" : 157, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_min", + "opcode" : 158, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_min", + "opcode" : 159, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_mul_hi", + "opcode" : 160, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "rotate", + "opcode" : 161, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "s_sub_sat", + "opcode" : 162, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_sub_sat", + "opcode" : 163, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_upsample", + "opcode" : 164, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "s_upsample", + "opcode" : 165, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "popcount", + "opcode" : 166, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad24", + "opcode" : 167, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "u_mad24", + "opcode" : 168, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mul24", + "opcode" : 169, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul24", + "opcode" : 170, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_abs", + "opcode" : 201, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "u_abs_diff", + "opcode" : 202, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul_hi", + "opcode" : 203, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mad_hi", + "opcode" : 204, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fclamp", + "opcode" : 95, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "degrees", + "opcode" :96, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "fmax_common", + "opcode" : 97, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin_common", + "opcode" : 98, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "mix", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "radians", + "opcode" : 100, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "step", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "smoothstep", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sign", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cross", + "opcode" : 104, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "distance", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "length", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "normalize", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_distance", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "fast_length", + "opcode" : 109, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_normalize", + "opcode" : 110, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "bitselect", + "opcode" : 186, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "select", + "opcode" : 187, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "vloadn", + "opcode" : 171, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstoren", + "opcode" : 172, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_half", + "opcode" : 173, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_halfn", + "opcode" : 174, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstore_half", + "opcode" : 175, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_half_r", + "opcode" : 176, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vstore_halfn", + "opcode" : 177, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_halfn_r", + "opcode" : 178, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vloada_halfn", + "opcode" : 179, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstorea_halfn", + "opcode" : 180, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstorea_halfn_r", + "opcode" : 181, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "shuffle", + "opcode" : 182, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "shuffle2", + "opcode" : 183, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "printf", + "opcode" : 184, + "operands" : [ + { "kind" : "IdRef", "name" : "'format'" }, + { "kind" : "IdRef", "name" : "'additional arguments'", "quantifier" : "*" } + ] + }, + { + "opname" : "prefetch", + "opcode" : 185, + "operands" : [ + { "kind" : "IdRef", "name" : "'ptr'" }, + { "kind" : "IdRef", "name" : "'num elements'" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.core.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.core.grammar.json new file mode 100644 index 000000000000..c142e60a1750 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.core.grammar.json @@ -0,0 +1,5938 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "magic_number" : "0x07230203", + "major_version" : 1, + "minor_version" : 1, + "revision" : 8, + "instructions" : [ + { + "opname" : "OpNop", + "opcode" : 0 + }, + { + "opname" : "OpUndef", + "opcode" : 1, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSourceContinued", + "opcode" : 2, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Continued Source'" } + ] + }, + { + "opname" : "OpSource", + "opcode" : 3, + "operands" : [ + { "kind" : "SourceLanguage" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" }, + { "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" } + ] + }, + { + "opname" : "OpSourceExtension", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Extension'" } + ] + }, + { + "opname" : "OpName", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpMemberName", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpString", + "opcode" : 7, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'String'" } + ] + }, + { + "opname" : "OpLine", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "OpExtension", + "opcode" : 10, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInstImport", + "opcode" : 11, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInst", + "opcode" : 12, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ] + }, + { + "opname" : "OpMemoryModel", + "opcode" : 14, + "operands" : [ + { "kind" : "AddressingModel" }, + { "kind" : "MemoryModel" } + ] + }, + { + "opname" : "OpEntryPoint", + "opcode" : 15, + "operands" : [ + { "kind" : "ExecutionModel" }, + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } + ] + }, + { + "opname" : "OpExecutionMode", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ] + }, + { + "opname" : "OpCapability", + "opcode" : 17, + "operands" : [ + { "kind" : "Capability", "name" : "'Capability'" } + ] + }, + { + "opname" : "OpTypeVoid", + "opcode" : 19, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeBool", + "opcode" : 20, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeInt", + "opcode" : 21, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" }, + { "kind" : "LiteralInteger", "name" : "'Signedness'" } + ] + }, + { + "opname" : "OpTypeFloat", + "opcode" : 22, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" } + ] + }, + { + "opname" : "OpTypeVector", + "opcode" : 23, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "OpTypeMatrix", + "opcode" : 24, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Column Type'" }, + { "kind" : "LiteralInteger", "name" : "'Column Count'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpTypeImage", + "opcode" : 25, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Type'" }, + { "kind" : "Dim" }, + { "kind" : "LiteralInteger", "name" : "'Depth'" }, + { "kind" : "LiteralInteger", "name" : "'Arrayed'" }, + { "kind" : "LiteralInteger", "name" : "'MS'" }, + { "kind" : "LiteralInteger", "name" : "'Sampled'" }, + { "kind" : "ImageFormat" }, + { "kind" : "AccessQualifier", "quantifier" : "?" } + ] + }, + { + "opname" : "OpTypeSampler", + "opcode" : 26, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeSampledImage", + "opcode" : 27, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ] + }, + { + "opname" : "OpTypeArray", + "opcode" : 28, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" }, + { "kind" : "IdRef", "name" : "'Length'" } + ] + }, + { + "opname" : "OpTypeRuntimeArray", + "opcode" : 29, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpTypeStruct", + "opcode" : 30, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ] + }, + { + "opname" : "OpTypeOpaque", + "opcode" : 31, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "The name of the opaque type." } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypePointer", + "opcode" : 32, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "name" : "'Type'" } + ] + }, + { + "opname" : "OpTypeFunction", + "opcode" : 33, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." } + ] + }, + { + "opname" : "OpTypeEvent", + "opcode" : 34, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypeDeviceEvent", + "opcode" : 35, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypeReserveId", + "opcode" : 36, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeQueue", + "opcode" : 37, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypePipe", + "opcode" : 38, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "AccessQualifier", "name" : "'Qualifier'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeForwardPointer", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer Type'" }, + { "kind" : "StorageClass" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpConstantTrue", + "opcode" : 41, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstantFalse", + "opcode" : 42, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstant", + "opcode" : 43, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConstantComposite", + "opcode" : 44, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpConstantSampler", + "opcode" : 45, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "SamplerAddressingMode" }, + { "kind" : "LiteralInteger", "name" : "'Param'" }, + { "kind" : "SamplerFilterMode" } + ], + "capabilities" : [ "LiteralSampler" ] + }, + { + "opname" : "OpConstantNull", + "opcode" : 46, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantTrue", + "opcode" : 48, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantFalse", + "opcode" : 49, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstant", + "opcode" : 50, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpSpecConstantComposite", + "opcode" : 51, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpSpecConstantOp", + "opcode" : 52, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" } + ] + }, + { + "opname" : "OpFunction", + "opcode" : 54, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "FunctionControl" }, + { "kind" : "IdRef", "name" : "'Function Type'" } + ] + }, + { + "opname" : "OpFunctionParameter", + "opcode" : 55, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpFunctionEnd", + "opcode" : 56 + }, + { + "opname" : "OpFunctionCall", + "opcode" : 57, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." } + ] + }, + { + "opname" : "OpVariable", + "opcode" : 59, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" } + ] + }, + { + "opname" : "OpImageTexelPointer", + "opcode" : 60, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Sample'" } + ] + }, + { + "opname" : "OpLoad", + "opcode" : 61, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpStore", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemory", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemorySized", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpAccessChain", + "opcode" : 65, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpInBoundsAccessChain", + "opcode" : 66, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpPtrAccessChain", + "opcode" : 67, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ + "Addresses", + "VariablePointers", + "VariablePointersStorageBuffer" + ] + }, + { + "opname" : "OpArrayLength", + "opcode" : 68, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Structure'" }, + { "kind" : "LiteralInteger", "name" : "'Array member'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpGenericPtrMemSemantics", + "opcode" : 69, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpInBoundsPtrAccessChain", + "opcode" : 70, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpDecorate", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpMemberDecorate", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'Structure Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpDecorationGroup", + "opcode" : 73, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpGroupDecorate", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpGroupMemberDecorate", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpVectorExtractDynamic", + "opcode" : 77, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorInsertDynamic", + "opcode" : 78, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorShuffle", + "opcode" : 79, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" } + ] + }, + { + "opname" : "OpCompositeConstruct", + "opcode" : 80, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpCompositeExtract", + "opcode" : 81, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCompositeInsert", + "opcode" : 82, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCopyObject", + "opcode" : 83, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpTranspose", + "opcode" : 84, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpSampledImage", + "opcode" : 86, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ] + }, + { + "opname" : "OpImageSampleImplicitLod", + "opcode" : 87, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleExplicitLod", + "opcode" : 88, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ] + }, + { + "opname" : "OpImageSampleDrefImplicitLod", + "opcode" : 89, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleDrefExplicitLod", + "opcode" : 90, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjImplicitLod", + "opcode" : 91, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjExplicitLod", + "opcode" : 92, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefImplicitLod", + "opcode" : 93, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefExplicitLod", + "opcode" : 94, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageFetch", + "opcode" : 95, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageGather", + "opcode" : 96, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageDrefGather", + "opcode" : 97, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageRead", + "opcode" : 98, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageWrite", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Texel'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImage", + "opcode" : 100, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" } + ] + }, + { + "opname" : "OpImageQueryFormat", + "opcode" : 101, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQueryOrder", + "opcode" : 102, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQuerySizeLod", + "opcode" : 103, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Level of Detail'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySize", + "opcode" : 104, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLod", + "opcode" : 105, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLevels", + "opcode" : 106, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySamples", + "opcode" : 107, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpConvertFToU", + "opcode" : 109, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertFToS", + "opcode" : 110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertSToF", + "opcode" : 111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpConvertUToF", + "opcode" : 112, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpUConvert", + "opcode" : 113, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpSConvert", + "opcode" : 114, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpFConvert", + "opcode" : 115, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpQuantizeToF16", + "opcode" : 116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConvertPtrToU", + "opcode" : 117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpSatConvertSToU", + "opcode" : 118, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSatConvertUToS", + "opcode" : 119, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpConvertUToPtr", + "opcode" : 120, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Integer Value'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpPtrCastToGeneric", + "opcode" : 121, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtr", + "opcode" : 122, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtrExplicit", + "opcode" : 123, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "StorageClass", "name" : "'Storage'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpBitcast", + "opcode" : 124, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSNegate", + "opcode" : 126, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpFNegate", + "opcode" : 127, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpIAdd", + "opcode" : 128, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFAdd", + "opcode" : 129, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISub", + "opcode" : 130, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFSub", + "opcode" : 131, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpIMul", + "opcode" : 132, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMul", + "opcode" : 133, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUDiv", + "opcode" : 134, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSDiv", + "opcode" : 135, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFDiv", + "opcode" : 136, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMod", + "opcode" : 137, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSRem", + "opcode" : 138, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMod", + "opcode" : 139, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFRem", + "opcode" : 140, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMod", + "opcode" : 141, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpVectorTimesScalar", + "opcode" : 142, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ] + }, + { + "opname" : "OpMatrixTimesScalar", + "opcode" : 143, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpVectorTimesMatrix", + "opcode" : 144, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesVector", + "opcode" : 145, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesMatrix", + "opcode" : 146, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'LeftMatrix'" }, + { "kind" : "IdRef", "name" : "'RightMatrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpOuterProduct", + "opcode" : 147, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpDot", + "opcode" : 148, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ] + }, + { + "opname" : "OpIAddCarry", + "opcode" : 149, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISubBorrow", + "opcode" : 150, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMulExtended", + "opcode" : 151, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMulExtended", + "opcode" : 152, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpAny", + "opcode" : 154, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpAll", + "opcode" : 155, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpIsNan", + "opcode" : 156, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsInf", + "opcode" : 157, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsFinite", + "opcode" : 158, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpIsNormal", + "opcode" : 159, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSignBitSet", + "opcode" : 160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLessOrGreater", + "opcode" : 161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpOrdered", + "opcode" : 162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpUnordered", + "opcode" : 163, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLogicalEqual", + "opcode" : 164, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNotEqual", + "opcode" : 165, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalOr", + "opcode" : 166, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalAnd", + "opcode" : 167, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNot", + "opcode" : 168, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSelect", + "opcode" : 169, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'Object 1'" }, + { "kind" : "IdRef", "name" : "'Object 2'" } + ] + }, + { + "opname" : "OpIEqual", + "opcode" : 170, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpINotEqual", + "opcode" : 171, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThan", + "opcode" : 172, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThan", + "opcode" : 173, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThanEqual", + "opcode" : 174, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThanEqual", + "opcode" : 175, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThan", + "opcode" : 176, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThan", + "opcode" : 177, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThanEqual", + "opcode" : 178, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThanEqual", + "opcode" : 179, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdEqual", + "opcode" : 180, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordEqual", + "opcode" : 181, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdNotEqual", + "opcode" : 182, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordNotEqual", + "opcode" : 183, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThan", + "opcode" : 184, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThan", + "opcode" : 185, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThan", + "opcode" : 186, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThan", + "opcode" : 187, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThanEqual", + "opcode" : 188, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThanEqual", + "opcode" : 189, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThanEqual", + "opcode" : 190, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThanEqual", + "opcode" : 191, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpShiftRightLogical", + "opcode" : 194, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftRightArithmetic", + "opcode" : 195, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftLeftLogical", + "opcode" : 196, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpBitwiseOr", + "opcode" : 197, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseXor", + "opcode" : 198, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseAnd", + "opcode" : 199, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpNot", + "opcode" : 200, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpBitFieldInsert", + "opcode" : 201, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Insert'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldSExtract", + "opcode" : 202, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldUExtract", + "opcode" : 203, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitReverse", + "opcode" : 204, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitCount", + "opcode" : 205, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ] + }, + { + "opname" : "OpDPdx", + "opcode" : 207, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdy", + "opcode" : 208, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpFwidth", + "opcode" : 209, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdxFine", + "opcode" : 210, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyFine", + "opcode" : 211, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthFine", + "opcode" : 212, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdxCoarse", + "opcode" : 213, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyCoarse", + "opcode" : 214, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthCoarse", + "opcode" : 215, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpEmitVertex", + "opcode" : 218, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEndPrimitive", + "opcode" : 219, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEmitStreamVertex", + "opcode" : 220, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpEndStreamPrimitive", + "opcode" : 221, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpControlBarrier", + "opcode" : 224, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpMemoryBarrier", + "opcode" : 225, + "operands" : [ + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicLoad", + "opcode" : 227, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicStore", + "opcode" : 228, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicExchange", + "opcode" : 229, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicCompareExchange", + "opcode" : 230, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ] + }, + { + "opname" : "OpAtomicCompareExchangeWeak", + "opcode" : 231, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicIIncrement", + "opcode" : 232, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIDecrement", + "opcode" : 233, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIAdd", + "opcode" : 234, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicISub", + "opcode" : 235, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMin", + "opcode" : 236, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMin", + "opcode" : 237, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMax", + "opcode" : 238, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMax", + "opcode" : 239, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicAnd", + "opcode" : 240, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicOr", + "opcode" : 241, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicXor", + "opcode" : 242, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpPhi", + "opcode" : 245, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" } + ] + }, + { + "opname" : "OpLoopMerge", + "opcode" : 246, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "IdRef", "name" : "'Continue Target'" }, + { "kind" : "LoopControl" } + ] + }, + { + "opname" : "OpSelectionMerge", + "opcode" : 247, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "SelectionControl" } + ] + }, + { + "opname" : "OpLabel", + "opcode" : 248, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpBranch", + "opcode" : 249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target Label'" } + ] + }, + { + "opname" : "OpBranchConditional", + "opcode" : 250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'True Label'" }, + { "kind" : "IdRef", "name" : "'False Label'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" } + ] + }, + { + "opname" : "OpSwitch", + "opcode" : 251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Selector'" }, + { "kind" : "IdRef", "name" : "'Default'" }, + { "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" } + ] + }, + { + "opname" : "OpKill", + "opcode" : 252, + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpReturn", + "opcode" : 253 + }, + { + "opname" : "OpReturnValue", + "opcode" : 254, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpUnreachable", + "opcode" : 255 + }, + { + "opname" : "OpLifetimeStart", + "opcode" : 256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLifetimeStop", + "opcode" : 257, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAsyncCopy", + "opcode" : 259, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Destination'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Num Elements'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupWaitEvents", + "opcode" : 260, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Events List'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAll", + "opcode" : 261, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupAny", + "opcode" : 262, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupBroadcast", + "opcode" : 263, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'LocalId'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupIAdd", + "opcode" : 264, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAdd", + "opcode" : 265, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMin", + "opcode" : 266, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMin", + "opcode" : 267, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMin", + "opcode" : 268, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMax", + "opcode" : 269, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMax", + "opcode" : 270, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMax", + "opcode" : 271, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpReadPipe", + "opcode" : 274, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpWritePipe", + "opcode" : 275, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedReadPipe", + "opcode" : 276, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedWritePipe", + "opcode" : 277, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveReadPipePackets", + "opcode" : 278, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveWritePipePackets", + "opcode" : 279, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitReadPipe", + "opcode" : 280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitWritePipe", + "opcode" : 281, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpIsValidReserveId", + "opcode" : 282, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetNumPipePackets", + "opcode" : 283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetMaxPipePackets", + "opcode" : 284, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveReadPipePackets", + "opcode" : 285, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveWritePipePackets", + "opcode" : 286, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitReadPipe", + "opcode" : 287, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitWritePipe", + "opcode" : 288, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpEnqueueMarker", + "opcode" : 291, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpEnqueueKernel", + "opcode" : 292, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeSubGroupCount", + "opcode" : 293, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeMaxSubGroupSize", + "opcode" : 294, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelWorkGroupSize", + "opcode" : 295, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelPreferredWorkGroupSizeMultiple", + "opcode" : 296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpRetainEvent", + "opcode" : 297, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpReleaseEvent", + "opcode" : 298, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCreateUserEvent", + "opcode" : 299, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpIsValidEvent", + "opcode" : 300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpSetUserEventStatus", + "opcode" : 301, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Status'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCaptureEventProfilingInfo", + "opcode" : 302, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Profiling Info'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetDefaultQueue", + "opcode" : 303, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpBuildNDRange", + "opcode" : 304, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'GlobalWorkSize'" }, + { "kind" : "IdRef", "name" : "'LocalWorkSize'" }, + { "kind" : "IdRef", "name" : "'GlobalWorkOffset'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpImageSparseSampleImplicitLod", + "opcode" : 305, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleExplicitLod", + "opcode" : 306, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefImplicitLod", + "opcode" : 307, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefExplicitLod", + "opcode" : 308, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjImplicitLod", + "opcode" : 309, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjExplicitLod", + "opcode" : 310, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefImplicitLod", + "opcode" : 311, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefExplicitLod", + "opcode" : 312, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseFetch", + "opcode" : 313, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseGather", + "opcode" : 314, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseDrefGather", + "opcode" : 315, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseTexelsResident", + "opcode" : 316, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Resident Code'" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpNoLine", + "opcode" : 317 + }, + { + "opname" : "OpAtomicFlagTestAndSet", + "opcode" : 318, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicFlagClear", + "opcode" : 319, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageSparseRead", + "opcode" : 320, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpSizeOf", + "opcode" : 321, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpTypePipeStorage", + "opcode" : 322, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpConstantPipeStorage", + "opcode" : 323, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Packet Size'" }, + { "kind" : "LiteralInteger", "name" : "'Packet Alignment'" }, + { "kind" : "LiteralInteger", "name" : "'Capacity'" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpCreatePipeFromPipeStorage", + "opcode" : 324, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe Storage'" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpGetKernelLocalSizeForSubgroupCount", + "opcode" : 325, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ] + }, + { + "opname" : "OpGetKernelMaxNumSubgroups", + "opcode" : 326, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ] + }, + { + "opname" : "OpTypeNamedBarrier", + "opcode" : 327, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpNamedBarrierInitialize", + "opcode" : 328, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpMemoryNamedBarrier", + "opcode" : 329, + "operands" : [ + { "kind" : "IdRef", "name" : "'Named Barrier'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpModuleProcessed", + "opcode" : 330, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Process'" } + ] + }, + { + "opname" : "OpDecorateId", + "opcode" : 332, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "opname" : "OpSubgroupBallotKHR", + "opcode" : 4421, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupFirstInvocationKHR", + "opcode" : 4422, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupAllKHR", + "opcode" : 4428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAnyKHR", + "opcode" : 4429, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAllEqualKHR", + "opcode" : 4430, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupReadInvocationKHR", + "opcode" : 4432, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpGroupIAddNonUniformAMD", + "opcode" : 5000, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAddNonUniformAMD", + "opcode" : 5001, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMinNonUniformAMD", + "opcode" : 5002, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMinNonUniformAMD", + "opcode" : 5003, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMinNonUniformAMD", + "opcode" : 5004, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMaxNonUniformAMD", + "opcode" : 5005, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMaxNonUniformAMD", + "opcode" : 5006, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMaxNonUniformAMD", + "opcode" : 5007, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpFragmentMaskFetchAMD", + "opcode" : 5011, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpFragmentFetchAMD", + "opcode" : 5012, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Fragment Index'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpSubgroupShuffleINTEL", + "opcode" : 5571, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'InvocationId'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleDownINTEL", + "opcode" : 5572, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Next'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleUpINTEL", + "opcode" : 5573, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Previous'" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleXorINTEL", + "opcode" : 5574, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupBlockReadINTEL", + "opcode" : 5575, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupBlockWriteINTEL", + "opcode" : 5576, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockReadINTEL", + "opcode" : 5577, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockWriteINTEL", + "opcode" : 5578, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpDecorateStringGOOGLE", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + }, + { + "opname" : "OpMemberDecorateStringGOOGLE", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "ImageOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Bias", + "value" : "0x0001", + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Lod", + "value" : "0x0002", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Grad", + "value" : "0x0004", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffset", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Offset", + "value" : "0x0010", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffsets", + "value" : "0x0020", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Sample", + "value" : "0x0040", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "MinLod", + "value" : "0x0080", + "capabilities" : [ "MinLod" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FPFastMathMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "NotNaN", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NotInf", + "value" : "0x0002", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NSZ", + "value" : "0x0004", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AllowRecip", + "value" : "0x0008", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Fast", + "value" : "0x0010", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "SelectionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Flatten", + "value" : "0x0001" + }, + { + "enumerant" : "DontFlatten", + "value" : "0x0002" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "LoopControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Unroll", + "value" : "0x0001" + }, + { + "enumerant" : "DontUnroll", + "value" : "0x0002" + }, + { + "enumerant" : "DependencyInfinite", + "value" : "0x0004" + }, + { + "enumerant" : "DependencyLength", + "value" : "0x0008", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FunctionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Inline", + "value" : "0x0001" + }, + { + "enumerant" : "DontInline", + "value" : "0x0002" + }, + { + "enumerant" : "Pure", + "value" : "0x0004" + }, + { + "enumerant" : "Const", + "value" : "0x0008" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemorySemantics", + "enumerants" : [ + { + "enumerant" : "Relaxed", + "value" : "0x0000" + }, + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Acquire", + "value" : "0x0002" + }, + { + "enumerant" : "Release", + "value" : "0x0004" + }, + { + "enumerant" : "AcquireRelease", + "value" : "0x0008" + }, + { + "enumerant" : "SequentiallyConsistent", + "value" : "0x0010" + }, + { + "enumerant" : "UniformMemory", + "value" : "0x0040", + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupMemory", + "value" : "0x0080" + }, + { + "enumerant" : "WorkgroupMemory", + "value" : "0x0100" + }, + { + "enumerant" : "CrossWorkgroupMemory", + "value" : "0x0200" + }, + { + "enumerant" : "AtomicCounterMemory", + "value" : "0x0400", + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "ImageMemory", + "value" : "0x0800" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemoryAccess", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Volatile", + "value" : "0x0001" + }, + { + "enumerant" : "Aligned", + "value" : "0x0002", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Nontemporal", + "value" : "0x0004" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "KernelProfilingInfo", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "CmdExecTime", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SourceLanguage", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "ESSL", + "value" : 1 + }, + { + "enumerant" : "GLSL", + "value" : 2 + }, + { + "enumerant" : "OpenCL_C", + "value" : 3 + }, + { + "enumerant" : "OpenCL_CPP", + "value" : 4 + }, + { + "enumerant" : "HLSL", + "value" : 5 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionModel", + "enumerants" : [ + { + "enumerant" : "Vertex", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TessellationControl", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessellationEvaluation", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Geometry", + "value" : 3, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Fragment", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLCompute", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Kernel", + "value" : 6, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AddressingModel", + "enumerants" : [ + { + "enumerant" : "Logical", + "value" : 0 + }, + { + "enumerant" : "Physical32", + "value" : 1, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Physical64", + "value" : 2, + "capabilities" : [ "Addresses" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "MemoryModel", + "enumerants" : [ + { + "enumerant" : "Simple", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSL450", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OpenCL", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionMode", + "enumerants" : [ + { + "enumerant" : "Invocations", + "value" : 0, + "capabilities" : [ "Geometry" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of <>'" } + ] + }, + { + "enumerant" : "SpacingEqual", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalEven", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalOdd", + "value" : 3, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCw", + "value" : 4, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCcw", + "value" : 5, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PixelCenterInteger", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginUpperLeft", + "value" : 7, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginLowerLeft", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "EarlyFragmentTests", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointMode", + "value" : 10, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Xfb", + "value" : 11, + "capabilities" : [ "TransformFeedback" ] + }, + { + "enumerant" : "DepthReplacing", + "value" : 12, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthGreater", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthLess", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthUnchanged", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "LocalSize", + "value" : 17, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "LocalSizeHint", + "value" : 18, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "InputPoints", + "value" : 19, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLines", + "value" : 20, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLinesAdjacency", + "value" : 21, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Triangles", + "value" : 22, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InputTrianglesAdjacency", + "value" : 23, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Quads", + "value" : 24, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Isolines", + "value" : 25, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "OutputVertices", + "value" : 26, + "capabilities" : [ "Geometry", "Tessellation" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vertex count'" } + ] + }, + { + "enumerant" : "OutputPoints", + "value" : 27, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputLineStrip", + "value" : 28, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputTriangleStrip", + "value" : 29, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "VecTypeHint", + "value" : 30, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vector type'" } + ] + }, + { + "enumerant" : "ContractionOff", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Initializer", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Finalizer", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 35, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroup Size'" } + ] + }, + { + "enumerant" : "SubgroupsPerWorkgroup", + "value" : 36, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroups Per Workgroup'" } + ] + }, + { + "enumerant" : "PostDepthCoverage", + "value" : 4446, + "capabilities" : [ "SampleMaskPostDepthCoverage" ] + }, + { + "enumerant" : "StencilRefReplacingEXT", + "value" : 5027, + "capabilities" : [ "StencilExportEXT" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StorageClass", + "enumerants" : [ + { + "enumerant" : "UniformConstant", + "value" : 0 + }, + { + "enumerant" : "Input", + "value" : 1 + }, + { + "enumerant" : "Uniform", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Output", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Workgroup", + "value" : 4 + }, + { + "enumerant" : "CrossWorkgroup", + "value" : 5 + }, + { + "enumerant" : "Private", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Function", + "value" : 7 + }, + { + "enumerant" : "Generic", + "value" : 8, + "capabilities" : [ "GenericPointer" ] + }, + { + "enumerant" : "PushConstant", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "AtomicCounter", + "value" : 10, + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "Image", + "value" : 11 + }, + { + "enumerant" : "StorageBuffer", + "value" : 12, + "extensions" : [ + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers" + ], + "capabilities" : [ "Shader" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Dim", + "enumerants" : [ + { + "enumerant" : "1D", + "value" : 0, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "2D", + "value" : 1 + }, + { + "enumerant" : "3D", + "value" : 2 + }, + { + "enumerant" : "Cube", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rect", + "value" : 4, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "Buffer", + "value" : 5, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "SubpassData", + "value" : 6, + "capabilities" : [ "InputAttachment" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerAddressingMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ClampToEdge", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Clamp", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Repeat", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RepeatMirrored", + "value" : 4, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerFilterMode", + "enumerants" : [ + { + "enumerant" : "Nearest", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Linear", + "value" : 1, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageFormat", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "Rgba32f", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16f", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32f", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8Snorm", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32f", + "value" : 6, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16f", + "value" : 7, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R11fG11fB10f", + "value" : 8, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16f", + "value" : 9, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16", + "value" : 10, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgb10A2", + "value" : 11, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16", + "value" : 12, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8", + "value" : 13, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16", + "value" : 14, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8", + "value" : 15, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16Snorm", + "value" : 16, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16Snorm", + "value" : 17, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8Snorm", + "value" : 18, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16Snorm", + "value" : 19, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8Snorm", + "value" : 20, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32i", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16i", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8i", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32i", + "value" : 24, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32i", + "value" : 25, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16i", + "value" : 26, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8i", + "value" : 27, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16i", + "value" : 28, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8i", + "value" : 29, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32ui", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16ui", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8ui", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32ui", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgb10a2ui", + "value" : 34, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg32ui", + "value" : 35, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16ui", + "value" : 36, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8ui", + "value" : 37, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16ui", + "value" : 38, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8ui", + "value" : 39, + "capabilities" : [ "StorageImageExtendedFormats" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelOrder", + "enumerants" : [ + { + "enumerant" : "R", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "A", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RG", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RA", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGB", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBA", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BGRA", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ARGB", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Intensity", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Luminance", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Rx", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGx", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBx", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Depth", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "DepthStencil", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGB", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBx", + "value" : 16, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBA", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sBGRA", + "value" : 18, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ABGR", + "value" : 19, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelDataType", + "enumerants" : [ + { + "enumerant" : "SnormInt8", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SnormInt16", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt8", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt16", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort565", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort555", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt8", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt16", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt32", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt8", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt16", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt32", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "HalfFloat", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt24", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010_2", + "value" : 16, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPRoundingMode", + "enumerants" : [ + { + "enumerant" : "RTE", + "value" : 0, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTZ", + "value" : 1, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTP", + "value" : 2, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTN", + "value" : 3, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LinkageType", + "enumerants" : [ + { + "enumerant" : "Export", + "value" : 0, + "capabilities" : [ "Linkage" ] + }, + { + "enumerant" : "Import", + "value" : 1, + "capabilities" : [ "Linkage" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AccessQualifier", + "enumerants" : [ + { + "enumerant" : "ReadOnly", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WriteOnly", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ReadWrite", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FunctionParameterAttribute", + "enumerants" : [ + { + "enumerant" : "Zext", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sext", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ByVal", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sret", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoAlias", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoCapture", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoWrite", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoReadWrite", + "value" : 7, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Decoration", + "enumerants" : [ + { + "enumerant" : "RelaxedPrecision", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SpecId", + "value" : 1, + "capabilities" : [ "Shader", "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" } + ] + }, + { + "enumerant" : "Block", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "BufferBlock", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "RowMajor", + "value" : 4, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ColMajor", + "value" : 5, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ArrayStride", + "value" : 6, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Array Stride'" } + ] + }, + { + "enumerant" : "MatrixStride", + "value" : 7, + "capabilities" : [ "Matrix" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Matrix Stride'" } + ] + }, + { + "enumerant" : "GLSLShared", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSLPacked", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CPacked", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BuiltIn", + "value" : 11, + "parameters" : [ + { "kind" : "BuiltIn" } + ] + }, + { + "enumerant" : "NoPerspective", + "value" : 13, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Flat", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Patch", + "value" : 15, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Centroid", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sample", + "value" : 17, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "Invariant", + "value" : 18, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Restrict", + "value" : 19 + }, + { + "enumerant" : "Aliased", + "value" : 20 + }, + { + "enumerant" : "Volatile", + "value" : 21 + }, + { + "enumerant" : "Constant", + "value" : 22, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Coherent", + "value" : 23 + }, + { + "enumerant" : "NonWritable", + "value" : 24 + }, + { + "enumerant" : "NonReadable", + "value" : 25 + }, + { + "enumerant" : "Uniform", + "value" : 26, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SaturatedConversion", + "value" : 28, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Stream", + "value" : 29, + "capabilities" : [ "GeometryStreams" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stream Number'" } + ] + }, + { + "enumerant" : "Location", + "value" : 30, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Location'" } + ] + }, + { + "enumerant" : "Component", + "value" : 31, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Component'" } + ] + }, + { + "enumerant" : "Index", + "value" : 32, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Index'" } + ] + }, + { + "enumerant" : "Binding", + "value" : 33, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Binding Point'" } + ] + }, + { + "enumerant" : "DescriptorSet", + "value" : 34, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Descriptor Set'" } + ] + }, + { + "enumerant" : "Offset", + "value" : 35, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Byte Offset'" } + ] + }, + { + "enumerant" : "XfbBuffer", + "value" : 36, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" } + ] + }, + { + "enumerant" : "XfbStride", + "value" : 37, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Stride'" } + ] + }, + { + "enumerant" : "FuncParamAttr", + "value" : 38, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" } + ] + }, + { + "enumerant" : "FPRoundingMode", + "value" : 39, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ], + "parameters" : [ + { "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" } + ] + }, + { + "enumerant" : "FPFastMathMode", + "value" : 40, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" } + ] + }, + { + "enumerant" : "LinkageAttributes", + "value" : 41, + "capabilities" : [ "Linkage" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "LinkageType", "name" : "'Linkage Type'" } + ] + }, + { + "enumerant" : "NoContraction", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InputAttachmentIndex", + "value" : 43, + "capabilities" : [ "InputAttachment" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Attachment Index'" } + ] + }, + { + "enumerant" : "Alignment", + "value" : 44, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Alignment'" } + ] + }, + { + "enumerant" : "MaxByteOffset", + "value" : 45, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Max Byte Offset'" } + ] + }, + { + "enumerant" : "ExplicitInterpAMD", + "value" : 4999 + }, + { + "enumerant" : "OverrideCoverageNV", + "value" : 5248, + "capabilities" : [ "SampleMaskOverrideCoverageNV" ] + }, + { + "enumerant" : "PassthroughNV", + "value" : 5250, + "capabilities" : [ "GeometryShaderPassthroughNV" ] + }, + { + "enumerant" : "ViewportRelativeNV", + "value" : 5252, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryViewportRelativeNV", + "value" : 5256, + "capabilities" : [ "ShaderStereoViewNV" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ] + }, + { + "enumerant" : "HlslCounterBufferGOOGLE", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "enumerant" : "HlslSemanticGOOGLE", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "BuiltIn", + "enumerants" : [ + { + "enumerant" : "Position", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointSize", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 3, + "capabilities" : [ "ClipDistance" ] + }, + { + "enumerant" : "CullDistance", + "value" : 4, + "capabilities" : [ "CullDistance" ] + }, + { + "enumerant" : "VertexId", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceId", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PrimitiveId", + "value" : 7, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InvocationId", + "value" : 8, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "Layer", + "value" : 9, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ViewportIndex", + "value" : 10, + "capabilities" : [ "MultiViewport" ] + }, + { + "enumerant" : "TessLevelOuter", + "value" : 11, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessLevelInner", + "value" : 12, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessCoord", + "value" : 13, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PatchVertices", + "value" : 14, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "FragCoord", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointCoord", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FrontFacing", + "value" : 17, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampleId", + "value" : 18, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SamplePosition", + "value" : 19, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SampleMask", + "value" : 20, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FragDepth", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "HelperInvocation", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "NumWorkgroups", + "value" : 24 + }, + { + "enumerant" : "WorkgroupSize", + "value" : 25 + }, + { + "enumerant" : "WorkgroupId", + "value" : 26 + }, + { + "enumerant" : "LocalInvocationId", + "value" : 27 + }, + { + "enumerant" : "GlobalInvocationId", + "value" : 28 + }, + { + "enumerant" : "LocalInvocationIndex", + "value" : 29 + }, + { + "enumerant" : "WorkDim", + "value" : 30, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalSize", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "EnqueuedWorkgroupSize", + "value" : 32, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalOffset", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalLinearId", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 36, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupMaxSize", + "value" : 37, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumSubgroups", + "value" : 38, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumEnqueuedSubgroups", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupId", + "value" : 40, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupLocalInvocationId", + "value" : 41, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "VertexIndex", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceIndex", + "value" : 43, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupEqMaskKHR", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGeMaskKHR", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGtMaskKHR", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLeMaskKHR", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLtMaskKHR", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "BaseVertex", + "value" : 4424, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "BaseInstance", + "value" : 4425, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DrawIndex", + "value" : 4426, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DeviceIndex", + "value" : 4438, + "capabilities" : [ "DeviceGroup" ] + }, + { + "enumerant" : "ViewIndex", + "value" : 4440, + "capabilities" : [ "MultiView" ] + }, + { + "enumerant" : "BaryCoordNoPerspAMD", + "value" : 4992 + }, + { + "enumerant" : "BaryCoordNoPerspCentroidAMD", + "value" : 4993 + }, + { + "enumerant" : "BaryCoordNoPerspSampleAMD", + "value" : 4994 + }, + { + "enumerant" : "BaryCoordSmoothAMD", + "value" : 4995 + }, + { + "enumerant" : "BaryCoordSmoothCentroidAMD", + "value" : 4996 + }, + { + "enumerant" : "BaryCoordSmoothSampleAMD", + "value" : 4997 + }, + { + "enumerant" : "BaryCoordPullModelAMD", + "value" : 4998 + }, + { + "enumerant" : "FragStencilRefEXT", + "value" : 5014, + "capabilities" : [ "StencilExportEXT" ] + }, + { + "enumerant" : "ViewportMaskNV", + "value" : 5253, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryPositionNV", + "value" : 5257, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "SecondaryViewportMaskNV", + "value" : 5258, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "PositionPerViewNV", + "value" : 5261, + "capabilities" : [ "PerViewAttributesNV" ] + }, + { + "enumerant" : "ViewportMaskPerViewNV", + "value" : 5262, + "capabilities" : [ "PerViewAttributesNV" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Scope", + "enumerants" : [ + { + "enumerant" : "CrossDevice", + "value" : 0 + }, + { + "enumerant" : "Device", + "value" : 1 + }, + { + "enumerant" : "Workgroup", + "value" : 2 + }, + { + "enumerant" : "Subgroup", + "value" : 3 + }, + { + "enumerant" : "Invocation", + "value" : 4 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "GroupOperation", + "enumerants" : [ + { + "enumerant" : "Reduce", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InclusiveScan", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ExclusiveScan", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "KernelEnqueueFlags", + "enumerants" : [ + { + "enumerant" : "NoWait", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitKernel", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitWorkGroup", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Capability", + "enumerants" : [ + { + "enumerant" : "Matrix", + "value" : 0 + }, + { + "enumerant" : "Shader", + "value" : 1, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "Geometry", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Tessellation", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Addresses", + "value" : 4 + }, + { + "enumerant" : "Linkage", + "value" : 5 + }, + { + "enumerant" : "Kernel", + "value" : 6 + }, + { + "enumerant" : "Vector16", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16Buffer", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16", + "value" : 9 + }, + { + "enumerant" : "Float64", + "value" : 10 + }, + { + "enumerant" : "Int64", + "value" : 11 + }, + { + "enumerant" : "Int64Atomics", + "value" : 12, + "capabilities" : [ "Int64" ] + }, + { + "enumerant" : "ImageBasic", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ImageReadWrite", + "value" : 14, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "ImageMipmap", + "value" : 15, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "Pipes", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Groups", + "value" : 18 + }, + { + "enumerant" : "DeviceEnqueue", + "value" : 19, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "LiteralSampler", + "value" : 20, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AtomicStorage", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Int16", + "value" : 22 + }, + { + "enumerant" : "TessellationPointSize", + "value" : 23, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "GeometryPointSize", + "value" : 24, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ImageGatherExtended", + "value" : 25, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageMultisample", + "value" : 27, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "UniformBufferArrayDynamicIndexing", + "value" : 28, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledImageArrayDynamicIndexing", + "value" : 29, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageBufferArrayDynamicIndexing", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageArrayDynamicIndexing", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CullDistance", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageCubeArray", + "value" : 34, + "capabilities" : [ "SampledCubeArray" ] + }, + { + "enumerant" : "SampleRateShading", + "value" : 35, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageRect", + "value" : 36, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "SampledRect", + "value" : 37, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GenericPointer", + "value" : 38, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Int8", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InputAttachment", + "value" : 40, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SparseResidency", + "value" : 41, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MinLod", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sampled1D", + "value" : 43 + }, + { + "enumerant" : "Image1D", + "value" : 44, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "SampledCubeArray", + "value" : 45, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledBuffer", + "value" : 46 + }, + { + "enumerant" : "ImageBuffer", + "value" : 47, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "ImageMSArray", + "value" : 48, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageExtendedFormats", + "value" : 49, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageQuery", + "value" : 50, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DerivativeControl", + "value" : 51, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InterpolationFunction", + "value" : 52, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TransformFeedback", + "value" : 53, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GeometryStreams", + "value" : 54, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "StorageImageReadWithoutFormat", + "value" : 55, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageWriteWithoutFormat", + "value" : 56, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MultiViewport", + "value" : 57, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "SubgroupDispatch", + "value" : 58, + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "enumerant" : "NamedBarrier", + "value" : 59, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "PipeStorage", + "value" : 60, + "capabilities" : [ "Pipes" ] + }, + { + "enumerant" : "SubgroupBallotKHR", + "value" : 4423, + "extensions" : [ "SPV_KHR_shader_ballot" ] + }, + { + "enumerant" : "DrawParameters", + "value" : 4427, + "extensions" : [ "SPV_KHR_shader_draw_parameters" ] + }, + { + "enumerant" : "SubgroupVoteKHR", + "value" : 4431, + "extensions" : [ "SPV_KHR_subgroup_vote" ] + }, + { + "enumerant" : "StorageBuffer16BitAccess", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniformBufferBlock16", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "UniformAndStorageBuffer16BitAccess", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniform16", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StoragePushConstant16", + "value" : 4435, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageInputOutput16", + "value" : 4436, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "DeviceGroup", + "value" : 4437, + "extensions" : [ "SPV_KHR_device_group" ] + }, + { + "enumerant" : "MultiView", + "value" : 4439, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_multiview" ] + }, + { + "enumerant" : "VariablePointersStorageBuffer", + "value" : 4441, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant" : "VariablePointers", + "value" : 4442, + "capabilities" : [ "VariablePointersStorageBuffer" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant": "AtomicStorageOps", + "value": 4445, + "extensions": [ "SPV_KHR_shader_atomic_counter_ops" ] + }, + { + "enumerant" : "SampleMaskPostDepthCoverage", + "value" : 4447, + "extensions" : [ "SPV_KHR_post_depth_coverage" ] + }, + { + "enumerant" : "ImageGatherBiasLodAMD", + "value" : 5009, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_texture_gather_bias_lod" ] + }, + { + "enumerant" : "FragmentMaskAMD", + "value" : 5010, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ] + }, + { + "enumerant" : "StencilExportEXT", + "value" : 5013, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ] + }, + { + "enumerant" : "ImageReadWriteLodAMD", + "value" : 5015, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_image_load_store_lod" ] + }, + { + "enumerant" : "SampleMaskOverrideCoverageNV", + "value" : 5249, + "capabilities" : [ "SampleRateShading" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ] + }, + { + "enumerant" : "GeometryShaderPassthroughNV", + "value" : 5251, + "capabilities" : [ "Geometry" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerEXT", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_EXT_shader_viewport_index_layer" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerNV", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderViewportMaskNV", + "value" : 5255, + "capabilities" : [ "ShaderViewportIndexLayerNV" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderStereoViewNV", + "value" : 5259, + "capabilities" : [ "ShaderViewportMaskNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ] + }, + { + "enumerant" : "PerViewAttributesNV", + "value" : 5260, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes" ] + }, + { + "enumerant" : "SubgroupShuffleINTEL", + "value" : 5568, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupBufferBlockIOINTEL", + "value" : 5569, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupImageBlockIOINTEL", + "value" : 5570, + "extensions" : [ "SPV_INTEL_subgroups" ] + } + ] + }, + { + "category" : "Id", + "kind" : "IdResultType", + "doc" : "Reference to an representing the result's type of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdResult", + "doc" : "Definition of an representing the result of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdMemorySemantics", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the MemorySemantics operand kind" + }, + { + "category" : "Id", + "kind" : "IdScope", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the Scope operand kind" + }, + { + "category" : "Id", + "kind" : "IdRef", + "doc" : "Reference to an " + }, + { + "category" : "Literal", + "kind" : "LiteralInteger", + "doc" : "An integer consuming one or more words" + }, + { + "category" : "Literal", + "kind" : "LiteralString", + "doc" : "A null-terminated stream of characters consuming an integral number of words" + }, + { + "category" : "Literal", + "kind" : "LiteralContextDependentNumber", + "doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction" + }, + { + "category" : "Literal", + "kind" : "LiteralExtInstInteger", + "doc" : "A 32-bit unsigned integer indicating which instruction to use and determining the layout of following operands (for OpExtInst)" + }, + { + "category" : "Literal", + "kind" : "LiteralSpecConstantOpInteger", + "doc" : "An opcode indicating the operation to be performed and determining the layout of following operands (for OpSpecConstantOp)" + }, + { + "category" : "Composite", + "kind" : "PairLiteralIntegerIdRef", + "bases" : [ "LiteralInteger", "IdRef" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefLiteralInteger", + "bases" : [ "IdRef", "LiteralInteger" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefIdRef", + "bases" : [ "IdRef", "IdRef" ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.cs b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.cs new file mode 100644 index 000000000000..99194e514503 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.cs @@ -0,0 +1,1015 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C# +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + + public static class Specification + { + public const uint MagicNumber = 0x07230203; + public const uint Version = 0x00010100; + public const uint Revision = 8; + public const uint OpCodeMask = 0xffff; + public const uint WordCountShift = 16; + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + } + + public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + } + + public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + } + + public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + } + + public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + } + + public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + } + + public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + } + + public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + } + + public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + } + + public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + } + + public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + } + + public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + } + + public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + } + + public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + } + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.h b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.h new file mode 100644 index 000000000000..971c3be6d25d --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.h @@ -0,0 +1,1015 @@ +/* +** Copyright (c) 2014-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10100 +#define SPV_REVISION 8 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010100; +static const unsigned int SpvRevision = 8; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModeInitializer = 33, + SpvExecutionModeFinalizer = 34, + SpvExecutionModeSubgroupSize = 35, + SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationMaxByteOffset = 45, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlDependencyInfiniteShift = 2, + SpvLoopControlDependencyLengthShift = 3, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, + SpvLoopControlDependencyInfiniteMask = 0x00000004, + SpvLoopControlDependencyLengthMask = 0x00000008, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupDispatch = 58, + SpvCapabilityNamedBarrier = 59, + SpvCapabilityPipeStorage = 60, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpSizeOf = 321, + SpvOpTypePipeStorage = 322, + SpvOpConstantPipeStorage = 323, + SpvOpCreatePipeFromPipeStorage = 324, + SpvOpGetKernelLocalSizeForSubgroupCount = 325, + SpvOpGetKernelMaxNumSubgroups = 326, + SpvOpTypeNamedBarrier = 327, + SpvOpNamedBarrierInitialize = 328, + SpvOpMemoryNamedBarrier = 329, + SpvOpModuleProcessed = 330, + SpvOpDecorateId = 332, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#endif // #ifndef spirv_H + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.hpp b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.hpp new file mode 100644 index 000000000000..c26ac1f26c6d --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.hpp @@ -0,0 +1,1024 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10100 +#define SPV_REVISION 8 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010100; +static const unsigned int Revision = 8; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModeInitializer = 33, + ExecutionModeFinalizer = 34, + ExecutionModeSubgroupSize = 35, + ExecutionModeSubgroupsPerWorkgroup = 36, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationMaxByteOffset = 45, + DecorationExplicitInterpAMD = 4999, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlDependencyInfiniteShift = 2, + LoopControlDependencyLengthShift = 3, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, + LoopControlDependencyInfiniteMask = 0x00000004, + LoopControlDependencyLengthMask = 0x00000008, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupDispatch = 58, + CapabilityNamedBarrier = 59, + CapabilityPipeStorage = 60, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilityMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + OpMax = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.hpp11 b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.hpp11 new file mode 100644 index 000000000000..992d43b5f542 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.hpp11 @@ -0,0 +1,1024 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10100 +#define SPV_REVISION 8 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010100; +static const unsigned int Revision = 8; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + Max = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.json b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.json new file mode 100644 index 000000000000..4c18e0192a36 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.json @@ -0,0 +1,1040 @@ +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2018 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "", + "Some tokens act like mask values, which can be OR'd together,", + "while others are mutually exclusive. The mask-like ones have", + "\"Mask\" in their name, and a parallel enum that has the shift", + "amount (1 << x) for each corresponding enumerant." + ] + ], + "MagicNumber": 119734787, + "Version": 65792, + "Revision": 8, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "Initializer": 33, + "Finalizer": 34, + "SubgroupSize": 35, + "SubgroupsPerWorkgroup": 36, + "PostDepthCoverage": 4446, + "StencilRefReplacingEXT": 5027 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "MaxByteOffset": 45, + "ExplicitInterpAMD": 4999, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1, + "DependencyInfinite": 2, + "DependencyLength": 3 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupDispatch": 58, + "NamedBarrier": 59, + "PipeStorage": 60, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpSizeOf": 321, + "OpTypePipeStorage": 322, + "OpConstantPipeStorage": 323, + "OpCreatePipeFromPipeStorage": 324, + "OpGetKernelLocalSizeForSubgroupCount": 325, + "OpGetKernelMaxNumSubgroups": 326, + "OpTypeNamedBarrier": 327, + "OpNamedBarrierInitialize": 328, + "OpMemoryNamedBarrier": 329, + "OpModuleProcessed": 330, + "OpDecorateId": 332, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpSubgroupReadInvocationKHR": 4432, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateStringGOOGLE": 5633 + } + } + ] + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.lua b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.lua new file mode 100644 index 000000000000..ad34e0abe9d5 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.lua @@ -0,0 +1,971 @@ +-- Copyright (c) 2014-2018 The Khronos Group Inc. +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and/or associated documentation files (the "Materials"), +-- to deal in the Materials without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Materials, and to permit persons to whom the +-- Materials are furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Materials. +-- +-- MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +-- STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +-- HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +-- +-- THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +-- IN THE MATERIALS. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- +-- Some tokens act like mask values, which can be OR'd together, +-- while others are mutually exclusive. The mask-like ones have +-- "Mask" in their name, and a parallel enum that has the shift +-- amount (1 << x) for each corresponding enumerant. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010100, + Revision = 8, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + }, + +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.py b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.py new file mode 100644 index 000000000000..519a59710d19 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.1/spirv.py @@ -0,0 +1,971 @@ +# Copyright (c) 2014-2018 The Khronos Group Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and/or associated documentation files (the "Materials"), +# to deal in the Materials without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Materials, and to permit persons to whom the +# Materials are furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Materials. +# +# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +# STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +# HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +# +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +# IN THE MATERIALS. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# +# Some tokens act like mask values, which can be OR'd together, +# while others are mutually exclusive. The mask-like ones have +# "Mask" in their name, and a parallel enum that has the shift +# amount (1 << x) for each corresponding enumerant. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010100, + 'Revision' : 8, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'Initializer' : 33, + 'Finalizer' : 34, + 'SubgroupSize' : 35, + 'SubgroupsPerWorkgroup' : 36, + 'PostDepthCoverage' : 4446, + 'StencilRefReplacingEXT' : 5027, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'MaxByteOffset' : 45, + 'ExplicitInterpAMD' : 4999, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + 'DependencyInfinite' : 2, + 'DependencyLength' : 3, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + 'DependencyInfinite' : 0x00000004, + 'DependencyLength' : 0x00000008, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupDispatch' : 58, + 'NamedBarrier' : 59, + 'PipeStorage' : 60, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpSizeOf' : 321, + 'OpTypePipeStorage' : 322, + 'OpConstantPipeStorage' : 323, + 'OpCreatePipeFromPipeStorage' : 324, + 'OpGetKernelLocalSizeForSubgroupCount' : 325, + 'OpGetKernelMaxNumSubgroups' : 326, + 'OpTypeNamedBarrier' : 327, + 'OpNamedBarrierInitialize' : 328, + 'OpMemoryNamedBarrier' : 329, + 'OpModuleProcessed' : 330, + 'OpDecorateId' : 332, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateStringGOOGLE' : 5633, + }, + +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/GLSL.std.450.h b/thirdparty/glslang/glslang/Include/spirv/1.2/GLSL.std.450.h new file mode 100644 index 000000000000..54cc00e9a888 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/GLSL.std.450.h @@ -0,0 +1,131 @@ +/* +** Copyright (c) 2014-2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLstd450_H +#define GLSLstd450_H + +static const int GLSLstd450Version = 100; +static const int GLSLstd450Revision = 3; + +enum GLSLstd450 { + GLSLstd450Bad = 0, // Don't use + + GLSLstd450Round = 1, + GLSLstd450RoundEven = 2, + GLSLstd450Trunc = 3, + GLSLstd450FAbs = 4, + GLSLstd450SAbs = 5, + GLSLstd450FSign = 6, + GLSLstd450SSign = 7, + GLSLstd450Floor = 8, + GLSLstd450Ceil = 9, + GLSLstd450Fract = 10, + + GLSLstd450Radians = 11, + GLSLstd450Degrees = 12, + GLSLstd450Sin = 13, + GLSLstd450Cos = 14, + GLSLstd450Tan = 15, + GLSLstd450Asin = 16, + GLSLstd450Acos = 17, + GLSLstd450Atan = 18, + GLSLstd450Sinh = 19, + GLSLstd450Cosh = 20, + GLSLstd450Tanh = 21, + GLSLstd450Asinh = 22, + GLSLstd450Acosh = 23, + GLSLstd450Atanh = 24, + GLSLstd450Atan2 = 25, + + GLSLstd450Pow = 26, + GLSLstd450Exp = 27, + GLSLstd450Log = 28, + GLSLstd450Exp2 = 29, + GLSLstd450Log2 = 30, + GLSLstd450Sqrt = 31, + GLSLstd450InverseSqrt = 32, + + GLSLstd450Determinant = 33, + GLSLstd450MatrixInverse = 34, + + GLSLstd450Modf = 35, // second operand needs an OpVariable to write to + GLSLstd450ModfStruct = 36, // no OpVariable operand + GLSLstd450FMin = 37, + GLSLstd450UMin = 38, + GLSLstd450SMin = 39, + GLSLstd450FMax = 40, + GLSLstd450UMax = 41, + GLSLstd450SMax = 42, + GLSLstd450FClamp = 43, + GLSLstd450UClamp = 44, + GLSLstd450SClamp = 45, + GLSLstd450FMix = 46, + GLSLstd450IMix = 47, // Reserved + GLSLstd450Step = 48, + GLSLstd450SmoothStep = 49, + + GLSLstd450Fma = 50, + GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to + GLSLstd450FrexpStruct = 52, // no OpVariable operand + GLSLstd450Ldexp = 53, + + GLSLstd450PackSnorm4x8 = 54, + GLSLstd450PackUnorm4x8 = 55, + GLSLstd450PackSnorm2x16 = 56, + GLSLstd450PackUnorm2x16 = 57, + GLSLstd450PackHalf2x16 = 58, + GLSLstd450PackDouble2x32 = 59, + GLSLstd450UnpackSnorm2x16 = 60, + GLSLstd450UnpackUnorm2x16 = 61, + GLSLstd450UnpackHalf2x16 = 62, + GLSLstd450UnpackSnorm4x8 = 63, + GLSLstd450UnpackUnorm4x8 = 64, + GLSLstd450UnpackDouble2x32 = 65, + + GLSLstd450Length = 66, + GLSLstd450Distance = 67, + GLSLstd450Cross = 68, + GLSLstd450Normalize = 69, + GLSLstd450FaceForward = 70, + GLSLstd450Reflect = 71, + GLSLstd450Refract = 72, + + GLSLstd450FindILsb = 73, + GLSLstd450FindSMsb = 74, + GLSLstd450FindUMsb = 75, + + GLSLstd450InterpolateAtCentroid = 76, + GLSLstd450InterpolateAtSample = 77, + GLSLstd450InterpolateAtOffset = 78, + + GLSLstd450NMin = 79, + GLSLstd450NMax = 80, + GLSLstd450NClamp = 81, + + GLSLstd450Count +}; + +#endif // #ifndef GLSLstd450_H diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/OpenCL.std.h b/thirdparty/glslang/glslang/Include/spirv/1.2/OpenCL.std.h new file mode 100644 index 000000000000..19a6688490c7 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/OpenCL.std.h @@ -0,0 +1,210 @@ +/* +** Copyright (c) 2015-2017 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +namespace OpenCLLIB { + +enum Entrypoints { + + // Section 2.1: Math extended instructions + Acos = 0, + Acosh = 1, + Acospi = 2, + Asin = 3, + Asinh = 4, + Asinpi = 5, + Atan = 6, + Atan2 = 7, + Atanh = 8, + Atanpi = 9, + Atan2pi = 10, + Cbrt = 11, + Ceil = 12, + Copysign = 13, + Cos = 14, + Cosh = 15, + Cospi = 16, + Erfc = 17, + Erf = 18, + Exp = 19, + Exp2 = 20, + Exp10 = 21, + Expm1 = 22, + Fabs = 23, + Fdim = 24, + Floor = 25, + Fma = 26, + Fmax = 27, + Fmin = 28, + Fmod = 29, + Fract = 30, + Frexp = 31, + Hypot = 32, + Ilogb = 33, + Ldexp = 34, + Lgamma = 35, + Lgamma_r = 36, + Log = 37, + Log2 = 38, + Log10 = 39, + Log1p = 40, + Logb = 41, + Mad = 42, + Maxmag = 43, + Minmag = 44, + Modf = 45, + Nan = 46, + Nextafter = 47, + Pow = 48, + Pown = 49, + Powr = 50, + Remainder = 51, + Remquo = 52, + Rint = 53, + Rootn = 54, + Round = 55, + Rsqrt = 56, + Sin = 57, + Sincos = 58, + Sinh = 59, + Sinpi = 60, + Sqrt = 61, + Tan = 62, + Tanh = 63, + Tanpi = 64, + Tgamma = 65, + Trunc = 66, + Half_cos = 67, + Half_divide = 68, + Half_exp = 69, + Half_exp2 = 70, + Half_exp10 = 71, + Half_log = 72, + Half_log2 = 73, + Half_log10 = 74, + Half_powr = 75, + Half_recip = 76, + Half_rsqrt = 77, + Half_sin = 78, + Half_sqrt = 79, + Half_tan = 80, + Native_cos = 81, + Native_divide = 82, + Native_exp = 83, + Native_exp2 = 84, + Native_exp10 = 85, + Native_log = 86, + Native_log2 = 87, + Native_log10 = 88, + Native_powr = 89, + Native_recip = 90, + Native_rsqrt = 91, + Native_sin = 92, + Native_sqrt = 93, + Native_tan = 94, + + // Section 2.2: Integer instructions + SAbs = 141, + SAbs_diff = 142, + SAdd_sat = 143, + UAdd_sat = 144, + SHadd = 145, + UHadd = 146, + SRhadd = 147, + URhadd = 148, + SClamp = 149, + UClamp = 150, + Clz = 151, + Ctz = 152, + SMad_hi = 153, + UMad_sat = 154, + SMad_sat = 155, + SMax = 156, + UMax = 157, + SMin = 158, + UMin = 159, + SMul_hi = 160, + Rotate = 161, + SSub_sat = 162, + USub_sat = 163, + U_Upsample = 164, + S_Upsample = 165, + Popcount = 166, + SMad24 = 167, + UMad24 = 168, + SMul24 = 169, + UMul24 = 170, + UAbs = 201, + UAbs_diff = 202, + UMul_hi = 203, + UMad_hi = 204, + + // Section 2.3: Common instructions + FClamp = 95, + Degrees = 96, + FMax_common = 97, + FMin_common = 98, + Mix = 99, + Radians = 100, + Step = 101, + Smoothstep = 102, + Sign = 103, + + // Section 2.4: Geometric instructions + Cross = 104, + Distance = 105, + Length = 106, + Normalize = 107, + Fast_distance = 108, + Fast_length = 109, + Fast_normalize = 110, + + // Section 2.5: Relational instructions + Bitselect = 186, + Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + Vloadn = 171, + Vstoren = 172, + Vload_half = 173, + Vload_halfn = 174, + Vstore_half = 175, + Vstore_half_r = 176, + Vstore_halfn = 177, + Vstore_halfn_r = 178, + Vloada_halfn = 179, + Vstorea_halfn = 180, + Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + Shuffle = 182, + Shuffle2 = 183, + + // Section 2.8: Misc instructions + Printf = 184, + Prefetch = 185, +}; + +} // end namespace OpenCLLIB diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/extinst.glsl.std.450.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.2/extinst.glsl.std.450.grammar.json new file mode 100644 index 000000000000..3d9f39e76c9c --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/extinst.glsl.std.450.grammar.json @@ -0,0 +1,642 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "Round", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "RoundEven", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Trunc", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FAbs", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SAbs", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FSign", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SSign", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Floor", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ceil", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fract", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Radians", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "Degrees", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "Sin", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tan", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asin", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acos", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'y_over_x'" } + ] + }, + { + "opname" : "Sinh", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cosh", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tanh", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asinh", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acosh", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atanh", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan2", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Pow", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Exp", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Exp2", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log2", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Sqrt", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "InverseSqrt", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Determinant", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "MatrixInverse", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Modf", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "ModfStruct", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FMin", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMin", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMin", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FMax", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMax", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMax", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FClamp", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "UClamp", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "SClamp", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "FMix", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "IMix", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "Step", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SmoothStep", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fma", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "Frexp", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "FrexpStruct", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ldexp", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "PackSnorm4x8", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm4x8", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackSnorm2x16", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm2x16", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackHalf2x16", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackDouble2x32", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "UnpackSnorm2x16", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm2x16", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackHalf2x16", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "UnpackSnorm4x8", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm4x8", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackDouble2x32", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "Length", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Distance", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "Cross", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Normalize", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FaceForward", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'Nref'" } + ] + }, + { + "opname" : "Reflect", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" } + ] + }, + { + "opname" : "Refract", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'eta'" } + ] + }, + { + "opname" : "FindILsb", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindSMsb", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindUMsb", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "InterpolateAtCentroid", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtSample", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'sample'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtOffset", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "NMin", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NMax", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NClamp", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/extinst.opencl.std.100.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.2/extinst.opencl.std.100.grammar.json new file mode 100644 index 000000000000..4fe45060bb98 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/extinst.opencl.std.100.grammar.json @@ -0,0 +1,1279 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "acos", + "opcode" : 0, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acosh", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acospi", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asin", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinh", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinpi", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanh", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanpi", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2pi", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cbrt", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ceil", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "copysign", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cosh", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cospi", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erfc", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erf", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp2", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp10", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "expm1", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fabs", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fdim", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "floor", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fma", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fmax", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmod", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fract", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'ptr'" } + ] + }, + { + "opname" : "frexp", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "hypot", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "ilogb", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ldexp", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'k'" } + ] + }, + { + "opname" : "lgamma", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "lgamma_r", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'signp'" } + ] + }, + { + "opname" : "log", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log2", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log10", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log1p", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "logb", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "mad", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "maxmag", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "minmag", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "modf", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'iptr'" } + ] + }, + { + "opname" : "nan", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'nancode'" } + ] + }, + { + "opname" : "nextafter", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "pow", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y" } + ] + }, + { + "opname" : "pown", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "powr", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remainder", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remquo", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'quo'" } + ] + }, + { + "opname" : "rint", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rootn", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "round", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rsqrt", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sin", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sincos", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'cosval'" } + ] + }, + { + "opname" : "sinh", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sinpi", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sqrt", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tan", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanh", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanpi", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tgamma", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "trunc", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_cos", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_divide", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_exp", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp2", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp10", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log2", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log10", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_powr", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_recip", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_rsqrt", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sin", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sqrt", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_tan", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_cos", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_divide", + "opcode" : 82, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_exp", + "opcode" : 83, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp2", + "opcode" : 84, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp10", + "opcode" : 85, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log", + "opcode" : 86, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log2", + "opcode" : 87, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log10", + "opcode" : 88, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_powr", + "opcode" : 89, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_recip", + "opcode" : 90, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_rsqrt", + "opcode" : 91, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sin", + "opcode" : 92, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sqrt", + "opcode" : 93, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_tan", + "opcode" : 94, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs", + "opcode" : 141, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs_diff", + "opcode" : 142, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_add_sat", + "opcode" : 143, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_add_sat", + "opcode" : 144, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_hadd", + "opcode" : 145, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_hadd", + "opcode" : 146, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_rhadd", + "opcode" : 147, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_rhadd", + "opcode" : 148, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_clamp", + "opcode" : 149, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "u_clamp", + "opcode" : 150, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "clz", + "opcode" : 151, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ctz", + "opcode" : 152, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad_hi", + "opcode" : 153, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "u_mad_sat", + "opcode" : 154, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mad_sat", + "opcode" : 155, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_max", + "opcode" : 156, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_max", + "opcode" : 157, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_min", + "opcode" : 158, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_min", + "opcode" : 159, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_mul_hi", + "opcode" : 160, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "rotate", + "opcode" : 161, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "s_sub_sat", + "opcode" : 162, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_sub_sat", + "opcode" : 163, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_upsample", + "opcode" : 164, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "s_upsample", + "opcode" : 165, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "popcount", + "opcode" : 166, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad24", + "opcode" : 167, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "u_mad24", + "opcode" : 168, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mul24", + "opcode" : 169, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul24", + "opcode" : 170, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_abs", + "opcode" : 201, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "u_abs_diff", + "opcode" : 202, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul_hi", + "opcode" : 203, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mad_hi", + "opcode" : 204, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fclamp", + "opcode" : 95, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "degrees", + "opcode" :96, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "fmax_common", + "opcode" : 97, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin_common", + "opcode" : 98, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "mix", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "radians", + "opcode" : 100, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "step", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "smoothstep", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sign", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cross", + "opcode" : 104, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "distance", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "length", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "normalize", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_distance", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "fast_length", + "opcode" : 109, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_normalize", + "opcode" : 110, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "bitselect", + "opcode" : 186, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "select", + "opcode" : 187, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "vloadn", + "opcode" : 171, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstoren", + "opcode" : 172, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_half", + "opcode" : 173, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_halfn", + "opcode" : 174, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstore_half", + "opcode" : 175, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_half_r", + "opcode" : 176, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vstore_halfn", + "opcode" : 177, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_halfn_r", + "opcode" : 178, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vloada_halfn", + "opcode" : 179, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstorea_halfn", + "opcode" : 180, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstorea_halfn_r", + "opcode" : 181, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "shuffle", + "opcode" : 182, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "shuffle2", + "opcode" : 183, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "printf", + "opcode" : 184, + "operands" : [ + { "kind" : "IdRef", "name" : "'format'" }, + { "kind" : "IdRef", "name" : "'additional arguments'", "quantifier" : "*" } + ] + }, + { + "opname" : "prefetch", + "opcode" : 185, + "operands" : [ + { "kind" : "IdRef", "name" : "'ptr'" }, + { "kind" : "IdRef", "name" : "'num elements'" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.core.grammar.json b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.core.grammar.json new file mode 100644 index 000000000000..393ee3c8497d --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.core.grammar.json @@ -0,0 +1,5986 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2016 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "magic_number" : "0x07230203", + "major_version" : 1, + "minor_version" : 2, + "revision" : 2, + "instructions" : [ + { + "opname" : "OpNop", + "opcode" : 0 + }, + { + "opname" : "OpUndef", + "opcode" : 1, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSourceContinued", + "opcode" : 2, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Continued Source'" } + ] + }, + { + "opname" : "OpSource", + "opcode" : 3, + "operands" : [ + { "kind" : "SourceLanguage" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" }, + { "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" } + ] + }, + { + "opname" : "OpSourceExtension", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Extension'" } + ] + }, + { + "opname" : "OpName", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpMemberName", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpString", + "opcode" : 7, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'String'" } + ] + }, + { + "opname" : "OpLine", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "OpExtension", + "opcode" : 10, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInstImport", + "opcode" : 11, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ] + }, + { + "opname" : "OpExtInst", + "opcode" : 12, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ] + }, + { + "opname" : "OpMemoryModel", + "opcode" : 14, + "operands" : [ + { "kind" : "AddressingModel" }, + { "kind" : "MemoryModel" } + ] + }, + { + "opname" : "OpEntryPoint", + "opcode" : 15, + "operands" : [ + { "kind" : "ExecutionModel" }, + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } + ] + }, + { + "opname" : "OpExecutionMode", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ] + }, + { + "opname" : "OpCapability", + "opcode" : 17, + "operands" : [ + { "kind" : "Capability", "name" : "'Capability'" } + ] + }, + { + "opname" : "OpTypeVoid", + "opcode" : 19, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeBool", + "opcode" : 20, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeInt", + "opcode" : 21, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" }, + { "kind" : "LiteralInteger", "name" : "'Signedness'" } + ] + }, + { + "opname" : "OpTypeFloat", + "opcode" : 22, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" } + ] + }, + { + "opname" : "OpTypeVector", + "opcode" : 23, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "OpTypeMatrix", + "opcode" : 24, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Column Type'" }, + { "kind" : "LiteralInteger", "name" : "'Column Count'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpTypeImage", + "opcode" : 25, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Type'" }, + { "kind" : "Dim" }, + { "kind" : "LiteralInteger", "name" : "'Depth'" }, + { "kind" : "LiteralInteger", "name" : "'Arrayed'" }, + { "kind" : "LiteralInteger", "name" : "'MS'" }, + { "kind" : "LiteralInteger", "name" : "'Sampled'" }, + { "kind" : "ImageFormat" }, + { "kind" : "AccessQualifier", "quantifier" : "?" } + ] + }, + { + "opname" : "OpTypeSampler", + "opcode" : 26, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpTypeSampledImage", + "opcode" : 27, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ] + }, + { + "opname" : "OpTypeArray", + "opcode" : 28, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" }, + { "kind" : "IdRef", "name" : "'Length'" } + ] + }, + { + "opname" : "OpTypeRuntimeArray", + "opcode" : 29, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpTypeStruct", + "opcode" : 30, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ] + }, + { + "opname" : "OpTypeOpaque", + "opcode" : 31, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "The name of the opaque type." } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypePointer", + "opcode" : 32, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "name" : "'Type'" } + ] + }, + { + "opname" : "OpTypeFunction", + "opcode" : 33, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." } + ] + }, + { + "opname" : "OpTypeEvent", + "opcode" : 34, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpTypeDeviceEvent", + "opcode" : 35, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypeReserveId", + "opcode" : 36, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeQueue", + "opcode" : 37, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpTypePipe", + "opcode" : 38, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "AccessQualifier", "name" : "'Qualifier'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpTypeForwardPointer", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer Type'" }, + { "kind" : "StorageClass" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpConstantTrue", + "opcode" : 41, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstantFalse", + "opcode" : 42, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpConstant", + "opcode" : 43, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConstantComposite", + "opcode" : 44, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpConstantSampler", + "opcode" : 45, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "SamplerAddressingMode" }, + { "kind" : "LiteralInteger", "name" : "'Param'" }, + { "kind" : "SamplerFilterMode" } + ], + "capabilities" : [ "LiteralSampler" ] + }, + { + "opname" : "OpConstantNull", + "opcode" : 46, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantTrue", + "opcode" : 48, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstantFalse", + "opcode" : 49, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpSpecConstant", + "opcode" : 50, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ] + }, + { + "opname" : "OpSpecConstantComposite", + "opcode" : 51, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpSpecConstantOp", + "opcode" : 52, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" } + ] + }, + { + "opname" : "OpFunction", + "opcode" : 54, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "FunctionControl" }, + { "kind" : "IdRef", "name" : "'Function Type'" } + ] + }, + { + "opname" : "OpFunctionParameter", + "opcode" : 55, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpFunctionEnd", + "opcode" : 56 + }, + { + "opname" : "OpFunctionCall", + "opcode" : 57, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." } + ] + }, + { + "opname" : "OpVariable", + "opcode" : 59, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" } + ] + }, + { + "opname" : "OpImageTexelPointer", + "opcode" : 60, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Sample'" } + ] + }, + { + "opname" : "OpLoad", + "opcode" : 61, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpStore", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemory", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ] + }, + { + "opname" : "OpCopyMemorySized", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpAccessChain", + "opcode" : 65, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpInBoundsAccessChain", + "opcode" : 66, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpPtrAccessChain", + "opcode" : 67, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ + "Addresses", + "VariablePointers", + "VariablePointersStorageBuffer" + ] + }, + { + "opname" : "OpArrayLength", + "opcode" : 68, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Structure'" }, + { "kind" : "LiteralInteger", "name" : "'Array member'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpGenericPtrMemSemantics", + "opcode" : 69, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpInBoundsPtrAccessChain", + "opcode" : 70, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpDecorate", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpMemberDecorate", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'Structure Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpDecorationGroup", + "opcode" : 73, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpGroupDecorate", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpGroupMemberDecorate", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" } + ] + }, + { + "opname" : "OpVectorExtractDynamic", + "opcode" : 77, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorInsertDynamic", + "opcode" : 78, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ] + }, + { + "opname" : "OpVectorShuffle", + "opcode" : 79, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" } + ] + }, + { + "opname" : "OpCompositeConstruct", + "opcode" : 80, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ] + }, + { + "opname" : "OpCompositeExtract", + "opcode" : 81, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCompositeInsert", + "opcode" : 82, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ] + }, + { + "opname" : "OpCopyObject", + "opcode" : 83, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpTranspose", + "opcode" : 84, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpSampledImage", + "opcode" : 86, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ] + }, + { + "opname" : "OpImageSampleImplicitLod", + "opcode" : 87, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleExplicitLod", + "opcode" : 88, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ] + }, + { + "opname" : "OpImageSampleDrefImplicitLod", + "opcode" : 89, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleDrefExplicitLod", + "opcode" : 90, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjImplicitLod", + "opcode" : 91, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjExplicitLod", + "opcode" : 92, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefImplicitLod", + "opcode" : 93, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageSampleProjDrefExplicitLod", + "opcode" : 94, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageFetch", + "opcode" : 95, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageGather", + "opcode" : 96, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageDrefGather", + "opcode" : 97, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpImageRead", + "opcode" : 98, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImageWrite", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Texel'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ] + }, + { + "opname" : "OpImage", + "opcode" : 100, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" } + ] + }, + { + "opname" : "OpImageQueryFormat", + "opcode" : 101, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQueryOrder", + "opcode" : 102, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageQuerySizeLod", + "opcode" : 103, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Level of Detail'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySize", + "opcode" : 104, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLod", + "opcode" : 105, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "ImageQuery" ] + }, + { + "opname" : "OpImageQueryLevels", + "opcode" : 106, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpImageQuerySamples", + "opcode" : 107, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ] + }, + { + "opname" : "OpConvertFToU", + "opcode" : 109, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertFToS", + "opcode" : 110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpConvertSToF", + "opcode" : 111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpConvertUToF", + "opcode" : 112, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpUConvert", + "opcode" : 113, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ] + }, + { + "opname" : "OpSConvert", + "opcode" : 114, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ] + }, + { + "opname" : "OpFConvert", + "opcode" : 115, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ] + }, + { + "opname" : "OpQuantizeToF16", + "opcode" : 116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpConvertPtrToU", + "opcode" : 117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpSatConvertSToU", + "opcode" : 118, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSatConvertUToS", + "opcode" : 119, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpConvertUToPtr", + "opcode" : 120, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Integer Value'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpPtrCastToGeneric", + "opcode" : 121, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtr", + "opcode" : 122, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGenericCastToPtrExplicit", + "opcode" : 123, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "StorageClass", "name" : "'Storage'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpBitcast", + "opcode" : 124, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSNegate", + "opcode" : 126, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpFNegate", + "opcode" : 127, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpIAdd", + "opcode" : 128, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFAdd", + "opcode" : 129, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISub", + "opcode" : 130, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFSub", + "opcode" : 131, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpIMul", + "opcode" : 132, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMul", + "opcode" : 133, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUDiv", + "opcode" : 134, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSDiv", + "opcode" : 135, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFDiv", + "opcode" : 136, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMod", + "opcode" : 137, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSRem", + "opcode" : 138, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMod", + "opcode" : 139, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFRem", + "opcode" : 140, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFMod", + "opcode" : 141, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpVectorTimesScalar", + "opcode" : 142, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ] + }, + { + "opname" : "OpMatrixTimesScalar", + "opcode" : 143, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpVectorTimesMatrix", + "opcode" : 144, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesVector", + "opcode" : 145, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpMatrixTimesMatrix", + "opcode" : 146, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'LeftMatrix'" }, + { "kind" : "IdRef", "name" : "'RightMatrix'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpOuterProduct", + "opcode" : 147, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "capabilities" : [ "Matrix" ] + }, + { + "opname" : "OpDot", + "opcode" : 148, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ] + }, + { + "opname" : "OpIAddCarry", + "opcode" : 149, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpISubBorrow", + "opcode" : 150, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUMulExtended", + "opcode" : 151, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSMulExtended", + "opcode" : 152, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpAny", + "opcode" : 154, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpAll", + "opcode" : 155, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ] + }, + { + "opname" : "OpIsNan", + "opcode" : 156, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsInf", + "opcode" : 157, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "OpIsFinite", + "opcode" : 158, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpIsNormal", + "opcode" : 159, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpSignBitSet", + "opcode" : 160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLessOrGreater", + "opcode" : 161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpOrdered", + "opcode" : 162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpUnordered", + "opcode" : 163, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLogicalEqual", + "opcode" : 164, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNotEqual", + "opcode" : 165, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalOr", + "opcode" : 166, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalAnd", + "opcode" : 167, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpLogicalNot", + "opcode" : 168, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpSelect", + "opcode" : 169, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'Object 1'" }, + { "kind" : "IdRef", "name" : "'Object 2'" } + ] + }, + { + "opname" : "OpIEqual", + "opcode" : 170, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpINotEqual", + "opcode" : 171, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThan", + "opcode" : 172, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThan", + "opcode" : 173, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpUGreaterThanEqual", + "opcode" : 174, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSGreaterThanEqual", + "opcode" : 175, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThan", + "opcode" : 176, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThan", + "opcode" : 177, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpULessThanEqual", + "opcode" : 178, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpSLessThanEqual", + "opcode" : 179, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdEqual", + "opcode" : 180, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordEqual", + "opcode" : 181, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdNotEqual", + "opcode" : 182, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordNotEqual", + "opcode" : 183, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThan", + "opcode" : 184, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThan", + "opcode" : 185, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThan", + "opcode" : 186, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThan", + "opcode" : 187, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdLessThanEqual", + "opcode" : 188, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordLessThanEqual", + "opcode" : 189, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFOrdGreaterThanEqual", + "opcode" : 190, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpFUnordGreaterThanEqual", + "opcode" : 191, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpShiftRightLogical", + "opcode" : 194, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftRightArithmetic", + "opcode" : 195, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpShiftLeftLogical", + "opcode" : 196, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ] + }, + { + "opname" : "OpBitwiseOr", + "opcode" : 197, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseXor", + "opcode" : 198, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpBitwiseAnd", + "opcode" : 199, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, + { + "opname" : "OpNot", + "opcode" : 200, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ] + }, + { + "opname" : "OpBitFieldInsert", + "opcode" : 201, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Insert'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldSExtract", + "opcode" : 202, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitFieldUExtract", + "opcode" : 203, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitReverse", + "opcode" : 204, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpBitCount", + "opcode" : 205, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ] + }, + { + "opname" : "OpDPdx", + "opcode" : 207, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdy", + "opcode" : 208, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpFwidth", + "opcode" : 209, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpDPdxFine", + "opcode" : 210, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyFine", + "opcode" : 211, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthFine", + "opcode" : 212, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdxCoarse", + "opcode" : 213, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpDPdyCoarse", + "opcode" : 214, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpFwidthCoarse", + "opcode" : 215, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ] + }, + { + "opname" : "OpEmitVertex", + "opcode" : 218, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEndPrimitive", + "opcode" : 219, + "capabilities" : [ "Geometry" ] + }, + { + "opname" : "OpEmitStreamVertex", + "opcode" : 220, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpEndStreamPrimitive", + "opcode" : 221, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ] + }, + { + "opname" : "OpControlBarrier", + "opcode" : 224, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpMemoryBarrier", + "opcode" : 225, + "operands" : [ + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicLoad", + "opcode" : 227, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicStore", + "opcode" : 228, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicExchange", + "opcode" : 229, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicCompareExchange", + "opcode" : 230, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ] + }, + { + "opname" : "OpAtomicCompareExchangeWeak", + "opcode" : 231, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicIIncrement", + "opcode" : 232, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIDecrement", + "opcode" : 233, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ] + }, + { + "opname" : "OpAtomicIAdd", + "opcode" : 234, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicISub", + "opcode" : 235, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMin", + "opcode" : 236, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMin", + "opcode" : 237, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicSMax", + "opcode" : 238, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicUMax", + "opcode" : 239, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicAnd", + "opcode" : 240, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicOr", + "opcode" : 241, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpAtomicXor", + "opcode" : 242, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpPhi", + "opcode" : 245, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" } + ] + }, + { + "opname" : "OpLoopMerge", + "opcode" : 246, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "IdRef", "name" : "'Continue Target'" }, + { "kind" : "LoopControl" } + ] + }, + { + "opname" : "OpSelectionMerge", + "opcode" : 247, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "SelectionControl" } + ] + }, + { + "opname" : "OpLabel", + "opcode" : 248, + "operands" : [ + { "kind" : "IdResult" } + ] + }, + { + "opname" : "OpBranch", + "opcode" : 249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target Label'" } + ] + }, + { + "opname" : "OpBranchConditional", + "opcode" : 250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'True Label'" }, + { "kind" : "IdRef", "name" : "'False Label'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" } + ] + }, + { + "opname" : "OpSwitch", + "opcode" : 251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Selector'" }, + { "kind" : "IdRef", "name" : "'Default'" }, + { "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" } + ] + }, + { + "opname" : "OpKill", + "opcode" : 252, + "capabilities" : [ "Shader" ] + }, + { + "opname" : "OpReturn", + "opcode" : 253 + }, + { + "opname" : "OpReturnValue", + "opcode" : 254, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "OpUnreachable", + "opcode" : 255 + }, + { + "opname" : "OpLifetimeStart", + "opcode" : 256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpLifetimeStop", + "opcode" : 257, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAsyncCopy", + "opcode" : 259, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Destination'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Num Elements'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupWaitEvents", + "opcode" : 260, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Events List'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpGroupAll", + "opcode" : 261, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupAny", + "opcode" : 262, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupBroadcast", + "opcode" : 263, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'LocalId'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupIAdd", + "opcode" : 264, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAdd", + "opcode" : 265, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMin", + "opcode" : 266, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMin", + "opcode" : 267, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMin", + "opcode" : 268, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMax", + "opcode" : 269, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMax", + "opcode" : 270, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMax", + "opcode" : 271, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpReadPipe", + "opcode" : 274, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpWritePipe", + "opcode" : 275, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedReadPipe", + "opcode" : 276, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReservedWritePipe", + "opcode" : 277, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveReadPipePackets", + "opcode" : 278, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpReserveWritePipePackets", + "opcode" : 279, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitReadPipe", + "opcode" : 280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpCommitWritePipe", + "opcode" : 281, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpIsValidReserveId", + "opcode" : 282, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetNumPipePackets", + "opcode" : 283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGetMaxPipePackets", + "opcode" : 284, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveReadPipePackets", + "opcode" : 285, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupReserveWritePipePackets", + "opcode" : 286, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitReadPipe", + "opcode" : 287, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpGroupCommitWritePipe", + "opcode" : 288, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ] + }, + { + "opname" : "OpEnqueueMarker", + "opcode" : 291, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpEnqueueKernel", + "opcode" : 292, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeSubGroupCount", + "opcode" : 293, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelNDrangeMaxSubGroupSize", + "opcode" : 294, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelWorkGroupSize", + "opcode" : 295, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetKernelPreferredWorkGroupSizeMultiple", + "opcode" : 296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpRetainEvent", + "opcode" : 297, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpReleaseEvent", + "opcode" : 298, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCreateUserEvent", + "opcode" : 299, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpIsValidEvent", + "opcode" : 300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpSetUserEventStatus", + "opcode" : 301, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Status'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpCaptureEventProfilingInfo", + "opcode" : 302, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Profiling Info'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpGetDefaultQueue", + "opcode" : 303, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpBuildNDRange", + "opcode" : 304, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'GlobalWorkSize'" }, + { "kind" : "IdRef", "name" : "'LocalWorkSize'" }, + { "kind" : "IdRef", "name" : "'GlobalWorkOffset'" } + ], + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "opname" : "OpImageSparseSampleImplicitLod", + "opcode" : 305, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleExplicitLod", + "opcode" : 306, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefImplicitLod", + "opcode" : 307, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleDrefExplicitLod", + "opcode" : 308, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjImplicitLod", + "opcode" : 309, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjExplicitLod", + "opcode" : 310, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefImplicitLod", + "opcode" : 311, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseSampleProjDrefExplicitLod", + "opcode" : 312, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseFetch", + "opcode" : 313, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseGather", + "opcode" : 314, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseDrefGather", + "opcode" : 315, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpImageSparseTexelsResident", + "opcode" : 316, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Resident Code'" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpNoLine", + "opcode" : 317 + }, + { + "opname" : "OpAtomicFlagTestAndSet", + "opcode" : 318, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpAtomicFlagClear", + "opcode" : 319, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ] + }, + { + "opname" : "OpImageSparseRead", + "opcode" : 320, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ] + }, + { + "opname" : "OpSizeOf", + "opcode" : 321, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ] + }, + { + "opname" : "OpTypePipeStorage", + "opcode" : 322, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpConstantPipeStorage", + "opcode" : 323, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Packet Size'" }, + { "kind" : "LiteralInteger", "name" : "'Packet Alignment'" }, + { "kind" : "LiteralInteger", "name" : "'Capacity'" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpCreatePipeFromPipeStorage", + "opcode" : 324, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe Storage'" } + ], + "capabilities" : [ "PipeStorage" ] + }, + { + "opname" : "OpGetKernelLocalSizeForSubgroupCount", + "opcode" : 325, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ] + }, + { + "opname" : "OpGetKernelMaxNumSubgroups", + "opcode" : 326, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ] + }, + { + "opname" : "OpTypeNamedBarrier", + "opcode" : 327, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpNamedBarrierInitialize", + "opcode" : 328, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpMemoryNamedBarrier", + "opcode" : 329, + "operands" : [ + { "kind" : "IdRef", "name" : "'Named Barrier'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "NamedBarrier" ] + }, + { + "opname" : "OpModuleProcessed", + "opcode" : 330, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Process'" } + ] + }, + { + "opname" : "OpExecutionModeId", + "opcode" : 331, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ] + }, + { + "opname" : "OpDecorateId", + "opcode" : 332, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ] + }, + { + "opname" : "OpSubgroupBallotKHR", + "opcode" : 4421, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupFirstInvocationKHR", + "opcode" : 4422, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpSubgroupAllKHR", + "opcode" : 4428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAnyKHR", + "opcode" : 4429, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupAllEqualKHR", + "opcode" : 4430, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupVoteKHR" ] + }, + { + "opname" : "OpSubgroupReadInvocationKHR", + "opcode" : 4432, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "opname" : "OpGroupIAddNonUniformAMD", + "opcode" : 5000, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFAddNonUniformAMD", + "opcode" : 5001, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMinNonUniformAMD", + "opcode" : 5002, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMinNonUniformAMD", + "opcode" : 5003, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMinNonUniformAMD", + "opcode" : 5004, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupFMaxNonUniformAMD", + "opcode" : 5005, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupUMaxNonUniformAMD", + "opcode" : 5006, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpGroupSMaxNonUniformAMD", + "opcode" : 5007, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ] + }, + { + "opname" : "OpFragmentMaskFetchAMD", + "opcode" : 5011, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpFragmentFetchAMD", + "opcode" : 5012, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Fragment Index'" } + ], + "capabilities" : [ "FragmentMaskAMD" ] + }, + { + "opname" : "OpSubgroupShuffleINTEL", + "opcode" : 5571, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'InvocationId'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleDownINTEL", + "opcode" : 5572, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Next'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleUpINTEL", + "opcode" : 5573, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Previous'" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupShuffleXorINTEL", + "opcode" : 5574, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ] + }, + { + "opname" : "OpSubgroupBlockReadINTEL", + "opcode" : 5575, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupBlockWriteINTEL", + "opcode" : 5576, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockReadINTEL", + "opcode" : 5577, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpSubgroupImageBlockWriteINTEL", + "opcode" : 5578, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ] + }, + { + "opname" : "OpDecorateStringGOOGLE", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + }, + { + "opname" : "OpMemberDecorateStringGOOGLE", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string" ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "ImageOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Bias", + "value" : "0x0001", + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Lod", + "value" : "0x0002", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Grad", + "value" : "0x0004", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffset", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Offset", + "value" : "0x0010", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "ConstOffsets", + "value" : "0x0020", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Sample", + "value" : "0x0040", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "MinLod", + "value" : "0x0080", + "capabilities" : [ "MinLod" ], + "parameters" : [ + { "kind" : "IdRef" } + ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FPFastMathMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "NotNaN", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NotInf", + "value" : "0x0002", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NSZ", + "value" : "0x0004", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AllowRecip", + "value" : "0x0008", + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Fast", + "value" : "0x0010", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "BitEnum", + "kind" : "SelectionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Flatten", + "value" : "0x0001" + }, + { + "enumerant" : "DontFlatten", + "value" : "0x0002" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "LoopControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Unroll", + "value" : "0x0001" + }, + { + "enumerant" : "DontUnroll", + "value" : "0x0002" + }, + { + "enumerant" : "DependencyInfinite", + "value" : "0x0004" + }, + { + "enumerant" : "DependencyLength", + "value" : "0x0008", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FunctionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Inline", + "value" : "0x0001" + }, + { + "enumerant" : "DontInline", + "value" : "0x0002" + }, + { + "enumerant" : "Pure", + "value" : "0x0004" + }, + { + "enumerant" : "Const", + "value" : "0x0008" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemorySemantics", + "enumerants" : [ + { + "enumerant" : "Relaxed", + "value" : "0x0000" + }, + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Acquire", + "value" : "0x0002" + }, + { + "enumerant" : "Release", + "value" : "0x0004" + }, + { + "enumerant" : "AcquireRelease", + "value" : "0x0008" + }, + { + "enumerant" : "SequentiallyConsistent", + "value" : "0x0010" + }, + { + "enumerant" : "UniformMemory", + "value" : "0x0040", + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupMemory", + "value" : "0x0080" + }, + { + "enumerant" : "WorkgroupMemory", + "value" : "0x0100" + }, + { + "enumerant" : "CrossWorkgroupMemory", + "value" : "0x0200" + }, + { + "enumerant" : "AtomicCounterMemory", + "value" : "0x0400", + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "ImageMemory", + "value" : "0x0800" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemoryAccess", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Volatile", + "value" : "0x0001" + }, + { + "enumerant" : "Aligned", + "value" : "0x0002", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Nontemporal", + "value" : "0x0004" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "KernelProfilingInfo", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "CmdExecTime", + "value" : "0x0001", + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SourceLanguage", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "ESSL", + "value" : 1 + }, + { + "enumerant" : "GLSL", + "value" : 2 + }, + { + "enumerant" : "OpenCL_C", + "value" : 3 + }, + { + "enumerant" : "OpenCL_CPP", + "value" : 4 + }, + { + "enumerant" : "HLSL", + "value" : 5 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionModel", + "enumerants" : [ + { + "enumerant" : "Vertex", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TessellationControl", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessellationEvaluation", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Geometry", + "value" : 3, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Fragment", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLCompute", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Kernel", + "value" : 6, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AddressingModel", + "enumerants" : [ + { + "enumerant" : "Logical", + "value" : 0 + }, + { + "enumerant" : "Physical32", + "value" : 1, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Physical64", + "value" : 2, + "capabilities" : [ "Addresses" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "MemoryModel", + "enumerants" : [ + { + "enumerant" : "Simple", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSL450", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OpenCL", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionMode", + "enumerants" : [ + { + "enumerant" : "Invocations", + "value" : 0, + "capabilities" : [ "Geometry" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of <>'" } + ] + }, + { + "enumerant" : "SpacingEqual", + "value" : 1, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalEven", + "value" : 2, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "SpacingFractionalOdd", + "value" : 3, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCw", + "value" : 4, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "VertexOrderCcw", + "value" : 5, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PixelCenterInteger", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginUpperLeft", + "value" : 7, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "OriginLowerLeft", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "EarlyFragmentTests", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointMode", + "value" : 10, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Xfb", + "value" : 11, + "capabilities" : [ "TransformFeedback" ] + }, + { + "enumerant" : "DepthReplacing", + "value" : 12, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthGreater", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthLess", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DepthUnchanged", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "LocalSize", + "value" : 17, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "LocalSizeHint", + "value" : 18, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ] + }, + { + "enumerant" : "InputPoints", + "value" : 19, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLines", + "value" : 20, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "InputLinesAdjacency", + "value" : 21, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Triangles", + "value" : 22, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InputTrianglesAdjacency", + "value" : 23, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "Quads", + "value" : 24, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Isolines", + "value" : 25, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "OutputVertices", + "value" : 26, + "capabilities" : [ "Geometry", "Tessellation" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vertex count'" } + ] + }, + { + "enumerant" : "OutputPoints", + "value" : 27, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputLineStrip", + "value" : 28, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "OutputTriangleStrip", + "value" : 29, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "VecTypeHint", + "value" : 30, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vector type'" } + ] + }, + { + "enumerant" : "ContractionOff", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Initializer", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Finalizer", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 35, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroup Size'" } + ] + }, + { + "enumerant" : "SubgroupsPerWorkgroup", + "value" : 36, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroups Per Workgroup'" } + ] + }, + { + "enumerant" : "SubgroupsPerWorkgroupId", + "value" : 37, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Subgroups Per Workgroup'" } + ] + }, + { + "enumerant" : "LocalSizeId", + "value" : 38, + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size'" }, + { "kind" : "IdRef", "name" : "'y size'" }, + { "kind" : "IdRef", "name" : "'z size'" } + ] + }, + { + "enumerant" : "LocalSizeHintId", + "value" : 39, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Local Size Hint'" } + ] + }, + { + "enumerant" : "PostDepthCoverage", + "value" : 4446, + "capabilities" : [ "SampleMaskPostDepthCoverage" ] + }, + { + "enumerant" : "StencilRefReplacingEXT", + "value" : 5027, + "capabilities" : [ "StencilExportEXT" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StorageClass", + "enumerants" : [ + { + "enumerant" : "UniformConstant", + "value" : 0 + }, + { + "enumerant" : "Input", + "value" : 1 + }, + { + "enumerant" : "Uniform", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Output", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Workgroup", + "value" : 4 + }, + { + "enumerant" : "CrossWorkgroup", + "value" : 5 + }, + { + "enumerant" : "Private", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Function", + "value" : 7 + }, + { + "enumerant" : "Generic", + "value" : 8, + "capabilities" : [ "GenericPointer" ] + }, + { + "enumerant" : "PushConstant", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "AtomicCounter", + "value" : 10, + "capabilities" : [ "AtomicStorage" ] + }, + { + "enumerant" : "Image", + "value" : 11 + }, + { + "enumerant" : "StorageBuffer", + "value" : 12, + "extensions" : [ + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers" + ], + "capabilities" : [ "Shader" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Dim", + "enumerants" : [ + { + "enumerant" : "1D", + "value" : 0, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "2D", + "value" : 1 + }, + { + "enumerant" : "3D", + "value" : 2 + }, + { + "enumerant" : "Cube", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rect", + "value" : 4, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "Buffer", + "value" : 5, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "SubpassData", + "value" : 6, + "capabilities" : [ "InputAttachment" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerAddressingMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ClampToEdge", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Clamp", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Repeat", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RepeatMirrored", + "value" : 4, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerFilterMode", + "enumerants" : [ + { + "enumerant" : "Nearest", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Linear", + "value" : 1, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageFormat", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0 + }, + { + "enumerant" : "Rgba32f", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16f", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32f", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8", + "value" : 4, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8Snorm", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32f", + "value" : 6, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16f", + "value" : 7, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R11fG11fB10f", + "value" : 8, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16f", + "value" : 9, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16", + "value" : 10, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgb10A2", + "value" : 11, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16", + "value" : 12, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8", + "value" : 13, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16", + "value" : 14, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8", + "value" : 15, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba16Snorm", + "value" : 16, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16Snorm", + "value" : 17, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8Snorm", + "value" : 18, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16Snorm", + "value" : 19, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8Snorm", + "value" : 20, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32i", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16i", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8i", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32i", + "value" : 24, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rg32i", + "value" : 25, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16i", + "value" : 26, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8i", + "value" : 27, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16i", + "value" : 28, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8i", + "value" : 29, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rgba32ui", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba16ui", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgba8ui", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "R32ui", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Rgb10a2ui", + "value" : 34, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg32ui", + "value" : 35, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg16ui", + "value" : 36, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "Rg8ui", + "value" : 37, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R16ui", + "value" : 38, + "capabilities" : [ "StorageImageExtendedFormats" ] + }, + { + "enumerant" : "R8ui", + "value" : 39, + "capabilities" : [ "StorageImageExtendedFormats" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelOrder", + "enumerants" : [ + { + "enumerant" : "R", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "A", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RG", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RA", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGB", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBA", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BGRA", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ARGB", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Intensity", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Luminance", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Rx", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGx", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "RGBx", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Depth", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "DepthStencil", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGB", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBx", + "value" : 16, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sRGBA", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "sBGRA", + "value" : 18, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ABGR", + "value" : 19, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelDataType", + "enumerants" : [ + { + "enumerant" : "SnormInt8", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SnormInt16", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt8", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt16", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort565", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormShort555", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt8", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt16", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SignedInt32", + "value" : 9, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt8", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt16", + "value" : 11, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnsignedInt32", + "value" : 12, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "HalfFloat", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float", + "value" : 14, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt24", + "value" : 15, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "UnormInt101010_2", + "value" : 16, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPRoundingMode", + "enumerants" : [ + { + "enumerant" : "RTE", + "value" : 0, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTZ", + "value" : 1, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTP", + "value" : 2, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + }, + { + "enumerant" : "RTN", + "value" : 3, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LinkageType", + "enumerants" : [ + { + "enumerant" : "Export", + "value" : 0, + "capabilities" : [ "Linkage" ] + }, + { + "enumerant" : "Import", + "value" : 1, + "capabilities" : [ "Linkage" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AccessQualifier", + "enumerants" : [ + { + "enumerant" : "ReadOnly", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WriteOnly", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ReadWrite", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FunctionParameterAttribute", + "enumerants" : [ + { + "enumerant" : "Zext", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sext", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ByVal", + "value" : 2, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Sret", + "value" : 3, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoAlias", + "value" : 4, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoCapture", + "value" : 5, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoWrite", + "value" : 6, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NoReadWrite", + "value" : 7, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Decoration", + "enumerants" : [ + { + "enumerant" : "RelaxedPrecision", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SpecId", + "value" : 1, + "capabilities" : [ "Shader", "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" } + ] + }, + { + "enumerant" : "Block", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "BufferBlock", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "RowMajor", + "value" : 4, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ColMajor", + "value" : 5, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "ArrayStride", + "value" : 6, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Array Stride'" } + ] + }, + { + "enumerant" : "MatrixStride", + "value" : 7, + "capabilities" : [ "Matrix" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Matrix Stride'" } + ] + }, + { + "enumerant" : "GLSLShared", + "value" : 8, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GLSLPacked", + "value" : 9, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CPacked", + "value" : 10, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "BuiltIn", + "value" : 11, + "parameters" : [ + { "kind" : "BuiltIn" } + ] + }, + { + "enumerant" : "NoPerspective", + "value" : 13, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Flat", + "value" : 14, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Patch", + "value" : 15, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "Centroid", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sample", + "value" : 17, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "Invariant", + "value" : 18, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Restrict", + "value" : 19 + }, + { + "enumerant" : "Aliased", + "value" : 20 + }, + { + "enumerant" : "Volatile", + "value" : 21 + }, + { + "enumerant" : "Constant", + "value" : 22, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Coherent", + "value" : 23 + }, + { + "enumerant" : "NonWritable", + "value" : 24 + }, + { + "enumerant" : "NonReadable", + "value" : 25 + }, + { + "enumerant" : "Uniform", + "value" : 26, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SaturatedConversion", + "value" : 28, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Stream", + "value" : 29, + "capabilities" : [ "GeometryStreams" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stream Number'" } + ] + }, + { + "enumerant" : "Location", + "value" : 30, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Location'" } + ] + }, + { + "enumerant" : "Component", + "value" : 31, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Component'" } + ] + }, + { + "enumerant" : "Index", + "value" : 32, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Index'" } + ] + }, + { + "enumerant" : "Binding", + "value" : 33, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Binding Point'" } + ] + }, + { + "enumerant" : "DescriptorSet", + "value" : 34, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Descriptor Set'" } + ] + }, + { + "enumerant" : "Offset", + "value" : 35, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Byte Offset'" } + ] + }, + { + "enumerant" : "XfbBuffer", + "value" : 36, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" } + ] + }, + { + "enumerant" : "XfbStride", + "value" : 37, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Stride'" } + ] + }, + { + "enumerant" : "FuncParamAttr", + "value" : 38, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" } + ] + }, + { + "enumerant" : "FPRoundingMode", + "value" : 39, + "capabilities" : [ + "Kernel", + "StorageUniformBufferBlock16", + "StorageUniform16", + "StoragePushConstant16", + "StorageInputOutput16" + ], + "parameters" : [ + { "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" } + ] + }, + { + "enumerant" : "FPFastMathMode", + "value" : 40, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" } + ] + }, + { + "enumerant" : "LinkageAttributes", + "value" : 41, + "capabilities" : [ "Linkage" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "LinkageType", "name" : "'Linkage Type'" } + ] + }, + { + "enumerant" : "NoContraction", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InputAttachmentIndex", + "value" : 43, + "capabilities" : [ "InputAttachment" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Attachment Index'" } + ] + }, + { + "enumerant" : "Alignment", + "value" : 44, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Alignment'" } + ] + }, + { + "enumerant" : "MaxByteOffset", + "value" : 45, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Max Byte Offset'" } + ] + }, + { + "enumerant" : "AlignmentId", + "value" : 46, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Alignment'" } + ] + }, + { + "enumerant" : "MaxByteOffsetId", + "value" : 47, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Max Byte Offset'" } + ] + }, + { + "enumerant" : "ExplicitInterpAMD", + "value" : 4999 + }, + { + "enumerant" : "OverrideCoverageNV", + "value" : 5248, + "capabilities" : [ "SampleMaskOverrideCoverageNV" ] + }, + { + "enumerant" : "PassthroughNV", + "value" : 5250, + "capabilities" : [ "GeometryShaderPassthroughNV" ] + }, + { + "enumerant" : "ViewportRelativeNV", + "value" : 5252, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryViewportRelativeNV", + "value" : 5256, + "capabilities" : [ "ShaderStereoViewNV" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ] + }, + { + "enumerant" : "HlslCounterBufferGOOGLE", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + }, + { + "enumerant" : "HlslSemanticGOOGLE", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "BuiltIn", + "enumerants" : [ + { + "enumerant" : "Position", + "value" : 0, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointSize", + "value" : 1, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 3, + "capabilities" : [ "ClipDistance" ] + }, + { + "enumerant" : "CullDistance", + "value" : 4, + "capabilities" : [ "CullDistance" ] + }, + { + "enumerant" : "VertexId", + "value" : 5, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceId", + "value" : 6, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PrimitiveId", + "value" : 7, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "InvocationId", + "value" : 8, + "capabilities" : [ "Geometry", "Tessellation" ] + }, + { + "enumerant" : "Layer", + "value" : 9, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ViewportIndex", + "value" : 10, + "capabilities" : [ "MultiViewport" ] + }, + { + "enumerant" : "TessLevelOuter", + "value" : 11, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessLevelInner", + "value" : 12, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "TessCoord", + "value" : 13, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "PatchVertices", + "value" : 14, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "FragCoord", + "value" : 15, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "PointCoord", + "value" : 16, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FrontFacing", + "value" : 17, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampleId", + "value" : 18, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SamplePosition", + "value" : 19, + "capabilities" : [ "SampleRateShading" ] + }, + { + "enumerant" : "SampleMask", + "value" : 20, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "FragDepth", + "value" : 22, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "HelperInvocation", + "value" : 23, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "NumWorkgroups", + "value" : 24 + }, + { + "enumerant" : "WorkgroupSize", + "value" : 25 + }, + { + "enumerant" : "WorkgroupId", + "value" : 26 + }, + { + "enumerant" : "LocalInvocationId", + "value" : 27 + }, + { + "enumerant" : "GlobalInvocationId", + "value" : 28 + }, + { + "enumerant" : "LocalInvocationIndex", + "value" : 29 + }, + { + "enumerant" : "WorkDim", + "value" : 30, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalSize", + "value" : 31, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "EnqueuedWorkgroupSize", + "value" : 32, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalOffset", + "value" : 33, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "GlobalLinearId", + "value" : 34, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupSize", + "value" : 36, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupMaxSize", + "value" : 37, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumSubgroups", + "value" : 38, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "NumEnqueuedSubgroups", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupId", + "value" : 40, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "SubgroupLocalInvocationId", + "value" : 41, + "capabilities" : [ "Kernel", "SubgroupBallotKHR" ] + }, + { + "enumerant" : "VertexIndex", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InstanceIndex", + "value" : 43, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SubgroupEqMaskKHR", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGeMaskKHR", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupGtMaskKHR", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLeMaskKHR", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "SubgroupLtMaskKHR", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR" ] + }, + { + "enumerant" : "BaseVertex", + "value" : 4424, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "BaseInstance", + "value" : 4425, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DrawIndex", + "value" : 4426, + "capabilities" : [ "DrawParameters" ] + }, + { + "enumerant" : "DeviceIndex", + "value" : 4438, + "capabilities" : [ "DeviceGroup" ] + }, + { + "enumerant" : "ViewIndex", + "value" : 4440, + "capabilities" : [ "MultiView" ] + }, + { + "enumerant" : "BaryCoordNoPerspAMD", + "value" : 4992 + }, + { + "enumerant" : "BaryCoordNoPerspCentroidAMD", + "value" : 4993 + }, + { + "enumerant" : "BaryCoordNoPerspSampleAMD", + "value" : 4994 + }, + { + "enumerant" : "BaryCoordSmoothAMD", + "value" : 4995 + }, + { + "enumerant" : "BaryCoordSmoothCentroidAMD", + "value" : 4996 + }, + { + "enumerant" : "BaryCoordSmoothSampleAMD", + "value" : 4997 + }, + { + "enumerant" : "BaryCoordPullModelAMD", + "value" : 4998 + }, + { + "enumerant" : "FragStencilRefEXT", + "value" : 5014, + "capabilities" : [ "StencilExportEXT" ] + }, + { + "enumerant" : "ViewportMaskNV", + "value" : 5253, + "capabilities" : [ "ShaderViewportMaskNV" ] + }, + { + "enumerant" : "SecondaryPositionNV", + "value" : 5257, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "SecondaryViewportMaskNV", + "value" : 5258, + "capabilities" : [ "ShaderStereoViewNV" ] + }, + { + "enumerant" : "PositionPerViewNV", + "value" : 5261, + "capabilities" : [ "PerViewAttributesNV" ] + }, + { + "enumerant" : "ViewportMaskPerViewNV", + "value" : 5262, + "capabilities" : [ "PerViewAttributesNV" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Scope", + "enumerants" : [ + { + "enumerant" : "CrossDevice", + "value" : 0 + }, + { + "enumerant" : "Device", + "value" : 1 + }, + { + "enumerant" : "Workgroup", + "value" : 2 + }, + { + "enumerant" : "Subgroup", + "value" : 3 + }, + { + "enumerant" : "Invocation", + "value" : 4 + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "GroupOperation", + "enumerants" : [ + { + "enumerant" : "Reduce", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InclusiveScan", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ExclusiveScan", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "KernelEnqueueFlags", + "enumerants" : [ + { + "enumerant" : "NoWait", + "value" : 0, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitKernel", + "value" : 1, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "WaitWorkGroup", + "value" : 2, + "capabilities" : [ "Kernel" ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Capability", + "enumerants" : [ + { + "enumerant" : "Matrix", + "value" : 0 + }, + { + "enumerant" : "Shader", + "value" : 1, + "capabilities" : [ "Matrix" ] + }, + { + "enumerant" : "Geometry", + "value" : 2, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Tessellation", + "value" : 3, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Addresses", + "value" : 4 + }, + { + "enumerant" : "Linkage", + "value" : 5 + }, + { + "enumerant" : "Kernel", + "value" : 6 + }, + { + "enumerant" : "Vector16", + "value" : 7, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16Buffer", + "value" : 8, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Float16", + "value" : 9 + }, + { + "enumerant" : "Float64", + "value" : 10 + }, + { + "enumerant" : "Int64", + "value" : 11 + }, + { + "enumerant" : "Int64Atomics", + "value" : 12, + "capabilities" : [ "Int64" ] + }, + { + "enumerant" : "ImageBasic", + "value" : 13, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "ImageReadWrite", + "value" : 14, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "ImageMipmap", + "value" : 15, + "capabilities" : [ "ImageBasic" ] + }, + { + "enumerant" : "Pipes", + "value" : 17, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "Groups", + "value" : 18 + }, + { + "enumerant" : "DeviceEnqueue", + "value" : 19, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "LiteralSampler", + "value" : 20, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "AtomicStorage", + "value" : 21, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Int16", + "value" : 22 + }, + { + "enumerant" : "TessellationPointSize", + "value" : 23, + "capabilities" : [ "Tessellation" ] + }, + { + "enumerant" : "GeometryPointSize", + "value" : 24, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "ImageGatherExtended", + "value" : 25, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageMultisample", + "value" : 27, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "UniformBufferArrayDynamicIndexing", + "value" : 28, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledImageArrayDynamicIndexing", + "value" : 29, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageBufferArrayDynamicIndexing", + "value" : 30, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageArrayDynamicIndexing", + "value" : 31, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ClipDistance", + "value" : 32, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "CullDistance", + "value" : 33, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageCubeArray", + "value" : 34, + "capabilities" : [ "SampledCubeArray" ] + }, + { + "enumerant" : "SampleRateShading", + "value" : 35, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageRect", + "value" : 36, + "capabilities" : [ "SampledRect" ] + }, + { + "enumerant" : "SampledRect", + "value" : 37, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GenericPointer", + "value" : 38, + "capabilities" : [ "Addresses" ] + }, + { + "enumerant" : "Int8", + "value" : 39, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "InputAttachment", + "value" : 40, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SparseResidency", + "value" : 41, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MinLod", + "value" : 42, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "Sampled1D", + "value" : 43 + }, + { + "enumerant" : "Image1D", + "value" : 44, + "capabilities" : [ "Sampled1D" ] + }, + { + "enumerant" : "SampledCubeArray", + "value" : 45, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "SampledBuffer", + "value" : 46 + }, + { + "enumerant" : "ImageBuffer", + "value" : 47, + "capabilities" : [ "SampledBuffer" ] + }, + { + "enumerant" : "ImageMSArray", + "value" : 48, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageExtendedFormats", + "value" : 49, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "ImageQuery", + "value" : 50, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "DerivativeControl", + "value" : 51, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "InterpolationFunction", + "value" : 52, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "TransformFeedback", + "value" : 53, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "GeometryStreams", + "value" : 54, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "StorageImageReadWithoutFormat", + "value" : 55, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "StorageImageWriteWithoutFormat", + "value" : 56, + "capabilities" : [ "Shader" ] + }, + { + "enumerant" : "MultiViewport", + "value" : 57, + "capabilities" : [ "Geometry" ] + }, + { + "enumerant" : "SubgroupDispatch", + "value" : 58, + "capabilities" : [ "DeviceEnqueue" ] + }, + { + "enumerant" : "NamedBarrier", + "value" : 59, + "capabilities" : [ "Kernel" ] + }, + { + "enumerant" : "PipeStorage", + "value" : 60, + "capabilities" : [ "Pipes" ] + }, + { + "enumerant" : "SubgroupBallotKHR", + "value" : 4423, + "extensions" : [ "SPV_KHR_shader_ballot" ] + }, + { + "enumerant" : "DrawParameters", + "value" : 4427, + "extensions" : [ "SPV_KHR_shader_draw_parameters" ] + }, + { + "enumerant" : "SubgroupVoteKHR", + "value" : 4431, + "extensions" : [ "SPV_KHR_subgroup_vote" ] + }, + { + "enumerant" : "StorageBuffer16BitAccess", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniformBufferBlock16", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "UniformAndStorageBuffer16BitAccess", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageUniform16", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StoragePushConstant16", + "value" : 4435, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "StorageInputOutput16", + "value" : 4436, + "extensions" : [ "SPV_KHR_16bit_storage" ] + }, + { + "enumerant" : "DeviceGroup", + "value" : 4437, + "extensions" : [ "SPV_KHR_device_group" ] + }, + { + "enumerant" : "MultiView", + "value" : 4439, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_multiview" ] + }, + { + "enumerant" : "VariablePointersStorageBuffer", + "value" : 4441, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant" : "VariablePointers", + "value" : 4442, + "capabilities" : [ "VariablePointersStorageBuffer" ], + "extensions" : [ "SPV_KHR_variable_pointers" ] + }, + { + "enumerant": "AtomicStorageOps", + "value": 4445, + "extensions": [ "SPV_KHR_shader_atomic_counter_ops" ] + }, + { + "enumerant" : "SampleMaskPostDepthCoverage", + "value" : 4447, + "extensions" : [ "SPV_KHR_post_depth_coverage" ] + }, + { + "enumerant" : "ImageGatherBiasLodAMD", + "value" : 5009, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_texture_gather_bias_lod" ] + }, + { + "enumerant" : "FragmentMaskAMD", + "value" : 5010, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ] + }, + { + "enumerant" : "StencilExportEXT", + "value" : 5013, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ] + }, + { + "enumerant" : "ImageReadWriteLodAMD", + "value" : 5015, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_image_load_store_lod" ] + }, + { + "enumerant" : "SampleMaskOverrideCoverageNV", + "value" : 5249, + "capabilities" : [ "SampleRateShading" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ] + }, + { + "enumerant" : "GeometryShaderPassthroughNV", + "value" : 5251, + "capabilities" : [ "Geometry" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerEXT", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_EXT_shader_viewport_index_layer" ] + }, + { + "enumerant" : "ShaderViewportIndexLayerNV", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderViewportMaskNV", + "value" : 5255, + "capabilities" : [ "ShaderViewportIndexLayerNV" ], + "extensions" : [ "SPV_NV_viewport_array2" ] + }, + { + "enumerant" : "ShaderStereoViewNV", + "value" : 5259, + "capabilities" : [ "ShaderViewportMaskNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ] + }, + { + "enumerant" : "PerViewAttributesNV", + "value" : 5260, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes" ] + }, + { + "enumerant" : "SubgroupShuffleINTEL", + "value" : 5568, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupBufferBlockIOINTEL", + "value" : 5569, + "extensions" : [ "SPV_INTEL_subgroups" ] + }, + { + "enumerant" : "SubgroupImageBlockIOINTEL", + "value" : 5570, + "extensions" : [ "SPV_INTEL_subgroups" ] + } + ] + }, + { + "category" : "Id", + "kind" : "IdResultType", + "doc" : "Reference to an representing the result's type of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdResult", + "doc" : "Definition of an representing the result of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdMemorySemantics", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the MemorySemantics operand kind" + }, + { + "category" : "Id", + "kind" : "IdScope", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the Scope operand kind" + }, + { + "category" : "Id", + "kind" : "IdRef", + "doc" : "Reference to an " + }, + { + "category" : "Literal", + "kind" : "LiteralInteger", + "doc" : "An integer consuming one or more words" + }, + { + "category" : "Literal", + "kind" : "LiteralString", + "doc" : "A null-terminated stream of characters consuming an integral number of words" + }, + { + "category" : "Literal", + "kind" : "LiteralContextDependentNumber", + "doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction" + }, + { + "category" : "Literal", + "kind" : "LiteralExtInstInteger", + "doc" : "A 32-bit unsigned integer indicating which instruction to use and determining the layout of following operands (for OpExtInst)" + }, + { + "category" : "Literal", + "kind" : "LiteralSpecConstantOpInteger", + "doc" : "An opcode indicating the operation to be performed and determining the layout of following operands (for OpSpecConstantOp)" + }, + { + "category" : "Composite", + "kind" : "PairLiteralIntegerIdRef", + "bases" : [ "LiteralInteger", "IdRef" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefLiteralInteger", + "bases" : [ "IdRef", "LiteralInteger" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefIdRef", + "bases" : [ "IdRef", "IdRef" ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.cs b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.cs new file mode 100644 index 000000000000..493303d6ab08 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.cs @@ -0,0 +1,1021 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C# +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + + public static class Specification + { + public const uint MagicNumber = 0x07230203; + public const uint Version = 0x00010200; + public const uint Revision = 2; + public const uint OpCodeMask = 0xffff; + public const uint WordCountShift = 16; + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + } + + public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + } + + public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + } + + public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + } + + public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + } + + public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + } + + public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + } + + public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + } + + public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + } + + public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + } + + public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + } + + public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + } + + public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + } + + public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + } + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.h b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.h new file mode 100644 index 000000000000..7c6d884d8e49 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.h @@ -0,0 +1,1021 @@ +/* +** Copyright (c) 2014-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10200 +#define SPV_REVISION 2 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010200; +static const unsigned int SpvRevision = 2; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModeInitializer = 33, + SpvExecutionModeFinalizer = 34, + SpvExecutionModeSubgroupSize = 35, + SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModeSubgroupsPerWorkgroupId = 37, + SpvExecutionModeLocalSizeId = 38, + SpvExecutionModeLocalSizeHintId = 39, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationMaxByteOffset = 45, + SpvDecorationAlignmentId = 46, + SpvDecorationMaxByteOffsetId = 47, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlDependencyInfiniteShift = 2, + SpvLoopControlDependencyLengthShift = 3, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, + SpvLoopControlDependencyInfiniteMask = 0x00000004, + SpvLoopControlDependencyLengthMask = 0x00000008, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupDispatch = 58, + SpvCapabilityNamedBarrier = 59, + SpvCapabilityPipeStorage = 60, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpSizeOf = 321, + SpvOpTypePipeStorage = 322, + SpvOpConstantPipeStorage = 323, + SpvOpCreatePipeFromPipeStorage = 324, + SpvOpGetKernelLocalSizeForSubgroupCount = 325, + SpvOpGetKernelMaxNumSubgroups = 326, + SpvOpTypeNamedBarrier = 327, + SpvOpNamedBarrierInitialize = 328, + SpvOpMemoryNamedBarrier = 329, + SpvOpModuleProcessed = 330, + SpvOpExecutionModeId = 331, + SpvOpDecorateId = 332, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#endif // #ifndef spirv_H + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.hpp b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.hpp new file mode 100644 index 000000000000..57bd97a02109 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.hpp @@ -0,0 +1,1030 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10200 +#define SPV_REVISION 2 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010200; +static const unsigned int Revision = 2; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModeInitializer = 33, + ExecutionModeFinalizer = 34, + ExecutionModeSubgroupSize = 35, + ExecutionModeSubgroupsPerWorkgroup = 36, + ExecutionModeSubgroupsPerWorkgroupId = 37, + ExecutionModeLocalSizeId = 38, + ExecutionModeLocalSizeHintId = 39, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationMaxByteOffset = 45, + DecorationAlignmentId = 46, + DecorationMaxByteOffsetId = 47, + DecorationExplicitInterpAMD = 4999, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlDependencyInfiniteShift = 2, + LoopControlDependencyLengthShift = 3, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, + LoopControlDependencyInfiniteMask = 0x00000004, + LoopControlDependencyLengthMask = 0x00000008, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupDispatch = 58, + CapabilityNamedBarrier = 59, + CapabilityPipeStorage = 60, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilityMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + OpMax = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.hpp11 b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.hpp11 new file mode 100644 index 000000000000..7a875fdb1665 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.hpp11 @@ -0,0 +1,1030 @@ +// Copyright (c) 2014-2018 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10200 +#define SPV_REVISION 2 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010200; +static const unsigned int Revision = 2; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + Max = 0x7fffffff, +}; + +// Overload operator| for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.json b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.json new file mode 100644 index 000000000000..9c0ff0a43e32 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.json @@ -0,0 +1,1046 @@ +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2018 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "", + "Some tokens act like mask values, which can be OR'd together,", + "while others are mutually exclusive. The mask-like ones have", + "\"Mask\" in their name, and a parallel enum that has the shift", + "amount (1 << x) for each corresponding enumerant." + ] + ], + "MagicNumber": 119734787, + "Version": 66048, + "Revision": 2, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "Initializer": 33, + "Finalizer": 34, + "SubgroupSize": 35, + "SubgroupsPerWorkgroup": 36, + "SubgroupsPerWorkgroupId": 37, + "LocalSizeId": 38, + "LocalSizeHintId": 39, + "PostDepthCoverage": 4446, + "StencilRefReplacingEXT": 5027 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "MaxByteOffset": 45, + "AlignmentId": 46, + "MaxByteOffsetId": 47, + "ExplicitInterpAMD": 4999, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1, + "DependencyInfinite": 2, + "DependencyLength": 3 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupDispatch": 58, + "NamedBarrier": 59, + "PipeStorage": 60, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpSizeOf": 321, + "OpTypePipeStorage": 322, + "OpConstantPipeStorage": 323, + "OpCreatePipeFromPipeStorage": 324, + "OpGetKernelLocalSizeForSubgroupCount": 325, + "OpGetKernelMaxNumSubgroups": 326, + "OpTypeNamedBarrier": 327, + "OpNamedBarrierInitialize": 328, + "OpMemoryNamedBarrier": 329, + "OpModuleProcessed": 330, + "OpExecutionModeId": 331, + "OpDecorateId": 332, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpSubgroupReadInvocationKHR": 4432, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateStringGOOGLE": 5633 + } + } + ] + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.lua b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.lua new file mode 100644 index 000000000000..0de507d5c913 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.lua @@ -0,0 +1,977 @@ +-- Copyright (c) 2014-2018 The Khronos Group Inc. +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and/or associated documentation files (the "Materials"), +-- to deal in the Materials without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Materials, and to permit persons to whom the +-- Materials are furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Materials. +-- +-- MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +-- STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +-- HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +-- +-- THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +-- IN THE MATERIALS. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- +-- Some tokens act like mask values, which can be OR'd together, +-- while others are mutually exclusive. The mask-like ones have +-- "Mask" in their name, and a parallel enum that has the shift +-- amount (1 << x) for each corresponding enumerant. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010200, + Revision = 2, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + PostDepthCoverage = 4446, + StencilRefReplacingEXT = 5027, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + ExplicitInterpAMD = 4999, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + SubgroupEqMaskKHR = 4416, + SubgroupGeMaskKHR = 4417, + SubgroupGtMaskKHR = 4418, + SubgroupLeMaskKHR = 4419, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + DeviceIndex = 4438, + ViewIndex = 4440, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpSubgroupReadInvocationKHR = 4432, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, + }, + +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.py b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.py new file mode 100644 index 000000000000..cefee4d66ac4 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/1.2/spirv.py @@ -0,0 +1,977 @@ +# Copyright (c) 2014-2018 The Khronos Group Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and/or associated documentation files (the "Materials"), +# to deal in the Materials without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Materials, and to permit persons to whom the +# Materials are furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Materials. +# +# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +# STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +# HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +# +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +# IN THE MATERIALS. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# +# Some tokens act like mask values, which can be OR'd together, +# while others are mutually exclusive. The mask-like ones have +# "Mask" in their name, and a parallel enum that has the shift +# amount (1 << x) for each corresponding enumerant. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010200, + 'Revision' : 2, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'Initializer' : 33, + 'Finalizer' : 34, + 'SubgroupSize' : 35, + 'SubgroupsPerWorkgroup' : 36, + 'SubgroupsPerWorkgroupId' : 37, + 'LocalSizeId' : 38, + 'LocalSizeHintId' : 39, + 'PostDepthCoverage' : 4446, + 'StencilRefReplacingEXT' : 5027, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'MaxByteOffset' : 45, + 'AlignmentId' : 46, + 'MaxByteOffsetId' : 47, + 'ExplicitInterpAMD' : 4999, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + 'DependencyInfinite' : 2, + 'DependencyLength' : 3, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + 'DependencyInfinite' : 0x00000004, + 'DependencyLength' : 0x00000008, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupDispatch' : 58, + 'NamedBarrier' : 59, + 'PipeStorage' : 60, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpSizeOf' : 321, + 'OpTypePipeStorage' : 322, + 'OpConstantPipeStorage' : 323, + 'OpCreatePipeFromPipeStorage' : 324, + 'OpGetKernelLocalSizeForSubgroupCount' : 325, + 'OpGetKernelMaxNumSubgroups' : 326, + 'OpTypeNamedBarrier' : 327, + 'OpNamedBarrierInitialize' : 328, + 'OpMemoryNamedBarrier' : 329, + 'OpModuleProcessed' : 330, + 'OpExecutionModeId' : 331, + 'OpDecorateId' : 332, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateStringGOOGLE' : 5633, + }, + +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/spir-v.xml b/thirdparty/glslang/glslang/Include/spirv/spir-v.xml new file mode 100644 index 000000000000..4a2de831410f --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/spir-v.xml @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_gcn_shader.h b/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_gcn_shader.h new file mode 100644 index 000000000000..e626a7a9568d --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_gcn_shader.h @@ -0,0 +1,52 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_AMD_gcn_shader_H_ +#define SPIRV_UNIFIED1_AMD_gcn_shader_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AMD_gcn_shaderRevision = 2, + AMD_gcn_shaderRevision_BitWidthPadding = 0x7fffffff +}; + +enum AMD_gcn_shaderInstructions { + AMD_gcn_shaderCubeFaceIndexAMD = 1, + AMD_gcn_shaderCubeFaceCoordAMD = 2, + AMD_gcn_shaderTimeAMD = 3, + AMD_gcn_shaderInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_AMD_gcn_shader_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_ballot.h b/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_ballot.h new file mode 100644 index 000000000000..563c0b622d51 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_ballot.h @@ -0,0 +1,53 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_AMD_shader_ballot_H_ +#define SPIRV_UNIFIED1_AMD_shader_ballot_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AMD_shader_ballotRevision = 5, + AMD_shader_ballotRevision_BitWidthPadding = 0x7fffffff +}; + +enum AMD_shader_ballotInstructions { + AMD_shader_ballotSwizzleInvocationsAMD = 1, + AMD_shader_ballotSwizzleInvocationsMaskedAMD = 2, + AMD_shader_ballotWriteInvocationAMD = 3, + AMD_shader_ballotMbcntAMD = 4, + AMD_shader_ballotInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_AMD_shader_ballot_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h b/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h new file mode 100644 index 000000000000..e663330c19fa --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h @@ -0,0 +1,50 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_AMD_shader_explicit_vertex_parameter_H_ +#define SPIRV_UNIFIED1_AMD_shader_explicit_vertex_parameter_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AMD_shader_explicit_vertex_parameterRevision = 4, + AMD_shader_explicit_vertex_parameterRevision_BitWidthPadding = 0x7fffffff +}; + +enum AMD_shader_explicit_vertex_parameterInstructions { + AMD_shader_explicit_vertex_parameterInterpolateAtVertexAMD = 1, + AMD_shader_explicit_vertex_parameterInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_AMD_shader_explicit_vertex_parameter_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_trinary_minmax.h b/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_trinary_minmax.h new file mode 100644 index 000000000000..dd51c5fc81f7 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/AMD_shader_trinary_minmax.h @@ -0,0 +1,58 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_AMD_shader_trinary_minmax_H_ +#define SPIRV_UNIFIED1_AMD_shader_trinary_minmax_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AMD_shader_trinary_minmaxRevision = 4, + AMD_shader_trinary_minmaxRevision_BitWidthPadding = 0x7fffffff +}; + +enum AMD_shader_trinary_minmaxInstructions { + AMD_shader_trinary_minmaxFMin3AMD = 1, + AMD_shader_trinary_minmaxUMin3AMD = 2, + AMD_shader_trinary_minmaxSMin3AMD = 3, + AMD_shader_trinary_minmaxFMax3AMD = 4, + AMD_shader_trinary_minmaxUMax3AMD = 5, + AMD_shader_trinary_minmaxSMax3AMD = 6, + AMD_shader_trinary_minmaxFMid3AMD = 7, + AMD_shader_trinary_minmaxUMid3AMD = 8, + AMD_shader_trinary_minmaxSMid3AMD = 9, + AMD_shader_trinary_minmaxInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_AMD_shader_trinary_minmax_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/DebugInfo.h b/thirdparty/glslang/glslang/Include/spirv/unified1/DebugInfo.h new file mode 100644 index 000000000000..a3c0af456203 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/DebugInfo.h @@ -0,0 +1,144 @@ +// Copyright (c) 2017-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +#ifndef SPIRV_UNIFIED1_DebugInfo_H_ +#define SPIRV_UNIFIED1_DebugInfo_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + DebugInfoVersion = 100, + DebugInfoVersion_BitWidthPadding = 0x7fffffff +}; +enum { + DebugInfoRevision = 1, + DebugInfoRevision_BitWidthPadding = 0x7fffffff +}; + +enum DebugInfoInstructions { + DebugInfoDebugInfoNone = 0, + DebugInfoDebugCompilationUnit = 1, + DebugInfoDebugTypeBasic = 2, + DebugInfoDebugTypePointer = 3, + DebugInfoDebugTypeQualifier = 4, + DebugInfoDebugTypeArray = 5, + DebugInfoDebugTypeVector = 6, + DebugInfoDebugTypedef = 7, + DebugInfoDebugTypeFunction = 8, + DebugInfoDebugTypeEnum = 9, + DebugInfoDebugTypeComposite = 10, + DebugInfoDebugTypeMember = 11, + DebugInfoDebugTypeInheritance = 12, + DebugInfoDebugTypePtrToMember = 13, + DebugInfoDebugTypeTemplate = 14, + DebugInfoDebugTypeTemplateParameter = 15, + DebugInfoDebugTypeTemplateTemplateParameter = 16, + DebugInfoDebugTypeTemplateParameterPack = 17, + DebugInfoDebugGlobalVariable = 18, + DebugInfoDebugFunctionDeclaration = 19, + DebugInfoDebugFunction = 20, + DebugInfoDebugLexicalBlock = 21, + DebugInfoDebugLexicalBlockDiscriminator = 22, + DebugInfoDebugScope = 23, + DebugInfoDebugNoScope = 24, + DebugInfoDebugInlinedAt = 25, + DebugInfoDebugLocalVariable = 26, + DebugInfoDebugInlinedVariable = 27, + DebugInfoDebugDeclare = 28, + DebugInfoDebugValue = 29, + DebugInfoDebugOperation = 30, + DebugInfoDebugExpression = 31, + DebugInfoDebugMacroDef = 32, + DebugInfoDebugMacroUndef = 33, + DebugInfoInstructionsMax = 0x7fffffff +}; + + +enum DebugInfoDebugInfoFlags { + DebugInfoNone = 0x0000, + DebugInfoFlagIsProtected = 0x01, + DebugInfoFlagIsPrivate = 0x02, + DebugInfoFlagIsPublic = 0x03, + DebugInfoFlagIsLocal = 0x04, + DebugInfoFlagIsDefinition = 0x08, + DebugInfoFlagFwdDecl = 0x10, + DebugInfoFlagArtificial = 0x20, + DebugInfoFlagExplicit = 0x40, + DebugInfoFlagPrototyped = 0x80, + DebugInfoFlagObjectPointer = 0x100, + DebugInfoFlagStaticMember = 0x200, + DebugInfoFlagIndirectVariable = 0x400, + DebugInfoFlagLValueReference = 0x800, + DebugInfoFlagRValueReference = 0x1000, + DebugInfoFlagIsOptimized = 0x2000, + DebugInfoDebugInfoFlagsMax = 0x7fffffff +}; + +enum DebugInfoDebugBaseTypeAttributeEncoding { + DebugInfoUnspecified = 0, + DebugInfoAddress = 1, + DebugInfoBoolean = 2, + DebugInfoFloat = 4, + DebugInfoSigned = 5, + DebugInfoSignedChar = 6, + DebugInfoUnsigned = 7, + DebugInfoUnsignedChar = 8, + DebugInfoDebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum DebugInfoDebugCompositeType { + DebugInfoClass = 0, + DebugInfoStructure = 1, + DebugInfoUnion = 2, + DebugInfoDebugCompositeTypeMax = 0x7fffffff +}; + +enum DebugInfoDebugTypeQualifier { + DebugInfoConstType = 0, + DebugInfoVolatileType = 1, + DebugInfoRestrictType = 2, + DebugInfoDebugTypeQualifierMax = 0x7fffffff +}; + +enum DebugInfoDebugOperation { + DebugInfoDeref = 0, + DebugInfoPlus = 1, + DebugInfoMinus = 2, + DebugInfoPlusUconst = 3, + DebugInfoBitPiece = 4, + DebugInfoSwap = 5, + DebugInfoXderef = 6, + DebugInfoStackValue = 7, + DebugInfoConstu = 8, + DebugInfoDebugOperationMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_DebugInfo_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/GLSL.std.450.h b/thirdparty/glslang/glslang/Include/spirv/unified1/GLSL.std.450.h new file mode 100644 index 000000000000..0594f907a145 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/GLSL.std.450.h @@ -0,0 +1,131 @@ +/* +** Copyright (c) 2014-2024 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLstd450_H +#define GLSLstd450_H + +static const int GLSLstd450Version = 100; +static const int GLSLstd450Revision = 3; + +enum GLSLstd450 { + GLSLstd450Bad = 0, // Don't use + + GLSLstd450Round = 1, + GLSLstd450RoundEven = 2, + GLSLstd450Trunc = 3, + GLSLstd450FAbs = 4, + GLSLstd450SAbs = 5, + GLSLstd450FSign = 6, + GLSLstd450SSign = 7, + GLSLstd450Floor = 8, + GLSLstd450Ceil = 9, + GLSLstd450Fract = 10, + + GLSLstd450Radians = 11, + GLSLstd450Degrees = 12, + GLSLstd450Sin = 13, + GLSLstd450Cos = 14, + GLSLstd450Tan = 15, + GLSLstd450Asin = 16, + GLSLstd450Acos = 17, + GLSLstd450Atan = 18, + GLSLstd450Sinh = 19, + GLSLstd450Cosh = 20, + GLSLstd450Tanh = 21, + GLSLstd450Asinh = 22, + GLSLstd450Acosh = 23, + GLSLstd450Atanh = 24, + GLSLstd450Atan2 = 25, + + GLSLstd450Pow = 26, + GLSLstd450Exp = 27, + GLSLstd450Log = 28, + GLSLstd450Exp2 = 29, + GLSLstd450Log2 = 30, + GLSLstd450Sqrt = 31, + GLSLstd450InverseSqrt = 32, + + GLSLstd450Determinant = 33, + GLSLstd450MatrixInverse = 34, + + GLSLstd450Modf = 35, // second operand needs an OpVariable to write to + GLSLstd450ModfStruct = 36, // no OpVariable operand + GLSLstd450FMin = 37, + GLSLstd450UMin = 38, + GLSLstd450SMin = 39, + GLSLstd450FMax = 40, + GLSLstd450UMax = 41, + GLSLstd450SMax = 42, + GLSLstd450FClamp = 43, + GLSLstd450UClamp = 44, + GLSLstd450SClamp = 45, + GLSLstd450FMix = 46, + GLSLstd450IMix = 47, // Reserved + GLSLstd450Step = 48, + GLSLstd450SmoothStep = 49, + + GLSLstd450Fma = 50, + GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to + GLSLstd450FrexpStruct = 52, // no OpVariable operand + GLSLstd450Ldexp = 53, + + GLSLstd450PackSnorm4x8 = 54, + GLSLstd450PackUnorm4x8 = 55, + GLSLstd450PackSnorm2x16 = 56, + GLSLstd450PackUnorm2x16 = 57, + GLSLstd450PackHalf2x16 = 58, + GLSLstd450PackDouble2x32 = 59, + GLSLstd450UnpackSnorm2x16 = 60, + GLSLstd450UnpackUnorm2x16 = 61, + GLSLstd450UnpackHalf2x16 = 62, + GLSLstd450UnpackSnorm4x8 = 63, + GLSLstd450UnpackUnorm4x8 = 64, + GLSLstd450UnpackDouble2x32 = 65, + + GLSLstd450Length = 66, + GLSLstd450Distance = 67, + GLSLstd450Cross = 68, + GLSLstd450Normalize = 69, + GLSLstd450FaceForward = 70, + GLSLstd450Reflect = 71, + GLSLstd450Refract = 72, + + GLSLstd450FindILsb = 73, + GLSLstd450FindSMsb = 74, + GLSLstd450FindUMsb = 75, + + GLSLstd450InterpolateAtCentroid = 76, + GLSLstd450InterpolateAtSample = 77, + GLSLstd450InterpolateAtOffset = 78, + + GLSLstd450NMin = 79, + GLSLstd450NMax = 80, + GLSLstd450NClamp = 81, + + GLSLstd450Count +}; + +#endif // #ifndef GLSLstd450_H diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticClspvReflection.h b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticClspvReflection.h new file mode 100644 index 000000000000..b6c27fa9b9e0 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticClspvReflection.h @@ -0,0 +1,97 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticClspvReflection_H_ +#define SPIRV_UNIFIED1_NonSemanticClspvReflection_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticClspvReflectionRevision = 6, + NonSemanticClspvReflectionRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticClspvReflectionInstructions { + NonSemanticClspvReflectionKernel = 1, + NonSemanticClspvReflectionArgumentInfo = 2, + NonSemanticClspvReflectionArgumentStorageBuffer = 3, + NonSemanticClspvReflectionArgumentUniform = 4, + NonSemanticClspvReflectionArgumentPodStorageBuffer = 5, + NonSemanticClspvReflectionArgumentPodUniform = 6, + NonSemanticClspvReflectionArgumentPodPushConstant = 7, + NonSemanticClspvReflectionArgumentSampledImage = 8, + NonSemanticClspvReflectionArgumentStorageImage = 9, + NonSemanticClspvReflectionArgumentSampler = 10, + NonSemanticClspvReflectionArgumentWorkgroup = 11, + NonSemanticClspvReflectionSpecConstantWorkgroupSize = 12, + NonSemanticClspvReflectionSpecConstantGlobalOffset = 13, + NonSemanticClspvReflectionSpecConstantWorkDim = 14, + NonSemanticClspvReflectionPushConstantGlobalOffset = 15, + NonSemanticClspvReflectionPushConstantEnqueuedLocalSize = 16, + NonSemanticClspvReflectionPushConstantGlobalSize = 17, + NonSemanticClspvReflectionPushConstantRegionOffset = 18, + NonSemanticClspvReflectionPushConstantNumWorkgroups = 19, + NonSemanticClspvReflectionPushConstantRegionGroupOffset = 20, + NonSemanticClspvReflectionConstantDataStorageBuffer = 21, + NonSemanticClspvReflectionConstantDataUniform = 22, + NonSemanticClspvReflectionLiteralSampler = 23, + NonSemanticClspvReflectionPropertyRequiredWorkgroupSize = 24, + NonSemanticClspvReflectionSpecConstantSubgroupMaxSize = 25, + NonSemanticClspvReflectionArgumentPointerPushConstant = 26, + NonSemanticClspvReflectionArgumentPointerUniform = 27, + NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer = 28, + NonSemanticClspvReflectionProgramScopeVariablePointerRelocation = 29, + NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant = 30, + NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant = 31, + NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform = 32, + NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform = 33, + NonSemanticClspvReflectionArgumentStorageTexelBuffer = 34, + NonSemanticClspvReflectionArgumentUniformTexelBuffer = 35, + NonSemanticClspvReflectionConstantDataPointerPushConstant = 36, + NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant = 37, + NonSemanticClspvReflectionPrintfInfo = 38, + NonSemanticClspvReflectionPrintfBufferStorageBuffer = 39, + NonSemanticClspvReflectionPrintfBufferPointerPushConstant = 40, + NonSemanticClspvReflectionNormalizedSamplerMaskPushConstant = 41, + NonSemanticClspvReflectionInstructionsMax = 0x7fffffff +}; + + +enum NonSemanticClspvReflectionKernelPropertyFlags { + NonSemanticClspvReflectionNone = 0x0, + NonSemanticClspvReflectionMayUsePrintf = 0x1, + NonSemanticClspvReflectionKernelPropertyFlagsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticClspvReflection_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticDebugBreak.h b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticDebugBreak.h new file mode 100644 index 000000000000..8604fe7842f0 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticDebugBreak.h @@ -0,0 +1,50 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticDebugBreak_H_ +#define SPIRV_UNIFIED1_NonSemanticDebugBreak_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticDebugBreakRevision = 1, + NonSemanticDebugBreakRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticDebugBreakInstructions { + NonSemanticDebugBreakDebugBreak = 1, + NonSemanticDebugBreakInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticDebugBreak_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticDebugPrintf.h b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticDebugPrintf.h new file mode 100644 index 000000000000..bc24683ec040 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticDebugPrintf.h @@ -0,0 +1,50 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ +#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticDebugPrintfRevision = 1, + NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticDebugPrintfInstructions { + NonSemanticDebugPrintfDebugPrintf = 1, + NonSemanticDebugPrintfInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticShaderDebugInfo100.h b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticShaderDebugInfo100.h new file mode 100644 index 000000000000..b276b560cbc8 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticShaderDebugInfo100.h @@ -0,0 +1,171 @@ +// Copyright (c) 2018-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +#ifndef SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ +#define SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticShaderDebugInfo100Version = 100, + NonSemanticShaderDebugInfo100Version_BitWidthPadding = 0x7fffffff +}; +enum { + NonSemanticShaderDebugInfo100Revision = 6, + NonSemanticShaderDebugInfo100Revision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100Instructions { + NonSemanticShaderDebugInfo100DebugInfoNone = 0, + NonSemanticShaderDebugInfo100DebugCompilationUnit = 1, + NonSemanticShaderDebugInfo100DebugTypeBasic = 2, + NonSemanticShaderDebugInfo100DebugTypePointer = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifier = 4, + NonSemanticShaderDebugInfo100DebugTypeArray = 5, + NonSemanticShaderDebugInfo100DebugTypeVector = 6, + NonSemanticShaderDebugInfo100DebugTypedef = 7, + NonSemanticShaderDebugInfo100DebugTypeFunction = 8, + NonSemanticShaderDebugInfo100DebugTypeEnum = 9, + NonSemanticShaderDebugInfo100DebugTypeComposite = 10, + NonSemanticShaderDebugInfo100DebugTypeMember = 11, + NonSemanticShaderDebugInfo100DebugTypeInheritance = 12, + NonSemanticShaderDebugInfo100DebugTypePtrToMember = 13, + NonSemanticShaderDebugInfo100DebugTypeTemplate = 14, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameter = 15, + NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter = 16, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack = 17, + NonSemanticShaderDebugInfo100DebugGlobalVariable = 18, + NonSemanticShaderDebugInfo100DebugFunctionDeclaration = 19, + NonSemanticShaderDebugInfo100DebugFunction = 20, + NonSemanticShaderDebugInfo100DebugLexicalBlock = 21, + NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator = 22, + NonSemanticShaderDebugInfo100DebugScope = 23, + NonSemanticShaderDebugInfo100DebugNoScope = 24, + NonSemanticShaderDebugInfo100DebugInlinedAt = 25, + NonSemanticShaderDebugInfo100DebugLocalVariable = 26, + NonSemanticShaderDebugInfo100DebugInlinedVariable = 27, + NonSemanticShaderDebugInfo100DebugDeclare = 28, + NonSemanticShaderDebugInfo100DebugValue = 29, + NonSemanticShaderDebugInfo100DebugOperation = 30, + NonSemanticShaderDebugInfo100DebugExpression = 31, + NonSemanticShaderDebugInfo100DebugMacroDef = 32, + NonSemanticShaderDebugInfo100DebugMacroUndef = 33, + NonSemanticShaderDebugInfo100DebugImportedEntity = 34, + NonSemanticShaderDebugInfo100DebugSource = 35, + NonSemanticShaderDebugInfo100DebugFunctionDefinition = 101, + NonSemanticShaderDebugInfo100DebugSourceContinued = 102, + NonSemanticShaderDebugInfo100DebugLine = 103, + NonSemanticShaderDebugInfo100DebugNoLine = 104, + NonSemanticShaderDebugInfo100DebugBuildIdentifier = 105, + NonSemanticShaderDebugInfo100DebugStoragePath = 106, + NonSemanticShaderDebugInfo100DebugEntryPoint = 107, + NonSemanticShaderDebugInfo100DebugTypeMatrix = 108, + NonSemanticShaderDebugInfo100InstructionsMax = 0x7fffffff +}; + + +enum NonSemanticShaderDebugInfo100DebugInfoFlags { + NonSemanticShaderDebugInfo100None = 0x0000, + NonSemanticShaderDebugInfo100FlagIsProtected = 0x01, + NonSemanticShaderDebugInfo100FlagIsPrivate = 0x02, + NonSemanticShaderDebugInfo100FlagIsPublic = 0x03, + NonSemanticShaderDebugInfo100FlagIsLocal = 0x04, + NonSemanticShaderDebugInfo100FlagIsDefinition = 0x08, + NonSemanticShaderDebugInfo100FlagFwdDecl = 0x10, + NonSemanticShaderDebugInfo100FlagArtificial = 0x20, + NonSemanticShaderDebugInfo100FlagExplicit = 0x40, + NonSemanticShaderDebugInfo100FlagPrototyped = 0x80, + NonSemanticShaderDebugInfo100FlagObjectPointer = 0x100, + NonSemanticShaderDebugInfo100FlagStaticMember = 0x200, + NonSemanticShaderDebugInfo100FlagIndirectVariable = 0x400, + NonSemanticShaderDebugInfo100FlagLValueReference = 0x800, + NonSemanticShaderDebugInfo100FlagRValueReference = 0x1000, + NonSemanticShaderDebugInfo100FlagIsOptimized = 0x2000, + NonSemanticShaderDebugInfo100FlagIsEnumClass = 0x4000, + NonSemanticShaderDebugInfo100FlagTypePassByValue = 0x8000, + NonSemanticShaderDebugInfo100FlagTypePassByReference = 0x10000, + NonSemanticShaderDebugInfo100FlagUnknownPhysicalLayout = 0x20000, + NonSemanticShaderDebugInfo100DebugInfoFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100BuildIdentifierFlags { + NonSemanticShaderDebugInfo100IdentifierPossibleDuplicates = 0x01, + NonSemanticShaderDebugInfo100BuildIdentifierFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncoding { + NonSemanticShaderDebugInfo100Unspecified = 0, + NonSemanticShaderDebugInfo100Address = 1, + NonSemanticShaderDebugInfo100Boolean = 2, + NonSemanticShaderDebugInfo100Float = 3, + NonSemanticShaderDebugInfo100Signed = 4, + NonSemanticShaderDebugInfo100SignedChar = 5, + NonSemanticShaderDebugInfo100Unsigned = 6, + NonSemanticShaderDebugInfo100UnsignedChar = 7, + NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugCompositeType { + NonSemanticShaderDebugInfo100Class = 0, + NonSemanticShaderDebugInfo100Structure = 1, + NonSemanticShaderDebugInfo100Union = 2, + NonSemanticShaderDebugInfo100DebugCompositeTypeMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugTypeQualifier { + NonSemanticShaderDebugInfo100ConstType = 0, + NonSemanticShaderDebugInfo100VolatileType = 1, + NonSemanticShaderDebugInfo100RestrictType = 2, + NonSemanticShaderDebugInfo100AtomicType = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifierMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugOperation { + NonSemanticShaderDebugInfo100Deref = 0, + NonSemanticShaderDebugInfo100Plus = 1, + NonSemanticShaderDebugInfo100Minus = 2, + NonSemanticShaderDebugInfo100PlusUconst = 3, + NonSemanticShaderDebugInfo100BitPiece = 4, + NonSemanticShaderDebugInfo100Swap = 5, + NonSemanticShaderDebugInfo100Xderef = 6, + NonSemanticShaderDebugInfo100StackValue = 7, + NonSemanticShaderDebugInfo100Constu = 8, + NonSemanticShaderDebugInfo100Fragment = 9, + NonSemanticShaderDebugInfo100DebugOperationMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugImportedEntity { + NonSemanticShaderDebugInfo100ImportedModule = 0, + NonSemanticShaderDebugInfo100ImportedDeclaration = 1, + NonSemanticShaderDebugInfo100DebugImportedEntityMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticVkspReflection.h b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticVkspReflection.h new file mode 100644 index 000000000000..0ef478a8caac --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/NonSemanticVkspReflection.h @@ -0,0 +1,57 @@ +// Copyright (c) 2020-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticVkspReflection_H_ +#define SPIRV_UNIFIED1_NonSemanticVkspReflection_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticVkspReflectionRevision = 1, + NonSemanticVkspReflectionRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticVkspReflectionInstructions { + NonSemanticVkspReflectionConfiguration = 1, + NonSemanticVkspReflectionStartCounter = 2, + NonSemanticVkspReflectionStopCounter = 3, + NonSemanticVkspReflectionPushConstants = 4, + NonSemanticVkspReflectionSpecializationMapEntry = 5, + NonSemanticVkspReflectionDescriptorSetBuffer = 6, + NonSemanticVkspReflectionDescriptorSetImage = 7, + NonSemanticVkspReflectionDescriptorSetSampler = 8, + NonSemanticVkspReflectionInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticVkspReflection_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/OpenCL.std.h b/thirdparty/glslang/glslang/Include/spirv/unified1/OpenCL.std.h new file mode 100644 index 000000000000..ed74f203e196 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/OpenCL.std.h @@ -0,0 +1,401 @@ +/* +** Copyright (c) 2015-2024 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef OPENCLstd_H +#define OPENCLstd_H + +#ifdef __cplusplus +namespace OpenCLLIB { + +enum Entrypoints { + + // Section 2.1: Math extended instructions + Acos = 0, + Acosh = 1, + Acospi = 2, + Asin = 3, + Asinh = 4, + Asinpi = 5, + Atan = 6, + Atan2 = 7, + Atanh = 8, + Atanpi = 9, + Atan2pi = 10, + Cbrt = 11, + Ceil = 12, + Copysign = 13, + Cos = 14, + Cosh = 15, + Cospi = 16, + Erfc = 17, + Erf = 18, + Exp = 19, + Exp2 = 20, + Exp10 = 21, + Expm1 = 22, + Fabs = 23, + Fdim = 24, + Floor = 25, + Fma = 26, + Fmax = 27, + Fmin = 28, + Fmod = 29, + Fract = 30, + Frexp = 31, + Hypot = 32, + Ilogb = 33, + Ldexp = 34, + Lgamma = 35, + Lgamma_r = 36, + Log = 37, + Log2 = 38, + Log10 = 39, + Log1p = 40, + Logb = 41, + Mad = 42, + Maxmag = 43, + Minmag = 44, + Modf = 45, + Nan = 46, + Nextafter = 47, + Pow = 48, + Pown = 49, + Powr = 50, + Remainder = 51, + Remquo = 52, + Rint = 53, + Rootn = 54, + Round = 55, + Rsqrt = 56, + Sin = 57, + Sincos = 58, + Sinh = 59, + Sinpi = 60, + Sqrt = 61, + Tan = 62, + Tanh = 63, + Tanpi = 64, + Tgamma = 65, + Trunc = 66, + Half_cos = 67, + Half_divide = 68, + Half_exp = 69, + Half_exp2 = 70, + Half_exp10 = 71, + Half_log = 72, + Half_log2 = 73, + Half_log10 = 74, + Half_powr = 75, + Half_recip = 76, + Half_rsqrt = 77, + Half_sin = 78, + Half_sqrt = 79, + Half_tan = 80, + Native_cos = 81, + Native_divide = 82, + Native_exp = 83, + Native_exp2 = 84, + Native_exp10 = 85, + Native_log = 86, + Native_log2 = 87, + Native_log10 = 88, + Native_powr = 89, + Native_recip = 90, + Native_rsqrt = 91, + Native_sin = 92, + Native_sqrt = 93, + Native_tan = 94, + + // Section 2.2: Integer instructions + SAbs = 141, + SAbs_diff = 142, + SAdd_sat = 143, + UAdd_sat = 144, + SHadd = 145, + UHadd = 146, + SRhadd = 147, + URhadd = 148, + SClamp = 149, + UClamp = 150, + Clz = 151, + Ctz = 152, + SMad_hi = 153, + UMad_sat = 154, + SMad_sat = 155, + SMax = 156, + UMax = 157, + SMin = 158, + UMin = 159, + SMul_hi = 160, + Rotate = 161, + SSub_sat = 162, + USub_sat = 163, + U_Upsample = 164, + S_Upsample = 165, + Popcount = 166, + SMad24 = 167, + UMad24 = 168, + SMul24 = 169, + UMul24 = 170, + UAbs = 201, + UAbs_diff = 202, + UMul_hi = 203, + UMad_hi = 204, + + // Section 2.3: Common instructions + FClamp = 95, + Degrees = 96, + FMax_common = 97, + FMin_common = 98, + Mix = 99, + Radians = 100, + Step = 101, + Smoothstep = 102, + Sign = 103, + + // Section 2.4: Geometric instructions + Cross = 104, + Distance = 105, + Length = 106, + Normalize = 107, + Fast_distance = 108, + Fast_length = 109, + Fast_normalize = 110, + + // Section 2.5: Relational instructions + Bitselect = 186, + Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + Vloadn = 171, + Vstoren = 172, + Vload_half = 173, + Vload_halfn = 174, + Vstore_half = 175, + Vstore_half_r = 176, + Vstore_halfn = 177, + Vstore_halfn_r = 178, + Vloada_halfn = 179, + Vstorea_halfn = 180, + Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + Shuffle = 182, + Shuffle2 = 183, + + // Section 2.8: Misc instructions + Printf = 184, + Prefetch = 185, +}; + +} // end namespace OpenCLLIB + +#else + +enum OpenCLstd_Entrypoints { + + // Section 2.1: Math extended instructions + OpenCLstd_Acos = 0, + OpenCLstd_Acosh = 1, + OpenCLstd_Acospi = 2, + OpenCLstd_Asin = 3, + OpenCLstd_Asinh = 4, + OpenCLstd_Asinpi = 5, + OpenCLstd_Atan = 6, + OpenCLstd_Atan2 = 7, + OpenCLstd_Atanh = 8, + OpenCLstd_Atanpi = 9, + OpenCLstd_Atan2pi = 10, + OpenCLstd_Cbrt = 11, + OpenCLstd_Ceil = 12, + OpenCLstd_Copysign = 13, + OpenCLstd_Cos = 14, + OpenCLstd_Cosh = 15, + OpenCLstd_Cospi = 16, + OpenCLstd_Erfc = 17, + OpenCLstd_Erf = 18, + OpenCLstd_Exp = 19, + OpenCLstd_Exp2 = 20, + OpenCLstd_Exp10 = 21, + OpenCLstd_Expm1 = 22, + OpenCLstd_Fabs = 23, + OpenCLstd_Fdim = 24, + OpenCLstd_Floor = 25, + OpenCLstd_Fma = 26, + OpenCLstd_Fmax = 27, + OpenCLstd_Fmin = 28, + OpenCLstd_Fmod = 29, + OpenCLstd_Fract = 30, + OpenCLstd_Frexp = 31, + OpenCLstd_Hypot = 32, + OpenCLstd_Ilogb = 33, + OpenCLstd_Ldexp = 34, + OpenCLstd_Lgamma = 35, + OpenCLstd_Lgamma_r = 36, + OpenCLstd_Log = 37, + OpenCLstd_Log2 = 38, + OpenCLstd_Log10 = 39, + OpenCLstd_Log1p = 40, + OpenCLstd_Logb = 41, + OpenCLstd_Mad = 42, + OpenCLstd_Maxmag = 43, + OpenCLstd_Minmag = 44, + OpenCLstd_Modf = 45, + OpenCLstd_Nan = 46, + OpenCLstd_Nextafter = 47, + OpenCLstd_Pow = 48, + OpenCLstd_Pown = 49, + OpenCLstd_Powr = 50, + OpenCLstd_Remainder = 51, + OpenCLstd_Remquo = 52, + OpenCLstd_Rint = 53, + OpenCLstd_Rootn = 54, + OpenCLstd_Round = 55, + OpenCLstd_Rsqrt = 56, + OpenCLstd_Sin = 57, + OpenCLstd_Sincos = 58, + OpenCLstd_Sinh = 59, + OpenCLstd_Sinpi = 60, + OpenCLstd_Sqrt = 61, + OpenCLstd_Tan = 62, + OpenCLstd_Tanh = 63, + OpenCLstd_Tanpi = 64, + OpenCLstd_Tgamma = 65, + OpenCLstd_Trunc = 66, + OpenCLstd_Half_cos = 67, + OpenCLstd_Half_divide = 68, + OpenCLstd_Half_exp = 69, + OpenCLstd_Half_exp2 = 70, + OpenCLstd_Half_exp10 = 71, + OpenCLstd_Half_log = 72, + OpenCLstd_Half_log2 = 73, + OpenCLstd_Half_log10 = 74, + OpenCLstd_Half_powr = 75, + OpenCLstd_Half_recip = 76, + OpenCLstd_Half_rsqrt = 77, + OpenCLstd_Half_sin = 78, + OpenCLstd_Half_sqrt = 79, + OpenCLstd_Half_tan = 80, + OpenCLstd_Native_cos = 81, + OpenCLstd_Native_divide = 82, + OpenCLstd_Native_exp = 83, + OpenCLstd_Native_exp2 = 84, + OpenCLstd_Native_exp10 = 85, + OpenCLstd_Native_log = 86, + OpenCLstd_Native_log2 = 87, + OpenCLstd_Native_log10 = 88, + OpenCLstd_Native_powr = 89, + OpenCLstd_Native_recip = 90, + OpenCLstd_Native_rsqrt = 91, + OpenCLstd_Native_sin = 92, + OpenCLstd_Native_sqrt = 93, + OpenCLstd_Native_tan = 94, + + // Section 2.2: Integer instructions + OpenCLstd_SAbs = 141, + OpenCLstd_SAbs_diff = 142, + OpenCLstd_SAdd_sat = 143, + OpenCLstd_UAdd_sat = 144, + OpenCLstd_SHadd = 145, + OpenCLstd_UHadd = 146, + OpenCLstd_SRhadd = 147, + OpenCLstd_URhadd = 148, + OpenCLstd_SClamp = 149, + OpenCLstd_UClamp = 150, + OpenCLstd_Clz = 151, + OpenCLstd_Ctz = 152, + OpenCLstd_SMad_hi = 153, + OpenCLstd_UMad_sat = 154, + OpenCLstd_SMad_sat = 155, + OpenCLstd_SMax = 156, + OpenCLstd_UMax = 157, + OpenCLstd_SMin = 158, + OpenCLstd_UMin = 159, + OpenCLstd_SMul_hi = 160, + OpenCLstd_Rotate = 161, + OpenCLstd_SSub_sat = 162, + OpenCLstd_USub_sat = 163, + OpenCLstd_U_Upsample = 164, + OpenCLstd_S_Upsample = 165, + OpenCLstd_Popcount = 166, + OpenCLstd_SMad24 = 167, + OpenCLstd_UMad24 = 168, + OpenCLstd_SMul24 = 169, + OpenCLstd_UMul24 = 170, + OpenCLstd_UAbs = 201, + OpenCLstd_UAbs_diff = 202, + OpenCLstd_UMul_hi = 203, + OpenCLstd_UMad_hi = 204, + + // Section 2.3: Common instructions + OpenCLstd_FClamp = 95, + OpenCLstd_Degrees = 96, + OpenCLstd_FMax_common = 97, + OpenCLstd_FMin_common = 98, + OpenCLstd_Mix = 99, + OpenCLstd_Radians = 100, + OpenCLstd_Step = 101, + OpenCLstd_Smoothstep = 102, + OpenCLstd_Sign = 103, + + // Section 2.4: Geometric instructions + OpenCLstd_Cross = 104, + OpenCLstd_Distance = 105, + OpenCLstd_Length = 106, + OpenCLstd_Normalize = 107, + OpenCLstd_Fast_distance = 108, + OpenCLstd_Fast_length = 109, + OpenCLstd_Fast_normalize = 110, + + // Section 2.5: Relational instructions + OpenCLstd_Bitselect = 186, + OpenCLstd_Select = 187, + + // Section 2.6: Vector Data Load and Store instructions + OpenCLstd_Vloadn = 171, + OpenCLstd_Vstoren = 172, + OpenCLstd_Vload_half = 173, + OpenCLstd_Vload_halfn = 174, + OpenCLstd_Vstore_half = 175, + OpenCLstd_Vstore_half_r = 176, + OpenCLstd_Vstore_halfn = 177, + OpenCLstd_Vstore_halfn_r = 178, + OpenCLstd_Vloada_halfn = 179, + OpenCLstd_Vstorea_halfn = 180, + OpenCLstd_Vstorea_halfn_r = 181, + + // Section 2.7: Miscellaneous Vector instructions + OpenCLstd_Shuffle = 182, + OpenCLstd_Shuffle2 = 183, + + // Section 2.8: Misc instructions + OpenCLstd_Printf = 184, + OpenCLstd_Prefetch = 185, +}; + +#endif + +#endif // #ifndef OPENCLstd_H diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/OpenCLDebugInfo100.h b/thirdparty/glslang/glslang/Include/spirv/unified1/OpenCLDebugInfo100.h new file mode 100644 index 000000000000..ffbd16f1d732 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/OpenCLDebugInfo100.h @@ -0,0 +1,158 @@ +// Copyright (c) 2018-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +#ifndef SPIRV_UNIFIED1_OpenCLDebugInfo100_H_ +#define SPIRV_UNIFIED1_OpenCLDebugInfo100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + OpenCLDebugInfo100Version = 200, + OpenCLDebugInfo100Version_BitWidthPadding = 0x7fffffff +}; +enum { + OpenCLDebugInfo100Revision = 2, + OpenCLDebugInfo100Revision_BitWidthPadding = 0x7fffffff +}; + +enum OpenCLDebugInfo100Instructions { + OpenCLDebugInfo100DebugInfoNone = 0, + OpenCLDebugInfo100DebugCompilationUnit = 1, + OpenCLDebugInfo100DebugTypeBasic = 2, + OpenCLDebugInfo100DebugTypePointer = 3, + OpenCLDebugInfo100DebugTypeQualifier = 4, + OpenCLDebugInfo100DebugTypeArray = 5, + OpenCLDebugInfo100DebugTypeVector = 6, + OpenCLDebugInfo100DebugTypedef = 7, + OpenCLDebugInfo100DebugTypeFunction = 8, + OpenCLDebugInfo100DebugTypeEnum = 9, + OpenCLDebugInfo100DebugTypeComposite = 10, + OpenCLDebugInfo100DebugTypeMember = 11, + OpenCLDebugInfo100DebugTypeInheritance = 12, + OpenCLDebugInfo100DebugTypePtrToMember = 13, + OpenCLDebugInfo100DebugTypeTemplate = 14, + OpenCLDebugInfo100DebugTypeTemplateParameter = 15, + OpenCLDebugInfo100DebugTypeTemplateTemplateParameter = 16, + OpenCLDebugInfo100DebugTypeTemplateParameterPack = 17, + OpenCLDebugInfo100DebugGlobalVariable = 18, + OpenCLDebugInfo100DebugFunctionDeclaration = 19, + OpenCLDebugInfo100DebugFunction = 20, + OpenCLDebugInfo100DebugLexicalBlock = 21, + OpenCLDebugInfo100DebugLexicalBlockDiscriminator = 22, + OpenCLDebugInfo100DebugScope = 23, + OpenCLDebugInfo100DebugNoScope = 24, + OpenCLDebugInfo100DebugInlinedAt = 25, + OpenCLDebugInfo100DebugLocalVariable = 26, + OpenCLDebugInfo100DebugInlinedVariable = 27, + OpenCLDebugInfo100DebugDeclare = 28, + OpenCLDebugInfo100DebugValue = 29, + OpenCLDebugInfo100DebugOperation = 30, + OpenCLDebugInfo100DebugExpression = 31, + OpenCLDebugInfo100DebugMacroDef = 32, + OpenCLDebugInfo100DebugMacroUndef = 33, + OpenCLDebugInfo100DebugImportedEntity = 34, + OpenCLDebugInfo100DebugSource = 35, + OpenCLDebugInfo100DebugModuleINTEL = 36, + OpenCLDebugInfo100InstructionsMax = 0x7fffffff +}; + + +enum OpenCLDebugInfo100DebugInfoFlags { + OpenCLDebugInfo100None = 0x0000, + OpenCLDebugInfo100FlagIsProtected = 0x01, + OpenCLDebugInfo100FlagIsPrivate = 0x02, + OpenCLDebugInfo100FlagIsPublic = 0x03, + OpenCLDebugInfo100FlagIsLocal = 0x04, + OpenCLDebugInfo100FlagIsDefinition = 0x08, + OpenCLDebugInfo100FlagFwdDecl = 0x10, + OpenCLDebugInfo100FlagArtificial = 0x20, + OpenCLDebugInfo100FlagExplicit = 0x40, + OpenCLDebugInfo100FlagPrototyped = 0x80, + OpenCLDebugInfo100FlagObjectPointer = 0x100, + OpenCLDebugInfo100FlagStaticMember = 0x200, + OpenCLDebugInfo100FlagIndirectVariable = 0x400, + OpenCLDebugInfo100FlagLValueReference = 0x800, + OpenCLDebugInfo100FlagRValueReference = 0x1000, + OpenCLDebugInfo100FlagIsOptimized = 0x2000, + OpenCLDebugInfo100FlagIsEnumClass = 0x4000, + OpenCLDebugInfo100FlagTypePassByValue = 0x8000, + OpenCLDebugInfo100FlagTypePassByReference = 0x10000, + OpenCLDebugInfo100DebugInfoFlagsMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugBaseTypeAttributeEncoding { + OpenCLDebugInfo100Unspecified = 0, + OpenCLDebugInfo100Address = 1, + OpenCLDebugInfo100Boolean = 2, + OpenCLDebugInfo100Float = 3, + OpenCLDebugInfo100Signed = 4, + OpenCLDebugInfo100SignedChar = 5, + OpenCLDebugInfo100Unsigned = 6, + OpenCLDebugInfo100UnsignedChar = 7, + OpenCLDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugCompositeType { + OpenCLDebugInfo100Class = 0, + OpenCLDebugInfo100Structure = 1, + OpenCLDebugInfo100Union = 2, + OpenCLDebugInfo100DebugCompositeTypeMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugTypeQualifier { + OpenCLDebugInfo100ConstType = 0, + OpenCLDebugInfo100VolatileType = 1, + OpenCLDebugInfo100RestrictType = 2, + OpenCLDebugInfo100AtomicType = 3, + OpenCLDebugInfo100DebugTypeQualifierMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugOperation { + OpenCLDebugInfo100Deref = 0, + OpenCLDebugInfo100Plus = 1, + OpenCLDebugInfo100Minus = 2, + OpenCLDebugInfo100PlusUconst = 3, + OpenCLDebugInfo100BitPiece = 4, + OpenCLDebugInfo100Swap = 5, + OpenCLDebugInfo100Xderef = 6, + OpenCLDebugInfo100StackValue = 7, + OpenCLDebugInfo100Constu = 8, + OpenCLDebugInfo100Fragment = 9, + OpenCLDebugInfo100DebugOperationMax = 0x7fffffff +}; + +enum OpenCLDebugInfo100DebugImportedEntity { + OpenCLDebugInfo100ImportedModule = 0, + OpenCLDebugInfo100ImportedDeclaration = 1, + OpenCLDebugInfo100DebugImportedEntityMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_OpenCLDebugInfo100_H_ diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.debuginfo.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.debuginfo.grammar.json new file mode 100644 index 000000000000..918a9e547be4 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.debuginfo.grammar.json @@ -0,0 +1,572 @@ +{ + "copyright" : [ + "Copyright (c) 2017-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 1, + "instructions" : [ + { + "opname" : "DebugInfoNone", + "opcode" : 0 + }, + { + "opname" : "DebugCompilationUnit", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "LiteralInteger", "name" : "'DWARF Version'" } + ] + }, + { + "opname" : "DebugTypeBasic", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugBaseTypeAttributeEncoding", "name" : "'Encoding'" } + ] + }, + { + "opname" : "DebugTypePointer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "StorageClass", "name" : "'Storage Class'" }, + { "kind" : "DebugInfoFlags", "name" : "'Literal Flags'" } + ] + }, + { + "opname" : "DebugTypeQualifier", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "DebugTypeQualifier", "name" : "'Type Qualifier'" } + ] + }, + { + "opname" : "DebugTypeArray", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeVector", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "DebugTypedef", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeFunction", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "name" : "'Paramter Types'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeEnum", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Underlying Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeComposite", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "DebugCompositeType", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeMember", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugTypeInheritance", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'Child'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePtrToMember", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'Member Type'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeTemplate", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeTemplateParameter", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Actual Type'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateTemplateParameter", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Template Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateParameterPack", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugGlobalVariable", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDeclaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugFunction", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "LiteralInteger", "name" : "'Scope Line'" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlock", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlockDiscriminator", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "LiteralInteger", "name" : "'Discriminator'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugScope", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugNoScope", + "opcode" : 24 + }, + { + "opname" : "DebugInlinedAt", + "opcode" : 25, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLocalVariable", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "LiteralInteger", "name" : "'Arg Number'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugInlinedVariable", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Inlined'" } + ] + }, + { + "opname" : "DebugDeclare", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Expression'" } + ] + }, + { + "opname" : "DebugValue", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugOperation", + "opcode" : 30, + "operands" : [ + { "kind" : "DebugOperation", "name" : "'OpCode'" }, + { "kind" : "LiteralInteger", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugExpression", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugMacroDef", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugMacroUndef", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Macro'" } + ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "DebugInfoFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "FlagIsProtected", + "value" : "0x01" + }, + { + "enumerant" : "FlagIsPrivate", + "value" : "0x02" + }, + { + "enumerant" : "FlagIsPublic", + "value" : "0x03" + }, + { + "enumerant" : "FlagIsLocal", + "value" : "0x04" + }, + { + "enumerant" : "FlagIsDefinition", + "value" : "0x08" + }, + { + "enumerant" : "FlagFwdDecl", + "value" : "0x10" + }, + { + "enumerant" : "FlagArtificial", + "value" : "0x20" + }, + { + "enumerant" : "FlagExplicit", + "value" : "0x40" + }, + { + "enumerant" : "FlagPrototyped", + "value" : "0x80" + }, + { + "enumerant" : "FlagObjectPointer", + "value" : "0x100" + }, + { + "enumerant" : "FlagStaticMember", + "value" : "0x200" + }, + { + "enumerant" : "FlagIndirectVariable", + "value" : "0x400" + }, + { + "enumerant" : "FlagLValueReference", + "value" : "0x800" + }, + { + "enumerant" : "FlagRValueReference", + "value" : "0x1000" + }, + { + "enumerant" : "FlagIsOptimized", + "value" : "0x2000" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugBaseTypeAttributeEncoding", + "enumerants" : [ + { + "enumerant" : "Unspecified", + "value" : "0" + }, + { + "enumerant" : "Address", + "value" : "1" + }, + { + "enumerant" : "Boolean", + "value" : "2" + }, + { + "enumerant" : "Float", + "value" : "4" + }, + { + "enumerant" : "Signed", + "value" : "5" + }, + { + "enumerant" : "SignedChar", + "value" : "6" + }, + { + "enumerant" : "Unsigned", + "value" : "7" + }, + { + "enumerant" : "UnsignedChar", + "value" : "8" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugCompositeType", + "enumerants" : [ + { + "enumerant" : "Class", + "value" : "0" + }, + { + "enumerant" : "Structure", + "value" : "1" + }, + { + "enumerant" : "Union", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugTypeQualifier", + "enumerants" : [ + { + "enumerant" : "ConstType", + "value" : "0" + }, + { + "enumerant" : "VolatileType", + "value" : "1" + }, + { + "enumerant" : "RestrictType", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugOperation", + "enumerants" : [ + { + "enumerant" : "Deref", + "value" : "0" + }, + { + "enumerant" : "Plus", + "value" : "1" + }, + { + "enumerant" : "Minus", + "value" : "2" + }, + { + "enumerant" : "PlusUconst", + "value" : "3", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "BitPiece", + "value" : "4", + "parameters" : [ + { "kind" : "LiteralInteger" }, + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Swap", + "value" : "5" + }, + { + "enumerant" : "Xderef", + "value" : "6" + }, + { + "enumerant" : "StackValue", + "value" : "7" + }, + { + "enumerant" : "Constu", + "value" : "8", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.glsl.std.450.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.glsl.std.450.grammar.json new file mode 100644 index 000000000000..ac8fc6dda6ed --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.glsl.std.450.grammar.json @@ -0,0 +1,642 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "Round", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "RoundEven", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Trunc", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FAbs", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SAbs", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FSign", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SSign", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Floor", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ceil", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fract", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Radians", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "Degrees", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "Sin", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tan", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asin", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acos", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'y_over_x'" } + ] + }, + { + "opname" : "Sinh", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Cosh", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Tanh", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Asinh", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Acosh", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atanh", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Atan2", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Pow", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Exp", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Exp2", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Log2", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Sqrt", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "InverseSqrt", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Determinant", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "MatrixInverse", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Modf", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "ModfStruct", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FMin", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMin", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMin", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FMax", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "UMax", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "SMax", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "FClamp", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "UClamp", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "SClamp", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + }, + { + "opname" : "FMix", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "IMix", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "Step", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "SmoothStep", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Fma", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "Frexp", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "FrexpStruct", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Ldexp", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "PackSnorm4x8", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm4x8", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackSnorm2x16", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackUnorm2x16", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackHalf2x16", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "PackDouble2x32", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "UnpackSnorm2x16", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm2x16", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackHalf2x16", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ] + }, + { + "opname" : "UnpackSnorm4x8", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackUnorm4x8", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "UnpackDouble2x32", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" } + ], + "capabilities" : [ "Float64" ] + }, + { + "opname" : "Length", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "Distance", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "Cross", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "Normalize", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "FaceForward", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'Nref'" } + ] + }, + { + "opname" : "Reflect", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" } + ] + }, + { + "opname" : "Refract", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'I'" }, + { "kind" : "IdRef", "name" : "'N'" }, + { "kind" : "IdRef", "name" : "'eta'" } + ] + }, + { + "opname" : "FindILsb", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindSMsb", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "FindUMsb", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ] + }, + { + "opname" : "InterpolateAtCentroid", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtSample", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'sample'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "InterpolateAtOffset", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "capabilities" : [ "InterpolationFunction" ] + }, + { + "opname" : "NMin", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NMax", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "NClamp", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minVal'" }, + { "kind" : "IdRef", "name" : "'maxVal'" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json new file mode 100644 index 000000000000..cfccc80b6d57 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json @@ -0,0 +1,426 @@ +{ + "revision" : 6, + "instructions" : [ + { + "opname" : "Kernel", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Name" }, + { "kind" : "IdRef", "name" : "NumArguments", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Flags", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Attributes", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentInfo", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "Name" }, + { "kind" : "IdRef", "name" : "Type Name", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Address Qualifier", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Access Qualifier", "quantifier" : "?" }, + { "kind" : "IdRef", "name" : "Type Qualifier", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentStorageBuffer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentUniform", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentPodStorageBuffer", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentPodUniform", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentPodPushConstant", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentSampledImage", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentStorageImage", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentSampler", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentWorkgroup", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "SpecId" }, + { "kind" : "IdRef", "name" : "ElemSize" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "SpecConstantWorkgroupSize", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "X" }, + { "kind" : "IdRef", "name" : "Y" }, + { "kind" : "IdRef", "name" : "Z" } + ] + }, + { + "opname" : "SpecConstantGlobalOffset", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "X" }, + { "kind" : "IdRef", "name" : "Y" }, + { "kind" : "IdRef", "name" : "Z" } + ] + }, + { + "opname" : "SpecConstantWorkDim", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "Dim" } + ] + }, + { + "opname" : "PushConstantGlobalOffset", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantEnqueuedLocalSize", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantGlobalSize", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantRegionOffset", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantNumWorkgroups", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "PushConstantRegionGroupOffset", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ConstantDataStorageBuffer", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "ConstantDataUniform", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "LiteralSampler", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Mask" } + ] + }, + { + "opname" : "PropertyRequiredWorkgroupSize", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "X" }, + { "kind" : "IdRef", "name" : "Y" }, + { "kind" : "IdRef", "name" : "Z" } + ] + }, + { + "opname" : "SpecConstantSubgroupMaxSize", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ArgumentPointerPushConstant", + "opcode" : 26, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentPointerUniform", + "opcode" : 27, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ProgramScopeVariablesStorageBuffer", + "opcode" : 28, + "operands": [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "ProgramScopeVariablePointerRelocation", + "opcode" : 29, + "operands": [ + { "kind" : "IdRef", "name" : "ObjectOffset" }, + { "kind" : "IdRef", "name" : "PointerOffset" }, + { "kind" : "IdRef", "name" : "PointerSize" } + ] + }, + { + "opname" : "ImageArgumentInfoChannelOrderPushConstant", + "opcode" : 30, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ImageArgumentInfoChannelDataTypePushConstant", + "opcode" : 31, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ImageArgumentInfoChannelOrderUniform", + "opcode" : 32, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ImageArgumentInfoChannelDataTypeUniform", + "opcode" : 33, + "operands": [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + }, + { + "opname" : "ArgumentStorageTexelBuffer", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ArgumentUniformTexelBuffer", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "Decl" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "ArgInfo", "quantifier" : "?" } + ] + }, + { + "opname" : "ConstantDataPointerPushConstant", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset"}, + { "kind" : "IdRef", "name" : "Size"}, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "ProgramScopeVariablePointerPushConstant", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset"}, + { "kind" : "IdRef", "name" : "Size"}, + { "kind" : "IdRef", "name" : "Data" } + ] + }, + { + "opname" : "PrintfInfo", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "PrintfID" }, + { "kind" : "IdRef", "name" : "FormatString" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "ArgumentSizes"} + ] + }, + { + "opname" : "PrintfBufferStorageBuffer", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "DescriptorSet" }, + { "kind" : "IdRef", "name" : "Binding" }, + { "kind" : "IdRef", "name" : "BufferSize"} + ] + }, + { + "opname" : "PrintfBufferPointerPushConstant", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size"}, + { "kind" : "IdRef", "name" : "BufferSize"} + ] + }, + { + "opname" : "NormalizedSamplerMaskPushConstant", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "Kernel" }, + { "kind" : "IdRef", "name" : "Ordinal" }, + { "kind" : "IdRef", "name" : "Offset" }, + { "kind" : "IdRef", "name" : "Size" } + ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "KernelPropertyFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0" + }, + { + "enumerant" : "MayUsePrintf", + "value" : "0x1" + } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json new file mode 100644 index 000000000000..ae288833811d --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json @@ -0,0 +1,9 @@ +{ + "revision" : 1, + "instructions" : [ + { + "opname" : "DebugBreak", + "opcode" : 1 + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json new file mode 100644 index 000000000000..71fa7112cfed --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json @@ -0,0 +1,13 @@ +{ + "revision" : 1, + "instructions" : [ + { + "opname" : "DebugPrintf", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'Format'" }, + { "kind" : "IdRef", "quantifier" : "*" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json new file mode 100644 index 000000000000..1eb2859a1093 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json @@ -0,0 +1,713 @@ +{ + "copyright" : [ + "Copyright (c) 2018-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 6, + "instructions" : [ + { + "opname" : "DebugInfoNone", + "opcode" : 0 + }, + { + "opname" : "DebugCompilationUnit", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'Version'" }, + { "kind" : "IdRef", "name" : "'DWARF Version'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Language'" } + ] + }, + { + "opname" : "DebugTypeBasic", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Encoding'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePointer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Storage Class'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypeQualifier", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Type Qualifier'" } + ] + }, + { + "opname" : "DebugTypeArray", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeVector", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Count'" } + ] + }, + { + "opname" : "DebugTypedef", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeFunction", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "name" : "'Parameter Types'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeEnum", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Underlying Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeComposite", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeMember", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugTypeInheritance", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePtrToMember", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'Member Type'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeTemplate", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeTemplateParameter", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Actual Type'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateTemplateParameter", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Template Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateParameterPack", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugGlobalVariable", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDeclaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugFunction", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Scope Line'" }, + { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlock", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlockDiscriminator", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Discriminator'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugScope", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugNoScope", + "opcode" : 24 + }, + { + "opname" : "DebugInlinedAt", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLocalVariable", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Arg Number'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugInlinedVariable", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Inlined'" } + ] + }, + { + "opname" : "DebugDeclare", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugValue", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugOperation", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'OpCode'" }, + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugExpression", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugMacroDef", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugMacroUndef", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Macro'" } + ] + }, + { + "opname" : "DebugImportedEntity", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Entity'" }, + { "kind" : "IdRef", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugSource", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "IdRef", "name" : "'Text'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDefinition", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "name" : "'Definition'" } + ] + }, + { + "opname" : "DebugSourceContinued", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'Text'" } + ] + }, + { + "opname" : "DebugLine", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line Start'" }, + { "kind" : "IdRef", "name" : "'Line End'" }, + { "kind" : "IdRef", "name" : "'Column Start'" }, + { "kind" : "IdRef", "name" : "'Column End'" } + ] + }, + { + "opname" : "DebugNoLine", + "opcode" : 104 + }, + { + "opname" : "DebugBuildIdentifier", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'Identifier'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugStoragePath", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'Path'" } + ] + }, + { + "opname" : "DebugEntryPoint", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "IdRef", "name" : "'Compilation Unit'" }, + { "kind" : "IdRef", "name" : "'Compiler Signature'" }, + { "kind" : "IdRef", "name" : "'Command-line Arguments'" } + ] + }, + { + "opname" : "DebugTypeMatrix", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'Vector Type'" }, + { "kind" : "IdRef", "name" : "'Vector Count'" }, + { "kind" : "IdRef", "name" : "'Column Major'" } + ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "DebugInfoFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "FlagIsProtected", + "value" : "0x01" + }, + { + "enumerant" : "FlagIsPrivate", + "value" : "0x02" + }, + { + "enumerant" : "FlagIsPublic", + "value" : "0x03" + }, + { + "enumerant" : "FlagIsLocal", + "value" : "0x04" + }, + { + "enumerant" : "FlagIsDefinition", + "value" : "0x08" + }, + { + "enumerant" : "FlagFwdDecl", + "value" : "0x10" + }, + { + "enumerant" : "FlagArtificial", + "value" : "0x20" + }, + { + "enumerant" : "FlagExplicit", + "value" : "0x40" + }, + { + "enumerant" : "FlagPrototyped", + "value" : "0x80" + }, + { + "enumerant" : "FlagObjectPointer", + "value" : "0x100" + }, + { + "enumerant" : "FlagStaticMember", + "value" : "0x200" + }, + { + "enumerant" : "FlagIndirectVariable", + "value" : "0x400" + }, + { + "enumerant" : "FlagLValueReference", + "value" : "0x800" + }, + { + "enumerant" : "FlagRValueReference", + "value" : "0x1000" + }, + { + "enumerant" : "FlagIsOptimized", + "value" : "0x2000" + }, + { + "enumerant" : "FlagIsEnumClass", + "value" : "0x4000" + }, + { + "enumerant" : "FlagTypePassByValue", + "value" : "0x8000" + }, + { + "enumerant" : "FlagTypePassByReference", + "value" : "0x10000" + }, + { + "enumerant" : "FlagUnknownPhysicalLayout", + "value" : "0x20000" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "BuildIdentifierFlags", + "enumerants" : [ + { + "enumerant" : "IdentifierPossibleDuplicates", + "value" : "0x01" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugBaseTypeAttributeEncoding", + "enumerants" : [ + { + "enumerant" : "Unspecified", + "value" : "0" + }, + { + "enumerant" : "Address", + "value" : "1" + }, + { + "enumerant" : "Boolean", + "value" : "2" + }, + { + "enumerant" : "Float", + "value" : "3" + }, + { + "enumerant" : "Signed", + "value" : "4" + }, + { + "enumerant" : "SignedChar", + "value" : "5" + }, + { + "enumerant" : "Unsigned", + "value" : "6" + }, + { + "enumerant" : "UnsignedChar", + "value" : "7" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugCompositeType", + "enumerants" : [ + { + "enumerant" : "Class", + "value" : "0" + }, + { + "enumerant" : "Structure", + "value" : "1" + }, + { + "enumerant" : "Union", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugTypeQualifier", + "enumerants" : [ + { + "enumerant" : "ConstType", + "value" : "0" + }, + { + "enumerant" : "VolatileType", + "value" : "1" + }, + { + "enumerant" : "RestrictType", + "value" : "2" + }, + { + "enumerant" : "AtomicType", + "value" : "3" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugOperation", + "enumerants" : [ + { + "enumerant" : "Deref", + "value" : "0" + }, + { + "enumerant" : "Plus", + "value" : "1" + }, + { + "enumerant" : "Minus", + "value" : "2" + }, + { + "enumerant" : "PlusUconst", + "value" : "3", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "BitPiece", + "value" : "4", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Swap", + "value" : "5" + }, + { + "enumerant" : "Xderef", + "value" : "6" + }, + { + "enumerant" : "StackValue", + "value" : "7" + }, + { + "enumerant" : "Constu", + "value" : "8", + "parameters" : [ + { "kind" : "IdRef" } + ] + }, + { + "enumerant" : "Fragment", + "value" : "9", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugImportedEntity", + "enumerants" : [ + { + "enumerant" : "ImportedModule", + "value" : "0" + }, + { + "enumerant" : "ImportedDeclaration", + "value" : "1" + } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json new file mode 100644 index 000000000000..bee1bea3f9b8 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json @@ -0,0 +1,135 @@ +{ + "revision" : 1, + "instructions" : [ + { + "opname" : "Configuration", + "opcode" : 1, + "operands" : [ + {"kind" : "LiteralString", "name" : "enabledExtensionNames" }, + {"kind" : "LiteralInteger", "name" : "specializationInfoDataSize" }, + {"kind" : "LiteralString", "name" : "specializationInfoData" }, + {"kind" : "LiteralString", "name" : "shaderName" }, + {"kind" : "LiteralString", "name" : "EntryPoint" }, + {"kind" : "LiteralInteger", "name" : "groupCountX" }, + {"kind" : "LiteralInteger", "name" : "groupCountY" }, + {"kind" : "LiteralInteger", "name" : "groupCountZ" } + ] + }, + { + "opname" : "StartCounter", + "opcode" : 2, + "operands" : [ + {"kind" : "LiteralString", "name" : "name" } + ] + }, + { + "opname" : "StopCounter", + "opcode" : 3, + "operands" : [ + {"kind" : "IdRef", "name" : "counter" } + ] + }, + { + "opname" : "PushConstants", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "offset" }, + { "kind" : "LiteralInteger", "name" : "size" }, + { "kind" : "LiteralString", "name" : "pValues" }, + { "kind" : "LiteralInteger", "name" : "stageFlags" } + ] + }, + { + "opname" : "SpecializationMapEntry", + "opcode" : 5, + "operands" : [ + {"kind" : "LiteralInteger", "name" : "constantID" }, + {"kind" : "LiteralInteger", "name" : "offset" }, + {"kind" : "LiteralInteger", "name" : "size" } + ] + }, + { + "opname" : "DescriptorSetBuffer", + "opcode" : 6, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "ds" }, + { "kind" : "LiteralInteger", "name" : "binding" }, + { "kind" : "LiteralInteger", "name" : "type" }, + { "kind" : "LiteralInteger", "name" : "flags" }, + { "kind" : "LiteralInteger", "name" : "queueFamilyIndexCount" }, + { "kind" : "LiteralInteger", "name" : "sharingMode" }, + { "kind" : "LiteralInteger", "name" : "size" }, + { "kind" : "LiteralInteger", "name" : "usage" }, + { "kind" : "LiteralInteger", "name" : "range" }, + { "kind" : "LiteralInteger", "name" : "offset" }, + { "kind" : "LiteralInteger", "name" : "memorySize" }, + { "kind" : "LiteralInteger", "name" : "memoryType" }, + { "kind" : "LiteralInteger", "name" : "bindOffset" } + ] + }, + { + "opname" : "DescriptorSetImage", + "opcode" : 7, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "ds" }, + { "kind" : "LiteralInteger", "name" : "binding" }, + { "kind" : "LiteralInteger", "name" : "type" }, + { "kind" : "LiteralInteger", "name" : "imageLayout"}, + { "kind" : "LiteralInteger", "name" : "imageFlags"}, + { "kind" : "LiteralInteger", "name" : "imageType"}, + { "kind" : "LiteralInteger", "name" : "imageformat"}, + { "kind" : "LiteralInteger", "name" : "width"}, + { "kind" : "LiteralInteger", "name" : "height"}, + { "kind" : "LiteralInteger", "name" : "depth"}, + { "kind" : "LiteralInteger", "name" : "mipLevels"}, + { "kind" : "LiteralInteger", "name" : "arrayLayers"}, + { "kind" : "LiteralInteger", "name" : "samples"}, + { "kind" : "LiteralInteger", "name" : "tiling"}, + { "kind" : "LiteralInteger", "name" : "usage"}, + { "kind" : "LiteralInteger", "name" : "sharingMode"}, + { "kind" : "LiteralInteger", "name" : "queueFamilyIndexCount"}, + { "kind" : "LiteralInteger", "name" : "initialLayout"}, + { "kind" : "LiteralInteger", "name" : "aspectMask"}, + { "kind" : "LiteralInteger", "name" : "baseMipLevel"}, + { "kind" : "LiteralInteger", "name" : "levelCount"}, + { "kind" : "LiteralInteger", "name" : "baseArrayLayer"}, + { "kind" : "LiteralInteger", "name" : "layerCount"}, + { "kind" : "LiteralInteger", "name" : "viewFlags"}, + { "kind" : "LiteralInteger", "name" : "viewType"}, + { "kind" : "LiteralInteger", "name" : "viewFormat"}, + { "kind" : "LiteralInteger", "name" : "component_a"}, + { "kind" : "LiteralInteger", "name" : "component_b"}, + { "kind" : "LiteralInteger", "name" : "component_g"}, + { "kind" : "LiteralInteger", "name" : "component_r"}, + { "kind" : "LiteralInteger", "name" : "memorySize" }, + { "kind" : "LiteralInteger", "name" : "memoryType" }, + { "kind" : "LiteralInteger", "name" : "bindOffset"} + ] + }, + { + "opname" : "DescriptorSetSampler", + "opcode" : 8, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "ds" }, + { "kind" : "LiteralInteger", "name" : "binding" }, + { "kind" : "LiteralInteger", "name" : "type" }, + { "kind" : "LiteralInteger", "name" : "flags"}, + { "kind" : "LiteralInteger", "name" : "magFilter"}, + { "kind" : "LiteralInteger", "name" : "minFilter"}, + { "kind" : "LiteralInteger", "name" : "mipmapMode"}, + { "kind" : "LiteralInteger", "name" : "addressModeU"}, + { "kind" : "LiteralInteger", "name" : "addressModeV"}, + { "kind" : "LiteralInteger", "name" : "addressModeW"}, + { "kind" : "LiteralFloat", "name" : "mipLodBias"}, + { "kind" : "LiteralInteger", "name" : "anisotropyEnable"}, + { "kind" : "LiteralFloat", "name" : "maxAnisotropy"}, + { "kind" : "LiteralInteger", "name" : "compareEnable"}, + { "kind" : "LiteralInteger", "name" : "compareOp"}, + { "kind" : "LiteralFloat", "name" : "minLod"}, + { "kind" : "LiteralFloat", "name" : "maxLod"}, + { "kind" : "LiteralInteger", "name" : "borderColor"}, + { "kind" : "LiteralInteger", "name" : "unnormalizedCoordinates"} + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json new file mode 100644 index 000000000000..53b001c530d4 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json @@ -0,0 +1,651 @@ +{ + "copyright" : [ + "Copyright (c) 2018-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 200, + "revision" : 2, + "instructions" : [ + { + "opname" : "DebugInfoNone", + "opcode" : 0 + }, + { + "opname" : "DebugCompilationUnit", + "opcode" : 1, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "LiteralInteger", "name" : "'DWARF Version'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "SourceLanguage", "name" : "'Language'" } + ] + }, + { + "opname" : "DebugTypeBasic", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugBaseTypeAttributeEncoding", "name" : "'Encoding'" } + ] + }, + { + "opname" : "DebugTypePointer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "StorageClass", "name" : "'Storage Class'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypeQualifier", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "DebugTypeQualifier", "name" : "'Type Qualifier'" } + ] + }, + { + "opname" : "DebugTypeArray", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeVector", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "DebugTypedef", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeFunction", + "opcode" : 8, + "operands" : [ + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "name" : "'Parameter Types'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeEnum", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Underlying Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeComposite", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "DebugCompositeType", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeMember", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugTypeInheritance", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'Child'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePtrToMember", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'Member Type'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeTemplate", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeTemplateParameter", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Actual Type'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateTemplateParameter", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Template Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateParameterPack", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugGlobalVariable", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDeclaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugFunction", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "LiteralInteger", "name" : "'Scope Line'" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlock", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlockDiscriminator", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Discriminator'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugScope", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugNoScope", + "opcode" : 24 + }, + { + "opname" : "DebugInlinedAt", + "opcode" : 25, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLocalVariable", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "LiteralInteger", "name" : "'Arg Number'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugInlinedVariable", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Inlined'" } + ] + }, + { + "opname" : "DebugDeclare", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Expression'" } + ] + }, + { + "opname" : "DebugValue", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugOperation", + "opcode" : 30, + "operands" : [ + { "kind" : "DebugOperation", "name" : "'OpCode'" }, + { "kind" : "LiteralInteger", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugExpression", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugMacroDef", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugMacroUndef", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Macro'" } + ] + }, + { + "opname" : "DebugImportedEntity", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "DebugImportedEntity", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Entity'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugSource", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "IdRef", "name" : "'Text'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugModuleINTEL", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'ConfigurationMacros'" }, + { "kind" : "IdRef", "name" : "'IncludePath'" }, + { "kind" : "IdRef", "name" : "'APINotesFile'" }, + { "kind" : "LiteralInteger", "name" : "'IsDeclaration'" } + ], + "capability" : "DebugInfoModuleINTEL" + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "DebugInfoFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "FlagIsProtected", + "value" : "0x01" + }, + { + "enumerant" : "FlagIsPrivate", + "value" : "0x02" + }, + { + "enumerant" : "FlagIsPublic", + "value" : "0x03" + }, + { + "enumerant" : "FlagIsLocal", + "value" : "0x04" + }, + { + "enumerant" : "FlagIsDefinition", + "value" : "0x08" + }, + { + "enumerant" : "FlagFwdDecl", + "value" : "0x10" + }, + { + "enumerant" : "FlagArtificial", + "value" : "0x20" + }, + { + "enumerant" : "FlagExplicit", + "value" : "0x40" + }, + { + "enumerant" : "FlagPrototyped", + "value" : "0x80" + }, + { + "enumerant" : "FlagObjectPointer", + "value" : "0x100" + }, + { + "enumerant" : "FlagStaticMember", + "value" : "0x200" + }, + { + "enumerant" : "FlagIndirectVariable", + "value" : "0x400" + }, + { + "enumerant" : "FlagLValueReference", + "value" : "0x800" + }, + { + "enumerant" : "FlagRValueReference", + "value" : "0x1000" + }, + { + "enumerant" : "FlagIsOptimized", + "value" : "0x2000" + }, + { + "enumerant" : "FlagIsEnumClass", + "value" : "0x4000" + }, + { + "enumerant" : "FlagTypePassByValue", + "value" : "0x8000" + }, + { + "enumerant" : "FlagTypePassByReference", + "value" : "0x10000" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugBaseTypeAttributeEncoding", + "enumerants" : [ + { + "enumerant" : "Unspecified", + "value" : "0" + }, + { + "enumerant" : "Address", + "value" : "1" + }, + { + "enumerant" : "Boolean", + "value" : "2" + }, + { + "enumerant" : "Float", + "value" : "3" + }, + { + "enumerant" : "Signed", + "value" : "4" + }, + { + "enumerant" : "SignedChar", + "value" : "5" + }, + { + "enumerant" : "Unsigned", + "value" : "6" + }, + { + "enumerant" : "UnsignedChar", + "value" : "7" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugCompositeType", + "enumerants" : [ + { + "enumerant" : "Class", + "value" : "0" + }, + { + "enumerant" : "Structure", + "value" : "1" + }, + { + "enumerant" : "Union", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugTypeQualifier", + "enumerants" : [ + { + "enumerant" : "ConstType", + "value" : "0" + }, + { + "enumerant" : "VolatileType", + "value" : "1" + }, + { + "enumerant" : "RestrictType", + "value" : "2" + }, + { + "enumerant" : "AtomicType", + "value" : "3" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugOperation", + "enumerants" : [ + { + "enumerant" : "Deref", + "value" : "0" + }, + { + "enumerant" : "Plus", + "value" : "1" + }, + { + "enumerant" : "Minus", + "value" : "2" + }, + { + "enumerant" : "PlusUconst", + "value" : "3", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "BitPiece", + "value" : "4", + "parameters" : [ + { "kind" : "LiteralInteger" }, + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Swap", + "value" : "5" + }, + { + "enumerant" : "Xderef", + "value" : "6" + }, + { + "enumerant" : "StackValue", + "value" : "7" + }, + { + "enumerant" : "Constu", + "value" : "8", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Fragment", + "value" : "9", + "parameters" : [ + { "kind" : "LiteralInteger" }, + { "kind" : "LiteralInteger" } + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugImportedEntity", + "enumerants" : [ + { + "enumerant" : "ImportedModule", + "value" : "0" + }, + { + "enumerant" : "ImportedDeclaration", + "value" : "1" + } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.opencl.std.100.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.opencl.std.100.grammar.json new file mode 100644 index 000000000000..21b7876b0e64 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.opencl.std.100.grammar.json @@ -0,0 +1,1279 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 100, + "revision" : 2, + "instructions" : [ + { + "opname" : "acos", + "opcode" : 0, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acosh", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "acospi", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asin", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinh", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "asinpi", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanh", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atanpi", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "atan2pi", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cbrt", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ceil", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "copysign", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "cos", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cosh", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cospi", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erfc", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "erf", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp2", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "exp10", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "expm1", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fabs", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fdim", + "opcode" : 24, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "floor", + "opcode" : 25, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "fma", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fmax", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmod", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fract", + "opcode" : 30, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'ptr'" } + ] + }, + { + "opname" : "frexp", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'exp'" } + ] + }, + { + "opname" : "hypot", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "ilogb", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ldexp", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'k'" } + ] + }, + { + "opname" : "lgamma", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "lgamma_r", + "opcode" : 36, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'signp'" } + ] + }, + { + "opname" : "log", + "opcode" : 37, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log2", + "opcode" : 38, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log10", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "log1p", + "opcode" : 40, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "logb", + "opcode" : 41, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "mad", + "opcode" : 42, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "maxmag", + "opcode" : 43, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "minmag", + "opcode" : 44, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "modf", + "opcode" : 45, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'iptr'" } + ] + }, + { + "opname" : "nan", + "opcode" : 46, + "operands" : [ + { "kind" : "IdRef", "name" : "'nancode'" } + ] + }, + { + "opname" : "nextafter", + "opcode" : 47, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "pow", + "opcode" : 48, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y" } + ] + }, + { + "opname" : "pown", + "opcode" : 49, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "powr", + "opcode" : 50, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remainder", + "opcode" : 51, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "remquo", + "opcode" : 52, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'quo'" } + ] + }, + { + "opname" : "rint", + "opcode" : 53, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rootn", + "opcode" : 54, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "round", + "opcode" : 55, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "rsqrt", + "opcode" : 56, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sin", + "opcode" : 57, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sincos", + "opcode" : 58, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'cosval'" } + ] + }, + { + "opname" : "sinh", + "opcode" : 59, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sinpi", + "opcode" : 60, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sqrt", + "opcode" : 61, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tan", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanh", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tanpi", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "tgamma", + "opcode" : 65, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "trunc", + "opcode" : 66, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_cos", + "opcode" : 67, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_divide", + "opcode" : 68, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_exp", + "opcode" : 69, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp2", + "opcode" : 70, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_exp10", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log2", + "opcode" : 73, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_log10", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_powr", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "half_recip", + "opcode" : 76, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_rsqrt", + "opcode" : 77, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sin", + "opcode" : 78, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_sqrt", + "opcode" : 79, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "half_tan", + "opcode" : 80, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_cos", + "opcode" : 81, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_divide", + "opcode" : 82, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_exp", + "opcode" : 83, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp2", + "opcode" : 84, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_exp10", + "opcode" : 85, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log", + "opcode" : 86, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log2", + "opcode" : 87, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_log10", + "opcode" : 88, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_powr", + "opcode" : 89, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "native_recip", + "opcode" : 90, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_rsqrt", + "opcode" : 91, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sin", + "opcode" : 92, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_sqrt", + "opcode" : 93, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "native_tan", + "opcode" : 94, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs", + "opcode" : 141, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_abs_diff", + "opcode" : 142, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_add_sat", + "opcode" : 143, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_add_sat", + "opcode" : 144, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_hadd", + "opcode" : 145, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_hadd", + "opcode" : 146, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_rhadd", + "opcode" : 147, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_rhadd", + "opcode" : 148, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_clamp", + "opcode" : 149, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "u_clamp", + "opcode" : 150, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "clz", + "opcode" : 151, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "ctz", + "opcode" : 152, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad_hi", + "opcode" : 153, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "u_mad_sat", + "opcode" : 154, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mad_sat", + "opcode" : 155, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_max", + "opcode" : 156, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_max", + "opcode" : 157, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_min", + "opcode" : 158, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_min", + "opcode" : 159, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "s_mul_hi", + "opcode" : 160, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "rotate", + "opcode" : 161, + "operands" : [ + { "kind" : "IdRef", "name" : "'v'" }, + { "kind" : "IdRef", "name" : "'i'" } + ] + }, + { + "opname" : "s_sub_sat", + "opcode" : 162, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_sub_sat", + "opcode" : 163, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_upsample", + "opcode" : 164, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "s_upsample", + "opcode" : 165, + "operands" : [ + { "kind" : "IdRef", "name" : "'hi'" }, + { "kind" : "IdRef", "name" : "'lo'" } + ] + }, + { + "opname" : "popcount", + "opcode" : 166, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "s_mad24", + "opcode" : 167, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "u_mad24", + "opcode" : 168, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ] + }, + { + "opname" : "s_mul24", + "opcode" : 169, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul24", + "opcode" : 170, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_abs", + "opcode" : 201, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "u_abs_diff", + "opcode" : 202, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mul_hi", + "opcode" : 203, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "u_mad_hi", + "opcode" : 204, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "fclamp", + "opcode" : 95, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'minval'" }, + { "kind" : "IdRef", "name" : "'maxval'" } + ] + }, + { + "opname" : "degrees", + "opcode" :96, + "operands" : [ + { "kind" : "IdRef", "name" : "'radians'" } + ] + }, + { + "opname" : "fmax_common", + "opcode" : 97, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "fmin_common", + "opcode" : 98, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ] + }, + { + "opname" : "mix", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'a'" } + ] + }, + { + "opname" : "radians", + "opcode" : 100, + "operands" : [ + { "kind" : "IdRef", "name" : "'degrees'" } + ] + }, + { + "opname" : "step", + "opcode" : 101, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "smoothstep", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'edge0'" }, + { "kind" : "IdRef", "name" : "'edge1'" }, + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "sign", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" } + ] + }, + { + "opname" : "cross", + "opcode" : 104, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "distance", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "length", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "normalize", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_distance", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'p0'" }, + { "kind" : "IdRef", "name" : "'p1'" } + ] + }, + { + "opname" : "fast_length", + "opcode" : 109, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "fast_normalize", + "opcode" : 110, + "operands" : [ + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "bitselect", + "opcode" : 186, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "select", + "opcode" : 187, + "operands" : [ + { "kind" : "IdRef", "name" : "'a'" }, + { "kind" : "IdRef", "name" : "'b'" }, + { "kind" : "IdRef", "name" : "'c'" } + ] + }, + { + "opname" : "vloadn", + "opcode" : 171, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstoren", + "opcode" : 172, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_half", + "opcode" : 173, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vload_halfn", + "opcode" : 174, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstore_half", + "opcode" : 175, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_half_r", + "opcode" : 176, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vstore_halfn", + "opcode" : 177, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstore_halfn_r", + "opcode" : 178, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "vloada_halfn", + "opcode" : 179, + "operands" : [ + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "LiteralInteger", "name" : "'n'" } + ] + }, + { + "opname" : "vstorea_halfn", + "opcode" : 180, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" } + ] + }, + { + "opname" : "vstorea_halfn_r", + "opcode" : 181, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" }, + { "kind" : "IdRef", "name" : "'p'" }, + { "kind" : "FPRoundingMode", "name" : "'mode'" } + ] + }, + { + "opname" : "shuffle", + "opcode" : 182, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "shuffle2", + "opcode" : 183, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'shuffle mask'" } + ] + }, + { + "opname" : "printf", + "opcode" : 184, + "operands" : [ + { "kind" : "IdRef", "name" : "'format'" }, + { "kind" : "IdRef", "name" : "'additional arguments'", "quantifier" : "*" } + ] + }, + { + "opname" : "prefetch", + "opcode" : 185, + "operands" : [ + { "kind" : "IdRef", "name" : "'ptr'" }, + { "kind" : "IdRef", "name" : "'num elements'" } + ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json new file mode 100644 index 000000000000..e18251bba1b2 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json @@ -0,0 +1,26 @@ +{ + "revision" : 2, + "instructions" : [ + { + "opname" : "CubeFaceIndexAMD", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'P'" } + ], + "extensions" : [ "SPV_AMD_gcn_shader" ] + }, + { + "opname" : "CubeFaceCoordAMD", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'P'" } + ], + "extensions" : [ "SPV_AMD_gcn_shader" ] + }, + { + "opname" : "TimeAMD", + "opcode" : 3, + "extensions" : [ "SPV_AMD_gcn_shader" ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json new file mode 100644 index 000000000000..62a470eeb658 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json @@ -0,0 +1,41 @@ +{ + "revision" : 5, + "instructions" : [ + { + "opname" : "SwizzleInvocationsAMD", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'offset'" } + ], + "extensions" : [ "SPV_AMD_shader_ballot" ] + }, + { + "opname" : "SwizzleInvocationsMaskedAMD", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'data'" }, + { "kind" : "IdRef", "name" : "'mask'" } + ], + "extensions" : [ "SPV_AMD_shader_ballot" ] + }, + { + "opname" : "WriteInvocationAMD", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'inputValue'" }, + { "kind" : "IdRef", "name" : "'writeValue'" }, + { "kind" : "IdRef", "name" : "'invocationIndex'" } + ], + "extensions" : [ "SPV_AMD_shader_ballot" ] + }, + { + "opname" : "MbcntAMD", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'mask'" } + ], + "extensions" : [ "SPV_AMD_shader_ballot" ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json new file mode 100644 index 000000000000..e156b1b6f817 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json @@ -0,0 +1,14 @@ +{ + "revision" : 4, + "instructions" : [ + { + "opname" : "InterpolateAtVertexAMD", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'interpolant'" }, + { "kind" : "IdRef", "name" : "'vertexIdx'" } + ], + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json new file mode 100644 index 000000000000..c681976fe924 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json @@ -0,0 +1,95 @@ +{ + "revision" : 4, + "instructions" : [ + { + "opname" : "FMin3AMD", + "opcode" : 1, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "UMin3AMD", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "SMin3AMD", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "FMax3AMD", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "UMax3AMD", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "SMax3AMD", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "FMid3AMD", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "UMid3AMD", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + }, + { + "opname" : "SMid3AMD", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" }, + { "kind" : "IdRef", "name" : "'z'" } + ], + "extensions" : [ "SPV_AMD_shader_trinary_minmax" ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.bf b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.bf new file mode 100644 index 000000000000..c1fa60bba6fa --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.bf @@ -0,0 +1,2149 @@ +// Copyright (c) 2014-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + using System; + + public static class Specification + { + public const uint32 MagicNumber = 0x07230203; + public const uint32 Version = 0x00010600; + public const uint32 Revision = 1; + public const uint32 OpCodeMask = 0xffff; + public const uint32 WordCountShift = 16; + + [AllowDuplicates, CRepr] public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + } + + [AllowDuplicates, CRepr] public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + } + + [AllowDuplicates, CRepr] public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + } + + [AllowDuplicates, CRepr] public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + } + + [AllowDuplicates, CRepr] public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + } + + [AllowDuplicates, CRepr] public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + NodeOutputPayloadAMDX = 5076, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + } + + [AllowDuplicates, CRepr] public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + } + + [AllowDuplicates, CRepr] public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + [AllowDuplicates, CRepr] public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + [AllowDuplicates, CRepr] public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + } + + [AllowDuplicates, CRepr] public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + [AllowDuplicates, CRepr] public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + } + + [AllowDuplicates, CRepr] public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + } + + [AllowDuplicates, CRepr] public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, + } + + [AllowDuplicates, CRepr] public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + } + + [AllowDuplicates, CRepr] public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, + } + + [AllowDuplicates, CRepr] public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + [AllowDuplicates, CRepr] public enum LinkageType + { + Export = 0, + Import = 1, + LinkOnceODR = 2, + } + + [AllowDuplicates, CRepr] public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + [AllowDuplicates, CRepr] public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + } + + [AllowDuplicates, CRepr] public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + } + + [AllowDuplicates, CRepr] public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + CoalescedInputCountAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + } + + [AllowDuplicates, CRepr] public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + [AllowDuplicates, CRepr] public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + [AllowDuplicates, CRepr] public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + } + + [AllowDuplicates, CRepr] public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, + } + + [AllowDuplicates, CRepr] public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, + } + + [AllowDuplicates, CRepr] public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, + } + + [AllowDuplicates, CRepr] public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + } + + [AllowDuplicates, CRepr] public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, + } + + [AllowDuplicates, CRepr] public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + } + + [AllowDuplicates, CRepr] public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, + } + + [AllowDuplicates, CRepr] public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + } + + [AllowDuplicates, CRepr] public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + } + + [AllowDuplicates, CRepr] public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + [AllowDuplicates, CRepr] public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + [AllowDuplicates, CRepr] public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + [AllowDuplicates, CRepr] public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + } + + [AllowDuplicates, CRepr] public enum RayFlagsShift + { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + } + + [AllowDuplicates, CRepr] public enum RayFlagsMask + { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, + } + + [AllowDuplicates, CRepr] public enum RayQueryIntersection + { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + } + + [AllowDuplicates, CRepr] public enum RayQueryCommittedIntersectionType + { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + } + + [AllowDuplicates, CRepr] public enum RayQueryCandidateIntersectionType + { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + } + + [AllowDuplicates, CRepr] public enum FragmentShadingRateShift + { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + } + + [AllowDuplicates, CRepr] public enum FragmentShadingRateMask + { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, + } + + [AllowDuplicates, CRepr] public enum FPDenormMode + { + Preserve = 0, + FlushToZero = 1, + } + + [AllowDuplicates, CRepr] public enum FPOperationMode + { + IEEE = 0, + ALT = 1, + } + + [AllowDuplicates, CRepr] public enum QuantizationModes + { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + } + + [AllowDuplicates, CRepr] public enum OverflowModes + { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + } + + [AllowDuplicates, CRepr] public enum PackedVectorFormat + { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + } + + [AllowDuplicates, CRepr] public enum CooperativeMatrixOperandsShift + { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + } + + [AllowDuplicates, CRepr] public enum CooperativeMatrixOperandsMask + { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, + } + + [AllowDuplicates, CRepr] public enum CooperativeMatrixLayout + { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + } + + [AllowDuplicates, CRepr] public enum CooperativeMatrixUse + { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + } + + [AllowDuplicates, CRepr] public enum InitializationModeQualifier + { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + } + + [AllowDuplicates, CRepr] public enum HostAccessQualifier + { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + } + + [AllowDuplicates, CRepr] public enum LoadCacheControl + { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + } + + [AllowDuplicates, CRepr] public enum StoreCacheControl + { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + } + + [AllowDuplicates, CRepr] public enum NamedMaximumNumberOfRegisters + { + AutoINTEL = 0, + } + + [AllowDuplicates, CRepr] public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + } + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.core.grammar.json b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.core.grammar.json new file mode 100644 index 000000000000..ba449335262a --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.core.grammar.json @@ -0,0 +1,16853 @@ +{ + "copyright" : [ + "Copyright (c) 2014-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "magic_number" : "0x07230203", + "major_version" : 1, + "minor_version" : 6, + "revision" : 1, + "instruction_printing_class" : [ + { + "tag" : "@exclude" + }, + { + "tag" : "Miscellaneous", + "heading" : "Miscellaneous Instructions" + }, + { + "tag" : "Debug", + "heading" : "Debug Instructions" + }, + { + "tag" : "Annotation", + "heading" : "Annotation Instructions" + }, + { + "tag" : "Extension", + "heading" : "Extension Instructions" + }, + { + "tag" : "Mode-Setting", + "heading" : "Mode-Setting Instructions" + }, + { + "tag" : "Type-Declaration", + "heading" : "Type-Declaration Instructions" + }, + { + "tag" : "Constant-Creation", + "heading" : "Constant-Creation Instructions" + }, + { + "tag" : "Memory", + "heading" : "Memory Instructions" + }, + { + "tag" : "Function", + "heading" : "Function Instructions" + }, + { + "tag" : "Image", + "heading" : "Image Instructions" + }, + { + "tag" : "Conversion", + "heading" : "Conversion Instructions" + }, + { + "tag" : "Composite", + "heading" : "Composite Instructions" + }, + { + "tag" : "Arithmetic", + "heading" : "Arithmetic Instructions" + }, + { + "tag" : "Bit", + "heading" : "Bit Instructions" + }, + { + "tag" : "Relational_and_Logical", + "heading" : "Relational and Logical Instructions" + }, + { + "tag" : "Derivative", + "heading" : "Derivative Instructions" + }, + { + "tag" : "Control-Flow", + "heading" : "Control-Flow Instructions" + }, + { + "tag" : "Atomic", + "heading" : "Atomic Instructions" + }, + { + "tag" : "Primitive", + "heading" : "Primitive Instructions" + }, + { + "tag" : "Barrier", + "heading" : "Barrier Instructions" + }, + { + "tag" : "Group", + "heading" : "Group and Subgroup Instructions" + }, + { + "tag" : "Device-Side_Enqueue", + "heading" : "Device-Side Enqueue Instructions" + }, + { + "tag" : "Pipe", + "heading" : "Pipe Instructions" + }, + { + "tag" : "Non-Uniform", + "heading" : "Non-Uniform Instructions" + }, + { + "tag" : "Reserved", + "heading" : "Reserved Instructions" + } + ], + "instructions" : [ + { + "opname" : "OpNop", + "class" : "Miscellaneous", + "opcode" : 0, + "version" : "1.0" + }, + { + "opname" : "OpUndef", + "class" : "Miscellaneous", + "opcode" : 1, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version" : "1.0" + }, + { + "opname" : "OpSourceContinued", + "class" : "Debug", + "opcode" : 2, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Continued Source'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSource", + "class" : "Debug", + "opcode" : 3, + "operands" : [ + { "kind" : "SourceLanguage" }, + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" }, + { "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSourceExtension", + "class" : "Debug", + "opcode" : 4, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Extension'" } + ], + "version": "1.0" + }, + { + "opname" : "OpName", + "class" : "Debug", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "version": "1.0" + }, + { + "opname" : "OpMemberName", + "class" : "Debug", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "version": "1.0" + }, + { + "opname" : "OpString", + "class" : "Debug", + "opcode" : 7, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'String'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLine", + "class" : "Debug", + "opcode" : 8, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ], + "version": "1.0" + }, + { + "opname" : "OpExtension", + "class" : "Extension", + "opcode" : 10, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "version": "1.0" + }, + { + "opname" : "OpExtInstImport", + "class" : "Extension", + "opcode" : 11, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "version": "1.0" + }, + { + "opname" : "OpExtInst", + "class" : "Extension", + "opcode" : 12, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ], + "version": "1.0" + }, + { + "opname" : "OpMemoryModel", + "class" : "Mode-Setting", + "opcode" : 14, + "operands" : [ + { "kind" : "AddressingModel" }, + { "kind" : "MemoryModel" } + ], + "version": "1.0" + }, + { + "opname" : "OpEntryPoint", + "class" : "Mode-Setting", + "opcode" : 15, + "operands" : [ + { "kind" : "ExecutionModel" }, + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } + ], + "version": "1.0" + }, + { + "opname" : "OpExecutionMode", + "class" : "Mode-Setting", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCapability", + "class" : "Mode-Setting", + "opcode" : 17, + "operands" : [ + { "kind" : "Capability", "name" : "'Capability'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeVoid", + "class" : "Type-Declaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeBool", + "class" : "Type-Declaration", + "opcode" : 20, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeInt", + "class" : "Type-Declaration", + "opcode" : 21, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" }, + { "kind" : "LiteralInteger", "name" : "'Signedness'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeFloat", + "class" : "Type-Declaration", + "opcode" : 22, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Width'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeVector", + "class" : "Type-Declaration", + "opcode" : 23, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeMatrix", + "class" : "Type-Declaration", + "opcode" : 24, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Column Type'" }, + { "kind" : "LiteralInteger", "name" : "'Column Count'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpTypeImage", + "class" : "Type-Declaration", + "opcode" : 25, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Type'" }, + { "kind" : "Dim" }, + { "kind" : "LiteralInteger", "name" : "'Depth'" }, + { "kind" : "LiteralInteger", "name" : "'Arrayed'" }, + { "kind" : "LiteralInteger", "name" : "'MS'" }, + { "kind" : "LiteralInteger", "name" : "'Sampled'" }, + { "kind" : "ImageFormat" }, + { "kind" : "AccessQualifier", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeSampler", + "class" : "Type-Declaration", + "opcode" : 26, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeSampledImage", + "class" : "Type-Declaration", + "opcode" : 27, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeArray", + "class" : "Type-Declaration", + "opcode" : 28, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" }, + { "kind" : "IdRef", "name" : "'Length'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeRuntimeArray", + "class" : "Type-Declaration", + "opcode" : 29, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Element Type'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpTypeStruct", + "class" : "Type-Declaration", + "opcode" : 30, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeOpaque", + "class" : "Type-Declaration", + "opcode" : 31, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "The name of the opaque type." } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpTypePointer", + "class" : "Type-Declaration", + "opcode" : 32, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "name" : "'Type'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeFunction", + "class" : "Type-Declaration", + "opcode" : 33, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." } + ], + "version": "1.0" + }, + { + "opname" : "OpTypeEvent", + "class" : "Type-Declaration", + "opcode" : 34, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpTypeDeviceEvent", + "class" : "Type-Declaration", + "opcode" : 35, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpTypeReserveId", + "class" : "Type-Declaration", + "opcode" : 36, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpTypeQueue", + "class" : "Type-Declaration", + "opcode" : 37, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpTypePipe", + "class" : "Type-Declaration", + "opcode" : 38, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "AccessQualifier", "name" : "'Qualifier'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpTypeForwardPointer", + "class" : "Type-Declaration", + "opcode" : 39, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer Type'" }, + { "kind" : "StorageClass" } + ], + "capabilities" : [ + "Addresses", + "PhysicalStorageBufferAddresses" + ], + "version": "1.0" + }, + { + "opname" : "OpConstantTrue", + "class" : "Constant-Creation", + "opcode" : 41, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpConstantFalse", + "class" : "Constant-Creation", + "opcode" : 42, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpConstant", + "class" : "Constant-Creation", + "opcode" : 43, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConstantComposite", + "class" : "Constant-Creation", + "opcode" : 44, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConstantSampler", + "class" : "Constant-Creation", + "opcode" : 45, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "SamplerAddressingMode" }, + { "kind" : "LiteralInteger", "name" : "'Param'" }, + { "kind" : "SamplerFilterMode" } + ], + "capabilities" : [ "LiteralSampler" ], + "version": "1.0" + }, + { + "opname" : "OpConstantNull", + "class" : "Constant-Creation", + "opcode" : 46, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstantTrue", + "class" : "Constant-Creation", + "opcode" : 48, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstantFalse", + "class" : "Constant-Creation", + "opcode" : 49, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstant", + "class" : "Constant-Creation", + "opcode" : 50, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstantComposite", + "class" : "Constant-Creation", + "opcode" : 51, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSpecConstantOp", + "class" : "Constant-Creation", + "opcode" : 52, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFunction", + "class" : "Function", + "opcode" : 54, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "FunctionControl" }, + { "kind" : "IdRef", "name" : "'Function Type'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFunctionParameter", + "class" : "Function", + "opcode" : 55, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpFunctionEnd", + "class" : "Function", + "opcode" : 56, + "version" : "1.0" + }, + { + "opname" : "OpFunctionCall", + "class" : "Function", + "opcode" : 57, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." } + ], + "version": "1.0" + }, + { + "opname" : "OpVariable", + "class" : "Memory", + "opcode" : 59, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "StorageClass" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageTexelPointer", + "class" : "Memory", + "opcode" : 60, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Sample'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLoad", + "class" : "Memory", + "opcode" : 61, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpStore", + "class" : "Memory", + "opcode" : 62, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpCopyMemory", + "class" : "Memory", + "opcode" : 63, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpCopyMemorySized", + "class" : "Memory", + "opcode" : 64, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "opname" : "OpAccessChain", + "class" : "Memory", + "opcode" : 65, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "version": "1.0" + }, + { + "opname" : "OpInBoundsAccessChain", + "class" : "Memory", + "opcode" : 66, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "version": "1.0" + }, + { + "opname" : "OpPtrAccessChain", + "class" : "Memory", + "opcode" : 67, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ + "Addresses", + "VariablePointers", + "VariablePointersStorageBuffer", + "PhysicalStorageBufferAddresses" + ], + "version": "1.0" + }, + { + "opname" : "OpArrayLength", + "class" : "Memory", + "opcode" : 68, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Structure'" }, + { "kind" : "LiteralInteger", "name" : "'Array member'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpGenericPtrMemSemantics", + "class" : "Memory", + "opcode" : 69, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpInBoundsPtrAccessChain", + "class" : "Memory", + "opcode" : 70, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Element'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" } + ], + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "opname" : "OpDecorate", + "class" : "Annotation", + "opcode" : 71, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "version": "1.0" + }, + { + "opname" : "OpMemberDecorate", + "class" : "Annotation", + "opcode" : 72, + "operands" : [ + { "kind" : "IdRef", "name" : "'Structure Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "version": "1.0" + }, + { + "opname" : "OpDecorationGroup", + "class" : "Annotation", + "opcode" : 73, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpGroupDecorate", + "class" : "Annotation", + "opcode" : 74, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" } + ], + "version": "1.0" + }, + { + "opname" : "OpGroupMemberDecorate", + "class" : "Annotation", + "opcode" : 75, + "operands" : [ + { "kind" : "IdRef", "name" : "'Decoration Group'" }, + { "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" } + ], + "version": "1.0" + }, + { + "opname" : "OpVectorExtractDynamic", + "class" : "Composite", + "opcode" : 77, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "version": "1.0" + }, + { + "opname" : "OpVectorInsertDynamic", + "class" : "Composite", + "opcode" : 78, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "version": "1.0" + }, + { + "opname" : "OpVectorShuffle", + "class" : "Composite", + "opcode" : 79, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCompositeConstruct", + "class" : "Composite", + "opcode" : 80, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCompositeExtract", + "class" : "Composite", + "opcode" : 81, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCompositeInsert", + "class" : "Composite", + "opcode" : 82, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Composite'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" } + ], + "version": "1.0" + }, + { + "opname" : "OpCopyObject", + "class" : "Composite", + "opcode" : 83, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpTranspose", + "class" : "Composite", + "opcode" : 84, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpSampledImage", + "class" : "Image", + "opcode" : 86, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleImplicitLod", + "class" : "Image", + "opcode" : 87, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleExplicitLod", + "class" : "Image", + "opcode" : 88, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleDrefImplicitLod", + "class" : "Image", + "opcode" : 89, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleDrefExplicitLod", + "class" : "Image", + "opcode" : 90, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleProjImplicitLod", + "class" : "Image", + "opcode" : 91, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleProjExplicitLod", + "class" : "Image", + "opcode" : 92, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleProjDrefImplicitLod", + "class" : "Image", + "opcode" : 93, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageSampleProjDrefExplicitLod", + "class" : "Image", + "opcode" : 94, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageFetch", + "class" : "Image", + "opcode" : 95, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageGather", + "class" : "Image", + "opcode" : 96, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageDrefGather", + "class" : "Image", + "opcode" : 97, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpImageRead", + "class" : "Image", + "opcode" : 98, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageWrite", + "class" : "Image", + "opcode" : 99, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Texel'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "version": "1.0" + }, + { + "opname" : "OpImage", + "class" : "Image", + "opcode" : 100, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" } + ], + "version": "1.0" + }, + { + "opname" : "OpImageQueryFormat", + "class" : "Image", + "opcode" : 101, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpImageQueryOrder", + "class" : "Image", + "opcode" : 102, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpImageQuerySizeLod", + "class" : "Image", + "opcode" : 103, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Level of Detail'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpImageQuerySize", + "class" : "Image", + "opcode" : 104, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpImageQueryLod", + "class" : "Image", + "opcode" : 105, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpImageQueryLevels", + "class" : "Image", + "opcode" : 106, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpImageQuerySamples", + "class" : "Image", + "opcode" : 107, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" } + ], + "capabilities" : [ "Kernel", "ImageQuery" ], + "version": "1.0" + }, + { + "opname" : "OpConvertFToU", + "class" : "Conversion", + "opcode" : 109, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConvertFToS", + "class" : "Conversion", + "opcode" : 110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConvertSToF", + "class" : "Conversion", + "opcode" : 111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConvertUToF", + "class" : "Conversion", + "opcode" : 112, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUConvert", + "class" : "Conversion", + "opcode" : 113, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSConvert", + "class" : "Conversion", + "opcode" : 114, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFConvert", + "class" : "Conversion", + "opcode" : 115, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpQuantizeToF16", + "class" : "Conversion", + "opcode" : 116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpConvertPtrToU", + "class" : "Conversion", + "opcode" : 117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ + "Addresses", + "PhysicalStorageBufferAddresses" + ], + "version": "1.0" + }, + { + "opname" : "OpSatConvertSToU", + "class" : "Conversion", + "opcode" : 118, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Signed Value'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpSatConvertUToS", + "class" : "Conversion", + "opcode" : 119, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Unsigned Value'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpConvertUToPtr", + "class" : "Conversion", + "opcode" : 120, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Integer Value'" } + ], + "capabilities" : [ + "Addresses", + "PhysicalStorageBufferAddresses" + ], + "version": "1.0" + }, + { + "opname" : "OpPtrCastToGeneric", + "class" : "Conversion", + "opcode" : 121, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGenericCastToPtr", + "class" : "Conversion", + "opcode" : 122, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGenericCastToPtrExplicit", + "class" : "Conversion", + "opcode" : 123, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "StorageClass", "name" : "'Storage'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpBitcast", + "class" : "Conversion", + "opcode" : 124, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSNegate", + "class" : "Arithmetic", + "opcode" : 126, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFNegate", + "class" : "Arithmetic", + "opcode" : 127, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIAdd", + "class" : "Arithmetic", + "opcode" : 128, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFAdd", + "class" : "Arithmetic", + "opcode" : 129, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpISub", + "class" : "Arithmetic", + "opcode" : 130, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFSub", + "class" : "Arithmetic", + "opcode" : 131, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIMul", + "class" : "Arithmetic", + "opcode" : 132, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFMul", + "class" : "Arithmetic", + "opcode" : 133, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUDiv", + "class" : "Arithmetic", + "opcode" : 134, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSDiv", + "class" : "Arithmetic", + "opcode" : 135, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFDiv", + "class" : "Arithmetic", + "opcode" : 136, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUMod", + "class" : "Arithmetic", + "opcode" : 137, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSRem", + "class" : "Arithmetic", + "opcode" : 138, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSMod", + "class" : "Arithmetic", + "opcode" : 139, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFRem", + "class" : "Arithmetic", + "opcode" : 140, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFMod", + "class" : "Arithmetic", + "opcode" : 141, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpVectorTimesScalar", + "class" : "Arithmetic", + "opcode" : 142, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "version": "1.0" + }, + { + "opname" : "OpMatrixTimesScalar", + "class" : "Arithmetic", + "opcode" : 143, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Scalar'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpVectorTimesMatrix", + "class" : "Arithmetic", + "opcode" : 144, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" }, + { "kind" : "IdRef", "name" : "'Matrix'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpMatrixTimesVector", + "class" : "Arithmetic", + "opcode" : 145, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Matrix'" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpMatrixTimesMatrix", + "class" : "Arithmetic", + "opcode" : 146, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'LeftMatrix'" }, + { "kind" : "IdRef", "name" : "'RightMatrix'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpOuterProduct", + "class" : "Arithmetic", + "opcode" : 147, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "opname" : "OpDot", + "class" : "Arithmetic", + "opcode" : 148, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIAddCarry", + "class" : "Arithmetic", + "opcode" : 149, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpISubBorrow", + "class" : "Arithmetic", + "opcode" : 150, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUMulExtended", + "class" : "Arithmetic", + "opcode" : 151, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSMulExtended", + "class" : "Arithmetic", + "opcode" : 152, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAny", + "class" : "Relational_and_Logical", + "opcode" : 154, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAll", + "class" : "Relational_and_Logical", + "opcode" : 155, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIsNan", + "class" : "Relational_and_Logical", + "opcode" : 156, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIsInf", + "class" : "Relational_and_Logical", + "opcode" : 157, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIsFinite", + "class" : "Relational_and_Logical", + "opcode" : 158, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpIsNormal", + "class" : "Relational_and_Logical", + "opcode" : 159, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpSignBitSet", + "class" : "Relational_and_Logical", + "opcode" : 160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpLessOrGreater", + "class" : "Relational_and_Logical", + "opcode" : 161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ], + "version" : "1.0", + "lastVersion" : "1.5" + }, + { + "opname" : "OpOrdered", + "class" : "Relational_and_Logical", + "opcode" : 162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpUnordered", + "class" : "Relational_and_Logical", + "opcode" : 163, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'x'" }, + { "kind" : "IdRef", "name" : "'y'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpLogicalEqual", + "class" : "Relational_and_Logical", + "opcode" : 164, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLogicalNotEqual", + "class" : "Relational_and_Logical", + "opcode" : 165, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLogicalOr", + "class" : "Relational_and_Logical", + "opcode" : 166, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLogicalAnd", + "class" : "Relational_and_Logical", + "opcode" : 167, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version" : "1.0" + }, + { + "opname" : "OpLogicalNot", + "class" : "Relational_and_Logical", + "opcode" : 168, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSelect", + "class" : "Relational_and_Logical", + "opcode" : 169, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'Object 1'" }, + { "kind" : "IdRef", "name" : "'Object 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpIEqual", + "class" : "Relational_and_Logical", + "opcode" : 170, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpINotEqual", + "class" : "Relational_and_Logical", + "opcode" : 171, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUGreaterThan", + "class" : "Relational_and_Logical", + "opcode" : 172, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSGreaterThan", + "class" : "Relational_and_Logical", + "opcode" : 173, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUGreaterThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 174, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSGreaterThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 175, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpULessThan", + "class" : "Relational_and_Logical", + "opcode" : 176, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSLessThan", + "class" : "Relational_and_Logical", + "opcode" : 177, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpULessThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 178, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSLessThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 179, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdEqual", + "class" : "Relational_and_Logical", + "opcode" : 180, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordEqual", + "class" : "Relational_and_Logical", + "opcode" : 181, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdNotEqual", + "class" : "Relational_and_Logical", + "opcode" : 182, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordNotEqual", + "class" : "Relational_and_Logical", + "opcode" : 183, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdLessThan", + "class" : "Relational_and_Logical", + "opcode" : 184, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordLessThan", + "class" : "Relational_and_Logical", + "opcode" : 185, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdGreaterThan", + "class" : "Relational_and_Logical", + "opcode" : 186, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordGreaterThan", + "class" : "Relational_and_Logical", + "opcode" : 187, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdLessThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 188, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordLessThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 189, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFOrdGreaterThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 190, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpFUnordGreaterThanEqual", + "class" : "Relational_and_Logical", + "opcode" : 191, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpShiftRightLogical", + "class" : "Bit", + "opcode" : 194, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ], + "version": "1.0" + }, + { + "opname" : "OpShiftRightArithmetic", + "class" : "Bit", + "opcode" : 195, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ], + "version": "1.0" + }, + { + "opname" : "OpShiftLeftLogical", + "class" : "Bit", + "opcode" : 196, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Shift'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBitwiseOr", + "class" : "Bit", + "opcode" : 197, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBitwiseXor", + "class" : "Bit", + "opcode" : 198, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBitwiseAnd", + "class" : "Bit", + "opcode" : 199, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version": "1.0" + }, + { + "opname" : "OpNot", + "class" : "Bit", + "opcode" : 200, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBitFieldInsert", + "class" : "Bit", + "opcode" : 201, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Insert'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader", "BitInstructions" ], + "version": "1.0" + }, + { + "opname" : "OpBitFieldSExtract", + "class" : "Bit", + "opcode" : 202, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader", "BitInstructions" ], + "version": "1.0" + }, + { + "opname" : "OpBitFieldUExtract", + "class" : "Bit", + "opcode" : 203, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Count'" } + ], + "capabilities" : [ "Shader", "BitInstructions" ], + "version": "1.0" + }, + { + "opname" : "OpBitReverse", + "class" : "Bit", + "opcode" : 204, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "capabilities" : [ "Shader", "BitInstructions" ], + "version": "1.0" + }, + { + "opname" : "OpBitCount", + "class" : "Bit", + "opcode" : 205, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" } + ], + "version": "1.0" + }, + { + "opname" : "OpDPdx", + "class" : "Derivative", + "opcode" : 207, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpDPdy", + "class" : "Derivative", + "opcode" : 208, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpFwidth", + "class" : "Derivative", + "opcode" : 209, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpDPdxFine", + "class" : "Derivative", + "opcode" : 210, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpDPdyFine", + "class" : "Derivative", + "opcode" : 211, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpFwidthFine", + "class" : "Derivative", + "opcode" : 212, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpDPdxCoarse", + "class" : "Derivative", + "opcode" : 213, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpDPdyCoarse", + "class" : "Derivative", + "opcode" : 214, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpFwidthCoarse", + "class" : "Derivative", + "opcode" : 215, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'P'" } + ], + "capabilities" : [ "DerivativeControl" ], + "version": "1.0" + }, + { + "opname" : "OpEmitVertex", + "class" : "Primitive", + "opcode" : 218, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "opname" : "OpEndPrimitive", + "class" : "Primitive", + "opcode" : 219, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "opname" : "OpEmitStreamVertex", + "class" : "Primitive", + "opcode" : 220, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ], + "version": "1.0" + }, + { + "opname" : "OpEndStreamPrimitive", + "class" : "Primitive", + "opcode" : 221, + "operands" : [ + { "kind" : "IdRef", "name" : "'Stream'" } + ], + "capabilities" : [ "GeometryStreams" ], + "version": "1.0" + }, + { + "opname" : "OpControlBarrier", + "class" : "Barrier", + "opcode" : 224, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpMemoryBarrier", + "class" : "Barrier", + "opcode" : 225, + "operands" : [ + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicLoad", + "class" : "Atomic", + "opcode" : 227, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicStore", + "class" : "Atomic", + "opcode" : 228, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicExchange", + "class" : "Atomic", + "opcode" : 229, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicCompareExchange", + "class" : "Atomic", + "opcode" : 230, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicCompareExchangeWeak", + "class" : "Atomic", + "opcode" : 231, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Equal'" }, + { "kind" : "IdMemorySemantics", "name" : "'Unequal'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Comparator'" } + ], + "capabilities" : [ "Kernel" ], + "version" : "1.0", + "lastVersion" : "1.3" + }, + { + "opname" : "OpAtomicIIncrement", + "class" : "Atomic", + "opcode" : 232, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicIDecrement", + "class" : "Atomic", + "opcode" : 233, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicIAdd", + "class" : "Atomic", + "opcode" : 234, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicISub", + "class" : "Atomic", + "opcode" : 235, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicSMin", + "class" : "Atomic", + "opcode" : 236, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicUMin", + "class" : "Atomic", + "opcode" : 237, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicSMax", + "class" : "Atomic", + "opcode" : 238, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicUMax", + "class" : "Atomic", + "opcode" : 239, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicAnd", + "class" : "Atomic", + "opcode" : 240, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicOr", + "class" : "Atomic", + "opcode" : 241, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpAtomicXor", + "class" : "Atomic", + "opcode" : 242, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpPhi", + "class" : "Control-Flow", + "opcode" : 245, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" } + ], + "version": "1.0" + }, + { + "opname" : "OpLoopMerge", + "class" : "Control-Flow", + "opcode" : 246, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "IdRef", "name" : "'Continue Target'" }, + { "kind" : "LoopControl" } + ], + "version": "1.0" + }, + { + "opname" : "OpSelectionMerge", + "class" : "Control-Flow", + "opcode" : 247, + "operands" : [ + { "kind" : "IdRef", "name" : "'Merge Block'" }, + { "kind" : "SelectionControl" } + ], + "version": "1.0" + }, + { + "opname" : "OpLabel", + "class" : "Control-Flow", + "opcode" : 248, + "operands" : [ + { "kind" : "IdResult" } + ], + "version": "1.0" + }, + { + "opname" : "OpBranch", + "class" : "Control-Flow", + "opcode" : 249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target Label'" } + ], + "version": "1.0" + }, + { + "opname" : "OpBranchConditional", + "class" : "Control-Flow", + "opcode" : 250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" }, + { "kind" : "IdRef", "name" : "'True Label'" }, + { "kind" : "IdRef", "name" : "'False Label'" }, + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" } + ], + "version": "1.0" + }, + { + "opname" : "OpSwitch", + "class" : "Control-Flow", + "opcode" : 251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Selector'" }, + { "kind" : "IdRef", "name" : "'Default'" }, + { "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" } + ], + "version": "1.0" + }, + { + "opname" : "OpKill", + "class" : "Control-Flow", + "opcode" : 252, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "opname" : "OpReturn", + "class" : "Control-Flow", + "opcode" : 253, + "version" : "1.0" + }, + { + "opname" : "OpReturnValue", + "class" : "Control-Flow", + "opcode" : 254, + "operands" : [ + { "kind" : "IdRef", "name" : "'Value'" } + ], + "version": "1.0" + }, + { + "opname" : "OpUnreachable", + "class" : "Control-Flow", + "opcode" : 255, + "version" : "1.0" + }, + { + "opname" : "OpLifetimeStart", + "class" : "Control-Flow", + "opcode" : 256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpLifetimeStop", + "class" : "Control-Flow", + "opcode" : 257, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGroupAsyncCopy", + "class" : "Group", + "opcode" : 259, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Destination'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Num Elements'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGroupWaitEvents", + "class" : "Group", + "opcode" : 260, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Events List'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpGroupAll", + "class" : "Group", + "opcode" : 261, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupAny", + "class" : "Group", + "opcode" : 262, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupBroadcast", + "class" : "Group", + "opcode" : 263, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'LocalId'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupIAdd", + "class" : "Group", + "opcode" : 264, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupFAdd", + "class" : "Group", + "opcode" : 265, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupFMin", + "class" : "Group", + "opcode" : 266, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupUMin", + "class" : "Group", + "opcode" : 267, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupSMin", + "class" : "Group", + "opcode" : 268, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupFMax", + "class" : "Group", + "opcode" : 269, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupUMax", + "class" : "Group", + "opcode" : 270, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpGroupSMax", + "class" : "Group", + "opcode" : 271, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "version": "1.0" + }, + { + "opname" : "OpReadPipe", + "class" : "Pipe", + "opcode" : 274, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpWritePipe", + "class" : "Pipe", + "opcode" : 275, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpReservedReadPipe", + "class" : "Pipe", + "opcode" : 276, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpReservedWritePipe", + "class" : "Pipe", + "opcode" : 277, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Index'" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpReserveReadPipePackets", + "class" : "Pipe", + "opcode" : 278, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpReserveWritePipePackets", + "class" : "Pipe", + "opcode" : 279, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpCommitReadPipe", + "class" : "Pipe", + "opcode" : 280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpCommitWritePipe", + "class" : "Pipe", + "opcode" : 281, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpIsValidReserveId", + "class" : "Pipe", + "opcode" : 282, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGetNumPipePackets", + "class" : "Pipe", + "opcode" : 283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGetMaxPipePackets", + "class" : "Pipe", + "opcode" : 284, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGroupReserveReadPipePackets", + "class" : "Pipe", + "opcode" : 285, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGroupReserveWritePipePackets", + "class" : "Pipe", + "opcode" : 286, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Num Packets'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGroupCommitReadPipe", + "class" : "Pipe", + "opcode" : 287, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpGroupCommitWritePipe", + "class" : "Pipe", + "opcode" : 288, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Pipe'" }, + { "kind" : "IdRef", "name" : "'Reserve Id'" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "Pipes" ], + "version": "1.0" + }, + { + "opname" : "OpEnqueueMarker", + "class" : "Device-Side_Enqueue", + "opcode" : 291, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpEnqueueKernel", + "class" : "Device-Side_Enqueue", + "opcode" : 292, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Queue'" }, + { "kind" : "IdRef", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Num Events'" }, + { "kind" : "IdRef", "name" : "'Wait Events'" }, + { "kind" : "IdRef", "name" : "'Ret Event'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetKernelNDrangeSubGroupCount", + "class" : "Device-Side_Enqueue", + "opcode" : 293, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetKernelNDrangeMaxSubGroupSize", + "class" : "Device-Side_Enqueue", + "opcode" : 294, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'ND Range'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetKernelWorkGroupSize", + "class" : "Device-Side_Enqueue", + "opcode" : 295, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetKernelPreferredWorkGroupSizeMultiple", + "class" : "Device-Side_Enqueue", + "opcode" : 296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpRetainEvent", + "class" : "Device-Side_Enqueue", + "opcode" : 297, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpReleaseEvent", + "class" : "Device-Side_Enqueue", + "opcode" : 298, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpCreateUserEvent", + "class" : "Device-Side_Enqueue", + "opcode" : 299, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpIsValidEvent", + "class" : "Device-Side_Enqueue", + "opcode" : 300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Event'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpSetUserEventStatus", + "class" : "Device-Side_Enqueue", + "opcode" : 301, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Status'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpCaptureEventProfilingInfo", + "class" : "Device-Side_Enqueue", + "opcode" : 302, + "operands" : [ + { "kind" : "IdRef", "name" : "'Event'" }, + { "kind" : "IdRef", "name" : "'Profiling Info'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpGetDefaultQueue", + "class" : "Device-Side_Enqueue", + "opcode" : 303, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpBuildNDRange", + "class" : "Device-Side_Enqueue", + "opcode" : 304, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'GlobalWorkSize'" }, + { "kind" : "IdRef", "name" : "'LocalWorkSize'" }, + { "kind" : "IdRef", "name" : "'GlobalWorkOffset'" } + ], + "capabilities" : [ "DeviceEnqueue" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleImplicitLod", + "class" : "Image", + "opcode" : 305, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleExplicitLod", + "class" : "Image", + "opcode" : 306, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleDrefImplicitLod", + "class" : "Image", + "opcode" : 307, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleDrefExplicitLod", + "class" : "Image", + "opcode" : 308, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseSampleProjImplicitLod", + "class" : "Image", + "opcode" : 309, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version" : "None" + }, + { + "opname" : "OpImageSparseSampleProjExplicitLod", + "class" : "Image", + "opcode" : 310, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ], + "version" : "None" + }, + { + "opname" : "OpImageSparseSampleProjDrefImplicitLod", + "class" : "Image", + "opcode" : 311, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version" : "None" + }, + { + "opname" : "OpImageSparseSampleProjDrefExplicitLod", + "class" : "Image", + "opcode" : 312, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands" } + ], + "capabilities" : [ "SparseResidency" ], + "version" : "None" + }, + { + "opname" : "OpImageSparseFetch", + "class" : "Image", + "opcode" : 313, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseGather", + "class" : "Image", + "opcode" : 314, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Component'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseDrefGather", + "class" : "Image", + "opcode" : 315, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'D~ref~'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseTexelsResident", + "class" : "Image", + "opcode" : 316, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Resident Code'" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpNoLine", + "class" : "Debug", + "opcode" : 317, + "version" : "1.0" + }, + { + "opname" : "OpAtomicFlagTestAndSet", + "class" : "Atomic", + "opcode" : 318, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpAtomicFlagClear", + "class" : "Atomic", + "opcode" : 319, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "opname" : "OpImageSparseRead", + "class" : "Image", + "opcode" : 320, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "SparseResidency" ], + "version": "1.0" + }, + { + "opname" : "OpSizeOf", + "class" : "Miscellaneous", + "opcode" : 321, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "Addresses" ], + "version" : "1.1" + }, + { + "opname" : "OpTypePipeStorage", + "class" : "Type-Declaration", + "opcode" : 322, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "PipeStorage" ], + "version" : "1.1" + }, + { + "opname" : "OpConstantPipeStorage", + "class" : "Pipe", + "opcode" : 323, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Packet Size'" }, + { "kind" : "LiteralInteger", "name" : "'Packet Alignment'" }, + { "kind" : "LiteralInteger", "name" : "'Capacity'" } + ], + "capabilities" : [ "PipeStorage" ], + "version" : "1.1" + }, + { + "opname" : "OpCreatePipeFromPipeStorage", + "class" : "Pipe", + "opcode" : 324, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pipe Storage'" } + ], + "capabilities" : [ "PipeStorage" ], + "version" : "1.1" + }, + { + "opname" : "OpGetKernelLocalSizeForSubgroupCount", + "class" : "Device-Side_Enqueue", + "opcode" : 325, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ], + "version" : "1.1" + }, + { + "opname" : "OpGetKernelMaxNumSubgroups", + "class" : "Device-Side_Enqueue", + "opcode" : 326, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Invoke'" }, + { "kind" : "IdRef", "name" : "'Param'" }, + { "kind" : "IdRef", "name" : "'Param Size'" }, + { "kind" : "IdRef", "name" : "'Param Align'" } + ], + "capabilities" : [ "SubgroupDispatch" ], + "version" : "1.1" + }, + { + "opname" : "OpTypeNamedBarrier", + "class" : "Type-Declaration", + "opcode" : 327, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "NamedBarrier" ], + "version" : "1.1" + }, + { + "opname" : "OpNamedBarrierInitialize", + "class" : "Barrier", + "opcode" : 328, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Subgroup Count'" } + ], + "capabilities" : [ "NamedBarrier" ], + "version" : "1.1" + }, + { + "opname" : "OpMemoryNamedBarrier", + "class" : "Barrier", + "opcode" : 329, + "operands" : [ + { "kind" : "IdRef", "name" : "'Named Barrier'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "NamedBarrier" ], + "version" : "1.1" + }, + { + "opname" : "OpModuleProcessed", + "class" : "Debug", + "opcode" : 330, + "operands" : [ + { "kind" : "LiteralString", "name" : "'Process'" } + ], + "version" : "1.1" + }, + { + "opname" : "OpExecutionModeId", + "class" : "Mode-Setting", + "opcode" : 331, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "ExecutionMode", "name" : "'Mode'" } + ], + "version" : "1.2" + }, + { + "opname" : "OpDecorateId", + "class" : "Annotation", + "opcode" : 332, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.2" + }, + { + "opname" : "OpGroupNonUniformElect", + "class" : "Non-Uniform", + "opcode" : 333, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" } + ], + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformAll", + "class" : "Non-Uniform", + "opcode" : 334, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "GroupNonUniformVote" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformAny", + "class" : "Non-Uniform", + "opcode" : 335, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "GroupNonUniformVote" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformAllEqual", + "class" : "Non-Uniform", + "opcode" : 336, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformVote" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBroadcast", + "class" : "Non-Uniform", + "opcode" : 337, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Id'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBroadcastFirst", + "class" : "Non-Uniform", + "opcode" : 338, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallot", + "class" : "Non-Uniform", + "opcode" : 339, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformInverseBallot", + "class" : "Non-Uniform", + "opcode" : 340, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallotBitExtract", + "class" : "Non-Uniform", + "opcode" : 341, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallotBitCount", + "class" : "Non-Uniform", + "opcode" : 342, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallotFindLSB", + "class" : "Non-Uniform", + "opcode" : 343, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBallotFindMSB", + "class" : "Non-Uniform", + "opcode" : 344, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformShuffle", + "class" : "Non-Uniform", + "opcode" : 345, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Id'" } + ], + "capabilities" : [ "GroupNonUniformShuffle" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformShuffleXor", + "class" : "Non-Uniform", + "opcode" : 346, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Mask'" } + ], + "capabilities" : [ "GroupNonUniformShuffle" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformShuffleUp", + "class" : "Non-Uniform", + "opcode" : 347, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "GroupNonUniformShuffleRelative" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformShuffleDown", + "class" : "Non-Uniform", + "opcode" : 348, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "GroupNonUniformShuffleRelative" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformIAdd", + "class" : "Non-Uniform", + "opcode" : 349, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformFAdd", + "class" : "Non-Uniform", + "opcode" : 350, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformIMul", + "class" : "Non-Uniform", + "opcode" : 351, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformFMul", + "class" : "Non-Uniform", + "opcode" : 352, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformSMin", + "class" : "Non-Uniform", + "opcode" : 353, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformUMin", + "class" : "Non-Uniform", + "opcode" : 354, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformFMin", + "class" : "Non-Uniform", + "opcode" : 355, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformSMax", + "class" : "Non-Uniform", + "opcode" : 356, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformUMax", + "class" : "Non-Uniform", + "opcode" : 357, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformFMax", + "class" : "Non-Uniform", + "opcode" : 358, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBitwiseAnd", + "class" : "Non-Uniform", + "opcode" : 359, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBitwiseOr", + "class" : "Non-Uniform", + "opcode" : 360, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformBitwiseXor", + "class" : "Non-Uniform", + "opcode" : 361, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformLogicalAnd", + "class" : "Non-Uniform", + "opcode" : 362, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformLogicalOr", + "class" : "Non-Uniform", + "opcode" : 363, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformLogicalXor", + "class" : "Non-Uniform", + "opcode" : 364, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformArithmetic", "GroupNonUniformClustered", "GroupNonUniformPartitionedNV" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformQuadBroadcast", + "class" : "Non-Uniform", + "opcode" : 365, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "GroupNonUniformQuad" ], + "version" : "1.3" + }, + { + "opname" : "OpGroupNonUniformQuadSwap", + "class" : "Non-Uniform", + "opcode" : 366, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "GroupNonUniformQuad" ], + "version" : "1.3" + }, + { + "opname" : "OpCopyLogical", + "class" : "Composite", + "opcode" : 400, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "version" : "1.4" + }, + { + "opname" : "OpPtrEqual", + "class" : "Memory", + "opcode" : 401, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version" : "1.4" + }, + { + "opname" : "OpPtrNotEqual", + "class" : "Memory", + "opcode" : 402, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "version" : "1.4" + }, + { + "opname" : "OpPtrDiff", + "class" : "Memory", + "opcode" : 403, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "Addresses", "VariablePointers", "VariablePointersStorageBuffer" ], + "version" : "1.4" + }, + { + "opname" : "OpColorAttachmentReadEXT", + "class" : "Image", + "opcode" : 4160, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Attachment'" }, + { "kind" : "IdRef", "name" : "'Sample'", "quantifier" : "?" } + ], + "capabilities": [ "TileImageColorReadAccessEXT" ], + "version" : "None" + }, + { + "opname" : "OpDepthAttachmentReadEXT", + "class" : "Image", + "opcode" : 4161, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sample'", "quantifier" : "?" } + ], + "capabilities" : [ "TileImageDepthReadAccessEXT" ], + "version" : "None" + }, + { + "opname" : "OpStencilAttachmentReadEXT", + "class" : "Image", + "opcode" : 4162, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sample'", "quantifier" : "?" } + ], + "capabilities" : [ "TileImageStencilReadAccessEXT" ], + "version" : "None" + }, + { + "opname" : "OpTerminateInvocation", + "class" : "Control-Flow", + "opcode" : 4416, + "extensions" : [ + "SPV_KHR_terminate_invocation" + ], + "capabilities" : [ "Shader" ], + "version" : "1.6" + }, + { + "opname" : "OpSubgroupBallotKHR", + "class" : "Group", + "opcode" : 4421, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupFirstInvocationKHR", + "class" : "Group", + "opcode" : 4422, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAllKHR", + "class" : "Group", + "opcode" : 4428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "extensions" : [ + "SPV_KHR_subgroup_vote" + ], + "capabilities" : [ "SubgroupVoteKHR" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAnyKHR", + "class" : "Group", + "opcode" : 4429, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "extensions" : [ + "SPV_KHR_subgroup_vote" + ], + "capabilities" : [ "SubgroupVoteKHR" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAllEqualKHR", + "class" : "Group", + "opcode" : 4430, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "extensions" : [ + "SPV_KHR_subgroup_vote" + ], + "capabilities" : [ "SubgroupVoteKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupNonUniformRotateKHR", + "class" : "Group", + "opcode" : 4431, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Delta'" }, + { "kind" : "IdRef", "name" : "'ClusterSize'", "quantifier" : "?" } + ], + "capabilities" : [ "GroupNonUniformRotateKHR" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupReadInvocationKHR", + "class" : "Group", + "opcode" : 4432, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Index'" } + ], + "capabilities" : [ "SubgroupBallotKHR" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpTraceRayKHR", + "class" : "Reserved", + "opcode" : 4445, + "operands" : [ + + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Ray Flags'" }, + { "kind" : "IdRef", "name" : "'Cull Mask'" }, + { "kind" : "IdRef", "name" : "'SBT Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Stride'" }, + { "kind" : "IdRef", "name" : "'Miss Index'" }, + { "kind" : "IdRef", "name" : "'Ray Origin'" }, + { "kind" : "IdRef", "name" : "'Ray Tmin'" }, + { "kind" : "IdRef", "name" : "'Ray Direction'" }, + { "kind" : "IdRef", "name" : "'Ray Tmax'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpExecuteCallableKHR", + "class" : "Reserved", + "opcode" : 4446, + "operands" : [ + + { "kind" : "IdRef", "name" : "'SBT Index'" }, + { "kind" : "IdRef", "name" : "'Callable Data'" } + ], + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpConvertUToAccelerationStructureKHR", + "class" : "Reserved", + "opcode" : 4447, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Accel'" } + ], + "capabilities" : [ "RayTracingKHR", "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing", "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpIgnoreIntersectionKHR", + "class" : "Reserved", + "opcode" : 4448, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTerminateRayKHR", + "class" : "Reserved", + "opcode" : 4449, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpSDot", + "class" : "Arithmetic", + "opcode" : 4450, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpSDotKHR", + "class" : "Arithmetic", + "opcode" : 4450, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpUDot", + "class" : "Arithmetic", + "opcode" : 4451, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpUDotKHR", + "class" : "Arithmetic", + "opcode" : 4451, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpSUDot", + "class" : "Arithmetic", + "opcode" : 4452, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpSUDotKHR", + "class" : "Arithmetic", + "opcode" : 4452, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpSDotAccSat", + "class" : "Arithmetic", + "opcode" : 4453, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpSDotAccSatKHR", + "class" : "Arithmetic", + "opcode" : 4453, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpUDotAccSat", + "class" : "Arithmetic", + "opcode" : 4454, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpUDotAccSatKHR", + "class" : "Arithmetic", + "opcode" : 4454, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpSUDotAccSat", + "class" : "Arithmetic", + "opcode" : 4455, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProduct" ], + "version" : "1.6" + }, + { + "opname" : "OpSUDotAccSatKHR", + "class" : "Arithmetic", + "opcode" : 4455, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Vector 1'" }, + { "kind" : "IdRef", "name" : "'Vector 2'" }, + { "kind" : "IdRef", "name" : "'Accumulator'" }, + { "kind" : "PackedVectorFormat", "name" : "'Packed Vector Format'", "quantifier" : "?" } + ], + "capabilities" : [ "DotProductKHR" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "opname" : "OpTypeCooperativeMatrixKHR", + "class" : "Type-Declaration", + "opcode" : 4456, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "IdScope", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Rows'" }, + { "kind" : "IdRef", "name" : "'Columns'" }, + { "kind" : "IdRef", "name" : "'Use'" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixLoadKHR", + "class" : "Memory", + "opcode" : 4457, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'MemoryLayout'" }, + { "kind" : "IdRef", "name" : "'Stride'", "quantifier": "?" }, + { "kind" : "MemoryAccess", "name" : "'Memory Operand'", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixStoreKHR", + "class" : "Memory", + "opcode" : 4458, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'MemoryLayout'" }, + { "kind" : "IdRef", "name" : "'Stride'", "quantifier": "?" }, + { "kind" : "MemoryAccess", "name" : "'Memory Operand'", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixMulAddKHR", + "class" : "Arithmetic", + "opcode" : 4459, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "IdRef", "name" : "'C'" }, + { "kind" : "CooperativeMatrixOperands", "name" : "'Cooperative Matrix Operands'", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixLengthKHR", + "class" : "Miscellaneous", + "opcode" : 4460, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Type'" } + ], + "capabilities" : [ "CooperativeMatrixKHR" ], + "version" : "None" + }, + { + "opname" : "OpTypeRayQueryKHR", + "class" : "Type-Declaration", + "opcode" : 4472, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryInitializeKHR", + "class" : "Reserved", + "opcode" : 4473, + "operands" : [ + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Accel'" + }, + { + "kind" : "IdRef", + "name" : "'RayFlags'" + }, + { + "kind" : "IdRef", + "name" : "'CullMask'" + }, + { + "kind" : "IdRef", + "name" : "'RayOrigin'" + }, + { + "kind" : "IdRef", + "name" : "'RayTMin'" + }, + { + "kind" : "IdRef", + "name" : "'RayDirection'" + }, + { + "kind" : "IdRef", + "name" : "'RayTMax'" + } + + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryTerminateKHR", + "class" : "Reserved", + "opcode" : 4474, + "operands" : [ + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGenerateIntersectionKHR", + "class" : "Reserved", + "opcode" : 4475, + "operands" : [ + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'HitT'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryConfirmIntersectionKHR", + "class" : "Reserved", + "opcode" : 4476, + "operands" : [ + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryProceedKHR", + "class" : "Reserved", + "opcode" : 4477, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionTypeKHR", + "class" : "Reserved", + "opcode" : 4479, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpImageSampleWeightedQCOM", + "class" : "Image", + "opcode" : 4480, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Texture'" }, + { "kind" : "IdRef", "name" : "'Coordinates'" }, + { "kind" : "IdRef", "name" : "'Weights'" } + ], + "capabilities" : [ "TextureSampleWeightedQCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBoxFilterQCOM", + "class" : "Image", + "opcode" : 4481, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Texture'" }, + { "kind" : "IdRef", "name" : "'Coordinates'" }, + { "kind" : "IdRef", "name" : "'Box Size'" } + ], + "capabilities" : [ "TextureBoxFilterQCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchSSDQCOM", + "class" : "Image", + "opcode" : 4482, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatchQCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchSADQCOM", + "class" : "Image", + "opcode" : 4483, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatchQCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchWindowSSDQCOM", + "class" : "Image", + "opcode" : 4500, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatch2QCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchWindowSADQCOM", + "class" : "Image", + "opcode" : 4501, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatch2QCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchGatherSSDQCOM", + "class" : "Image", + "opcode" : 4502, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatch2QCOM" ], + "version" : "None" + }, + { + "opname" : "OpImageBlockMatchGatherSADQCOM", + "class" : "Image", + "opcode" : 4503, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Target Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Target Coordinates'" }, + { "kind" : "IdRef", "name" : "'Reference Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Reference Coordinates'" }, + { "kind" : "IdRef", "name" : "'Block Size'" } + ], + "capabilities" : [ "TextureBlockMatch2QCOM" ], + "version" : "None" + }, + { + "opname" : "OpGroupIAddNonUniformAMD", + "class" : "Group", + "opcode" : 5000, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupFAddNonUniformAMD", + "class" : "Group", + "opcode" : 5001, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupFMinNonUniformAMD", + "class" : "Group", + "opcode" : 5002, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupUMinNonUniformAMD", + "class" : "Group", + "opcode" : 5003, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupSMinNonUniformAMD", + "class" : "Group", + "opcode" : 5004, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupFMaxNonUniformAMD", + "class" : "Group", + "opcode" : 5005, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupUMaxNonUniformAMD", + "class" : "Group", + "opcode" : 5006, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpGroupSMaxNonUniformAMD", + "class" : "Group", + "opcode" : 5007, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "Groups" ], + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version" : "None" + }, + { + "opname" : "OpFragmentMaskFetchAMD", + "class" : "Reserved", + "opcode" : 5011, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "FragmentMaskAMD" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ], + "version" : "None" + }, + { + "opname" : "OpFragmentFetchAMD", + "class" : "Reserved", + "opcode" : 5012, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Fragment Index'" } + ], + "capabilities" : [ "FragmentMaskAMD" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ], + "version" : "None" + }, + { + "opname" : "OpReadClockKHR", + "class" : "Reserved", + "opcode" : 5056, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Scope'" } + ], + "capabilities" : [ "ShaderClockKHR" ], + "version" : "None" + }, + { + "opname" : "OpFinalizeNodePayloadsAMDX", + "class" : "Reserved", + "opcode" : 5075, + "operands" : [ + { "kind" : "IdRef", "name": "'Payload Array'" } + ], + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "opname" : "OpFinishWritingNodePayloadAMDX", + "class" : "Reserved", + "opcode" : 5078, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name": "'Payload'" } + ], + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "opname" : "OpInitializeNodePayloadsAMDX", + "class" : "Reserved", + "opcode" : 5090, + "operands" : [ + { "kind" : "IdRef", "name": "'Payload Array'" }, + { "kind" : "IdScope", "name": "'Visibility'" }, + { "kind" : "IdRef", "name": "'Payload Count'" }, + { "kind" : "IdRef", "name": "'Node Index'" } + ], + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "opname" : "OpGroupNonUniformQuadAllKHR", + "class" : "Non-Uniform", + "opcode" : 5110, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "QuadControlKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupNonUniformQuadAnyKHR", + "class" : "Non-Uniform", + "opcode" : 5111, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Predicate'" } + ], + "capabilities" : [ "QuadControlKHR" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordHitMotionNV", + "class" : "Reserved", + "opcode" : 5249, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'" }, + { "kind" : "IdRef", "name" : "'InstanceId'" }, + { "kind" : "IdRef", "name" : "'PrimitiveId'" }, + { "kind" : "IdRef", "name" : "'GeometryIndex'" }, + { "kind" : "IdRef", "name" : "'Hit Kind'" }, + { "kind" : "IdRef", "name" : "'SBT Record Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Record Stride'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'Current Time'" }, + { "kind" : "IdRef", "name" : "'HitObject Attributes'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV", "RayTracingMotionBlurNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordHitWithIndexMotionNV", + "class" : "Reserved", + "opcode" : 5250, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'" }, + { "kind" : "IdRef", "name" : "'InstanceId'" }, + { "kind" : "IdRef", "name" : "'PrimitiveId'" }, + { "kind" : "IdRef", "name" : "'GeometryIndex'" }, + { "kind" : "IdRef", "name" : "'Hit Kind'" }, + { "kind" : "IdRef", "name" : "'SBT Record Index'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'Current Time'" }, + { "kind" : "IdRef", "name" : "'HitObject Attributes'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV", "RayTracingMotionBlurNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordMissMotionNV", + "class" : "Reserved", + "opcode" : 5251, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'SBT Index'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'Current Time'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV", "RayTracingMotionBlurNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetWorldToObjectNV", + "class" : "Reserved", + "opcode" : 5252, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetObjectToWorldNV", + "class" : "Reserved", + "opcode" : 5253, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetObjectRayDirectionNV", + "class" : "Reserved", + "opcode" : 5254, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetObjectRayOriginNV", + "class" : "Reserved", + "opcode" : 5255, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectTraceRayMotionNV", + "class" : "Reserved", + "opcode" : 5256, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'"}, + { "kind" : "IdRef", "name" : "'RayFlags'"}, + { "kind" : "IdRef", "name" : "'Cullmask'"}, + { "kind" : "IdRef", "name" : "'SBT Record Offset'"}, + { "kind" : "IdRef", "name" : "'SBT Record Stride'"}, + { "kind" : "IdRef", "name" : "'Miss Index'"}, + { "kind" : "IdRef", "name" : "'Origin'"}, + { "kind" : "IdRef", "name" : "'TMin'"}, + { "kind" : "IdRef", "name" : "'Direction'"}, + { "kind" : "IdRef", "name" : "'TMax'"}, + { "kind" : "IdRef", "name" : "'Time'"}, + { "kind" : "IdRef", "name" : "'Payload'"} + ], + "capabilities" : [ "ShaderInvocationReorderNV", "RayTracingMotionBlurNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetShaderRecordBufferHandleNV", + "class" : "Reserved", + "opcode" : 5257, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetShaderBindingTableRecordIndexNV", + "class" : "Reserved", + "opcode" : 5258, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordEmptyNV", + "class" : "Reserved", + "opcode" : 5259, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectTraceRayNV", + "class" : "Reserved", + "opcode" : 5260, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'"}, + { "kind" : "IdRef", "name" : "'RayFlags'"}, + { "kind" : "IdRef", "name" : "'Cullmask'"}, + { "kind" : "IdRef", "name" : "'SBT Record Offset'"}, + { "kind" : "IdRef", "name" : "'SBT Record Stride'"}, + { "kind" : "IdRef", "name" : "'Miss Index'"}, + { "kind" : "IdRef", "name" : "'Origin'"}, + { "kind" : "IdRef", "name" : "'TMin'"}, + { "kind" : "IdRef", "name" : "'Direction'"}, + { "kind" : "IdRef", "name" : "'TMax'"}, + { "kind" : "IdRef", "name" : "'Payload'"} + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordHitNV", + "class" : "Reserved", + "opcode" : 5261, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'" }, + { "kind" : "IdRef", "name" : "'InstanceId'" }, + { "kind" : "IdRef", "name" : "'PrimitiveId'" }, + { "kind" : "IdRef", "name" : "'GeometryIndex'" }, + { "kind" : "IdRef", "name" : "'Hit Kind'" }, + { "kind" : "IdRef", "name" : "'SBT Record Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Record Stride'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'HitObject Attributes'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordHitWithIndexNV", + "class" : "Reserved", + "opcode" : 5262, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Acceleration Structure'" }, + { "kind" : "IdRef", "name" : "'InstanceId'" }, + { "kind" : "IdRef", "name" : "'PrimitiveId'" }, + { "kind" : "IdRef", "name" : "'GeometryIndex'" }, + { "kind" : "IdRef", "name" : "'Hit Kind'" }, + { "kind" : "IdRef", "name" : "'SBT Record Index'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" }, + { "kind" : "IdRef", "name" : "'HitObject Attributes'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectRecordMissNV", + "class" : "Reserved", + "opcode" : 5263, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'SBT Index'" }, + { "kind" : "IdRef", "name" : "'Origin'" }, + { "kind" : "IdRef", "name" : "'TMin'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'TMax'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectExecuteShaderNV", + "class" : "Reserved", + "opcode" : 5264, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetCurrentTimeNV", + "class" : "Reserved", + "opcode" : 5265, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetAttributesNV", + "class" : "Reserved", + "opcode" : 5266, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "name" : "'Hit Object Attribute'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetHitKindNV", + "class" : "Reserved", + "opcode" : 5267, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetPrimitiveIndexNV", + "class" : "Reserved", + "opcode" : 5268, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetGeometryIndexNV", + "class" : "Reserved", + "opcode" : 5269, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetInstanceIdNV", + "class" : "Reserved", + "opcode" : 5270, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetInstanceCustomIndexNV", + "class" : "Reserved", + "opcode" : 5271, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetWorldRayDirectionNV", + "class" : "Reserved", + "opcode" : 5272, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetWorldRayOriginNV", + "class" : "Reserved", + "opcode" : 5273, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetRayTMaxNV", + "class" : "Reserved", + "opcode" : 5274, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectGetRayTMinNV", + "class" : "Reserved", + "opcode" : 5275, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectIsEmptyNV", + "class" : "Reserved", + "opcode" : 5276, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectIsHitNV", + "class" : "Reserved", + "opcode" : 5277, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpHitObjectIsMissNV", + "class" : "Reserved", + "opcode" : 5278, + "operands" : [ + { "kind" : "IdResultType"}, + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Hit Object'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpReorderThreadWithHitObjectNV", + "class" : "Reserved", + "opcode" : 5279, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hit Object'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Hint'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Bits'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpReorderThreadWithHintNV", + "class" : "Reserved", + "opcode" : 5280, + "operands" : [ + { "kind" : "IdRef", "name" : "'Hint'" }, + { "kind" : "IdRef", "name" : "'Bits'" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpTypeHitObjectNV", + "class" : "Type-Declaration", + "opcode" : 5281, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "opname" : "OpImageSampleFootprintNV", + "class" : "Image", + "opcode" : 5283, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Sampled Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Granularity'" }, + { "kind" : "IdRef", "name" : "'Coarse'" }, + { "kind" : "ImageOperands", "quantifier" : "?" } + ], + "capabilities" : [ "ImageFootprintNV" ], + "extensions" : [ "SPV_NV_shader_image_footprint" ], + "version" : "None" + }, + { + "opname" : "OpEmitMeshTasksEXT", + "class" : "Reserved", + "opcode" : 5294, + "operands" : [ + { "kind" : "IdRef", "name" : "'Group Count X'" }, + { "kind" : "IdRef", "name" : "'Group Count Y'" }, + { "kind" : "IdRef", "name" : "'Group Count Z'" }, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Payload'" } + ], + "capabilities" : [ "MeshShadingEXT" ], + "version" : "None" + }, + { + "opname" : "OpSetMeshOutputsEXT", + "class" : "Reserved", + "opcode" : 5295, + "operands" : [ + { "kind" : "IdRef", "name" : "'Vertex Count'" }, + { "kind" : "IdRef", "name" : "'Primitive Count'" } + ], + "capabilities" : [ "MeshShadingEXT" ], + "version" : "None" + }, + { + "opname" : "OpGroupNonUniformPartitionNV", + "class" : "Non-Uniform", + "opcode" : 5296, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "GroupNonUniformPartitionedNV" ], + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + }, + { + "opname" : "OpWritePackedPrimitiveIndices4x8NV", + "class" : "Reserved", + "opcode" : 5299, + "operands" : [ + { "kind" : "IdRef", "name" : "'Index Offset'" }, + { "kind" : "IdRef", "name" : "'Packed Indices'" } + ], + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "opname" : "OpFetchMicroTriangleVertexPositionNV", + "class" : "Reserved", + "opcode" : 5300, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Instance Id'" }, + { "kind" : "IdRef", "name" : "'Geometry Index'" }, + { "kind" : "IdRef", "name" : "'Primitive Index'" }, + { "kind" : "IdRef", "name" : "'Barycentric'" } + ], + "capabilities" : [ "DisplacementMicromapNV" ], + "version" : "None" + }, + { + "opname" : "OpFetchMicroTriangleVertexBarycentricNV", + "class" : "Reserved", + "opcode" : 5301, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Instance Id'" }, + { "kind" : "IdRef", "name" : "'Geometry Index'" }, + { "kind" : "IdRef", "name" : "'Primitive Index'" }, + { "kind" : "IdRef", "name" : "'Barycentric'" } + ], + "capabilities" : [ "DisplacementMicromapNV" ], + "version" : "None" + }, + { + "opname" : "OpReportIntersectionNV", + "class" : "Reserved", + "opcode" : 5334, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Hit'" }, + { "kind" : "IdRef", "name" : "'HitKind'" } + ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpReportIntersectionKHR", + "class" : "Reserved", + "opcode" : 5334, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Hit'" }, + { "kind" : "IdRef", "name" : "'HitKind'" } + ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpIgnoreIntersectionNV", + "class" : "Reserved", + "opcode" : 5335, + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTerminateRayNV", + "class" : "Reserved", + "opcode" : 5336, + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTraceNV", + "class" : "Reserved", + "opcode" : 5337, + "operands" : [ + + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Ray Flags'" }, + { "kind" : "IdRef", "name" : "'Cull Mask'" }, + { "kind" : "IdRef", "name" : "'SBT Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Stride'" }, + { "kind" : "IdRef", "name" : "'Miss Index'" }, + { "kind" : "IdRef", "name" : "'Ray Origin'" }, + { "kind" : "IdRef", "name" : "'Ray Tmin'" }, + { "kind" : "IdRef", "name" : "'Ray Direction'" }, + { "kind" : "IdRef", "name" : "'Ray Tmax'" }, + { "kind" : "IdRef", "name" : "'PayloadId'" } + ], + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTraceMotionNV", + "class" : "Reserved", + "opcode" : 5338, + "operands" : [ + + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Ray Flags'" }, + { "kind" : "IdRef", "name" : "'Cull Mask'" }, + { "kind" : "IdRef", "name" : "'SBT Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Stride'" }, + { "kind" : "IdRef", "name" : "'Miss Index'" }, + { "kind" : "IdRef", "name" : "'Ray Origin'" }, + { "kind" : "IdRef", "name" : "'Ray Tmin'" }, + { "kind" : "IdRef", "name" : "'Ray Direction'" }, + { "kind" : "IdRef", "name" : "'Ray Tmax'" }, + { "kind" : "IdRef", "name" : "'Time'" }, + { "kind" : "IdRef", "name" : "'PayloadId'" } + ], + "capabilities" : [ "RayTracingMotionBlurNV" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, + { + "opname" : "OpTraceRayMotionNV", + "class" : "Reserved", + "opcode" : 5339, + "operands" : [ + + { "kind" : "IdRef", "name" : "'Accel'" }, + { "kind" : "IdRef", "name" : "'Ray Flags'" }, + { "kind" : "IdRef", "name" : "'Cull Mask'" }, + { "kind" : "IdRef", "name" : "'SBT Offset'" }, + { "kind" : "IdRef", "name" : "'SBT Stride'" }, + { "kind" : "IdRef", "name" : "'Miss Index'" }, + { "kind" : "IdRef", "name" : "'Ray Origin'" }, + { "kind" : "IdRef", "name" : "'Ray Tmin'" }, + { "kind" : "IdRef", "name" : "'Ray Direction'" }, + { "kind" : "IdRef", "name" : "'Ray Tmax'" }, + { "kind" : "IdRef", "name" : "'Time'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "RayTracingMotionBlurNV" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionTriangleVertexPositionsKHR", + "class" : "Reserved", + "opcode" : 5340, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryPositionFetchKHR" ], + "version" : "None" + }, + { + "opname" : "OpTypeAccelerationStructureNV", + "class" : "Type-Declaration", + "opcode" : 5341, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR", "RayQueryKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing", "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpTypeAccelerationStructureKHR", + "class" : "Type-Declaration", + "opcode" : 5341, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR", "RayQueryKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing", "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpExecuteCallableNV", + "class" : "Reserved", + "opcode" : 5344, + "operands" : [ + + { "kind" : "IdRef", "name" : "'SBT Index'" }, + { "kind" : "IdRef", "name" : "'Callable DataId'" } + ], + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "opname" : "OpTypeCooperativeMatrixNV", + "class" : "Type-Declaration", + "opcode" : 5358, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Component Type'" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdRef", "name" : "'Rows'" }, + { "kind" : "IdRef", "name" : "'Columns'" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixLoadNV", + "class" : "Reserved", + "opcode" : 5359, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Column Major'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixStoreNV", + "class" : "Reserved", + "opcode" : 5360, + "operands" : [ + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdRef", "name" : "'Object'" }, + { "kind" : "IdRef", "name" : "'Stride'" }, + { "kind" : "IdRef", "name" : "'Column Major'" }, + { "kind" : "MemoryAccess", "quantifier" : "?" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixMulAddNV", + "class" : "Reserved", + "opcode" : 5361, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "IdRef", "name" : "'C'" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpCooperativeMatrixLengthNV", + "class" : "Reserved", + "opcode" : 5362, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Type'" } + ], + "capabilities" : [ "CooperativeMatrixNV" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "opname" : "OpBeginInvocationInterlockEXT", + "class" : "Reserved", + "opcode" : 5364, + "capabilities" : [ "FragmentShaderSampleInterlockEXT", "FragmentShaderPixelInterlockEXT", "FragmentShaderShadingRateInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "opname" : "OpEndInvocationInterlockEXT", + "class" : "Reserved", + "opcode" : 5365, + "capabilities" : [ "FragmentShaderSampleInterlockEXT", "FragmentShaderPixelInterlockEXT", "FragmentShaderShadingRateInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "opname" : "OpDemoteToHelperInvocation", + "class" : "Control-Flow", + "opcode" : 5380, + "capabilities" : [ "DemoteToHelperInvocation" ], + "version" : "1.6" + }, + { + "opname" : "OpDemoteToHelperInvocationEXT", + "class" : "Control-Flow", + "opcode" : 5380, + "capabilities" : [ "DemoteToHelperInvocationEXT" ], + "version" : "1.6" + }, + { + "opname" : "OpIsHelperInvocationEXT", + "class" : "Reserved", + "opcode" : 5381, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "DemoteToHelperInvocationEXT" ], + "extensions" : [ "SPV_EXT_demote_to_helper_invocation" ], + "version" : "None" + }, + { + "opname" : "OpConvertUToImageNV", + "class" : "Reserved", + "opcode" : 5391, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertUToSamplerNV", + "class" : "Reserved", + "opcode" : 5392, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertImageToUNV", + "class" : "Reserved", + "opcode" : 5393, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertSamplerToUNV", + "class" : "Reserved", + "opcode" : 5394, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertUToSampledImageNV", + "class" : "Reserved", + "opcode" : 5395, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpConvertSampledImageToUNV", + "class" : "Reserved", + "opcode" : 5396, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpSamplerImageAddressingModeNV", + "class" : "Reserved", + "opcode" : 5397, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Bit Width'" } + ], + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupShuffleINTEL", + "class" : "Group", + "opcode" : 5571, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'InvocationId'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupShuffleDownINTEL", + "class" : "Group", + "opcode" : 5572, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Next'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupShuffleUpINTEL", + "class" : "Group", + "opcode" : 5573, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Previous'" }, + { "kind" : "IdRef", "name" : "'Current'" }, + { "kind" : "IdRef", "name" : "'Delta'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupShuffleXorINTEL", + "class" : "Group", + "opcode" : 5574, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Data'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "SubgroupShuffleINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupBlockReadINTEL", + "class" : "Group", + "opcode" : 5575, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupBlockWriteINTEL", + "class" : "Group", + "opcode" : 5576, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupBufferBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupImageBlockReadINTEL", + "class" : "Group", + "opcode" : 5577, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupImageBlockWriteINTEL", + "class" : "Group", + "opcode" : 5578, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupImageMediaBlockReadINTEL", + "class" : "Group", + "opcode" : 5580, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Width'" }, + { "kind" : "IdRef", "name" : "'Height'" } + ], + "capabilities" : [ "SubgroupImageMediaBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupImageMediaBlockWriteINTEL", + "class" : "Group", + "opcode" : 5581, + "operands" : [ + { "kind" : "IdRef", "name" : "'Image'" }, + { "kind" : "IdRef", "name" : "'Coordinate'" }, + { "kind" : "IdRef", "name" : "'Width'" }, + { "kind" : "IdRef", "name" : "'Height'" }, + { "kind" : "IdRef", "name" : "'Data'" } + ], + "capabilities" : [ "SubgroupImageMediaBlockIOINTEL" ], + "version" : "None" + }, + { + "opname" : "OpUCountLeadingZerosINTEL", + "class" : "Reserved", + "opcode" : 5585, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUCountTrailingZerosINTEL", + "class" : "Reserved", + "opcode" : 5586, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpAbsISubINTEL", + "class" : "Reserved", + "opcode" : 5587, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpAbsUSubINTEL", + "class" : "Reserved", + "opcode" : 5588, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpIAddSatINTEL", + "class" : "Reserved", + "opcode" : 5589, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUAddSatINTEL", + "class" : "Reserved", + "opcode" : 5590, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpIAverageINTEL", + "class" : "Reserved", + "opcode" : 5591, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUAverageINTEL", + "class" : "Reserved", + "opcode" : 5592, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpIAverageRoundedINTEL", + "class" : "Reserved", + "opcode" : 5593, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUAverageRoundedINTEL", + "class" : "Reserved", + "opcode" : 5594, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpISubSatINTEL", + "class" : "Reserved", + "opcode" : 5595, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUSubSatINTEL", + "class" : "Reserved", + "opcode" : 5596, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpIMul32x16INTEL", + "class" : "Reserved", + "opcode" : 5597, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpUMul32x16INTEL", + "class" : "Reserved", + "opcode" : 5598, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ], + "capabilities" : [ "IntegerFunctions2INTEL" ], + "version" : "None" + }, + { + "opname" : "OpConstantFunctionPointerINTEL", + "class" : "@exclude", + "opcode" : 5600, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Function'" } + ], + "capabilities" : [ "FunctionPointersINTEL" ], + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "opname" : "OpFunctionPointerCallINTEL", + "class" : "@exclude", + "opcode" : 5601, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1'" } + ], + "capabilities" : [ "FunctionPointersINTEL" ], + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "opname" : "OpAsmTargetINTEL", + "class" : "@exclude", + "opcode" : 5609, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "LiteralString", "name" : "'Asm target'" } + ], + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "opname" : "OpAsmINTEL", + "class" : "@exclude", + "opcode" : 5610, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Asm type'" }, + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "LiteralString", "name" : "'Asm instructions'" }, + { "kind" : "LiteralString", "name" : "'Constraints'" } + ], + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "opname" : "OpAsmCallINTEL", + "class" : "@exclude", + "opcode" : 5611, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Asm'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0'" } + ], + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "opname" : "OpAtomicFMinEXT", + "class" : "Atomic", + "opcode" : 5614, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "AtomicFloat16MinMaxEXT", "AtomicFloat32MinMaxEXT", "AtomicFloat64MinMaxEXT", "AtomicFloat16VectorNV" ], + "version" : "None" + }, + { + "opname" : "OpAtomicFMaxEXT", + "class" : "Atomic", + "opcode" : 5615, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "AtomicFloat16MinMaxEXT", "AtomicFloat32MinMaxEXT", "AtomicFloat64MinMaxEXT", "AtomicFloat16VectorNV" ], + "version" : "None" + }, + { + "opname" : "OpAssumeTrueKHR", + "class" : "Miscellaneous", + "opcode" : 5630, + "operands" : [ + { "kind" : "IdRef", "name" : "'Condition'" } + ], + "capabilities" : [ "ExpectAssumeKHR" ], + "extensions" : [ "SPV_KHR_expect_assume" ], + "version" : "None" + }, + { + "opname" : "OpExpectKHR", + "class" : "Miscellaneous", + "opcode" : 5631, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'ExpectedValue'" } + ], + "capabilities" : [ "ExpectAssumeKHR" ], + "extensions" : [ "SPV_KHR_expect_assume" ], + "version" : "None" + }, + { + "opname" : "OpDecorateString", + "class" : "Annotation", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.4" + }, + { + "opname" : "OpDecorateStringGOOGLE", + "class" : "Annotation", + "opcode" : 5632, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.4" + }, + { + "opname" : "OpMemberDecorateString", + "class" : "Annotation", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.4" + }, + { + "opname" : "OpMemberDecorateStringGOOGLE", + "class" : "Annotation", + "opcode" : 5633, + "operands" : [ + { "kind" : "IdRef", "name" : "'Struct Type'" }, + { "kind" : "LiteralInteger", "name" : "'Member'" }, + { "kind" : "Decoration" } + ], + "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "1.4" + }, + { + "opname" : "OpVmeImageINTEL", + "class" : "@exclude", + "opcode" : 5699, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" }, + { "kind" : "IdRef", "name" : "'Sampler'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeVmeImageINTEL", + "class" : "@exclude", + "opcode" : 5700, + "operands" : [ + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Type'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImePayloadINTEL", + "class" : "@exclude", + "opcode" : 5701, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcRefPayloadINTEL", + "class" : "@exclude", + "opcode" : 5702, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcSicPayloadINTEL", + "class" : "@exclude", + "opcode" : 5703, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcMcePayloadINTEL", + "class" : "@exclude", + "opcode" : 5704, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcMceResultINTEL", + "class" : "@exclude", + "opcode" : 5705, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeResultINTEL", + "class" : "@exclude", + "opcode" : 5706, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeResultSingleReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5707, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeResultDualReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5708, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeSingleReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5709, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcImeDualReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5710, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcRefResultINTEL", + "class" : "@exclude", + "opcode" : 5711, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeAvcSicResultINTEL", + "class" : "@exclude", + "opcode" : 5712, + "operands" : [ + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5713, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5714, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reference Base Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5715, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetInterShapePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5716, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Shape Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL", + "class" : "@exclude", + "opcode" : 5717, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL", + "class" : "@exclude", + "opcode" : 5718, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Direction Cost'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5719, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL", + "class" : "@exclude", + "opcode" : 5720, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL", + "class" : "@exclude", + "opcode" : 5721, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL", + "class" : "@exclude", + "opcode" : 5722, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL", + "class" : "@exclude", + "opcode" : 5723, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL", + "class" : "@exclude", + "opcode" : 5724, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Cost Center Delta'" }, + { "kind" : "IdRef", "name" : "'Packed Cost Table'" }, + { "kind" : "IdRef", "name" : "'Cost Precision'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5725, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Slice Type'" }, + { "kind" : "IdRef", "name" : "'Qp'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL", + "class" : "@exclude", + "opcode" : 5726, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5727, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationChromaINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetAcOnlyHaarINTEL", + "class" : "@exclude", + "opcode" : 5728, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL", + "class" : "@exclude", + "opcode" : 5729, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Source Field Polarity'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL", + "class" : "@exclude", + "opcode" : 5730, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Reference Field Polarity'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL", + "class" : "@exclude", + "opcode" : 5731, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Forward Reference Field Polarity'" }, + { "kind" : "IdRef", "name" : "'Backward Reference Field Polarity'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToImePayloadINTEL", + "class" : "@exclude", + "opcode" : 5732, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToImeResultINTEL", + "class" : "@exclude", + "opcode" : 5733, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToRefPayloadINTEL", + "class" : "@exclude", + "opcode" : 5734, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToRefResultINTEL", + "class" : "@exclude", + "opcode" : 5735, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToSicPayloadINTEL", + "class" : "@exclude", + "opcode" : 5736, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceConvertToSicResultINTEL", + "class" : "@exclude", + "opcode" : 5737, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetMotionVectorsINTEL", + "class" : "@exclude", + "opcode" : 5738, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterDistortionsINTEL", + "class" : "@exclude", + "opcode" : 5739, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetBestInterDistortionsINTEL", + "class" : "@exclude", + "opcode" : 5740, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterMajorShapeINTEL", + "class" : "@exclude", + "opcode" : 5741, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterMinorShapeINTEL", + "class" : "@exclude", + "opcode" : 5742, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterDirectionsINTEL", + "class" : "@exclude", + "opcode" : 5743, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterMotionVectorCountINTEL", + "class" : "@exclude", + "opcode" : 5744, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterReferenceIdsINTEL", + "class" : "@exclude", + "opcode" : 5745, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL", + "class" : "@exclude", + "opcode" : 5746, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Parameter Field Polarities'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeInitializeINTEL", + "class" : "@exclude", + "opcode" : 5747, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Coord'" }, + { "kind" : "IdRef", "name" : "'Partition Mask'" }, + { "kind" : "IdRef", "name" : "'SAD Adjustment'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetSingleReferenceINTEL", + "class" : "@exclude", + "opcode" : 5748, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ref Offset'" }, + { "kind" : "IdRef", "name" : "'Search Window Config'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetDualReferenceINTEL", + "class" : "@exclude", + "opcode" : 5749, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Offset'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Offset'" }, + { "kind" : "IdRef", "name" : "'id> Search Window Config'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeRefWindowSizeINTEL", + "class" : "@exclude", + "opcode" : 5750, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Search Window Config'" }, + { "kind" : "IdRef", "name" : "'Dual Ref'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeAdjustRefOffsetINTEL", + "class" : "@exclude", + "opcode" : 5751, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Ref Offset'" }, + { "kind" : "IdRef", "name" : "'Src Coord'" }, + { "kind" : "IdRef", "name" : "'Ref Window Size'" }, + { "kind" : "IdRef", "name" : "'Image Size'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeConvertToMcePayloadINTEL", + "class" : "@exclude", + "opcode" : 5752, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL", + "class" : "@exclude", + "opcode" : 5753, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Max Motion Vector Count'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL", + "class" : "@exclude", + "opcode" : 5754, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL", + "class" : "@exclude", + "opcode" : 5755, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Threshold'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeSetWeightedSadINTEL", + "class" : "@exclude", + "opcode" : 5756, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Sad Weights'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL", + "class" : "@exclude", + "opcode" : 5757, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL", + "class" : "@exclude", + "opcode" : 5758, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5759, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Streamin Components'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5760, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Streamin Components'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5761, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5762, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL", + "class" : "@exclude", + "opcode" : 5763, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Streamin Components'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL", + "class" : "@exclude", + "opcode" : 5764, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Streamin Components'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeConvertToMceResultINTEL", + "class" : "@exclude", + "opcode" : 5765, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5766, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetDualReferenceStreaminINTEL", + "class" : "@exclude", + "opcode" : 5767, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5768, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL", + "class" : "@exclude", + "opcode" : 5769, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL", + "class" : "@exclude", + "opcode" : 5770, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL", + "class" : "@exclude", + "opcode" : 5771, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL", + "class" : "@exclude", + "opcode" : 5772, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL", + "class" : "@exclude", + "opcode" : 5773, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL", + "class" : "@exclude", + "opcode" : 5774, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL", + "class" : "@exclude", + "opcode" : 5775, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" }, + { "kind" : "IdRef", "name" : "'Major Shape'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetBorderReachedINTEL", + "class" : "@exclude", + "opcode" : 5776, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Image Select'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL", + "class" : "@exclude", + "opcode" : 5777, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL", + "class" : "@exclude", + "opcode" : 5778, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL", + "class" : "@exclude", + "opcode" : 5779, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL", + "class" : "@exclude", + "opcode" : 5780, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcFmeInitializeINTEL", + "class" : "@exclude", + "opcode" : 5781, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Coord'" }, + { "kind" : "IdRef", "name" : "'Motion Vectors'" }, + { "kind" : "IdRef", "name" : "'Major Shapes'" }, + { "kind" : "IdRef", "name" : "'Minor Shapes'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'Pixel Resolution'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcBmeInitializeINTEL", + "class" : "@exclude", + "opcode" : 5782, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Coord'" }, + { "kind" : "IdRef", "name" : "'Motion Vectors'" }, + { "kind" : "IdRef", "name" : "'Major Shapes'" }, + { "kind" : "IdRef", "name" : "'Minor Shapes'" }, + { "kind" : "IdRef", "name" : "'Direction'" }, + { "kind" : "IdRef", "name" : "'Pixel Resolution'" }, + { "kind" : "IdRef", "name" : "'Bidirectional Weight'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefConvertToMcePayloadINTEL", + "class" : "@exclude", + "opcode" : 5783, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL", + "class" : "@exclude", + "opcode" : 5784, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefSetBilinearFilterEnableINTEL", + "class" : "@exclude", + "opcode" : 5785, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL", + "class" : "@exclude", + "opcode" : 5786, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL", + "class" : "@exclude", + "opcode" : 5787, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL", + "class" : "@exclude", + "opcode" : 5788, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL", + "class" : "@exclude", + "opcode" : 5789, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Field Polarities'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcRefConvertToMceResultINTEL", + "class" : "@exclude", + "opcode" : 5790, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicInitializeINTEL", + "class" : "@exclude", + "opcode" : 5791, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Coord'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConfigureSkcINTEL", + "class" : "@exclude", + "opcode" : 5792, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Skip Block Partition Type'" }, + { "kind" : "IdRef", "name" : "'Skip Motion Vector Mask'" }, + { "kind" : "IdRef", "name" : "'Motion Vectors'" }, + { "kind" : "IdRef", "name" : "'Bidirectional Weight'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConfigureIpeLumaINTEL", + "class" : "@exclude", + "opcode" : 5793, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Luma Intra Partition Mask'" }, + { "kind" : "IdRef", "name" : "'Intra Neighbour Availabilty'" }, + { "kind" : "IdRef", "name" : "'Left Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Left Corner Luma Pixel'" }, + { "kind" : "IdRef", "name" : "'Upper Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Right Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL", + "class" : "@exclude", + "opcode" : 5794, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Luma Intra Partition Mask'" }, + { "kind" : "IdRef", "name" : "'Intra Neighbour Availabilty'" }, + { "kind" : "IdRef", "name" : "'Left Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Left Corner Luma Pixel'" }, + { "kind" : "IdRef", "name" : "'Upper Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Right Edge Luma Pixels'" }, + { "kind" : "IdRef", "name" : "'Left Edge Chroma Pixels'" }, + { "kind" : "IdRef", "name" : "'Upper Left Corner Chroma Pixel'" }, + { "kind" : "IdRef", "name" : "'Upper Edge Chroma Pixels'" }, + { "kind" : "IdRef", "name" : "'Sad Adjustment'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationChromaINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetMotionVectorMaskINTEL", + "class" : "@exclude", + "opcode" : 5795, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Skip Block Partition Type'" }, + { "kind" : "IdRef", "name" : "'Direction'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConvertToMcePayloadINTEL", + "class" : "@exclude", + "opcode" : 5796, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL", + "class" : "@exclude", + "opcode" : 5797, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Shape Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL", + "class" : "@exclude", + "opcode" : 5798, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Luma Mode Penalty'" }, + { "kind" : "IdRef", "name" : "'Luma Packed Neighbor Modes'" }, + { "kind" : "IdRef", "name" : "'Luma Packed Non Dc Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL", + "class" : "@exclude", + "opcode" : 5799, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Chroma Mode Base Penalty'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationChromaINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetBilinearFilterEnableINTEL", + "class" : "@exclude", + "opcode" : 5800, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL", + "class" : "@exclude", + "opcode" : 5801, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packed Sad Coefficients'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL", + "class" : "@exclude", + "opcode" : 5802, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Block Based Skip Type'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateIpeINTEL", + "class" : "@exclude", + "opcode" : 5803, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL", + "class" : "@exclude", + "opcode" : 5804, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL", + "class" : "@exclude", + "opcode" : 5805, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Fwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Bwd Ref Image'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL", + "class" : "@exclude", + "opcode" : 5806, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL", + "class" : "@exclude", + "opcode" : 5807, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Src Image'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Ids'" }, + { "kind" : "IdRef", "name" : "'Packed Reference Field Polarities'" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicConvertToMceResultINTEL", + "class" : "@exclude", + "opcode" : 5808, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetIpeLumaShapeINTEL", + "class" : "@exclude", + "opcode" : 5809, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL", + "class" : "@exclude", + "opcode" : 5810, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL", + "class" : "@exclude", + "opcode" : 5811, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL", + "class" : "@exclude", + "opcode" : 5812, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetIpeChromaModeINTEL", + "class" : "@exclude", + "opcode" : 5813, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationChromaINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", + "class" : "@exclude", + "opcode" : 5814, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", + "class" : "@exclude", + "opcode" : 5815, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL", "SubgroupAvcMotionEstimationIntraINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSubgroupAvcSicGetInterRawSadsINTEL", + "class" : "@exclude", + "opcode" : 5816, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Payload'" } + ], + "capabilities" : [ "SubgroupAvcMotionEstimationINTEL" ], + "version" : "None" + }, + { + "opname" : "OpVariableLengthArrayINTEL", + "class" : "@exclude", + "opcode" : 5818, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Lenght'" } + ], + "capabilities" : [ "VariableLengthArrayINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSaveMemoryINTEL", + "class" : "@exclude", + "opcode" : 5819, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" } + ], + "capabilities" : [ "VariableLengthArrayINTEL" ], + "version" : "None" + }, + { + "opname" : "OpRestoreMemoryINTEL", + "class" : "@exclude", + "opcode" : 5820, + "operands" : [ + { "kind" : "IdRef", "name" : "'Ptr'" } + ], + "capabilities" : [ "VariableLengthArrayINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSinCosPiINTEL", + "class" : "@exclude", + "opcode" : 5840, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'FromSign'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCastINTEL", + "class" : "@exclude", + "opcode" : 5841, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCastFromIntINTEL", + "class" : "@exclude", + "opcode" : 5842, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'FromSign'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCastToIntINTEL", + "class" : "@exclude", + "opcode" : 5843, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatAddINTEL", + "class" : "@exclude", + "opcode" : 5846, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSubINTEL", + "class" : "@exclude", + "opcode" : 5847, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatMulINTEL", + "class" : "@exclude", + "opcode" : 5848, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatDivINTEL", + "class" : "@exclude", + "opcode" : 5849, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatGTINTEL", + "class" : "@exclude", + "opcode" : 5850, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatGEINTEL", + "class" : "@exclude", + "opcode" : 5851, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLTINTEL", + "class" : "@exclude", + "opcode" : 5852, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLEINTEL", + "class" : "@exclude", + "opcode" : 5853, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatEQINTEL", + "class" : "@exclude", + "opcode" : 5854, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatRecipINTEL", + "class" : "@exclude", + "opcode" : 5855, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatRSqrtINTEL", + "class" : "@exclude", + "opcode" : 5856, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCbrtINTEL", + "class" : "@exclude", + "opcode" : 5857, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatHypotINTEL", + "class" : "@exclude", + "opcode" : 5858, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSqrtINTEL", + "class" : "@exclude", + "opcode" : 5859, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLogINTEL", + "class" : "@exclude", + "opcode" : 5860, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLog2INTEL", + "class" : "@exclude", + "opcode" : 5861, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLog10INTEL", + "class" : "@exclude", + "opcode" : 5862, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatLog1pINTEL", + "class" : "@exclude", + "opcode" : 5863, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatExpINTEL", + "class" : "@exclude", + "opcode" : 5864, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatExp2INTEL", + "class" : "@exclude", + "opcode" : 5865, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatExp10INTEL", + "class" : "@exclude", + "opcode" : 5866, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatExpm1INTEL", + "class" : "@exclude", + "opcode" : 5867, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSinINTEL", + "class" : "@exclude", + "opcode" : 5868, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCosINTEL", + "class" : "@exclude", + "opcode" : 5869, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSinCosINTEL", + "class" : "@exclude", + "opcode" : 5870, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatSinPiINTEL", + "class" : "@exclude", + "opcode" : 5871, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatCosPiINTEL", + "class" : "@exclude", + "opcode" : 5872, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatASinINTEL", + "class" : "@exclude", + "opcode" : 5873, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatASinPiINTEL", + "class" : "@exclude", + "opcode" : 5874, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatACosINTEL", + "class" : "@exclude", + "opcode" : 5875, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatACosPiINTEL", + "class" : "@exclude", + "opcode" : 5876, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatATanINTEL", + "class" : "@exclude", + "opcode" : 5877, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatATanPiINTEL", + "class" : "@exclude", + "opcode" : 5878, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatATan2INTEL", + "class" : "@exclude", + "opcode" : 5879, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatPowINTEL", + "class" : "@exclude", + "opcode" : 5880, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatPowRINTEL", + "class" : "@exclude", + "opcode" : 5881, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'M2'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpArbitraryFloatPowNINTEL", + "class" : "@exclude", + "opcode" : 5882, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'A'" }, + { "kind" : "LiteralInteger", "name" : "'M1'" }, + { "kind" : "IdRef", "name" : "'B'" }, + { "kind" : "LiteralInteger", "name" : "'Mout'" }, + { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingMode'" }, + { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" } + ], + "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpLoopControlINTEL", + "class" : "Reserved", + "opcode" : 5887, + "operands" : [ + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Loop Control Parameters'" } + ], + "capabilities" : [ "UnstructuredLoopControlsINTEL" ], + "extensions" : [ "SPV_INTEL_unstructured_loop_controls" ], + "version" : "None" + }, + { + "opname" : "OpAliasDomainDeclINTEL", + "class" : "@exclude", + "opcode" : 5911, + "operands" : [ + { "kind" : "IdResult"}, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Name'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "opname" : "OpAliasScopeDeclINTEL", + "class" : "@exclude", + "opcode" : 5912, + "operands" : [ + { "kind" : "IdResult"}, + { "kind" : "IdRef", "name" : "'Alias Domain'"}, + { "kind" : "IdRef", "quantifier" : "?", "name" : "'Name'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "opname" : "OpAliasScopeListDeclINTEL", + "class" : "@exclude", + "opcode" : 5913, + "operands" : [ + { "kind" : "IdResult"}, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'AliasScope1, AliasScope2, ...'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "opname" : "OpFixedSqrtINTEL", + "class" : "@exclude", + "opcode" : 5923, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedRecipINTEL", + "class" : "@exclude", + "opcode" : 5924, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedRsqrtINTEL", + "class" : "@exclude", + "opcode" : 5925, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedSinINTEL", + "class" : "@exclude", + "opcode" : 5926, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedCosINTEL", + "class" : "@exclude", + "opcode" : 5927, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedSinCosINTEL", + "class" : "@exclude", + "opcode" : 5928, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedSinPiINTEL", + "class" : "@exclude", + "opcode" : 5929, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedCosPiINTEL", + "class" : "@exclude", + "opcode" : 5930, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedSinCosPiINTEL", + "class" : "@exclude", + "opcode" : 5931, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedLogINTEL", + "class" : "@exclude", + "opcode" : 5932, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpFixedExpINTEL", + "class" : "@exclude", + "opcode" : 5933, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Input Type'" }, + { "kind" : "IdRef", "name" : "'Input'" }, + { "kind" : "LiteralInteger", "name" : "'S'" }, + { "kind" : "LiteralInteger", "name" : "'I'" }, + { "kind" : "LiteralInteger", "name" : "'rI'" }, + { "kind" : "LiteralInteger", "name" : "'Q'" }, + { "kind" : "LiteralInteger", "name" : "'O'" } + ], + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL" ], + "version" : "None" + }, + { + "opname" : "OpPtrCastToCrossWorkgroupINTEL", + "class" : "@exclude", + "opcode" : 5934, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "USMStorageClassesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpCrossWorkgroupCastToPtrINTEL", + "class" : "@exclude", + "opcode" : 5938, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" } + ], + "capabilities" : [ "USMStorageClassesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpReadPipeBlockingINTEL", + "class" : "Pipe", + "opcode" : 5946, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "BlockingPipesINTEL" ], + "extensions" : [ "SPV_INTEL_blocking_pipes" ], + "version" : "None" + }, + { + "opname" : "OpWritePipeBlockingINTEL", + "class" : "Pipe", + "opcode" : 5947, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Packet Size'" }, + { "kind" : "IdRef", "name" : "'Packet Alignment'" } + ], + "capabilities" : [ "BlockingPipesINTEL" ], + "extensions" : [ "SPV_INTEL_blocking_pipes" ], + "version" : "None" + }, + { + "opname" : "OpFPGARegINTEL", + "class" : "Reserved", + "opcode" : 5949, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Result'" }, + { "kind" : "IdRef", "name" : "'Input'" } + ], + "capabilities" : [ "FPGARegINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_reg" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetRayTMinKHR", + "class" : "Reserved", + "opcode" : 6016, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetRayFlagsKHR", + "class" : "Reserved", + "opcode" : 6017, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionTKHR", + "class" : "Reserved", + "opcode" : 6018, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionInstanceCustomIndexKHR", + "class" : "Reserved", + "opcode" : 6019, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionInstanceIdKHR", + "class" : "Reserved", + "opcode" : 6020, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR", + "class" : "Reserved", + "opcode" : 6021, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionGeometryIndexKHR", + "class" : "Reserved", + "opcode" : 6022, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionPrimitiveIndexKHR", + "class" : "Reserved", + "opcode" : 6023, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionBarycentricsKHR", + "class" : "Reserved", + "opcode" : 6024, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionFrontFaceKHR", + "class" : "Reserved", + "opcode" : 6025, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR", + "class" : "Reserved", + "opcode" : 6026, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionObjectRayDirectionKHR", + "class" : "Reserved", + "opcode" : 6027, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionObjectRayOriginKHR", + "class" : "Reserved", + "opcode" : 6028, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetWorldRayDirectionKHR", + "class" : "Reserved", + "opcode" : 6029, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetWorldRayOriginKHR", + "class" : "Reserved", + "opcode" : 6030, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionObjectToWorldKHR", + "class" : "Reserved", + "opcode" : 6031, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpRayQueryGetIntersectionWorldToObjectKHR", + "class" : "Reserved", + "opcode" : 6032, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { + "kind" : "IdRef", + "name" : "'RayQuery'" + }, + { + "kind" : "IdRef", + "name" : "'Intersection'" + } + ], + "capabilities" : [ "RayQueryKHR" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "opname" : "OpAtomicFAddEXT", + "class" : "Atomic", + "opcode" : 6035, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Pointer'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "AtomicFloat16AddEXT", "AtomicFloat32AddEXT", "AtomicFloat64AddEXT", "AtomicFloat16VectorNV" ], + "extensions" : [ "SPV_EXT_shader_atomic_float_add" ], + "version" : "None" + }, + { + "opname" : "OpTypeBufferSurfaceINTEL", + "class" : "Type-Declaration", + "opcode" : 6086, + "operands" : [ + { "kind" : "IdResult" }, + { + "kind" : "AccessQualifier", + "name" : "'AccessQualifier'" + } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "opname" : "OpTypeStructContinuedINTEL", + "class" : "Type-Declaration", + "opcode" : 6090, + "operands" : [ + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." } + ], + "capabilities" : [ "LongCompositesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpConstantCompositeContinuedINTEL", + "class" : "Constant-Creation", + "opcode" : 6091, + "operands" : [ + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "capabilities" : [ "LongCompositesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpSpecConstantCompositeContinuedINTEL", + "class" : "Constant-Creation", + "opcode" : 6092, + "operands" : [ + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "capabilities" : [ "LongCompositesINTEL" ], + "version" : "None" + }, + { + "opname" : "OpCompositeConstructContinuedINTEL", + "class" : "Composite", + "opcode" : 6096, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" } + ], + "capabilities" : [ "LongCompositesINTEL" ], + "version": "None" + }, + { + "opname" : "OpConvertFToBF16INTEL", + "class" : "Conversion", + "opcode" : 6116, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Float Value'" } + ], + "capabilities" : [ "BFloat16ConversionINTEL" ], + "version" : "None" + }, + { + "opname" : "OpConvertBF16ToFINTEL", + "class" : "Conversion", + "opcode" : 6117, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'BFloat16 Value'" } + ], + "capabilities" : [ "BFloat16ConversionINTEL" ], + "version" : "None" + }, + { + "opname" : "OpControlBarrierArriveINTEL", + "class" : "Barrier", + "opcode" : 6142, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "SplitBarrierINTEL" ], + "version" : "None" + }, + { + "opname" : "OpControlBarrierWaitINTEL", + "class" : "Barrier", + "opcode" : 6143, + "operands" : [ + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "IdScope", "name" : "'Memory'" }, + { "kind" : "IdMemorySemantics", "name" : "'Semantics'" } + ], + "capabilities" : [ "SplitBarrierINTEL" ], + "version" : "None" + }, + { + "opname" : "OpGroupIMulKHR", + "class" : "Group", + "opcode" : 6401, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupFMulKHR", + "class" : "Group", + "opcode" : 6402, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupBitwiseAndKHR", + "class" : "Group", + "opcode" : 6403, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupBitwiseOrKHR", + "class" : "Group", + "opcode" : 6404, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupBitwiseXorKHR", + "class" : "Group", + "opcode" : 6405, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupLogicalAndKHR", + "class" : "Group", + "opcode" : 6406, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupLogicalOrKHR", + "class" : "Group", + "opcode" : 6407, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpGroupLogicalXorKHR", + "class" : "Group", + "opcode" : 6408, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdScope", "name" : "'Execution'" }, + { "kind" : "GroupOperation", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'X'" } + ], + "capabilities" : [ "GroupUniformArithmeticKHR" ], + "version" : "None" + }, + { + "opname" : "OpMaskedGatherINTEL", + "class" : "Memory", + "opcode" : 6428, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'PtrVector'" }, + { "kind" : "LiteralInteger", "name" : "'Alignment'" }, + { "kind" : "IdRef", "name" : "'Mask'" }, + { "kind" : "IdRef", "name" : "'FillEmpty'" } + ], + "capabilities" : [ "MaskedGatherScatterINTEL" ], + "version" : "None" + }, + { + "opname" : "OpMaskedScatterINTEL", + "class" : "Memory", + "opcode" : 6429, + "operands" : [ + { "kind" : "IdRef", "name" : "'InputVector'" }, + { "kind" : "IdRef", "name" : "'PtrVector'" }, + { "kind" : "LiteralInteger", "name" : "'Alignment'" }, + { "kind" : "IdRef", "name" : "'Mask'" } + ], + "capabilities" : [ "MaskedGatherScatterINTEL" ], + "version" : "None" + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "ImageOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "Bias", + "value" : "0x0001", + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "Lod", + "value" : "0x0002", + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "Grad", + "value" : "0x0004", + "parameters" : [ + { "kind" : "IdRef" }, + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "ConstOffset", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "Offset", + "value" : "0x0010", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "ConstOffsets", + "value" : "0x0020", + "capabilities" : [ "ImageGatherExtended" ], + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "Sample", + "value" : "0x0040", + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "MinLod", + "value" : "0x0080", + "capabilities" : [ "MinLod" ], + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + }, + { + "enumerant" : "MakeTexelAvailable", + "value" : "0x0100", + "capabilities" : [ "VulkanMemoryModel" ], + "parameters" : [ + { "kind" : "IdScope" } + ], + "version" : "1.5" + }, + { + "enumerant" : "MakeTexelAvailableKHR", + "value" : "0x0100", + "capabilities" : [ "VulkanMemoryModel" ], + "parameters" : [ + { "kind" : "IdScope" } + ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeTexelVisible", + "value" : "0x0200", + "capabilities" : [ "VulkanMemoryModel" ], + "parameters" : [ + { "kind" : "IdScope" } + ], + "version" : "1.5" + }, + { + "enumerant" : "MakeTexelVisibleKHR", + "value" : "0x0200", + "capabilities" : [ "VulkanMemoryModel" ], + "parameters" : [ + { "kind" : "IdScope" } + ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "NonPrivateTexel", + "value" : "0x0400", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "NonPrivateTexelKHR", + "value" : "0x0400", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "VolatileTexel", + "value" : "0x0800", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "VolatileTexelKHR", + "value" : "0x0800", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "SignExtend", + "value" : "0x1000", + "version" : "1.4" + }, + { + "enumerant" : "ZeroExtend", + "value" : "0x2000", + "version" : "1.4" + }, + { + "enumerant" : "Nontemporal", + "value" : "0x4000", + "version" : "1.6" + }, + { + "enumerant" : "Offsets", + "value" : "0x10000", + "parameters" : [ + { "kind" : "IdRef" } + ], + "version": "1.0" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FPFastMathMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "NotNaN", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "NotInf", + "value" : "0x0002", + "version" : "1.0" + }, + { + "enumerant" : "NSZ", + "value" : "0x0004", + "version" : "1.0" + }, + { + "enumerant" : "AllowRecip", + "value" : "0x0008", + "version" : "1.0" + }, + { + "enumerant" : "Fast", + "value" : "0x0010", + "version" : "1.0" + }, + { + "enumerant" : "AllowContract", + "value" : "0x10000", + "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AllowContractFastINTEL", + "value" : "0x10000", + "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AllowReassoc", + "value" : "0x20000", + "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AllowReassocINTEL", + "value" : "0x20000", + "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AllowTransform", + "value" : "0x40000", + "capabilities" : [ "FloatControls2" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "SelectionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Flatten", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "DontFlatten", + "value" : "0x0002", + "version" : "1.0" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "LoopControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Unroll", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "DontUnroll", + "value" : "0x0002", + "version" : "1.0" + }, + { + "enumerant" : "DependencyInfinite", + "value" : "0x0004", + "version" : "1.1" + }, + { + "enumerant" : "DependencyLength", + "value" : "0x0008", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.1" + }, + { + "enumerant" : "MinIterations", + "value" : "0x0010", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "MaxIterations", + "value" : "0x0020", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "IterationMultiple", + "value" : "0x0040", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "PeelCount", + "value" : "0x0080", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "PartialCount", + "value" : "0x0100", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.4" + }, + { + "enumerant" : "InitiationIntervalINTEL", + "value" : "0x10000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxConcurrencyINTEL", + "value" : "0x20000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "DependencyArrayINTEL", + "value" : "0x40000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "PipelineEnableINTEL", + "value" : "0x80000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "LoopCoalesceINTEL", + "value" : "0x100000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxInterleavingINTEL", + "value" : "0x200000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "SpeculatedIterationsINTEL", + "value" : "0x400000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "NoFusionINTEL", + "value" : "0x800000", + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "LoopCountINTEL", + "value" : "0x1000000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxReinvocationDelayINTEL", + "value" : "0x2000000", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "capabilities" : [ "FPGALoopControlsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FunctionControl", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Inline", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "DontInline", + "value" : "0x0002", + "version" : "1.0" + }, + { + "enumerant" : "Pure", + "value" : "0x0004", + "version" : "1.0" + }, + { + "enumerant" : "Const", + "value" : "0x0008", + "version" : "1.0" + }, + { + "enumerant" : "OptNoneINTEL", + "value" : "0x10000", + "capabilities" : [ "OptNoneINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemorySemantics", + "enumerants" : [ + { + "enumerant" : "Relaxed", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Acquire", + "value" : "0x0002", + "version" : "1.0" + }, + { + "enumerant" : "Release", + "value" : "0x0004", + "version" : "1.0" + }, + { + "enumerant" : "AcquireRelease", + "value" : "0x0008", + "version" : "1.0" + }, + { + "enumerant" : "SequentiallyConsistent", + "value" : "0x0010", + "version" : "1.0" + }, + { + "enumerant" : "UniformMemory", + "value" : "0x0040", + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupMemory", + "value" : "0x0080", + "version" : "1.0" + }, + { + "enumerant" : "WorkgroupMemory", + "value" : "0x0100", + "version" : "1.0" + }, + { + "enumerant" : "CrossWorkgroupMemory", + "value" : "0x0200", + "version" : "1.0" + }, + { + "enumerant" : "AtomicCounterMemory", + "value" : "0x0400", + "capabilities" : [ "AtomicStorage" ], + "version": "1.0" + }, + { + "enumerant" : "ImageMemory", + "value" : "0x0800", + "version" : "1.0" + }, + { + "enumerant" : "OutputMemory", + "value" : "0x1000", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "OutputMemoryKHR", + "value" : "0x1000", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeAvailable", + "value" : "0x2000", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeAvailableKHR", + "value" : "0x2000", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeVisible", + "value" : "0x4000", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "MakeVisibleKHR", + "value" : "0x4000", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "Volatile", + "value" : "0x8000", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "MemoryAccess", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "Volatile", + "value" : "0x0001", + "version" : "1.0" + }, + { + "enumerant" : "Aligned", + "value" : "0x0002", + "parameters" : [ + { "kind" : "LiteralInteger" } + ], + "version" : "1.0" + }, + { + "enumerant" : "Nontemporal", + "value" : "0x0004", + "version" : "1.0" + }, + { + "enumerant" : "MakePointerAvailable", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdScope" } + ], + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "MakePointerAvailableKHR", + "value" : "0x0008", + "parameters" : [ + { "kind" : "IdScope" } + ], + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "MakePointerVisible", + "value" : "0x0010", + "parameters" : [ + { "kind" : "IdScope" } + ], + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "MakePointerVisibleKHR", + "value" : "0x0010", + "parameters" : [ + { "kind" : "IdScope" } + ], + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "NonPrivatePointer", + "value" : "0x0020", + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "NonPrivatePointerKHR", + "value" : "0x0020", + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "AliasScopeINTELMask", + "value" : "0x10000", + "parameters" : [ + { "kind" : "IdRef" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "enumerant" : "NoAliasINTELMask", + "parameters" : [ + { "kind" : "IdRef" } + ], + "value" : "0x20000", + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "KernelProfilingInfo", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000", + "version" : "1.0" + }, + { + "enumerant" : "CmdExecTime", + "value" : "0x0001", + "capabilities" : [ "Kernel" ], + "version": "1.0" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "RayFlags", + "enumerants" : [ + { + "enumerant" : "NoneKHR", + "value" : "0x0000", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "OpaqueKHR", + "value" : "0x0001", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "NoOpaqueKHR", + "value" : "0x0002", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "TerminateOnFirstHitKHR", + "value" : "0x0004", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "SkipClosestHitShaderKHR", + "value" : "0x0008", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CullBackFacingTrianglesKHR", + "value" : "0x0010", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CullFrontFacingTrianglesKHR", + "value" : "0x0020", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CullOpaqueKHR", + "value" : "0x0040", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CullNoOpaqueKHR", + "value" : "0x0080", + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "SkipTrianglesKHR", + "value" : "0x0100", + "capabilities" : [ "RayTraversalPrimitiveCullingKHR" ], + "version" : "None" + }, + { + "enumerant" : "SkipAABBsKHR", + "value" : "0x0200", + "capabilities" : [ "RayTraversalPrimitiveCullingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ForceOpacityMicromap2StateEXT", + "value" : "0x0400", + "capabilities" : [ "RayTracingOpacityMicromapEXT" ], + "version" : "None" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "FragmentShadingRate", + "enumerants" : [ + { + "enumerant" : "Vertical2Pixels", + "value" : "0x0001", + "capabilities" : [ "FragmentShadingRateKHR" ], + "version" : "None" + }, + { + "enumerant" : "Vertical4Pixels", + "value" : "0x0002", + "capabilities" : [ "FragmentShadingRateKHR" ], + "version" : "None" + }, + { + "enumerant" : "Horizontal2Pixels", + "value" : "0x0004", + "capabilities" : [ "FragmentShadingRateKHR" ], + "version" : "None" + }, + { + "enumerant" : "Horizontal4Pixels", + "value" : "0x0008", + "capabilities" : [ "FragmentShadingRateKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SourceLanguage", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "ESSL", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "GLSL", + "value" : 2, + "version" : "1.0" + }, + { + "enumerant" : "OpenCL_C", + "value" : 3, + "version" : "1.0" + }, + { + "enumerant" : "OpenCL_CPP", + "value" : 4, + "version" : "1.0" + }, + { + "enumerant" : "HLSL", + "value" : 5, + "version" : "1.0" + }, + { + "enumerant" : "CPP_for_OpenCL", + "value" : 6, + "version" : "1.0" + }, + { + "enumerant" : "SYCL", + "value" : 7, + "version" : "1.0" + }, + { + "enumerant" : "HERO_C", + "value" : 8, + "version" : "1.0" + }, + { + "enumerant" : "NZSL", + "value" : 9, + "version" : "1.0" + }, + { + "enumerant" : "WGSL", + "value" : 10, + "version" : "1.0" + }, + { + "enumerant" : "Slang", + "value" : 11, + "version" : "1.0" + }, + { + "enumerant" : "Zig", + "value" : 12, + "version" : "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionModel", + "enumerants" : [ + { + "enumerant" : "Vertex", + "value" : 0, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "TessellationControl", + "value" : 1, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "TessellationEvaluation", + "value" : 2, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Geometry", + "value" : 3, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "Fragment", + "value" : 4, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GLCompute", + "value" : 5, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Kernel", + "value" : 6, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "TaskNV", + "value" : 5267, + "capabilities" : [ "MeshShadingNV" ], + "version" : "None" + }, + { + "enumerant" : "MeshNV", + "value" : 5268, + "capabilities" : [ "MeshShadingNV" ], + "version" : "None" + }, + { + "enumerant" : "RayGenerationNV", + "value" : 5313, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayGenerationKHR", + "value" : 5313, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IntersectionNV", + "value" : 5314, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IntersectionKHR", + "value" : 5314, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "AnyHitNV", + "value" : 5315, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "AnyHitKHR", + "value" : 5315, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ClosestHitNV", + "value" : 5316, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ClosestHitKHR", + "value" : 5316, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "MissNV", + "value" : 5317, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "MissKHR", + "value" : 5317, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableNV", + "value" : 5318, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableKHR", + "value" : 5318, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "TaskEXT", + "value" : 5364, + "capabilities" : [ "MeshShadingEXT" ], + "version" : "None" + }, + { + "enumerant" : "MeshEXT", + "value" : 5365, + "capabilities" : [ "MeshShadingEXT" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AddressingModel", + "enumerants" : [ + { + "enumerant" : "Logical", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Physical32", + "value" : 1, + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "enumerant" : "Physical64", + "value" : 2, + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "enumerant" : "PhysicalStorageBuffer64", + "value" : 5348, + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "version" : "1.5" + }, + { + "enumerant" : "PhysicalStorageBuffer64EXT", + "value" : 5348, + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "version" : "1.5" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "MemoryModel", + "enumerants" : [ + { + "enumerant" : "Simple", + "value" : 0, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GLSL450", + "value" : 1, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "OpenCL", + "value" : 2, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Vulkan", + "value" : 3, + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "VulkanKHR", + "value" : 3, + "capabilities" : [ "VulkanMemoryModel" ], + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ExecutionMode", + "enumerants" : [ + { + "enumerant" : "Invocations", + "value" : 0, + "capabilities" : [ "Geometry" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of <>'" } + ], + "version": "1.0" + }, + { + "enumerant" : "SpacingEqual", + "value" : 1, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "SpacingFractionalEven", + "value" : 2, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "SpacingFractionalOdd", + "value" : 3, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "VertexOrderCw", + "value" : 4, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "VertexOrderCcw", + "value" : 5, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "PixelCenterInteger", + "value" : 6, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "OriginUpperLeft", + "value" : 7, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "OriginLowerLeft", + "value" : 8, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "EarlyFragmentTests", + "value" : 9, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "PointMode", + "value" : 10, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Xfb", + "value" : 11, + "capabilities" : [ "TransformFeedback" ], + "version": "1.0" + }, + { + "enumerant" : "DepthReplacing", + "value" : 12, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "DepthGreater", + "value" : 14, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "DepthLess", + "value" : 15, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "DepthUnchanged", + "value" : 16, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "LocalSize", + "value" : 17, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ], + "version": "1.0" + }, + { + "enumerant" : "LocalSizeHint", + "value" : 18, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'x size'" }, + { "kind" : "LiteralInteger", "name" : "'y size'" }, + { "kind" : "LiteralInteger", "name" : "'z size'" } + ], + "version": "1.0" + }, + { + "enumerant" : "InputPoints", + "value" : 19, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "InputLines", + "value" : 20, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "InputLinesAdjacency", + "value" : 21, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "Triangles", + "value" : 22, + "capabilities" : [ "Geometry", "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "InputTrianglesAdjacency", + "value" : 23, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "Quads", + "value" : 24, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Isolines", + "value" : 25, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "OutputVertices", + "value" : 26, + "capabilities" : [ "Geometry", "Tessellation", "MeshShadingNV", "MeshShadingEXT" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vertex count'" } + ], + "version": "1.0" + }, + { + "enumerant" : "OutputPoints", + "value" : 27, + "capabilities" : [ "Geometry", "MeshShadingNV", "MeshShadingEXT" ], + "version": "1.0" + }, + { + "enumerant" : "OutputLineStrip", + "value" : 28, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "OutputTriangleStrip", + "value" : 29, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "VecTypeHint", + "value" : 30, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Vector type'" } + ], + "version": "1.0" + }, + { + "enumerant" : "ContractionOff", + "value" : 31, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Initializer", + "value" : 33, + "capabilities" : [ "Kernel" ], + "version" : "1.1" + }, + { + "enumerant" : "Finalizer", + "value" : 34, + "capabilities" : [ "Kernel" ], + "version" : "1.1" + }, + { + "enumerant" : "SubgroupSize", + "value" : 35, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroup Size'" } + ], + "version" : "1.1" + }, + { + "enumerant" : "SubgroupsPerWorkgroup", + "value" : 36, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Subgroups Per Workgroup'" } + ], + "version" : "1.1" + }, + { + "enumerant" : "SubgroupsPerWorkgroupId", + "value" : 37, + "capabilities" : [ "SubgroupDispatch" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Subgroups Per Workgroup'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "LocalSizeId", + "value" : 38, + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size'" }, + { "kind" : "IdRef", "name" : "'y size'" }, + { "kind" : "IdRef", "name" : "'z size'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "LocalSizeHintId", + "value" : 39, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size hint'" }, + { "kind" : "IdRef", "name" : "'y size hint'" }, + { "kind" : "IdRef", "name" : "'z size hint'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "NonCoherentColorAttachmentReadEXT", + "value" : 4169, + "capabilities" : [ "TileImageColorReadAccessEXT" ], + "version" : "None" + }, + { + "enumerant" : "NonCoherentDepthAttachmentReadEXT", + "value" : 4170, + "capabilities" : [ "TileImageDepthReadAccessEXT" ], + "version" : "None" + }, + { + "enumerant" : "NonCoherentStencilAttachmentReadEXT", + "value" : 4171, + "capabilities" : [ "TileImageStencilReadAccessEXT" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupUniformControlFlowKHR", + "value" : 4421, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_subgroup_uniform_control_flow" ], + "version" : "None" + }, + { + "enumerant" : "PostDepthCoverage", + "value" : 4446, + "capabilities" : [ "SampleMaskPostDepthCoverage" ], + "extensions" : [ "SPV_KHR_post_depth_coverage" ], + "version" : "None" + }, + { + "enumerant" : "DenormPreserve", + "value" : 4459, + "capabilities" : [ "DenormPreserve" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "DenormFlushToZero", + "value" : 4460, + "capabilities" : [ "DenormFlushToZero" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "SignedZeroInfNanPreserve", + "value" : 4461, + "capabilities" : [ "SignedZeroInfNanPreserve" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "RoundingModeRTE", + "value" : 4462, + "capabilities" : [ "RoundingModeRTE" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "RoundingModeRTZ", + "value" : 4463, + "capabilities" : [ "RoundingModeRTZ" ], + "extensions" : [ "SPV_KHR_float_controls" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "version" : "1.4" + }, + { + "enumerant": "EarlyAndLateFragmentTestsAMD", + "value": 5017, + "capabilities": [ "Shader" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests" ], + "version": "None" + }, + { + "enumerant" : "StencilRefReplacingEXT", + "value" : 5027, + "capabilities" : [ "StencilExportEXT" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ], + "version" : "None" + }, + { + "enumerant" : "CoalescingAMDX", + "value" : 5069, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "MaxNodeRecursionAMDX", + "value" : 5071, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Number of recursions'" } + ], + "version" : "None" + }, + { + "enumerant" : "StaticNumWorkgroupsAMDX", + "value" : 5072, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size'" }, + { "kind" : "IdRef", "name" : "'y size'" }, + { "kind" : "IdRef", "name" : "'z size'" } + ], + "version" : "None" + }, + { + "enumerant" : "ShaderIndexAMDX", + "value" : 5073, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Shader Index'" } + ], + "version" : "None" + }, + { + "enumerant" : "MaxNumWorkgroupsAMDX", + "value" : 5077, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'x size'" }, + { "kind" : "IdRef", "name" : "'y size'" }, + { "kind" : "IdRef", "name" : "'z size'" } + ], + "version" : "None" + }, + { + "enumerant": "StencilRefUnchangedFrontAMD", + "value": 5079, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefGreaterFrontAMD", + "value": 5080, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefLessFrontAMD", + "value": 5081, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefUnchangedBackAMD", + "value": 5082, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefGreaterBackAMD", + "value": 5083, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "StencilRefLessBackAMD", + "value": 5084, + "capabilities": [ "StencilExportEXT" ], + "extensions": [ "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_EXT_shader_stencil_export" ], + "version": "None" + }, + { + "enumerant": "QuadDerivativesKHR", + "value": 5088, + "capabilities": [ "QuadControlKHR" ], + "version": "None" + }, + { + "enumerant" : "RequireFullQuadsKHR", + "value" : 5089, + "capabilities" : [ "QuadControlKHR" ], + "version" : "None" + }, + { + "enumerant" : "OutputLinesNV", + "value" : 5269, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputLinesEXT", + "value" : 5269, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputPrimitivesNV", + "value" : 5270, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Primitive count'" } + ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputPrimitivesEXT", + "value" : 5270, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Primitive count'" } + ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "DerivativeGroupQuadsNV", + "value" : 5289, + "capabilities" : [ "ComputeDerivativeGroupQuadsNV" ], + "extensions" : [ "SPV_NV_compute_shader_derivatives" ], + "version" : "None" + }, + { + "enumerant" : "DerivativeGroupLinearNV", + "value" : 5290, + "capabilities" : [ "ComputeDerivativeGroupLinearNV" ], + "extensions" : [ "SPV_NV_compute_shader_derivatives" ], + "version" : "None" + }, + { + "enumerant" : "OutputTrianglesNV", + "value" : 5298, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputTrianglesEXT", + "value" : 5298, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PixelInterlockOrderedEXT", + "value" : 5366, + "capabilities" : [ "FragmentShaderPixelInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "PixelInterlockUnorderedEXT", + "value" : 5367, + "capabilities" : [ "FragmentShaderPixelInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "SampleInterlockOrderedEXT", + "value" : 5368, + "capabilities" : [ "FragmentShaderSampleInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "SampleInterlockUnorderedEXT", + "value" : 5369, + "capabilities" : [ "FragmentShaderSampleInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "ShadingRateInterlockOrderedEXT", + "value" : 5370, + "capabilities" : [ "FragmentShaderShadingRateInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "ShadingRateInterlockUnorderedEXT", + "value" : 5371, + "capabilities" : [ "FragmentShaderShadingRateInterlockEXT" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "SharedLocalMemorySizeINTEL", + "value" : 5618, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Size'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RoundingModeRTPINTEL", + "value" : 5620, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "capabilities" : [ "RoundToInfinityINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RoundingModeRTNINTEL", + "value" : 5621, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "capabilities" : [ "RoundToInfinityINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FloatingPointModeALTINTEL", + "value" : 5622, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "capabilities" : [ "RoundToInfinityINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FloatingPointModeIEEEINTEL", + "value" : 5623, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" } + ], + "capabilities" : [ "RoundToInfinityINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxWorkgroupSizeINTEL", + "value" : 5893, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'max_x_size'" }, + { "kind" : "LiteralInteger", "name" : "'max_y_size'" }, + { "kind" : "LiteralInteger", "name" : "'max_z_size'" } + ], + "capabilities" : [ "KernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MaxWorkDimINTEL", + "value" : 5894, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'max_dimensions'" } + ], + "capabilities" : [ "KernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "NoGlobalOffsetINTEL", + "value" : 5895, + "capabilities" : [ "KernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "NumSIMDWorkitemsINTEL", + "value" : 5896, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'vector_width'" } + ], + "capabilities" : [ "FPGAKernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "SchedulerTargetFmaxMhzINTEL", + "value" : 5903, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'target_fmax'" } + ], + "capabilities" : [ "FPGAKernelAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaximallyReconvergesKHR", + "value" : 6023, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_maximal_reconvergence" ], + "version" : "None" + }, + { + "enumerant" : "FPFastMathDefault", + "value" : 6028, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Target Type'" }, + { "kind" : "IdRef", "name" : "'Fast-Math Mode'" } + ], + "capabilities" : [ "FloatControls2" ], + "version" : "None" + }, + { + "enumerant" : "StreamingInterfaceINTEL", + "value" : 6154, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'StallFreeReturn'" } + ], + "capabilities" : [ "FPGAKernelAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RegisterMapInterfaceINTEL", + "value" : 6160, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'WaitForDoneWrite'" } + ], + "capabilities" : [ "FPGAKernelAttributesv2INTEL" ], + "version" : "None" + }, + { + "enumerant" : "NamedBarrierCountINTEL", + "value" : 6417, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Barrier Count'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaximumRegistersINTEL", + "value" : 6461, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaximumRegistersIdINTEL", + "value" : 6462, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "NamedMaximumRegistersINTEL", + "value" : 6463, + "parameters" : [ + { "kind" : "NamedMaximumNumberOfRegisters", "name" : "'Named Maximum Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StorageClass", + "enumerants" : [ + { + "enumerant" : "UniformConstant", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Input", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "Uniform", + "value" : 2, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Output", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Workgroup", + "value" : 4, + "version" : "1.0" + }, + { + "enumerant" : "CrossWorkgroup", + "value" : 5, + "version" : "1.0" + }, + { + "enumerant" : "Private", + "value" : 6, + "capabilities" : [ "Shader", "VectorComputeINTEL" ], + "version": "1.0" + }, + { + "enumerant" : "Function", + "value" : 7, + "version" : "1.0" + }, + { + "enumerant" : "Generic", + "value" : 8, + "capabilities" : [ "GenericPointer" ], + "version": "1.0" + }, + { + "enumerant" : "PushConstant", + "value" : 9, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "AtomicCounter", + "value" : 10, + "capabilities" : [ "AtomicStorage" ], + "version": "1.0" + }, + { + "enumerant" : "Image", + "value" : 11, + "version" : "1.0" + }, + { + "enumerant" : "StorageBuffer", + "value" : 12, + "extensions" : [ + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers" + ], + "capabilities" : [ "Shader" ], + "version" : "1.3" + }, + { + "enumerant" : "TileImageEXT", + "value" : 4172, + "capabilities" : [ "TileImageColorReadAccessEXT" ], + "version" : "None" + }, + { + "enumerant" : "NodePayloadAMDX", + "value" : 5068, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "NodeOutputPayloadAMDX", + "value" : 5076, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "CallableDataNV", + "value" : 5328, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableDataKHR", + "value" : 5328, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IncomingCallableDataNV", + "value" : 5329, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IncomingCallableDataKHR", + "value" : 5329, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayPayloadNV", + "value" : 5338, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayPayloadKHR", + "value" : 5338, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "HitAttributeNV", + "value" : 5339, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "HitAttributeKHR", + "value" : 5339, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayPayloadNV", + "value" : 5342, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayPayloadKHR", + "value" : 5342, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ShaderRecordBufferNV", + "value" : 5343, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ShaderRecordBufferKHR", + "value" : 5343, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "PhysicalStorageBuffer", + "value" : 5349, + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "version" : "1.5" + }, + { + "enumerant" : "PhysicalStorageBufferEXT", + "value" : 5349, + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "version" : "1.5" + }, + { + "enumerant" : "HitObjectAttributeNV", + "value" : 5385, + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "enumerant" : "TaskPayloadWorkgroupEXT", + "value" : 5402, + "extensions" : [ "SPV_EXT_mesh_shader" ], + "capabilities" : [ "MeshShadingEXT" ], + "version" : "1.4" + }, + { + "enumerant" : "CodeSectionINTEL", + "value" : 5605, + "extensions" : [ "SPV_INTEL_function_pointers" ], + "capabilities" : [ "FunctionPointersINTEL" ], + "version" : "None" + }, + { + "enumerant" : "DeviceOnlyINTEL", + "value" : 5936, + "extensions" : [ + "SPV_INTEL_usm_storage_classes" + ], + "capabilities" : [ "USMStorageClassesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "HostOnlyINTEL", + "value" : 5937, + "extensions" : [ + "SPV_INTEL_usm_storage_classes" + ], + "capabilities" : [ "USMStorageClassesINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Dim", + "enumerants" : [ + { + "enumerant" : "1D", + "value" : 0, + "capabilities" : [ "Sampled1D" ], + "version": "1.0" + }, + { + "enumerant" : "2D", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "3D", + "value" : 2, + "version" : "1.0" + }, + { + "enumerant" : "Cube", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rect", + "value" : 4, + "capabilities" : [ "SampledRect" ], + "version": "1.0" + }, + { + "enumerant" : "Buffer", + "value" : 5, + "capabilities" : [ "SampledBuffer" ], + "version": "1.0" + }, + { + "enumerant" : "SubpassData", + "value" : 6, + "capabilities" : [ "InputAttachment" ], + "version": "1.0" + }, + { + "enumerant" : "TileImageDataEXT", + "value" : 4173, + "capabilities" : [ "TileImageColorReadAccessEXT" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerAddressingMode", + "enumerants" : [ + { + "enumerant" : "None", + "value" : 0, + "version": "1.0" + }, + { + "enumerant" : "ClampToEdge", + "value" : 1, + "version": "1.0" + }, + { + "enumerant" : "Clamp", + "value" : 2, + "version": "1.0" + }, + { + "enumerant" : "Repeat", + "value" : 3, + "version": "1.0" + }, + { + "enumerant" : "RepeatMirrored", + "value" : 4, + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "SamplerFilterMode", + "enumerants" : [ + { + "enumerant" : "Nearest", + "value" : 0, + "version": "1.0" + }, + { + "enumerant" : "Linear", + "value" : 1, + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageFormat", + "enumerants" : [ + { + "enumerant" : "Unknown", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Rgba32f", + "value" : 1, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16f", + "value" : 2, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "R32f", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba8", + "value" : 4, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba8Snorm", + "value" : 5, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rg32f", + "value" : 6, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16f", + "value" : 7, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R11fG11fB10f", + "value" : 8, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16f", + "value" : 9, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16", + "value" : 10, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgb10A2", + "value" : 11, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16", + "value" : 12, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg8", + "value" : 13, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16", + "value" : 14, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R8", + "value" : 15, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16Snorm", + "value" : 16, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16Snorm", + "value" : 17, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg8Snorm", + "value" : 18, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16Snorm", + "value" : 19, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R8Snorm", + "value" : 20, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba32i", + "value" : 21, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16i", + "value" : 22, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba8i", + "value" : 23, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "R32i", + "value" : 24, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rg32i", + "value" : 25, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16i", + "value" : 26, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg8i", + "value" : 27, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16i", + "value" : 28, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R8i", + "value" : 29, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba32ui", + "value" : 30, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba16ui", + "value" : 31, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgba8ui", + "value" : 32, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "R32ui", + "value" : 33, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Rgb10a2ui", + "value" : 34, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg32ui", + "value" : 35, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg16ui", + "value" : 36, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "Rg8ui", + "value" : 37, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R16ui", + "value" : 38, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R8ui", + "value" : 39, + "capabilities" : [ "StorageImageExtendedFormats" ], + "version": "1.0" + }, + { + "enumerant" : "R64ui", + "value" : 40, + "capabilities" : [ "Int64ImageEXT" ], + "version": "1.0" + }, + { + "enumerant" : "R64i", + "value" : 41, + "capabilities" : [ "Int64ImageEXT" ], + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelOrder", + "enumerants" : [ + { + "enumerant" : "R", + "value" : 0, + "version": "1.0" + }, + { + "enumerant" : "A", + "value" : 1, + "version": "1.0" + }, + { + "enumerant" : "RG", + "value" : 2, + "version": "1.0" + }, + { + "enumerant" : "RA", + "value" : 3, + "version": "1.0" + }, + { + "enumerant" : "RGB", + "value" : 4, + "version": "1.0" + }, + { + "enumerant" : "RGBA", + "value" : 5, + "version": "1.0" + }, + { + "enumerant" : "BGRA", + "value" : 6, + "version": "1.0" + }, + { + "enumerant" : "ARGB", + "value" : 7, + "version": "1.0" + }, + { + "enumerant" : "Intensity", + "value" : 8, + "version": "1.0" + }, + { + "enumerant" : "Luminance", + "value" : 9, + "version": "1.0" + }, + { + "enumerant" : "Rx", + "value" : 10, + "version": "1.0" + }, + { + "enumerant" : "RGx", + "value" : 11, + "version": "1.0" + }, + { + "enumerant" : "RGBx", + "value" : 12, + "version": "1.0" + }, + { + "enumerant" : "Depth", + "value" : 13, + "version": "1.0" + }, + { + "enumerant" : "DepthStencil", + "value" : 14, + "version": "1.0" + }, + { + "enumerant" : "sRGB", + "value" : 15, + "version": "1.0" + }, + { + "enumerant" : "sRGBx", + "value" : 16, + "version": "1.0" + }, + { + "enumerant" : "sRGBA", + "value" : 17, + "version": "1.0" + }, + { + "enumerant" : "sBGRA", + "value" : 18, + "version": "1.0" + }, + { + "enumerant" : "ABGR", + "value" : 19, + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "ImageChannelDataType", + "enumerants" : [ + { + "enumerant" : "SnormInt8", + "value" : 0, + "version": "1.0" + }, + { + "enumerant" : "SnormInt16", + "value" : 1, + "version": "1.0" + }, + { + "enumerant" : "UnormInt8", + "value" : 2, + "version": "1.0" + }, + { + "enumerant" : "UnormInt16", + "value" : 3, + "version": "1.0" + }, + { + "enumerant" : "UnormShort565", + "value" : 4, + "version": "1.0" + }, + { + "enumerant" : "UnormShort555", + "value" : 5, + "version": "1.0" + }, + { + "enumerant" : "UnormInt101010", + "value" : 6, + "version": "1.0" + }, + { + "enumerant" : "SignedInt8", + "value" : 7, + "version": "1.0" + }, + { + "enumerant" : "SignedInt16", + "value" : 8, + "version": "1.0" + }, + { + "enumerant" : "SignedInt32", + "value" : 9, + "version": "1.0" + }, + { + "enumerant" : "UnsignedInt8", + "value" : 10, + "version": "1.0" + }, + { + "enumerant" : "UnsignedInt16", + "value" : 11, + "version": "1.0" + }, + { + "enumerant" : "UnsignedInt32", + "value" : 12, + "version": "1.0" + }, + { + "enumerant" : "HalfFloat", + "value" : 13, + "version": "1.0" + }, + { + "enumerant" : "Float", + "value" : 14, + "version": "1.0" + }, + { + "enumerant" : "UnormInt24", + "value" : 15, + "version": "1.0" + }, + { + "enumerant" : "UnormInt101010_2", + "value" : 16, + "version": "1.0" + }, + { + "enumerant" : "UnsignedIntRaw10EXT", + "value" : 19, + "version": "1.0" + }, + { + "enumerant" : "UnsignedIntRaw12EXT", + "value" : 20, + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPRoundingMode", + "enumerants" : [ + { + "enumerant" : "RTE", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "RTZ", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "RTP", + "value" : 2, + "version" : "1.0" + }, + { + "enumerant" : "RTN", + "value" : 3, + "version" : "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPDenormMode", + "enumerants" : [ + { + "enumerant" : "Preserve", + "value" : 0, + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FlushToZero", + "value" : 1, + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "QuantizationModes", + "enumerants" : [ + { + "enumerant" : "TRN", + "value" : 0, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "TRN_ZERO", + "value" : 1, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND", + "value" : 2, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_ZERO", + "value" : 3, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_INF", + "value" : 4, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_MIN_INF", + "value" : 5, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_CONV", + "value" : 6, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "RND_CONV_ODD", + "value" : 7, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FPOperationMode", + "enumerants" : [ + { + "enumerant" : "IEEE", + "value" : 0, + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ALT", + "value" : 1, + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "OverflowModes", + "enumerants" : [ + { + "enumerant" : "WRAP", + "value" : 0, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "SAT", + "value" : 1, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "SAT_ZERO", + "value" : 2, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + }, + { + "enumerant" : "SAT_SYM", + "value" : 3, + "capabilities" : [ "ArbitraryPrecisionFixedPointINTEL"], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LinkageType", + "enumerants" : [ + { + "enumerant" : "Export", + "value" : 0, + "capabilities" : [ "Linkage" ], + "version": "1.0" + }, + { + "enumerant" : "Import", + "value" : 1, + "capabilities" : [ "Linkage" ], + "version": "1.0" + }, + { + "enumerant" : "LinkOnceODR", + "value" : 2, + "capabilities" : [ "Linkage" ], + "extensions" : [ "SPV_KHR_linkonce_odr" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "AccessQualifier", + "enumerants" : [ + { + "enumerant" : "ReadOnly", + "value" : 0, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "WriteOnly", + "value" : 1, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "ReadWrite", + "value" : 2, + "capabilities" : [ "Kernel" ], + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "HostAccessQualifier", + "enumerants" : [ + { + "enumerant" : "NoneINTEL", + "value" : 0, + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ReadINTEL", + "value" : 1, + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + }, + { + "enumerant" : "WriteINTEL", + "value" : 2, + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ReadWriteINTEL", + "value" : 3, + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "FunctionParameterAttribute", + "enumerants" : [ + { + "enumerant" : "Zext", + "value" : 0, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Sext", + "value" : 1, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "ByVal", + "value" : 2, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Sret", + "value" : 3, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NoAlias", + "value" : 4, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NoCapture", + "value" : 5, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NoWrite", + "value" : 6, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NoReadWrite", + "value" : 7, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "RuntimeAlignedINTEL", + "value" : 5940, + "capabilities" : [ "RuntimeAlignedAttributeINTEL" ], + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Decoration", + "enumerants" : [ + { + "enumerant" : "RelaxedPrecision", + "value" : 0, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SpecId", + "value" : 1, + "capabilities" : [ "Shader", "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Block", + "value" : 2, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "BufferBlock", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0", + "lastVersion" : "1.3" + }, + { + "enumerant" : "RowMajor", + "value" : 4, + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "enumerant" : "ColMajor", + "value" : 5, + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "enumerant" : "ArrayStride", + "value" : 6, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Array Stride'" } + ], + "version": "1.0" + }, + { + "enumerant" : "MatrixStride", + "value" : 7, + "capabilities" : [ "Matrix" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Matrix Stride'" } + ], + "version": "1.0" + }, + { + "enumerant" : "GLSLShared", + "value" : 8, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GLSLPacked", + "value" : 9, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "CPacked", + "value" : 10, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "BuiltIn", + "value" : 11, + "parameters" : [ + { "kind" : "BuiltIn" } + ], + "version": "1.0" + }, + { + "enumerant" : "NoPerspective", + "value" : 13, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Flat", + "value" : 14, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Patch", + "value" : 15, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Centroid", + "value" : 16, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Sample", + "value" : 17, + "capabilities" : [ "SampleRateShading" ], + "version": "1.0" + }, + { + "enumerant" : "Invariant", + "value" : 18, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Restrict", + "value" : 19, + "version" : "1.0" + }, + { + "enumerant" : "Aliased", + "value" : 20, + "version" : "1.0" + }, + { + "enumerant" : "Volatile", + "value" : 21, + "version" : "1.0" + }, + { + "enumerant" : "Constant", + "value" : 22, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Coherent", + "value" : 23, + "version": "1.0" + }, + { + "enumerant" : "NonWritable", + "value" : 24, + "version": "1.0" + }, + { + "enumerant" : "NonReadable", + "value" : 25, + "version": "1.0" + }, + { + "enumerant" : "Uniform", + "value" : 26, + "capabilities" : [ "Shader", "UniformDecoration" ], + "version": "1.0" + }, + { + "enumerant" : "UniformId", + "value" : 27, + "capabilities" : [ "Shader", "UniformDecoration" ], + "parameters" : [ + { "kind" : "IdScope", "name" : "'Execution'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "SaturatedConversion", + "value" : 28, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Stream", + "value" : 29, + "capabilities" : [ "GeometryStreams" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stream Number'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Location", + "value" : 30, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Location'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Component", + "value" : 31, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Component'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Index", + "value" : 32, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Index'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Binding", + "value" : 33, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Binding Point'" } + ], + "version": "1.0" + }, + { + "enumerant" : "DescriptorSet", + "value" : 34, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Descriptor Set'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Offset", + "value" : 35, + "capabilities" : [ "Shader" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Byte Offset'" } + ], + "version": "1.0" + }, + { + "enumerant" : "XfbBuffer", + "value" : 36, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" } + ], + "version": "1.0" + }, + { + "enumerant" : "XfbStride", + "value" : 37, + "capabilities" : [ "TransformFeedback" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'XFB Stride'" } + ], + "version": "1.0" + }, + { + "enumerant" : "FuncParamAttr", + "value" : 38, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" } + ], + "version": "1.0" + }, + { + "enumerant" : "FPRoundingMode", + "value" : 39, + "parameters" : [ + { "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" } + ], + "version": "1.0" + }, + { + "enumerant" : "FPFastMathMode", + "value" : 40, + "capabilities" : [ "Kernel", "FloatControls2" ], + "parameters" : [ + { "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" } + ], + "version": "1.0" + }, + { + "enumerant" : "LinkageAttributes", + "value" : 41, + "capabilities" : [ "Linkage" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Name'" }, + { "kind" : "LinkageType", "name" : "'Linkage Type'" } + ], + "version": "1.0" + }, + { + "enumerant" : "NoContraction", + "value" : 42, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "InputAttachmentIndex", + "value" : 43, + "capabilities" : [ "InputAttachment" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Attachment Index'" } + ], + "version": "1.0" + }, + { + "enumerant" : "Alignment", + "value" : 44, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Alignment'" } + ], + "version": "1.0" + }, + { + "enumerant" : "MaxByteOffset", + "value" : 45, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Max Byte Offset'" } + ], + "version" : "1.1" + }, + { + "enumerant" : "AlignmentId", + "value" : 46, + "capabilities" : [ "Kernel" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Alignment'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "MaxByteOffsetId", + "value" : 47, + "capabilities" : [ "Addresses" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Max Byte Offset'" } + ], + "version" : "1.2" + }, + { + "enumerant" : "NoSignedWrap", + "value" : 4469, + "extensions" : [ "SPV_KHR_no_integer_wrap_decoration" ], + "version" : "1.4" + }, + { + "enumerant" : "NoUnsignedWrap", + "value" : 4470, + "extensions" : [ "SPV_KHR_no_integer_wrap_decoration" ], + "version" : "1.4" + }, + { + "enumerant" : "WeightTextureQCOM", + "value" : 4487, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "BlockMatchTextureQCOM", + "value" : 4488, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "BlockMatchSamplerQCOM", + "value" : 4499, + "extensions" : [ "SPV_QCOM_image_processing2" ], + "version" : "None" + }, + { + "enumerant" : "ExplicitInterpAMD", + "value" : 4999, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "NodeSharesPayloadLimitsWithAMDX", + "value" : 5019, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Payload Array'" } + ], + "version" : "None" + }, + { + "enumerant" : "NodeMaxPayloadsAMDX", + "value" : 5020, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "IdRef", "name" : "'Max number of payloads'" } + ], + "version" : "None" + }, + { + "enumerant" : "TrackFinishWritingAMDX", + "value" : 5078, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "PayloadNodeNameAMDX", + "value" : 5091, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Node Name'" } + ], + "version" : "None" + }, + { + "enumerant" : "OverrideCoverageNV", + "value" : 5248, + "capabilities" : [ "SampleMaskOverrideCoverageNV" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ], + "version" : "None" + }, + { + "enumerant" : "PassthroughNV", + "value" : 5250, + "capabilities" : [ "GeometryShaderPassthroughNV" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ], + "version" : "None" + }, + { + "enumerant" : "ViewportRelativeNV", + "value" : 5252, + "capabilities" : [ "ShaderViewportMaskNV" ], + "version" : "None" + }, + { + "enumerant" : "SecondaryViewportRelativeNV", + "value" : 5256, + "capabilities" : [ "ShaderStereoViewNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ], + "version" : "None", + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ] + }, + { + "enumerant" : "PerPrimitiveNV", + "value" : 5271, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerPrimitiveEXT", + "value" : 5271, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerViewNV", + "value" : 5272, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerTaskNV", + "value" : 5273, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerVertexKHR", + "value" : 5285, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "PerVertexNV", + "value" : 5285, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "NonUniform", + "value" : 5300, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "NonUniformEXT", + "value" : 5300, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "RestrictPointer", + "value" : 5355, + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "RestrictPointerEXT", + "value" : 5355, + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "AliasedPointer", + "value" : 5356, + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "AliasedPointerEXT", + "value" : 5356, + "capabilities" : [ "PhysicalStorageBufferAddresses" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "HitObjectShaderRecordBufferNV", + "value" : 5386, + "capabilities" : [ "ShaderInvocationReorderNV" ], + "version" : "None" + }, + { + "enumerant" : "BindlessSamplerNV", + "value" : 5398, + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "enumerant" : "BindlessImageNV", + "value" : 5399, + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "enumerant" : "BoundSamplerNV", + "value" : 5400, + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "enumerant" : "BoundImageNV", + "value" : 5401, + "capabilities" : [ "BindlessTextureNV" ], + "version" : "None" + }, + { + "enumerant" : "SIMTCallINTEL", + "value" : 5599, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'N'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ReferencedIndirectlyINTEL", + "value" : 5602, + "capabilities" : [ "IndirectReferencesINTEL" ], + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "enumerant" : "ClobberINTEL", + "value" : 5607, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Register'" } + ], + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "enumerant" : "SideEffectsINTEL", + "value" : 5608, + "capabilities" : [ "AsmINTEL" ], + "version" : "None" + }, + { + "enumerant" : "VectorComputeVariableINTEL", + "value" : 5624, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FuncParamIOKindINTEL", + "value" : 5625, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Kind'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "VectorComputeFunctionINTEL", + "value" : 5626, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StackCallINTEL", + "value" : 5627, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "GlobalVariableOffsetINTEL", + "value" : 5628, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Offset'" } + ], + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "CounterBuffer", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "HlslCounterBufferGOOGLE", + "value" : 5634, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Counter Buffer'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "None" + }, + { + "enumerant" : "UserSemantic", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "version" : "1.4" + }, + { + "enumerant" : "HlslSemanticGOOGLE", + "value" : 5635, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Semantic'" } + ], + "extensions" : [ "SPV_GOOGLE_hlsl_functionality1" ], + "version" : "None" + }, + { + "enumerant" : "UserTypeGOOGLE", + "value" : 5636, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'User Type'" } + ], + "extensions" : [ "SPV_GOOGLE_user_type" ], + "version" : "None" + }, + { + "enumerant" : "FunctionRoundingModeINTEL", + "value" : 5822, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" }, + { "kind" : "FPRoundingMode", "name" : "'FP Rounding Mode'" } + ], + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FunctionDenormModeINTEL", + "value" : 5823, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" }, + { "kind" : "FPDenormMode", "name" : "'FP Denorm Mode'" } + ], + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RegisterINTEL", + "value" : 5825, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MemoryINTEL", + "value" : 5826, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Memory Type'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "NumbanksINTEL", + "value" : 5827, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Banks'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "BankwidthINTEL", + "value" : 5828, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Bank Width'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MaxPrivateCopiesINTEL", + "value" : 5829, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Maximum Copies'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "SinglepumpINTEL", + "value" : 5830, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "DoublepumpINTEL", + "value" : 5831, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MaxReplicatesINTEL", + "value" : 5832, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Maximum Replicates'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "SimpleDualPortINTEL", + "value" : 5833, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "MergeINTEL", + "value" : 5834, + "parameters" : [ + { "kind" : "LiteralString", "name" : "'Merge Key'" }, + { "kind" : "LiteralString", "name" : "'Merge Type'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "BankBitsINTEL", + "value" : 5835, + "parameters" : [ + { "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Bank Bits'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "ForcePow2DepthINTEL", + "value" : 5836, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Force Key'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "StridesizeINTEL", + "value" : 5883, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Stride Size'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "WordsizeINTEL", + "value" : 5884, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Word Size'" } + ], + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "TrueDualPortINTEL", + "value" : 5885, + "capabilities" : [ "FPGAMemoryAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "BurstCoalesceINTEL", + "value" : 5899, + "capabilities" : [ "FPGAMemoryAccessesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "CacheSizeINTEL", + "value" : 5900, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Cache Size in bytes'" } + ], + "capabilities" : [ "FPGAMemoryAccessesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "DontStaticallyCoalesceINTEL", + "value" : 5901, + "capabilities" : [ "FPGAMemoryAccessesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "PrefetchINTEL", + "value" : 5902, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Prefetcher Size in bytes'" } + ], + "capabilities" : [ "FPGAMemoryAccessesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StallEnableINTEL", + "value" : 5905, + "capabilities" : [ "FPGAClusterAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FuseLoopsInFunctionINTEL", + "value" : 5907, + "capabilities" : [ "LoopFuseINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MathOpDSPModeINTEL", + "value" : 5909, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Mode'" }, + { "kind" : "LiteralInteger", "name" : "'Propagate'" } + ], + "capabilities" : [ "FPGADSPControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "AliasScopeINTEL", + "value" : 5914, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Aliasing Scopes List'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "version" : "None" + }, + { + "enumerant" : "NoAliasINTEL", + "value" : 5915, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Aliasing Scopes List'" } + ], + "capabilities" : [ "MemoryAccessAliasingINTEL" ], + "version" : "None" + }, + { + "enumerant" : "InitiationIntervalINTEL", + "value" : 5917, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Cycles'" } + ], + "capabilities" : [ "FPGAInvocationPipeliningAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaxConcurrencyINTEL", + "value" : 5918, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Invocations'" } + ], + "capabilities" : [ "FPGAInvocationPipeliningAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "PipelineEnableINTEL", + "value" : 5919, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Enable'" } + ], + "capabilities" : [ "FPGAInvocationPipeliningAttributesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "BufferLocationINTEL", + "value" : 5921, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Buffer Location ID'" } + ], + "capabilities" : [ "FPGABufferLocationINTEL" ], + "version" : "None" + }, + { + "enumerant" : "IOPipeStorageINTEL", + "value" : 5944, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'IO Pipe ID'" } + ], + "capabilities" : [ "IOPipesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "FunctionFloatingPointModeINTEL", + "value" : 6080, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Target Width'" }, + { "kind" : "FPOperationMode", "name" : "'FP Operation Mode'" } + ], + "capabilities" : [ "FunctionFloatControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "SingleElementVectorINTEL", + "value" : 6085, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "VectorComputeCallableFunctionINTEL", + "value" : 6087, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MediaBlockIOINTEL", + "value" : 6140, + "capabilities" : [ "VectorComputeINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StallFreeINTEL", + "value" : 6151, + "capabilities" : [ "FPGAClusterAttributesV2INTEL" ], + "version" : "None" + }, + { + "enumerant" : "FPMaxErrorDecorationINTEL", + "value" : 6170, + "parameters" : [ + { "kind" : "LiteralFloat", "name" : "'Max Error'" } + ], + "capabilities" : [ "FPMaxErrorINTEL" ], + "version" : "None" + }, + { + "enumerant" : "LatencyControlLabelINTEL", + "value" : 6172, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Latency Label'" } + ], + "capabilities" : [ "FPGALatencyControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "LatencyControlConstraintINTEL", + "value" : 6173, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Relative To'" }, + { "kind" : "LiteralInteger", "name" : "'Control Type'" }, + { "kind" : "LiteralInteger", "name" : "'Relative Cycle'" } + ], + "capabilities" : [ "FPGALatencyControlINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ConduitKernelArgumentINTEL", + "value" : 6175, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "RegisterMapKernelArgumentINTEL", + "value" : 6176, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceAddressWidthINTEL", + "value" : 6177, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'AddressWidth'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceDataWidthINTEL", + "value" : 6178, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'DataWidth'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceLatencyINTEL", + "value" : 6179, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Latency'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceReadWriteModeINTEL", + "value" : 6180, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "AccessQualifier", "name" : "'ReadWriteMode'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceMaxBurstINTEL", + "value" : 6181, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'MaxBurstCount'" } + ], + "version" : "None" + }, + { + "enumerant" : "MMHostInterfaceWaitRequestINTEL", + "value" : 6182, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Waitrequest'" } + ], + "version" : "None" + }, + { + "enumerant" : "StableKernelArgumentINTEL", + "value" : 6183, + "capabilities" : [ "FPGAArgumentInterfacesINTEL" ], + "version" : "None" + }, + { + "enumerant" : "HostAccessINTEL", + "value" : 6188, + "parameters": [ + { "kind" : "HostAccessQualifier", "name" : "'Access'" }, + { "kind" : "LiteralString", "name" : "'Name'" } + ], + "capabilities" : [ "GlobalVariableHostAccessINTEL" ], + "version" : "None" + }, + { + "enumerant" : "InitModeINTEL", + "value" : 6190, + "parameters": [ + { "kind" : "InitializationModeQualifier", "name" : "'Trigger'" } + ], + "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ImplementInRegisterMapINTEL", + "value" : 6191, + "parameters": [ + { "kind" : "LiteralInteger", "name" : "Value" } + ], + "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "CacheControlLoadINTEL", + "value" : 6442, + "capabilities" : [ "CacheControlsINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Cache Level'" }, + { "kind" : "LoadCacheControl", "name" : "'Cache Control'" } + ], + "version" : "None" + }, + { + "enumerant" : "CacheControlStoreINTEL", + "value" : 6443, + "capabilities" : [ "CacheControlsINTEL" ], + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Cache Level'" }, + { "kind" : "StoreCacheControl", "name" : "'Cache Control'" } + ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "BuiltIn", + "enumerants" : [ + { + "enumerant" : "Position", + "value" : 0, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "PointSize", + "value" : 1, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ClipDistance", + "value" : 3, + "capabilities" : [ "ClipDistance" ], + "version": "1.0" + }, + { + "enumerant" : "CullDistance", + "value" : 4, + "capabilities" : [ "CullDistance" ], + "version": "1.0" + }, + { + "enumerant" : "VertexId", + "value" : 5, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "InstanceId", + "value" : 6, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "PrimitiveId", + "value" : 7, + "capabilities" : [ "Geometry", "Tessellation", "RayTracingNV", "RayTracingKHR", "MeshShadingNV", "MeshShadingEXT" ], + "version": "1.0" + }, + { + "enumerant" : "InvocationId", + "value" : 8, + "capabilities" : [ "Geometry", "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "Layer", + "value" : 9, + "capabilities" : [ "Geometry", "ShaderLayer", "ShaderViewportIndexLayerEXT", "MeshShadingNV", "MeshShadingEXT" ], + "version": "1.0" + }, + { + "enumerant" : "ViewportIndex", + "value" : 10, + "capabilities" : [ "MultiViewport", "ShaderViewportIndex", "ShaderViewportIndexLayerEXT", "MeshShadingNV", "MeshShadingEXT" ], + "version": "1.0" + }, + { + "enumerant" : "TessLevelOuter", + "value" : 11, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "TessLevelInner", + "value" : 12, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "TessCoord", + "value" : 13, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "PatchVertices", + "value" : 14, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "FragCoord", + "value" : 15, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "PointCoord", + "value" : 16, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "FrontFacing", + "value" : 17, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SampleId", + "value" : 18, + "capabilities" : [ "SampleRateShading" ], + "version": "1.0" + }, + { + "enumerant" : "SamplePosition", + "value" : 19, + "capabilities" : [ "SampleRateShading" ], + "version": "1.0" + }, + { + "enumerant" : "SampleMask", + "value" : 20, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "FragDepth", + "value" : 22, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "HelperInvocation", + "value" : 23, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "NumWorkgroups", + "value" : 24, + "version" : "1.0" + }, + { + "enumerant" : "WorkgroupSize", + "value" : 25, + "version" : "1.0" + }, + { + "enumerant" : "WorkgroupId", + "value" : 26, + "version" : "1.0" + }, + { + "enumerant" : "LocalInvocationId", + "value" : 27, + "version" : "1.0" + }, + { + "enumerant" : "GlobalInvocationId", + "value" : 28, + "version" : "1.0" + }, + { + "enumerant" : "LocalInvocationIndex", + "value" : 29, + "version" : "1.0" + }, + { + "enumerant" : "WorkDim", + "value" : 30, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "GlobalSize", + "value" : 31, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "EnqueuedWorkgroupSize", + "value" : 32, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "GlobalOffset", + "value" : 33, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "GlobalLinearId", + "value" : 34, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupSize", + "value" : 36, + "capabilities" : [ "Kernel", "GroupNonUniform", "SubgroupBallotKHR" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupMaxSize", + "value" : 37, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "NumSubgroups", + "value" : 38, + "capabilities" : [ "Kernel", "GroupNonUniform" ], + "version": "1.0" + }, + { + "enumerant" : "NumEnqueuedSubgroups", + "value" : 39, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupId", + "value" : 40, + "capabilities" : [ "Kernel", "GroupNonUniform" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupLocalInvocationId", + "value" : 41, + "capabilities" : [ "Kernel", "GroupNonUniform", "SubgroupBallotKHR" ], + "version": "1.0" + }, + { + "enumerant" : "VertexIndex", + "value" : 42, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "InstanceIndex", + "value" : 43, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "CoreIDARM", + "value" : 4160, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "CoreCountARM", + "value" : 4161, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "CoreMaxIDARM", + "value" : 4162, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "WarpIDARM", + "value" : 4163, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "WarpMaxIDARM", + "value" : 4164, + "capabilities" : [ "CoreBuiltinsARM" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupEqMask", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupEqMaskKHR", + "value" : 4416, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupGeMask", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupGeMaskKHR", + "value" : 4417, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupGtMask", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupGtMaskKHR", + "value" : 4418, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupLeMask", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupLeMaskKHR", + "value" : 4419, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupLtMask", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "version" : "1.3" + }, + { + "enumerant" : "SubgroupLtMaskKHR", + "value" : 4420, + "capabilities" : [ "SubgroupBallotKHR", "GroupNonUniformBallot" ], + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "1.3" + }, + { + "enumerant" : "BaseVertex", + "value" : 4424, + "capabilities" : [ "DrawParameters" ], + "extensions" : [ "SPV_KHR_shader_draw_parameters" ], + "version" : "1.3" + }, + { + "enumerant" : "BaseInstance", + "value" : 4425, + "capabilities" : [ "DrawParameters" ], + "extensions" : [ "SPV_KHR_shader_draw_parameters" ], + "version" : "1.3" + }, + { + "enumerant" : "DrawIndex", + "value" : 4426, + "capabilities" : [ "DrawParameters", "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_KHR_shader_draw_parameters", "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "1.3" + }, + { + "enumerant" : "PrimitiveShadingRateKHR", + "value" : 4432, + "capabilities" : [ "FragmentShadingRateKHR" ], + "extensions" : [ "SPV_KHR_fragment_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "DeviceIndex", + "value" : 4438, + "capabilities" : [ "DeviceGroup" ], + "extensions" : [ "SPV_KHR_device_group" ], + "version" : "1.3" + }, + { + "enumerant" : "ViewIndex", + "value" : 4440, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_KHR_multiview" ], + "version" : "1.3" + }, + { + "enumerant" : "ShadingRateKHR", + "value" : 4444, + "capabilities" : [ "FragmentShadingRateKHR" ], + "extensions" : [ "SPV_KHR_fragment_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspAMD", + "value" : 4992, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspCentroidAMD", + "value" : 4993, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspSampleAMD", + "value" : 4994, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordSmoothAMD", + "value" : 4995, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordSmoothCentroidAMD", + "value" : 4996, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordSmoothSampleAMD", + "value" : 4997, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordPullModelAMD", + "value" : 4998, + "extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ], + "version" : "None" + }, + { + "enumerant" : "FragStencilRefEXT", + "value" : 5014, + "capabilities" : [ "StencilExportEXT" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ], + "version" : "None" + }, + { + "enumerant" : "CoalescedInputCountAMDX", + "value" : 5021, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "ShaderIndexAMDX", + "value" : 5073, + "capabilities" : [ "ShaderEnqueueAMDX" ], + "version" : "None" + }, + { + "enumerant" : "ViewportMaskNV", + "value" : 5253, + "capabilities" : [ "ShaderViewportMaskNV", "MeshShadingNV" ], + "extensions" : [ "SPV_NV_viewport_array2", "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "SecondaryPositionNV", + "value" : 5257, + "capabilities" : [ "ShaderStereoViewNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ], + "version" : "None" + }, + { + "enumerant" : "SecondaryViewportMaskNV", + "value" : 5258, + "capabilities" : [ "ShaderStereoViewNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ], + "version" : "None" + }, + { + "enumerant" : "PositionPerViewNV", + "value" : 5261, + "capabilities" : [ "PerViewAttributesNV", "MeshShadingNV" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes", "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "ViewportMaskPerViewNV", + "value" : 5262, + "capabilities" : [ "PerViewAttributesNV", "MeshShadingNV" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes", "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "FullyCoveredEXT", + "value" : 5264, + "capabilities" : [ "FragmentFullyCoveredEXT" ], + "extensions" : [ "SPV_EXT_fragment_fully_covered" ], + "version" : "None" + }, + { + "enumerant" : "TaskCountNV", + "value" : 5274, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PrimitiveCountNV", + "value" : 5275, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PrimitiveIndicesNV", + "value" : 5276, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "ClipDistancePerViewNV", + "value" : 5277, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "CullDistancePerViewNV", + "value" : 5278, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "LayerPerViewNV", + "value" : 5279, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "MeshViewCountNV", + "value" : 5280, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "MeshViewIndicesNV", + "value" : 5281, + "capabilities" : [ "MeshShadingNV" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordKHR", + "value" : 5286, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNV", + "value" : 5286, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspKHR", + "value" : 5287, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "BaryCoordNoPerspNV", + "value" : 5287, + "capabilities" : [ "FragmentBarycentricNV", "FragmentBarycentricKHR" ], + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "FragSizeEXT", + "value" : 5292 , + "capabilities" : [ "FragmentDensityEXT", "ShadingRateNV" ], + "extensions" : [ "SPV_EXT_fragment_invocation_density", "SPV_NV_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "FragmentSizeNV", + "value" : 5292 , + "capabilities" : [ "ShadingRateNV", "FragmentDensityEXT" ], + "extensions" : [ "SPV_NV_shading_rate", "SPV_EXT_fragment_invocation_density" ], + "version" : "None" + }, + { + "enumerant" : "FragInvocationCountEXT", + "value" : 5293, + "capabilities" : [ "FragmentDensityEXT", "ShadingRateNV" ], + "extensions" : [ "SPV_EXT_fragment_invocation_density", "SPV_NV_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "InvocationsPerPixelNV", + "value" : 5293, + "capabilities" : [ "ShadingRateNV", "FragmentDensityEXT" ], + "extensions" : [ "SPV_NV_shading_rate", "SPV_EXT_fragment_invocation_density" ], + "version" : "None" + }, + { + "enumerant" : "PrimitivePointIndicesEXT", + "value" : 5294, + "capabilities" : [ "MeshShadingEXT" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PrimitiveLineIndicesEXT", + "value" : 5295, + "capabilities" : [ "MeshShadingEXT" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PrimitiveTriangleIndicesEXT", + "value" : 5296, + "capabilities" : [ "MeshShadingEXT" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "CullPrimitiveEXT", + "value" : 5299, + "capabilities" : [ "MeshShadingEXT" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "LaunchIdNV", + "value" : 5319, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "LaunchIdKHR", + "value" : 5319, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "LaunchSizeNV", + "value" : 5320, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "LaunchSizeKHR", + "value" : 5320, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldRayOriginNV", + "value" : 5321, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldRayOriginKHR", + "value" : 5321, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldRayDirectionNV", + "value" : 5322, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldRayDirectionKHR", + "value" : 5322, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectRayOriginNV", + "value" : 5323, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectRayOriginKHR", + "value" : 5323, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectRayDirectionNV", + "value" : 5324, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectRayDirectionKHR", + "value" : 5324, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTminNV", + "value" : 5325, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTminKHR", + "value" : 5325, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTmaxNV", + "value" : 5326, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTmaxKHR", + "value" : 5326, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "InstanceCustomIndexNV", + "value" : 5327, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "InstanceCustomIndexKHR", + "value" : 5327, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectToWorldNV", + "value" : 5330, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "ObjectToWorldKHR", + "value" : 5330, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldToObjectNV", + "value" : 5331, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WorldToObjectKHR", + "value" : 5331, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "HitTNV", + "value" : 5332, + "capabilities" : [ "RayTracingNV" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "HitKindNV", + "value" : 5333, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "HitKindKHR", + "value" : 5333, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "CurrentRayTimeNV", + "value" : 5334, + "capabilities" : [ "RayTracingMotionBlurNV" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, + { + "enumerant" : "HitTriangleVertexPositionsKHR", + "value" : 5335, + "capabilities" : [ "RayTracingPositionFetchKHR" ], + "version" : "None" + }, + { + "enumerant" : "HitMicroTriangleVertexPositionsNV", + "value" : 5337, + "capabilities" : [ "RayTracingDisplacementMicromapNV" ], + "version" : "None" + }, + { + "enumerant" : "HitMicroTriangleVertexBarycentricsNV", + "value" : 5344, + "capabilities" : [ "RayTracingDisplacementMicromapNV" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayFlagsNV", + "value" : 5351, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayFlagsKHR", + "value" : 5351, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayGeometryIndexKHR", + "value" : 5352, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "WarpsPerSMNV", + "value" : 5374, + "capabilities" : [ "ShaderSMBuiltinsNV" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "SMCountNV", + "value" : 5375, + "capabilities" : [ "ShaderSMBuiltinsNV" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "WarpIDNV", + "value" : 5376, + "capabilities" : [ "ShaderSMBuiltinsNV" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "SMIDNV", + "value" : 5377, + "capabilities" : [ "ShaderSMBuiltinsNV" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "HitKindFrontFacingMicroTriangleNV", + "value" : 5405, + "capabilities" : [ "RayTracingDisplacementMicromapNV" ], + "version" : "None" + }, + { + "enumerant" : "HitKindBackFacingMicroTriangleNV", + "value" : 5406, + "capabilities" : [ "RayTracingDisplacementMicromapNV" ], + "version" : "None" + }, + { + "enumerant" : "CullMaskKHR", + "value" : 6021, + "capabilities" : [ "RayCullMaskKHR" ], + "extensions" : [ "SPV_KHR_ray_cull_mask" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Scope", + "enumerants" : [ + { + "enumerant" : "CrossDevice", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Device", + "value" : 1, + "version" : "1.0" + }, + { + "enumerant" : "Workgroup", + "value" : 2, + "version" : "1.0" + }, + { + "enumerant" : "Subgroup", + "value" : 3, + "version" : "1.0" + }, + { + "enumerant" : "Invocation", + "value" : 4, + "version" : "1.0" + }, + { + "enumerant" : "QueueFamily", + "value" : 5, + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "QueueFamilyKHR", + "value" : 5, + "capabilities" : [ "VulkanMemoryModel" ], + "version" : "1.5" + }, + { + "enumerant" : "ShaderCallKHR", + "value" : 6, + "capabilities" : [ "RayTracingKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "GroupOperation", + "enumerants" : [ + { + "enumerant" : "Reduce", + "value" : 0, + "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ], + "version": "1.0" + }, + { + "enumerant" : "InclusiveScan", + "value" : 1, + "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ], + "version": "1.0" + }, + { + "enumerant" : "ExclusiveScan", + "value" : 2, + "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ], + "version": "1.0" + }, + { + "enumerant" : "ClusteredReduce", + "value" : 3, + "capabilities" : [ "GroupNonUniformClustered" ], + "version" : "1.3" + }, + { + "enumerant" : "PartitionedReduceNV", + "value" : 6, + "capabilities" : [ "GroupNonUniformPartitionedNV" ], + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + }, + { + "enumerant" : "PartitionedInclusiveScanNV", + "value" : 7, + "capabilities" : [ "GroupNonUniformPartitionedNV" ], + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + }, + { + "enumerant" : "PartitionedExclusiveScanNV", + "value" : 8, + "capabilities" : [ "GroupNonUniformPartitionedNV" ], + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "KernelEnqueueFlags", + "enumerants" : [ + { + "enumerant" : "NoWait", + "value" : 0, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "WaitKernel", + "value" : 1, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "WaitWorkGroup", + "value" : 2, + "capabilities" : [ "Kernel" ], + "version": "1.0" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "Capability", + "enumerants" : [ + { + "enumerant" : "Matrix", + "value" : 0, + "version" : "1.0" + }, + { + "enumerant" : "Shader", + "value" : 1, + "capabilities" : [ "Matrix" ], + "version": "1.0" + }, + { + "enumerant" : "Geometry", + "value" : 2, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Tessellation", + "value" : 3, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Addresses", + "value" : 4, + "version" : "1.0" + }, + { + "enumerant" : "Linkage", + "value" : 5, + "version" : "1.0" + }, + { + "enumerant" : "Kernel", + "value" : 6, + "version" : "1.0" + }, + { + "enumerant" : "Vector16", + "value" : 7, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Float16Buffer", + "value" : 8, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Float16", + "value" : 9, + "version" : "1.0" + }, + { + "enumerant" : "Float64", + "value" : 10, + "version" : "1.0" + }, + { + "enumerant" : "Int64", + "value" : 11, + "version" : "1.0" + }, + { + "enumerant" : "Int64Atomics", + "value" : 12, + "capabilities" : [ "Int64" ], + "version": "1.0" + }, + { + "enumerant" : "ImageBasic", + "value" : 13, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "ImageReadWrite", + "value" : 14, + "capabilities" : [ "ImageBasic" ], + "version": "1.0" + }, + { + "enumerant" : "ImageMipmap", + "value" : 15, + "capabilities" : [ "ImageBasic" ], + "version": "1.0" + }, + { + "enumerant" : "Pipes", + "value" : 17, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "Groups", + "value" : 18, + "extensions" : [ "SPV_AMD_shader_ballot" ], + "version": "1.0" + }, + { + "enumerant" : "DeviceEnqueue", + "value" : 19, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "LiteralSampler", + "value" : 20, + "capabilities" : [ "Kernel" ], + "version": "1.0" + }, + { + "enumerant" : "AtomicStorage", + "value" : 21, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Int16", + "value" : 22, + "version" : "1.0" + }, + { + "enumerant" : "TessellationPointSize", + "value" : 23, + "capabilities" : [ "Tessellation" ], + "version": "1.0" + }, + { + "enumerant" : "GeometryPointSize", + "value" : 24, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "ImageGatherExtended", + "value" : 25, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageMultisample", + "value" : 27, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "UniformBufferArrayDynamicIndexing", + "value" : 28, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SampledImageArrayDynamicIndexing", + "value" : 29, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageBufferArrayDynamicIndexing", + "value" : 30, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageArrayDynamicIndexing", + "value" : 31, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ClipDistance", + "value" : 32, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "CullDistance", + "value" : 33, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ImageCubeArray", + "value" : 34, + "capabilities" : [ "SampledCubeArray" ], + "version": "1.0" + }, + { + "enumerant" : "SampleRateShading", + "value" : 35, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ImageRect", + "value" : 36, + "capabilities" : [ "SampledRect" ], + "version": "1.0" + }, + { + "enumerant" : "SampledRect", + "value" : 37, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GenericPointer", + "value" : 38, + "capabilities" : [ "Addresses" ], + "version": "1.0" + }, + { + "enumerant" : "Int8", + "value" : 39, + "version" : "1.0" + }, + { + "enumerant" : "InputAttachment", + "value" : 40, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SparseResidency", + "value" : 41, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "MinLod", + "value" : 42, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "Sampled1D", + "value" : 43, + "version" : "1.0" + }, + { + "enumerant" : "Image1D", + "value" : 44, + "capabilities" : [ "Sampled1D" ], + "version": "1.0" + }, + { + "enumerant" : "SampledCubeArray", + "value" : 45, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "SampledBuffer", + "value" : 46, + "version" : "1.0" + }, + { + "enumerant" : "ImageBuffer", + "value" : 47, + "capabilities" : [ "SampledBuffer" ], + "version": "1.0" + }, + { + "enumerant" : "ImageMSArray", + "value" : 48, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageExtendedFormats", + "value" : 49, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "ImageQuery", + "value" : 50, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "DerivativeControl", + "value" : 51, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "InterpolationFunction", + "value" : 52, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "TransformFeedback", + "value" : 53, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "GeometryStreams", + "value" : 54, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageReadWithoutFormat", + "value" : 55, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "StorageImageWriteWithoutFormat", + "value" : 56, + "capabilities" : [ "Shader" ], + "version": "1.0" + }, + { + "enumerant" : "MultiViewport", + "value" : 57, + "capabilities" : [ "Geometry" ], + "version": "1.0" + }, + { + "enumerant" : "SubgroupDispatch", + "value" : 58, + "capabilities" : [ "DeviceEnqueue" ], + "version" : "1.1" + }, + { + "enumerant" : "NamedBarrier", + "value" : 59, + "capabilities" : [ "Kernel" ], + "version" : "1.1" + }, + { + "enumerant" : "PipeStorage", + "value" : 60, + "capabilities" : [ "Pipes" ], + "version" : "1.1" + }, + { + "enumerant" : "GroupNonUniform", + "value" : 61, + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformVote", + "value" : 62, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformArithmetic", + "value" : 63, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformBallot", + "value" : 64, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformShuffle", + "value" : 65, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformShuffleRelative", + "value" : 66, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformClustered", + "value" : 67, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "GroupNonUniformQuad", + "value" : 68, + "capabilities" : [ "GroupNonUniform" ], + "version" : "1.3" + }, + { + "enumerant" : "ShaderLayer", + "value" : 69, + "version" : "1.5" + }, + { + "enumerant" : "ShaderViewportIndex", + "value" : 70, + "version" : "1.5" + }, + { + "enumerant" : "UniformDecoration", + "value" : 71, + "version" : "1.6" + }, + { + "enumerant" : "CoreBuiltinsARM", + "value" : 4165, + "extensions" : [ "SPV_ARM_core_builtins" ], + "version": "None" + }, + { + "enumerant" : "TileImageColorReadAccessEXT", + "value" : 4166, + "extensions" : [ "SPV_EXT_shader_tile_image" ], + "version" : "None" + }, + { + "enumerant" : "TileImageDepthReadAccessEXT", + "value" : 4167, + "extensions" : [ "SPV_EXT_shader_tile_image" ], + "version" : "None" + }, + { + "enumerant" : "TileImageStencilReadAccessEXT", + "value" : 4168, + "extensions" : [ "SPV_EXT_shader_tile_image" ], + "version" : "None" + }, + { + "enumerant" : "FragmentShadingRateKHR", + "value" : 4422, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_fragment_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupBallotKHR", + "value" : 4423, + "extensions" : [ "SPV_KHR_shader_ballot" ], + "version" : "None" + }, + { + "enumerant" : "DrawParameters", + "value" : 4427, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_shader_draw_parameters" ], + "version" : "1.3" + }, + { + "enumerant" : "WorkgroupMemoryExplicitLayoutKHR", + "value" : 4428, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_workgroup_memory_explicit_layout" ], + "version" : "None" + }, + { + "enumerant" : "WorkgroupMemoryExplicitLayout8BitAccessKHR", + "value" : 4429, + "capabilities" : [ "WorkgroupMemoryExplicitLayoutKHR" ], + "extensions" : [ "SPV_KHR_workgroup_memory_explicit_layout" ], + "version" : "None" + }, + { + "enumerant" : "WorkgroupMemoryExplicitLayout16BitAccessKHR", + "value" : 4430, + "capabilities" : [ "WorkgroupMemoryExplicitLayoutKHR" ], + "extensions" : [ "SPV_KHR_workgroup_memory_explicit_layout" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupVoteKHR", + "value" : 4431, + "extensions" : [ "SPV_KHR_subgroup_vote" ], + "version" : "None" + }, + { + "enumerant" : "StorageBuffer16BitAccess", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "StorageUniformBufferBlock16", + "value" : 4433, + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "UniformAndStorageBuffer16BitAccess", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "StorageUniform16", + "value" : 4434, + "capabilities" : [ + "StorageBuffer16BitAccess", + "StorageUniformBufferBlock16" + ], + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "StoragePushConstant16", + "value" : 4435, + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "StorageInputOutput16", + "value" : 4436, + "extensions" : [ "SPV_KHR_16bit_storage" ], + "version" : "1.3" + }, + { + "enumerant" : "DeviceGroup", + "value" : 4437, + "extensions" : [ "SPV_KHR_device_group" ], + "version" : "1.3" + }, + { + "enumerant" : "MultiView", + "value" : 4439, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_multiview" ], + "version" : "1.3" + }, + { + "enumerant" : "VariablePointersStorageBuffer", + "value" : 4441, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_variable_pointers" ], + "version" : "1.3" + }, + { + "enumerant" : "VariablePointers", + "value" : 4442, + "capabilities" : [ "VariablePointersStorageBuffer" ], + "extensions" : [ "SPV_KHR_variable_pointers" ], + "version" : "1.3" + }, + { + "enumerant" : "AtomicStorageOps", + "value" : 4445, + "extensions" : [ "SPV_KHR_shader_atomic_counter_ops" ], + "version" : "None" + }, + { + "enumerant" : "SampleMaskPostDepthCoverage", + "value" : 4447, + "extensions" : [ "SPV_KHR_post_depth_coverage" ], + "version" : "None" + }, + { + "enumerant" : "StorageBuffer8BitAccess", + "value" : 4448, + "extensions" : [ "SPV_KHR_8bit_storage" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformAndStorageBuffer8BitAccess", + "value" : 4449, + "capabilities" : [ "StorageBuffer8BitAccess" ], + "extensions" : [ "SPV_KHR_8bit_storage" ], + "version" : "1.5" + }, + { + "enumerant" : "StoragePushConstant8", + "value" : 4450, + "extensions" : [ "SPV_KHR_8bit_storage" ], + "version" : "1.5" + }, + { + "enumerant" : "DenormPreserve", + "value" : 4464, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "DenormFlushToZero", + "value" : 4465, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "SignedZeroInfNanPreserve", + "value" : 4466, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "RoundingModeRTE", + "value" : 4467, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "RoundingModeRTZ", + "value" : 4468, + "extensions" : [ "SPV_KHR_float_controls" ], + "version" : "1.4" + }, + { + "enumerant" : "RayQueryProvisionalKHR", + "value" : 4471, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryKHR", + "value" : 4472, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_query" ], + "version" : "None" + }, + { + "enumerant" : "RayTraversalPrimitiveCullingKHR", + "value" : 4478, + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "extensions" : [ "SPV_KHR_ray_query","SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingKHR", + "value" : 4479, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "TextureSampleWeightedQCOM", + "value" : 4484, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "TextureBoxFilterQCOM", + "value" : 4485, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "TextureBlockMatchQCOM", + "value" : 4486, + "extensions" : [ "SPV_QCOM_image_processing" ], + "version" : "None" + }, + { + "enumerant" : "TextureBlockMatch2QCOM", + "value" : 4498, + "extensions" : [ "SPV_QCOM_image_processing2" ], + "version" : "None" + }, + { + "enumerant" : "Float16ImageAMD", + "value" : 5008, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_gpu_shader_half_float_fetch" ], + "version" : "None" + }, + { + "enumerant" : "ImageGatherBiasLodAMD", + "value" : 5009, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_texture_gather_bias_lod" ], + "version" : "None" + }, + { + "enumerant" : "FragmentMaskAMD", + "value" : 5010, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_fragment_mask" ], + "version" : "None" + }, + { + "enumerant" : "StencilExportEXT", + "value" : 5013, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_stencil_export" ], + "version" : "None" + }, + { + "enumerant" : "ImageReadWriteLodAMD", + "value" : 5015, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMD_shader_image_load_store_lod" ], + "version" : "None" + }, + { + "enumerant" : "Int64ImageEXT", + "value" : 5016, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_shader_image_int64" ], + "version" : "None" + }, + { + "enumerant" : "ShaderClockKHR", + "value" : 5055, + "extensions" : [ "SPV_KHR_shader_clock" ], + "version" : "None" + }, + { + "enumerant" : "ShaderEnqueueAMDX", + "value" : 5067, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_AMDX_shader_enqueue" ], + "version" : "None" + }, + { + "enumerant" : "QuadControlKHR", + "value" : 5087, + "extensions" : [ "SPV_KHR_quad_control" ], + "version" : "None" + }, + { + "enumerant" : "SampleMaskOverrideCoverageNV", + "value" : 5249, + "capabilities" : [ "SampleRateShading" ], + "extensions" : [ "SPV_NV_sample_mask_override_coverage" ], + "version" : "None" + }, + { + "enumerant" : "GeometryShaderPassthroughNV", + "value" : 5251, + "capabilities" : [ "Geometry" ], + "extensions" : [ "SPV_NV_geometry_shader_passthrough" ], + "version" : "None" + }, + { + "enumerant" : "ShaderViewportIndexLayerEXT", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_EXT_shader_viewport_index_layer" ], + "version" : "None" + }, + { + "enumerant" : "ShaderViewportIndexLayerNV", + "value" : 5254, + "capabilities" : [ "MultiViewport" ], + "extensions" : [ "SPV_NV_viewport_array2" ], + "version" : "None" + }, + { + "enumerant" : "ShaderViewportMaskNV", + "value" : 5255, + "capabilities" : [ "ShaderViewportIndexLayerNV" ], + "extensions" : [ "SPV_NV_viewport_array2" ], + "version" : "None" + }, + { + "enumerant" : "ShaderStereoViewNV", + "value" : 5259, + "capabilities" : [ "ShaderViewportMaskNV" ], + "extensions" : [ "SPV_NV_stereo_view_rendering" ], + "version" : "None" + }, + { + "enumerant" : "PerViewAttributesNV", + "value" : 5260, + "capabilities" : [ "MultiView" ], + "extensions" : [ "SPV_NVX_multiview_per_view_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FragmentFullyCoveredEXT", + "value" : 5265, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_fully_covered" ], + "version" : "None" + }, + { + "enumerant" : "MeshShadingNV", + "value" : 5266, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "ImageFootprintNV", + "value" : 5282, + "extensions" : [ "SPV_NV_shader_image_footprint" ], + "version" : "None" + }, + { + "enumerant" : "MeshShadingEXT", + "value" : 5283, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "FragmentBarycentricKHR", + "value" : 5284, + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "FragmentBarycentricNV", + "value" : 5284, + "extensions" : [ "SPV_NV_fragment_shader_barycentric", "SPV_KHR_fragment_shader_barycentric" ], + "version" : "None" + }, + { + "enumerant" : "ComputeDerivativeGroupQuadsNV", + "value" : 5288, + "extensions" : [ "SPV_NV_compute_shader_derivatives" ], + "version" : "None" + }, + { + "enumerant" : "FragmentDensityEXT", + "value" : 5291, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_invocation_density", "SPV_NV_shading_rate" ], + "version" : "None" + }, + { + "enumerant" : "ShadingRateNV", + "value" : 5291, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_shading_rate", "SPV_EXT_fragment_invocation_density" ], + "version" : "None" + }, + { + "enumerant" : "GroupNonUniformPartitionedNV", + "value" : 5297, + "extensions" : [ "SPV_NV_shader_subgroup_partitioned" ], + "version" : "None" + }, + { + "enumerant" : "ShaderNonUniform", + "value" : 5301, + "capabilities" : [ "Shader" ], + "version" : "1.5" + }, + { + "enumerant" : "ShaderNonUniformEXT", + "value" : 5301, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "RuntimeDescriptorArray", + "value" : 5302, + "capabilities" : [ "Shader" ], + "version" : "1.5" + }, + { + "enumerant" : "RuntimeDescriptorArrayEXT", + "value" : 5302, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "InputAttachmentArrayDynamicIndexing", + "value" : 5303, + "capabilities" : [ "InputAttachment" ], + "version" : "1.5" + }, + { + "enumerant" : "InputAttachmentArrayDynamicIndexingEXT", + "value" : 5303, + "capabilities" : [ "InputAttachment" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformTexelBufferArrayDynamicIndexing", + "value" : 5304, + "capabilities" : [ "SampledBuffer" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformTexelBufferArrayDynamicIndexingEXT", + "value" : 5304, + "capabilities" : [ "SampledBuffer" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageTexelBufferArrayDynamicIndexing", + "value" : 5305, + "capabilities" : [ "ImageBuffer" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageTexelBufferArrayDynamicIndexingEXT", + "value" : 5305, + "capabilities" : [ "ImageBuffer" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformBufferArrayNonUniformIndexing", + "value" : 5306, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformBufferArrayNonUniformIndexingEXT", + "value" : 5306, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "SampledImageArrayNonUniformIndexing", + "value" : 5307, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "SampledImageArrayNonUniformIndexingEXT", + "value" : 5307, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageBufferArrayNonUniformIndexing", + "value" : 5308, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageBufferArrayNonUniformIndexingEXT", + "value" : 5308, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageImageArrayNonUniformIndexing", + "value" : 5309, + "capabilities" : [ "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageImageArrayNonUniformIndexingEXT", + "value" : 5309, + "capabilities" : [ "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "InputAttachmentArrayNonUniformIndexing", + "value" : 5310, + "capabilities" : [ "InputAttachment", "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "InputAttachmentArrayNonUniformIndexingEXT", + "value" : 5310, + "capabilities" : [ "InputAttachment", "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformTexelBufferArrayNonUniformIndexing", + "value" : 5311, + "capabilities" : [ "SampledBuffer", "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "UniformTexelBufferArrayNonUniformIndexingEXT", + "value" : 5311, + "capabilities" : [ "SampledBuffer", "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageTexelBufferArrayNonUniformIndexing", + "value" : 5312, + "capabilities" : [ "ImageBuffer", "ShaderNonUniform" ], + "version" : "1.5" + }, + { + "enumerant" : "StorageTexelBufferArrayNonUniformIndexingEXT", + "value" : 5312, + "capabilities" : [ "ImageBuffer", "ShaderNonUniform" ], + "extensions" : [ "SPV_EXT_descriptor_indexing" ], + "version" : "1.5" + }, + { + "enumerant" : "RayTracingPositionFetchKHR", + "value" : 5336, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_tracing_position_fetch" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingNV", + "value" : 5340, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingMotionBlurNV", + "value" : 5341, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, + { + "enumerant" : "VulkanMemoryModel", + "value" : 5345, + "version" : "1.5" + }, + { + "enumerant" : "VulkanMemoryModelKHR", + "value" : 5345, + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "VulkanMemoryModelDeviceScope", + "value" : 5346, + "version" : "1.5" + }, + { + "enumerant" : "VulkanMemoryModelDeviceScopeKHR", + "value" : 5346, + "extensions" : [ "SPV_KHR_vulkan_memory_model" ], + "version" : "1.5" + }, + { + "enumerant" : "PhysicalStorageBufferAddresses", + "value" : 5347, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer", "SPV_KHR_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "PhysicalStorageBufferAddressesEXT", + "value" : 5347, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_physical_storage_buffer" ], + "version" : "1.5" + }, + { + "enumerant" : "ComputeDerivativeGroupLinearNV", + "value" : 5350, + "extensions" : [ "SPV_NV_compute_shader_derivatives" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingProvisionalKHR", + "value" : 5353, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "CooperativeMatrixNV", + "value" : 5357, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_cooperative_matrix" ], + "version" : "None" + }, + { + "enumerant" : "FragmentShaderSampleInterlockEXT", + "value" : 5363, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "FragmentShaderShadingRateInterlockEXT", + "value" : 5372, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "ShaderSMBuiltinsNV", + "value" : 5373, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_shader_sm_builtins" ], + "version" : "None" + }, + { + "enumerant" : "FragmentShaderPixelInterlockEXT", + "value" : 5378, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_fragment_shader_interlock" ], + "version" : "None" + }, + { + "enumerant" : "DemoteToHelperInvocation", + "value" : 5379, + "capabilities" : [ "Shader" ], + "version" : "1.6" + }, + { + "enumerant" : "DemoteToHelperInvocationEXT", + "value" : 5379, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_EXT_demote_to_helper_invocation" ], + "version" : "1.6" + }, + { + "enumerant" : "DisplacementMicromapNV", + "value" : 5380, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_displacement_micromap" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingOpacityMicromapEXT", + "value" : 5381, + "capabilities" : [ "RayQueryKHR","RayTracingKHR" ], + "extensions" : [ "SPV_EXT_opacity_micromap" ], + "version" : "None" + }, + { + "enumerant" : "ShaderInvocationReorderNV", + "value" : 5383, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_NV_shader_invocation_reorder" ], + "version" : "None" + }, + { + "enumerant" : "BindlessTextureNV", + "value" : 5390, + "extensions" : [ "SPV_NV_bindless_texture" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryPositionFetchKHR", + "value" : 5391, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_KHR_ray_tracing_position_fetch" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat16VectorNV", + "value" : 5404, + "extensions" : [ "SPV_NV_shader_atomic_fp16_vector" ], + "version" : "None" + }, + { + "enumerant" : "RayTracingDisplacementMicromapNV", + "value" : 5409, + "capabilities" : [ "RayTracingKHR" ], + "extensions" : [ "SPV_NV_displacement_micromap" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupShuffleINTEL", + "value" : 5568, + "extensions" : [ "SPV_INTEL_subgroups" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupBufferBlockIOINTEL", + "value" : 5569, + "extensions" : [ "SPV_INTEL_subgroups" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupImageBlockIOINTEL", + "value" : 5570, + "extensions" : [ "SPV_INTEL_subgroups" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupImageMediaBlockIOINTEL", + "value" : 5579, + "extensions" : [ "SPV_INTEL_media_block_io" ], + "version" : "None" + }, + { + "enumerant" : "RoundToInfinityINTEL", + "value" : 5582, + "extensions" : [ "SPV_INTEL_float_controls2" ], + "version" : "None" + }, + { + "enumerant" : "FloatingPointModeINTEL", + "value" : 5583, + "extensions" : [ "SPV_INTEL_float_controls2" ], + "version" : "None" + }, + { + "enumerant" : "IntegerFunctions2INTEL", + "value" : 5584, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_INTEL_shader_integer_functions2" ], + "version" : "None" + }, + { + "enumerant" : "FunctionPointersINTEL", + "value" : 5603, + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "enumerant" : "IndirectReferencesINTEL", + "value" : 5604, + "extensions" : [ "SPV_INTEL_function_pointers" ], + "version" : "None" + }, + { + "enumerant" : "AsmINTEL", + "value" : 5606, + "extensions" : [ "SPV_INTEL_inline_assembly" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat32MinMaxEXT", + "value" : 5612, + "extensions" : [ "SPV_EXT_shader_atomic_float_min_max" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat64MinMaxEXT", + "value" : 5613, + "extensions" : [ "SPV_EXT_shader_atomic_float_min_max" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat16MinMaxEXT", + "value" : 5616, + "extensions" : [ "SPV_EXT_shader_atomic_float_min_max" ], + "version" : "None" + }, + { + "enumerant" : "VectorComputeINTEL", + "value" : 5617, + "capabilities" : [ "VectorAnyINTEL" ], + "extensions" : [ "SPV_INTEL_vector_compute" ], + "version" : "None" + }, + { + "enumerant" : "VectorAnyINTEL", + "value" : 5619, + "extensions" : [ "SPV_INTEL_vector_compute" ], + "version" : "None" + }, + { + "enumerant" : "ExpectAssumeKHR", + "value" : 5629, + "extensions" : [ "SPV_KHR_expect_assume" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupAvcMotionEstimationINTEL", + "value" : 5696, + "extensions" : [ "SPV_INTEL_device_side_avc_motion_estimation" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupAvcMotionEstimationIntraINTEL", + "value" : 5697, + "extensions" : [ "SPV_INTEL_device_side_avc_motion_estimation" ], + "version" : "None" + }, + { + "enumerant" : "SubgroupAvcMotionEstimationChromaINTEL", + "value" : 5698, + "extensions" : [ "SPV_INTEL_device_side_avc_motion_estimation" ], + "version" : "None" + }, + { + "enumerant" : "VariableLengthArrayINTEL", + "value" : 5817, + "extensions" : [ "SPV_INTEL_variable_length_array" ], + "version" : "None" + }, + { + "enumerant" : "FunctionFloatControlINTEL", + "value" : 5821, + "extensions" : [ "SPV_INTEL_float_controls2" ], + "version" : "None" + }, + { + "enumerant" : "FPGAMemoryAttributesINTEL", + "value" : 5824, + "extensions" : [ "SPV_INTEL_fpga_memory_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPFastMathModeINTEL", + "value" : 5837, + "capabilities" : [ "Kernel" ], + "extensions" : [ "SPV_INTEL_fp_fast_math_mode" ], + "version" : "None" + }, + { + "enumerant" : "ArbitraryPrecisionIntegersINTEL", + "value" : 5844, + "extensions" : [ "SPV_INTEL_arbitrary_precision_integers" ], + "version" : "None" + }, + { + "enumerant" : "ArbitraryPrecisionFloatingPointINTEL", + "value" : 5845, + "extensions" : [ "SPV_INTEL_arbitrary_precision_floating_point" ], + "version" : "None" + }, + { + "enumerant" : "UnstructuredLoopControlsINTEL", + "value" : 5886, + "extensions" : [ "SPV_INTEL_unstructured_loop_controls" ], + "version" : "None" + }, + { + "enumerant" : "FPGALoopControlsINTEL", + "value" : 5888, + "extensions" : [ "SPV_INTEL_fpga_loop_controls" ], + "version" : "None" + }, + { + "enumerant" : "KernelAttributesINTEL", + "value" : 5892, + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPGAKernelAttributesINTEL", + "value" : 5897, + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPGAMemoryAccessesINTEL", + "value" : 5898, + "extensions" : [ "SPV_INTEL_fpga_memory_accesses" ], + "version" : "None" + }, + { + "enumerant" : "FPGAClusterAttributesINTEL", + "value" : 5904, + "extensions" : [ "SPV_INTEL_fpga_cluster_attributes" ], + "version" : "None" + }, + { + "enumerant" : "LoopFuseINTEL", + "value" : 5906, + "extensions" : [ "SPV_INTEL_loop_fuse" ], + "version" : "None" + }, + { + "enumerant" : "FPGADSPControlINTEL", + "value" : 5908, + "extensions" : [ "SPV_INTEL_fpga_dsp_control" ], + "version" : "None" + }, + { + "enumerant" : "MemoryAccessAliasingINTEL", + "value" : 5910, + "extensions" : [ "SPV_INTEL_memory_access_aliasing" ], + "version" : "None" + }, + { + "enumerant" : "FPGAInvocationPipeliningAttributesINTEL", + "value" : 5916, + "extensions" : [ "SPV_INTEL_fpga_invocation_pipelining_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPGABufferLocationINTEL", + "value" : 5920, + "extensions" : [ "SPV_INTEL_fpga_buffer_location" ], + "version" : "None" + }, + { + "enumerant" : "ArbitraryPrecisionFixedPointINTEL", + "value" : 5922, + "extensions" : [ "SPV_INTEL_arbitrary_precision_fixed_point" ], + "version" : "None" + }, + { + "enumerant" : "USMStorageClassesINTEL", + "value" : 5935, + "extensions" : [ "SPV_INTEL_usm_storage_classes" ], + "version" : "None" + }, + { + "enumerant" : "RuntimeAlignedAttributeINTEL", + "value" : 5939, + "extensions" : [ "SPV_INTEL_runtime_aligned" ], + "version" : "None" + }, + { + "enumerant" : "IOPipesINTEL", + "value" : 5943, + "extensions" : [ "SPV_INTEL_io_pipes" ], + "version" : "None" + }, + { + "enumerant" : "BlockingPipesINTEL", + "value" : 5945, + "extensions" : [ "SPV_INTEL_blocking_pipes" ], + "version" : "None" + }, + { + "enumerant" : "FPGARegINTEL", + "value" : 5948, + "extensions" : [ "SPV_INTEL_fpga_reg" ], + "version" : "None" + }, + { + "enumerant" : "DotProductInputAll", + "value" : 6016, + "version" : "1.6" + }, + { + "enumerant" : "DotProductInputAllKHR", + "value" : 6016, + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "enumerant" : "DotProductInput4x8Bit", + "value" : 6017, + "capabilities" : [ "Int8" ], + "version" : "1.6" + }, + { + "enumerant" : "DotProductInput4x8BitKHR", + "value" : 6017, + "capabilities" : [ "Int8" ], + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "enumerant" : "DotProductInput4x8BitPacked", + "value" : 6018, + "version" : "1.6" + }, + { + "enumerant" : "DotProductInput4x8BitPackedKHR", + "value" : 6018, + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "enumerant" : "DotProduct", + "value" : 6019, + "version" : "1.6" + }, + { + "enumerant" : "DotProductKHR", + "value" : 6019, + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + }, + { + "enumerant" : "RayCullMaskKHR", + "value" : 6020, + "extensions" : [ "SPV_KHR_ray_cull_mask" ], + "version" : "None" + }, + { + "enumerant" : "CooperativeMatrixKHR", + "value" : 6022, + "extensions" : [ "SPV_KHR_cooperative_matrix" ], + "version" : "None" + }, + { + "enumerant" : "BitInstructions", + "value" : 6025, + "extensions" : [ "SPV_KHR_bit_instructions" ], + "version" : "None" + }, + { + "enumerant" : "GroupNonUniformRotateKHR", + "value" : 6026, + "capabilities" : [ "GroupNonUniform" ], + "extensions" : [ "SPV_KHR_subgroup_rotate" ], + "version" : "None" + }, + { + "enumerant" : "FloatControls2", + "value" : 6029, + "extensions" : [ "SPV_KHR_float_controls2" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat32AddEXT", + "value" : 6033, + "extensions" : [ "SPV_EXT_shader_atomic_float_add" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat64AddEXT", + "value" : 6034, + "extensions" : [ "SPV_EXT_shader_atomic_float_add" ], + "version" : "None" + }, + { + "enumerant" : "LongCompositesINTEL", + "value" : 6089, + "extensions" : [ "SPV_INTEL_long_composites" ], + "version" : "None" + }, + { + "enumerant" : "OptNoneINTEL", + "value" : 6094, + "extensions" : [ "SPV_INTEL_optnone" ], + "version" : "None" + }, + { + "enumerant" : "AtomicFloat16AddEXT", + "value" : 6095, + "extensions" : [ "SPV_EXT_shader_atomic_float16_add" ], + "version" : "None" + }, + { + "enumerant" : "DebugInfoModuleINTEL", + "value" : 6114, + "extensions" : [ "SPV_INTEL_debug_module" ], + "version" : "None" + }, + { + "enumerant" : "BFloat16ConversionINTEL", + "value" : 6115, + "extensions" : [ "SPV_INTEL_bfloat16_conversion" ], + "version" : "None" + }, + { + "enumerant" : "SplitBarrierINTEL", + "value" : 6141, + "extensions" : [ "SPV_INTEL_split_barrier" ], + "version" : "None" + }, + { + "enumerant" : "FPGAClusterAttributesV2INTEL", + "value" : 6150, + "capabilities" : [ "FPGAClusterAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_fpga_cluster_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPGAKernelAttributesv2INTEL", + "value" : 6161, + "capabilities" : [ "FPGAKernelAttributesINTEL" ], + "extensions" : [ "SPV_INTEL_kernel_attributes" ], + "version" : "None" + }, + { + "enumerant" : "FPMaxErrorINTEL", + "value" : 6169, + "extensions" : [ "SPV_INTEL_fp_max_error" ], + "version" : "None" + }, + { + "enumerant" : "FPGALatencyControlINTEL", + "value" : 6171, + "extensions" : [ "SPV_INTEL_fpga_latency_control" ], + "version" : "None" + }, + { + "enumerant" : "FPGAArgumentInterfacesINTEL", + "value" : 6174, + "extensions" : [ "SPV_INTEL_fpga_argument_interfaces" ], + "version" : "None" + }, + { + "enumerant" : "GlobalVariableHostAccessINTEL", + "value" : 6187, + "extensions": [ "SPV_INTEL_global_variable_host_access" ], + "version" : "None" + }, + { + "enumerant" : "GlobalVariableFPGADecorationsINTEL", + "value" : 6189, + "extensions": [ "SPV_INTEL_global_variable_fpga_decorations" ], + "version" : "None" + }, + { + "enumerant" : "GroupUniformArithmeticKHR", + "value" : 6400, + "extensions" : [ "SPV_KHR_uniform_group_instructions"], + "version" : "None" + }, + { + "enumerant" : "MaskedGatherScatterINTEL", + "value" : 6427, + "extensions" : [ "SPV_INTEL_masked_gather_scatter"], + "version" : "None" + }, + { + "enumerant" : "CacheControlsINTEL", + "value" : 6441, + "extensions" : [ "SPV_INTEL_cache_controls" ], + "version" : "None" + }, + { + "enumerant" : "RegisterLimitsINTEL", + "value" : 6460, + "extensions" : [ "SPV_INTEL_maximum_registers" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "RayQueryIntersection", + "enumerants" : [ + { + "enumerant" : "RayQueryCandidateIntersectionKHR", + "value" : 0, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryCommittedIntersectionKHR", + "value" : 1, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "RayQueryCommittedIntersectionType", + "enumerants" : [ + { + "enumerant" : "RayQueryCommittedIntersectionNoneKHR", + "value" : 0, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryCommittedIntersectionTriangleKHR", + "value" : 1, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryCommittedIntersectionGeneratedKHR", + "value" : 2, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "RayQueryCandidateIntersectionType", + "enumerants" : [ + { + "enumerant" : "RayQueryCandidateIntersectionTriangleKHR", + "value" : 0, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayQueryCandidateIntersectionAABBKHR", + "value" : 1, + "capabilities" : [ "RayQueryKHR" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "PackedVectorFormat", + "enumerants" : [ + { + "enumerant" : "PackedVectorFormat4x8Bit", + "value" : 0, + "version" : "1.6" + }, + { + "enumerant" : "PackedVectorFormat4x8BitKHR", + "value" : 0, + "extensions" : [ "SPV_KHR_integer_dot_product" ], + "version" : "1.6" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "CooperativeMatrixOperands", + "enumerants" : [ + { + "enumerant" : "NoneKHR", + "value" : "0x0000", + "version" : "None" + }, + { + "enumerant" : "MatrixASignedComponentsKHR", + "value" : "0x0001", + "version" : "None" + }, + { + "enumerant" : "MatrixBSignedComponentsKHR", + "value" : "0x0002", + "version" : "None" + }, + { + "enumerant" : "MatrixCSignedComponentsKHR", + "value" : "0x0004", + "version" : "None" + }, + { + "enumerant" : "MatrixResultSignedComponentsKHR", + "value" : "0x0008", + "version" : "None" + }, + { + "enumerant" : "SaturatingAccumulationKHR", + "value" : "0x0010", + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "CooperativeMatrixLayout", + "enumerants" : [ + { + "enumerant" : "RowMajorKHR", + "value" : 0, + "version" : "None" + }, + { + "enumerant" : "ColumnMajorKHR", + "value" : 1, + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "CooperativeMatrixUse", + "enumerants" : [ + { + "enumerant" : "MatrixAKHR", + "value" : 0, + "version" : "None" + }, + { + "enumerant" : "MatrixBKHR", + "value" : 1, + "version" : "None" + }, + { + "enumerant" : "MatrixAccumulatorKHR", + "value" : 2, + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "InitializationModeQualifier", + "enumerants" : [ + { + "enumerant" : "InitOnDeviceReprogramINTEL", + "value" : 0, + "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "InitOnDeviceResetINTEL", + "value" : 1, + "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "LoadCacheControl", + "enumerants" : [ + { + "enumerant" : "UncachedINTEL", + "value" : 0, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "CachedINTEL", + "value" : 1, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StreamingINTEL", + "value" : 2, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "InvalidateAfterReadINTEL", + "value" : 3, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "ConstCachedINTEL", + "value" : 4, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "StoreCacheControl", + "enumerants" : [ + { + "enumerant" : "UncachedINTEL", + "value" : 0, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "WriteThroughINTEL", + "value" : 1, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "WriteBackINTEL", + "value" : 2, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "StreamingINTEL", + "value" : 3, + "capabilities" : [ "CacheControlsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "NamedMaximumNumberOfRegisters", + "enumerants" : [ + { + "enumerant" : "AutoINTEL", + "value" : 0, + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + } + ] + }, + { + "category" : "Id", + "kind" : "IdResultType", + "doc" : "Reference to an representing the result's type of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdResult", + "doc" : "Definition of an representing the result of the enclosing instruction" + }, + { + "category" : "Id", + "kind" : "IdMemorySemantics", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the MemorySemantics operand kind" + }, + { + "category" : "Id", + "kind" : "IdScope", + "doc" : "Reference to an representing a 32-bit integer that is a mask from the Scope operand kind" + }, + { + "category" : "Id", + "kind" : "IdRef", + "doc" : "Reference to an " + }, + { + "category" : "Literal", + "kind" : "LiteralInteger", + "doc" : "An integer consuming one or more words" + }, + { + "category" : "Literal", + "kind" : "LiteralString", + "doc" : "A null-terminated stream of characters consuming an integral number of words" + }, + { + "category" : "Literal", + "kind" : "LiteralFloat", + "doc" : "A float consuming one word" + }, + { + "category" : "Literal", + "kind" : "LiteralContextDependentNumber", + "doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction" + }, + { + "category" : "Literal", + "kind" : "LiteralExtInstInteger", + "doc" : "A 32-bit unsigned integer indicating which instruction to use and determining the layout of following operands (for OpExtInst)" + }, + { + "category" : "Literal", + "kind" : "LiteralSpecConstantOpInteger", + "doc" : "An opcode indicating the operation to be performed and determining the layout of following operands (for OpSpecConstantOp)" + }, + { + "category" : "Composite", + "kind" : "PairLiteralIntegerIdRef", + "bases" : [ "LiteralInteger", "IdRef" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefLiteralInteger", + "bases" : [ "IdRef", "LiteralInteger" ] + }, + { + "category" : "Composite", + "kind" : "PairIdRefIdRef", + "bases" : [ "IdRef", "IdRef" ] + } + ] +} diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.cs b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.cs new file mode 100644 index 000000000000..a91f4ff448a1 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.cs @@ -0,0 +1,2148 @@ +// Copyright (c) 2014-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +namespace Spv +{ + + public static class Specification + { + public const uint MagicNumber = 0x07230203; + public const uint Version = 0x00010600; + public const uint Revision = 1; + public const uint OpCodeMask = 0xffff; + public const uint WordCountShift = 16; + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + NodeOutputPayloadAMDX = 5076, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + } + + public enum ImageOperandsShift + { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + } + + public enum ImageOperandsMask + { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, + } + + public enum FPFastMathModeShift + { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + } + + public enum FPFastMathModeMask + { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + LinkOnceODR = 2, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + CoalescedInputCountAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + } + + public enum SelectionControlShift + { + Flatten = 0, + DontFlatten = 1, + } + + public enum SelectionControlMask + { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + } + + public enum LoopControlShift + { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + } + + public enum LoopControlMask + { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, + } + + public enum FunctionControlShift + { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, + } + + public enum FunctionControlMask + { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, + } + + public enum MemorySemanticsShift + { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + } + + public enum MemorySemanticsMask + { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, + } + + public enum MemoryAccessShift + { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + } + + public enum MemoryAccessMask + { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum KernelProfilingInfoShift + { + CmdExecTime = 0, + } + + public enum KernelProfilingInfoMask + { + MaskNone = 0, + CmdExecTime = 0x00000001, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + } + + public enum RayFlagsShift + { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + } + + public enum RayFlagsMask + { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, + } + + public enum RayQueryIntersection + { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + } + + public enum RayQueryCommittedIntersectionType + { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + } + + public enum RayQueryCandidateIntersectionType + { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + } + + public enum FragmentShadingRateShift + { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + } + + public enum FragmentShadingRateMask + { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, + } + + public enum FPDenormMode + { + Preserve = 0, + FlushToZero = 1, + } + + public enum FPOperationMode + { + IEEE = 0, + ALT = 1, + } + + public enum QuantizationModes + { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + } + + public enum OverflowModes + { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + } + + public enum PackedVectorFormat + { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + } + + public enum CooperativeMatrixOperandsShift + { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + } + + public enum CooperativeMatrixOperandsMask + { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, + } + + public enum CooperativeMatrixLayout + { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + } + + public enum CooperativeMatrixUse + { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + } + + public enum InitializationModeQualifier + { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + } + + public enum HostAccessQualifier + { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + } + + public enum LoadCacheControl + { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + } + + public enum StoreCacheControl + { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + } + + public enum NamedMaximumNumberOfRegisters + { + AutoINTEL = 0, + } + + public enum Op + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + } + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.h b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.h new file mode 100644 index 000000000000..9276b301b850 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.h @@ -0,0 +1,2879 @@ +/* +** Copyright (c) 2014-2024 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python, C#, D, Beef +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** - C# will use enum classes in the Specification class located in the "Spv" namespace, +** e.g.: Spv.Specification.SourceLanguage.GLSL +** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +** - Beef will use enum classes in the Specification class located in the "Spv" namespace, +** e.g.: Spv.Specification.SourceLanguage.GLSL +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010600; +static const unsigned int SpvRevision = 1; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageCPP_for_OpenCL = 6, + SpvSourceLanguageSYCL = 7, + SpvSourceLanguageHERO_C = 8, + SpvSourceLanguageNZSL = 9, + SpvSourceLanguageWGSL = 10, + SpvSourceLanguageSlang = 11, + SpvSourceLanguageZig = 12, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelTaskNV = 5267, + SpvExecutionModelMeshNV = 5268, + SpvExecutionModelRayGenerationKHR = 5313, + SpvExecutionModelRayGenerationNV = 5313, + SpvExecutionModelIntersectionKHR = 5314, + SpvExecutionModelIntersectionNV = 5314, + SpvExecutionModelAnyHitKHR = 5315, + SpvExecutionModelAnyHitNV = 5315, + SpvExecutionModelClosestHitKHR = 5316, + SpvExecutionModelClosestHitNV = 5316, + SpvExecutionModelMissKHR = 5317, + SpvExecutionModelMissNV = 5317, + SpvExecutionModelCallableKHR = 5318, + SpvExecutionModelCallableNV = 5318, + SpvExecutionModelTaskEXT = 5364, + SpvExecutionModelMeshEXT = 5365, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelPhysicalStorageBuffer64 = 5348, + SpvAddressingModelPhysicalStorageBuffer64EXT = 5348, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelVulkan = 3, + SpvMemoryModelVulkanKHR = 3, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModeInitializer = 33, + SpvExecutionModeFinalizer = 34, + SpvExecutionModeSubgroupSize = 35, + SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModeSubgroupsPerWorkgroupId = 37, + SpvExecutionModeLocalSizeId = 38, + SpvExecutionModeLocalSizeHintId = 39, + SpvExecutionModeNonCoherentColorAttachmentReadEXT = 4169, + SpvExecutionModeNonCoherentDepthAttachmentReadEXT = 4170, + SpvExecutionModeNonCoherentStencilAttachmentReadEXT = 4171, + SpvExecutionModeSubgroupUniformControlFlowKHR = 4421, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeDenormPreserve = 4459, + SpvExecutionModeDenormFlushToZero = 4460, + SpvExecutionModeSignedZeroInfNanPreserve = 4461, + SpvExecutionModeRoundingModeRTE = 4462, + SpvExecutionModeRoundingModeRTZ = 4463, + SpvExecutionModeEarlyAndLateFragmentTestsAMD = 5017, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeCoalescingAMDX = 5069, + SpvExecutionModeMaxNodeRecursionAMDX = 5071, + SpvExecutionModeStaticNumWorkgroupsAMDX = 5072, + SpvExecutionModeShaderIndexAMDX = 5073, + SpvExecutionModeMaxNumWorkgroupsAMDX = 5077, + SpvExecutionModeStencilRefUnchangedFrontAMD = 5079, + SpvExecutionModeStencilRefGreaterFrontAMD = 5080, + SpvExecutionModeStencilRefLessFrontAMD = 5081, + SpvExecutionModeStencilRefUnchangedBackAMD = 5082, + SpvExecutionModeStencilRefGreaterBackAMD = 5083, + SpvExecutionModeStencilRefLessBackAMD = 5084, + SpvExecutionModeQuadDerivativesKHR = 5088, + SpvExecutionModeRequireFullQuadsKHR = 5089, + SpvExecutionModeOutputLinesEXT = 5269, + SpvExecutionModeOutputLinesNV = 5269, + SpvExecutionModeOutputPrimitivesEXT = 5270, + SpvExecutionModeOutputPrimitivesNV = 5270, + SpvExecutionModeDerivativeGroupQuadsNV = 5289, + SpvExecutionModeDerivativeGroupLinearNV = 5290, + SpvExecutionModeOutputTrianglesEXT = 5298, + SpvExecutionModeOutputTrianglesNV = 5298, + SpvExecutionModePixelInterlockOrderedEXT = 5366, + SpvExecutionModePixelInterlockUnorderedEXT = 5367, + SpvExecutionModeSampleInterlockOrderedEXT = 5368, + SpvExecutionModeSampleInterlockUnorderedEXT = 5369, + SpvExecutionModeShadingRateInterlockOrderedEXT = 5370, + SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371, + SpvExecutionModeSharedLocalMemorySizeINTEL = 5618, + SpvExecutionModeRoundingModeRTPINTEL = 5620, + SpvExecutionModeRoundingModeRTNINTEL = 5621, + SpvExecutionModeFloatingPointModeALTINTEL = 5622, + SpvExecutionModeFloatingPointModeIEEEINTEL = 5623, + SpvExecutionModeMaxWorkgroupSizeINTEL = 5893, + SpvExecutionModeMaxWorkDimINTEL = 5894, + SpvExecutionModeNoGlobalOffsetINTEL = 5895, + SpvExecutionModeNumSIMDWorkitemsINTEL = 5896, + SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + SpvExecutionModeMaximallyReconvergesKHR = 6023, + SpvExecutionModeFPFastMathDefault = 6028, + SpvExecutionModeStreamingInterfaceINTEL = 6154, + SpvExecutionModeRegisterMapInterfaceINTEL = 6160, + SpvExecutionModeNamedBarrierCountINTEL = 6417, + SpvExecutionModeMaximumRegistersINTEL = 6461, + SpvExecutionModeMaximumRegistersIdINTEL = 6462, + SpvExecutionModeNamedMaximumRegistersINTEL = 6463, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassTileImageEXT = 4172, + SpvStorageClassNodePayloadAMDX = 5068, + SpvStorageClassNodeOutputPayloadAMDX = 5076, + SpvStorageClassCallableDataKHR = 5328, + SpvStorageClassCallableDataNV = 5328, + SpvStorageClassIncomingCallableDataKHR = 5329, + SpvStorageClassIncomingCallableDataNV = 5329, + SpvStorageClassRayPayloadKHR = 5338, + SpvStorageClassRayPayloadNV = 5338, + SpvStorageClassHitAttributeKHR = 5339, + SpvStorageClassHitAttributeNV = 5339, + SpvStorageClassIncomingRayPayloadKHR = 5342, + SpvStorageClassIncomingRayPayloadNV = 5342, + SpvStorageClassShaderRecordBufferKHR = 5343, + SpvStorageClassShaderRecordBufferNV = 5343, + SpvStorageClassPhysicalStorageBuffer = 5349, + SpvStorageClassPhysicalStorageBufferEXT = 5349, + SpvStorageClassHitObjectAttributeNV = 5385, + SpvStorageClassTaskPayloadWorkgroupEXT = 5402, + SpvStorageClassCodeSectionINTEL = 5605, + SpvStorageClassDeviceOnlyINTEL = 5936, + SpvStorageClassHostOnlyINTEL = 5937, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimTileImageDataEXT = 4173, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatR64ui = 40, + SpvImageFormatR64i = 41, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeUnsignedIntRaw10EXT = 19, + SpvImageChannelDataTypeUnsignedIntRaw12EXT = 20, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMakeTexelAvailableShift = 8, + SpvImageOperandsMakeTexelAvailableKHRShift = 8, + SpvImageOperandsMakeTexelVisibleShift = 9, + SpvImageOperandsMakeTexelVisibleKHRShift = 9, + SpvImageOperandsNonPrivateTexelShift = 10, + SpvImageOperandsNonPrivateTexelKHRShift = 10, + SpvImageOperandsVolatileTexelShift = 11, + SpvImageOperandsVolatileTexelKHRShift = 11, + SpvImageOperandsSignExtendShift = 12, + SpvImageOperandsZeroExtendShift = 13, + SpvImageOperandsNontemporalShift = 14, + SpvImageOperandsOffsetsShift = 16, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, + SpvImageOperandsMakeTexelAvailableMask = 0x00000100, + SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + SpvImageOperandsMakeTexelVisibleMask = 0x00000200, + SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + SpvImageOperandsNonPrivateTexelMask = 0x00000400, + SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400, + SpvImageOperandsVolatileTexelMask = 0x00000800, + SpvImageOperandsVolatileTexelKHRMask = 0x00000800, + SpvImageOperandsSignExtendMask = 0x00001000, + SpvImageOperandsZeroExtendMask = 0x00002000, + SpvImageOperandsNontemporalMask = 0x00004000, + SpvImageOperandsOffsetsMask = 0x00010000, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeAllowContractShift = 16, + SpvFPFastMathModeAllowContractFastINTELShift = 16, + SpvFPFastMathModeAllowReassocShift = 17, + SpvFPFastMathModeAllowReassocINTELShift = 17, + SpvFPFastMathModeAllowTransformShift = 18, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, + SpvFPFastMathModeAllowContractMask = 0x00010000, + SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000, + SpvFPFastMathModeAllowReassocMask = 0x00020000, + SpvFPFastMathModeAllowReassocINTELMask = 0x00020000, + SpvFPFastMathModeAllowTransformMask = 0x00040000, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeLinkOnceODR = 2, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeRuntimeAlignedINTEL = 5940, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationUniformId = 27, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationMaxByteOffset = 45, + SpvDecorationAlignmentId = 46, + SpvDecorationMaxByteOffsetId = 47, + SpvDecorationNoSignedWrap = 4469, + SpvDecorationNoUnsignedWrap = 4470, + SpvDecorationWeightTextureQCOM = 4487, + SpvDecorationBlockMatchTextureQCOM = 4488, + SpvDecorationBlockMatchSamplerQCOM = 4499, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationNodeSharesPayloadLimitsWithAMDX = 5019, + SpvDecorationNodeMaxPayloadsAMDX = 5020, + SpvDecorationTrackFinishWritingAMDX = 5078, + SpvDecorationPayloadNodeNameAMDX = 5091, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationPerPrimitiveEXT = 5271, + SpvDecorationPerPrimitiveNV = 5271, + SpvDecorationPerViewNV = 5272, + SpvDecorationPerTaskNV = 5273, + SpvDecorationPerVertexKHR = 5285, + SpvDecorationPerVertexNV = 5285, + SpvDecorationNonUniform = 5300, + SpvDecorationNonUniformEXT = 5300, + SpvDecorationRestrictPointer = 5355, + SpvDecorationRestrictPointerEXT = 5355, + SpvDecorationAliasedPointer = 5356, + SpvDecorationAliasedPointerEXT = 5356, + SpvDecorationHitObjectShaderRecordBufferNV = 5386, + SpvDecorationBindlessSamplerNV = 5398, + SpvDecorationBindlessImageNV = 5399, + SpvDecorationBoundSamplerNV = 5400, + SpvDecorationBoundImageNV = 5401, + SpvDecorationSIMTCallINTEL = 5599, + SpvDecorationReferencedIndirectlyINTEL = 5602, + SpvDecorationClobberINTEL = 5607, + SpvDecorationSideEffectsINTEL = 5608, + SpvDecorationVectorComputeVariableINTEL = 5624, + SpvDecorationFuncParamIOKindINTEL = 5625, + SpvDecorationVectorComputeFunctionINTEL = 5626, + SpvDecorationStackCallINTEL = 5627, + SpvDecorationGlobalVariableOffsetINTEL = 5628, + SpvDecorationCounterBuffer = 5634, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationUserSemantic = 5635, + SpvDecorationUserTypeGOOGLE = 5636, + SpvDecorationFunctionRoundingModeINTEL = 5822, + SpvDecorationFunctionDenormModeINTEL = 5823, + SpvDecorationRegisterINTEL = 5825, + SpvDecorationMemoryINTEL = 5826, + SpvDecorationNumbanksINTEL = 5827, + SpvDecorationBankwidthINTEL = 5828, + SpvDecorationMaxPrivateCopiesINTEL = 5829, + SpvDecorationSinglepumpINTEL = 5830, + SpvDecorationDoublepumpINTEL = 5831, + SpvDecorationMaxReplicatesINTEL = 5832, + SpvDecorationSimpleDualPortINTEL = 5833, + SpvDecorationMergeINTEL = 5834, + SpvDecorationBankBitsINTEL = 5835, + SpvDecorationForcePow2DepthINTEL = 5836, + SpvDecorationStridesizeINTEL = 5883, + SpvDecorationWordsizeINTEL = 5884, + SpvDecorationTrueDualPortINTEL = 5885, + SpvDecorationBurstCoalesceINTEL = 5899, + SpvDecorationCacheSizeINTEL = 5900, + SpvDecorationDontStaticallyCoalesceINTEL = 5901, + SpvDecorationPrefetchINTEL = 5902, + SpvDecorationStallEnableINTEL = 5905, + SpvDecorationFuseLoopsInFunctionINTEL = 5907, + SpvDecorationMathOpDSPModeINTEL = 5909, + SpvDecorationAliasScopeINTEL = 5914, + SpvDecorationNoAliasINTEL = 5915, + SpvDecorationInitiationIntervalINTEL = 5917, + SpvDecorationMaxConcurrencyINTEL = 5918, + SpvDecorationPipelineEnableINTEL = 5919, + SpvDecorationBufferLocationINTEL = 5921, + SpvDecorationIOPipeStorageINTEL = 5944, + SpvDecorationFunctionFloatingPointModeINTEL = 6080, + SpvDecorationSingleElementVectorINTEL = 6085, + SpvDecorationVectorComputeCallableFunctionINTEL = 6087, + SpvDecorationMediaBlockIOINTEL = 6140, + SpvDecorationStallFreeINTEL = 6151, + SpvDecorationFPMaxErrorDecorationINTEL = 6170, + SpvDecorationLatencyControlLabelINTEL = 6172, + SpvDecorationLatencyControlConstraintINTEL = 6173, + SpvDecorationConduitKernelArgumentINTEL = 6175, + SpvDecorationRegisterMapKernelArgumentINTEL = 6176, + SpvDecorationMMHostInterfaceAddressWidthINTEL = 6177, + SpvDecorationMMHostInterfaceDataWidthINTEL = 6178, + SpvDecorationMMHostInterfaceLatencyINTEL = 6179, + SpvDecorationMMHostInterfaceReadWriteModeINTEL = 6180, + SpvDecorationMMHostInterfaceMaxBurstINTEL = 6181, + SpvDecorationMMHostInterfaceWaitRequestINTEL = 6182, + SpvDecorationStableKernelArgumentINTEL = 6183, + SpvDecorationHostAccessINTEL = 6188, + SpvDecorationInitModeINTEL = 6190, + SpvDecorationImplementInRegisterMapINTEL = 6191, + SpvDecorationCacheControlLoadINTEL = 6442, + SpvDecorationCacheControlStoreINTEL = 6443, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInCoreIDARM = 4160, + SpvBuiltInCoreCountARM = 4161, + SpvBuiltInCoreMaxIDARM = 4162, + SpvBuiltInWarpIDARM = 4163, + SpvBuiltInWarpMaxIDARM = 4164, + SpvBuiltInSubgroupEqMask = 4416, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMask = 4417, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMask = 4418, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMask = 4419, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMask = 4420, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInPrimitiveShadingRateKHR = 4432, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInShadingRateKHR = 4444, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInCoalescedInputCountAMDX = 5021, + SpvBuiltInShaderIndexAMDX = 5073, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInFullyCoveredEXT = 5264, + SpvBuiltInTaskCountNV = 5274, + SpvBuiltInPrimitiveCountNV = 5275, + SpvBuiltInPrimitiveIndicesNV = 5276, + SpvBuiltInClipDistancePerViewNV = 5277, + SpvBuiltInCullDistancePerViewNV = 5278, + SpvBuiltInLayerPerViewNV = 5279, + SpvBuiltInMeshViewCountNV = 5280, + SpvBuiltInMeshViewIndicesNV = 5281, + SpvBuiltInBaryCoordKHR = 5286, + SpvBuiltInBaryCoordNV = 5286, + SpvBuiltInBaryCoordNoPerspKHR = 5287, + SpvBuiltInBaryCoordNoPerspNV = 5287, + SpvBuiltInFragSizeEXT = 5292, + SpvBuiltInFragmentSizeNV = 5292, + SpvBuiltInFragInvocationCountEXT = 5293, + SpvBuiltInInvocationsPerPixelNV = 5293, + SpvBuiltInPrimitivePointIndicesEXT = 5294, + SpvBuiltInPrimitiveLineIndicesEXT = 5295, + SpvBuiltInPrimitiveTriangleIndicesEXT = 5296, + SpvBuiltInCullPrimitiveEXT = 5299, + SpvBuiltInLaunchIdKHR = 5319, + SpvBuiltInLaunchIdNV = 5319, + SpvBuiltInLaunchSizeKHR = 5320, + SpvBuiltInLaunchSizeNV = 5320, + SpvBuiltInWorldRayOriginKHR = 5321, + SpvBuiltInWorldRayOriginNV = 5321, + SpvBuiltInWorldRayDirectionKHR = 5322, + SpvBuiltInWorldRayDirectionNV = 5322, + SpvBuiltInObjectRayOriginKHR = 5323, + SpvBuiltInObjectRayOriginNV = 5323, + SpvBuiltInObjectRayDirectionKHR = 5324, + SpvBuiltInObjectRayDirectionNV = 5324, + SpvBuiltInRayTminKHR = 5325, + SpvBuiltInRayTminNV = 5325, + SpvBuiltInRayTmaxKHR = 5326, + SpvBuiltInRayTmaxNV = 5326, + SpvBuiltInInstanceCustomIndexKHR = 5327, + SpvBuiltInInstanceCustomIndexNV = 5327, + SpvBuiltInObjectToWorldKHR = 5330, + SpvBuiltInObjectToWorldNV = 5330, + SpvBuiltInWorldToObjectKHR = 5331, + SpvBuiltInWorldToObjectNV = 5331, + SpvBuiltInHitTNV = 5332, + SpvBuiltInHitKindKHR = 5333, + SpvBuiltInHitKindNV = 5333, + SpvBuiltInCurrentRayTimeNV = 5334, + SpvBuiltInHitTriangleVertexPositionsKHR = 5335, + SpvBuiltInHitMicroTriangleVertexPositionsNV = 5337, + SpvBuiltInHitMicroTriangleVertexBarycentricsNV = 5344, + SpvBuiltInIncomingRayFlagsKHR = 5351, + SpvBuiltInIncomingRayFlagsNV = 5351, + SpvBuiltInRayGeometryIndexKHR = 5352, + SpvBuiltInWarpsPerSMNV = 5374, + SpvBuiltInSMCountNV = 5375, + SpvBuiltInWarpIDNV = 5376, + SpvBuiltInSMIDNV = 5377, + SpvBuiltInHitKindFrontFacingMicroTriangleNV = 5405, + SpvBuiltInHitKindBackFacingMicroTriangleNV = 5406, + SpvBuiltInCullMaskKHR = 6021, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlDependencyInfiniteShift = 2, + SpvLoopControlDependencyLengthShift = 3, + SpvLoopControlMinIterationsShift = 4, + SpvLoopControlMaxIterationsShift = 5, + SpvLoopControlIterationMultipleShift = 6, + SpvLoopControlPeelCountShift = 7, + SpvLoopControlPartialCountShift = 8, + SpvLoopControlInitiationIntervalINTELShift = 16, + SpvLoopControlMaxConcurrencyINTELShift = 17, + SpvLoopControlDependencyArrayINTELShift = 18, + SpvLoopControlPipelineEnableINTELShift = 19, + SpvLoopControlLoopCoalesceINTELShift = 20, + SpvLoopControlMaxInterleavingINTELShift = 21, + SpvLoopControlSpeculatedIterationsINTELShift = 22, + SpvLoopControlNoFusionINTELShift = 23, + SpvLoopControlLoopCountINTELShift = 24, + SpvLoopControlMaxReinvocationDelayINTELShift = 25, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, + SpvLoopControlDependencyInfiniteMask = 0x00000004, + SpvLoopControlDependencyLengthMask = 0x00000008, + SpvLoopControlMinIterationsMask = 0x00000010, + SpvLoopControlMaxIterationsMask = 0x00000020, + SpvLoopControlIterationMultipleMask = 0x00000040, + SpvLoopControlPeelCountMask = 0x00000080, + SpvLoopControlPartialCountMask = 0x00000100, + SpvLoopControlInitiationIntervalINTELMask = 0x00010000, + SpvLoopControlMaxConcurrencyINTELMask = 0x00020000, + SpvLoopControlDependencyArrayINTELMask = 0x00040000, + SpvLoopControlPipelineEnableINTELMask = 0x00080000, + SpvLoopControlLoopCoalesceINTELMask = 0x00100000, + SpvLoopControlMaxInterleavingINTELMask = 0x00200000, + SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000, + SpvLoopControlNoFusionINTELMask = 0x00800000, + SpvLoopControlLoopCountINTELMask = 0x01000000, + SpvLoopControlMaxReinvocationDelayINTELMask = 0x02000000, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlOptNoneINTELShift = 16, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, + SpvFunctionControlOptNoneINTELMask = 0x00010000, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsOutputMemoryShift = 12, + SpvMemorySemanticsOutputMemoryKHRShift = 12, + SpvMemorySemanticsMakeAvailableShift = 13, + SpvMemorySemanticsMakeAvailableKHRShift = 13, + SpvMemorySemanticsMakeVisibleShift = 14, + SpvMemorySemanticsMakeVisibleKHRShift = 14, + SpvMemorySemanticsVolatileShift = 15, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, + SpvMemorySemanticsOutputMemoryMask = 0x00001000, + SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000, + SpvMemorySemanticsMakeAvailableMask = 0x00002000, + SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000, + SpvMemorySemanticsMakeVisibleMask = 0x00004000, + SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000, + SpvMemorySemanticsVolatileMask = 0x00008000, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMakePointerAvailableShift = 3, + SpvMemoryAccessMakePointerAvailableKHRShift = 3, + SpvMemoryAccessMakePointerVisibleShift = 4, + SpvMemoryAccessMakePointerVisibleKHRShift = 4, + SpvMemoryAccessNonPrivatePointerShift = 5, + SpvMemoryAccessNonPrivatePointerKHRShift = 5, + SpvMemoryAccessAliasScopeINTELMaskShift = 16, + SpvMemoryAccessNoAliasINTELMaskShift = 17, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, + SpvMemoryAccessMakePointerAvailableMask = 0x00000008, + SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008, + SpvMemoryAccessMakePointerVisibleMask = 0x00000010, + SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, + SpvMemoryAccessNonPrivatePointerMask = 0x00000020, + SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, + SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000, + SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeQueueFamily = 5, + SpvScopeQueueFamilyKHR = 5, + SpvScopeShaderCallKHR = 6, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationClusteredReduce = 3, + SpvGroupOperationPartitionedReduceNV = 6, + SpvGroupOperationPartitionedInclusiveScanNV = 7, + SpvGroupOperationPartitionedExclusiveScanNV = 8, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupDispatch = 58, + SpvCapabilityNamedBarrier = 59, + SpvCapabilityPipeStorage = 60, + SpvCapabilityGroupNonUniform = 61, + SpvCapabilityGroupNonUniformVote = 62, + SpvCapabilityGroupNonUniformArithmetic = 63, + SpvCapabilityGroupNonUniformBallot = 64, + SpvCapabilityGroupNonUniformShuffle = 65, + SpvCapabilityGroupNonUniformShuffleRelative = 66, + SpvCapabilityGroupNonUniformClustered = 67, + SpvCapabilityGroupNonUniformQuad = 68, + SpvCapabilityShaderLayer = 69, + SpvCapabilityShaderViewportIndex = 70, + SpvCapabilityUniformDecoration = 71, + SpvCapabilityCoreBuiltinsARM = 4165, + SpvCapabilityTileImageColorReadAccessEXT = 4166, + SpvCapabilityTileImageDepthReadAccessEXT = 4167, + SpvCapabilityTileImageStencilReadAccessEXT = 4168, + SpvCapabilityFragmentShadingRateKHR = 4422, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityStorageBuffer8BitAccess = 4448, + SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449, + SpvCapabilityStoragePushConstant8 = 4450, + SpvCapabilityDenormPreserve = 4464, + SpvCapabilityDenormFlushToZero = 4465, + SpvCapabilitySignedZeroInfNanPreserve = 4466, + SpvCapabilityRoundingModeRTE = 4467, + SpvCapabilityRoundingModeRTZ = 4468, + SpvCapabilityRayQueryProvisionalKHR = 4471, + SpvCapabilityRayQueryKHR = 4472, + SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478, + SpvCapabilityRayTracingKHR = 4479, + SpvCapabilityTextureSampleWeightedQCOM = 4484, + SpvCapabilityTextureBoxFilterQCOM = 4485, + SpvCapabilityTextureBlockMatchQCOM = 4486, + SpvCapabilityTextureBlockMatch2QCOM = 4498, + SpvCapabilityFloat16ImageAMD = 5008, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilityInt64ImageEXT = 5016, + SpvCapabilityShaderClockKHR = 5055, + SpvCapabilityShaderEnqueueAMDX = 5067, + SpvCapabilityQuadControlKHR = 5087, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilityFragmentFullyCoveredEXT = 5265, + SpvCapabilityMeshShadingNV = 5266, + SpvCapabilityImageFootprintNV = 5282, + SpvCapabilityMeshShadingEXT = 5283, + SpvCapabilityFragmentBarycentricKHR = 5284, + SpvCapabilityFragmentBarycentricNV = 5284, + SpvCapabilityComputeDerivativeGroupQuadsNV = 5288, + SpvCapabilityFragmentDensityEXT = 5291, + SpvCapabilityShadingRateNV = 5291, + SpvCapabilityGroupNonUniformPartitionedNV = 5297, + SpvCapabilityShaderNonUniform = 5301, + SpvCapabilityShaderNonUniformEXT = 5301, + SpvCapabilityRuntimeDescriptorArray = 5302, + SpvCapabilityRuntimeDescriptorArrayEXT = 5302, + SpvCapabilityInputAttachmentArrayDynamicIndexing = 5303, + SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + SpvCapabilityUniformTexelBufferArrayDynamicIndexing = 5304, + SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + SpvCapabilityStorageTexelBufferArrayDynamicIndexing = 5305, + SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + SpvCapabilityUniformBufferArrayNonUniformIndexing = 5306, + SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + SpvCapabilitySampledImageArrayNonUniformIndexing = 5307, + SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + SpvCapabilityStorageBufferArrayNonUniformIndexing = 5308, + SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + SpvCapabilityStorageImageArrayNonUniformIndexing = 5309, + SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + SpvCapabilityInputAttachmentArrayNonUniformIndexing = 5310, + SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + SpvCapabilityRayTracingPositionFetchKHR = 5336, + SpvCapabilityRayTracingNV = 5340, + SpvCapabilityRayTracingMotionBlurNV = 5341, + SpvCapabilityVulkanMemoryModel = 5345, + SpvCapabilityVulkanMemoryModelKHR = 5345, + SpvCapabilityVulkanMemoryModelDeviceScope = 5346, + SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + SpvCapabilityPhysicalStorageBufferAddresses = 5347, + SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347, + SpvCapabilityComputeDerivativeGroupLinearNV = 5350, + SpvCapabilityRayTracingProvisionalKHR = 5353, + SpvCapabilityCooperativeMatrixNV = 5357, + SpvCapabilityFragmentShaderSampleInterlockEXT = 5363, + SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372, + SpvCapabilityShaderSMBuiltinsNV = 5373, + SpvCapabilityFragmentShaderPixelInterlockEXT = 5378, + SpvCapabilityDemoteToHelperInvocation = 5379, + SpvCapabilityDemoteToHelperInvocationEXT = 5379, + SpvCapabilityDisplacementMicromapNV = 5380, + SpvCapabilityRayTracingOpacityMicromapEXT = 5381, + SpvCapabilityShaderInvocationReorderNV = 5383, + SpvCapabilityBindlessTextureNV = 5390, + SpvCapabilityRayQueryPositionFetchKHR = 5391, + SpvCapabilityAtomicFloat16VectorNV = 5404, + SpvCapabilityRayTracingDisplacementMicromapNV = 5409, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579, + SpvCapabilityRoundToInfinityINTEL = 5582, + SpvCapabilityFloatingPointModeINTEL = 5583, + SpvCapabilityIntegerFunctions2INTEL = 5584, + SpvCapabilityFunctionPointersINTEL = 5603, + SpvCapabilityIndirectReferencesINTEL = 5604, + SpvCapabilityAsmINTEL = 5606, + SpvCapabilityAtomicFloat32MinMaxEXT = 5612, + SpvCapabilityAtomicFloat64MinMaxEXT = 5613, + SpvCapabilityAtomicFloat16MinMaxEXT = 5616, + SpvCapabilityVectorComputeINTEL = 5617, + SpvCapabilityVectorAnyINTEL = 5619, + SpvCapabilityExpectAssumeKHR = 5629, + SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696, + SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + SpvCapabilityVariableLengthArrayINTEL = 5817, + SpvCapabilityFunctionFloatControlINTEL = 5821, + SpvCapabilityFPGAMemoryAttributesINTEL = 5824, + SpvCapabilityFPFastMathModeINTEL = 5837, + SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844, + SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845, + SpvCapabilityUnstructuredLoopControlsINTEL = 5886, + SpvCapabilityFPGALoopControlsINTEL = 5888, + SpvCapabilityKernelAttributesINTEL = 5892, + SpvCapabilityFPGAKernelAttributesINTEL = 5897, + SpvCapabilityFPGAMemoryAccessesINTEL = 5898, + SpvCapabilityFPGAClusterAttributesINTEL = 5904, + SpvCapabilityLoopFuseINTEL = 5906, + SpvCapabilityFPGADSPControlINTEL = 5908, + SpvCapabilityMemoryAccessAliasingINTEL = 5910, + SpvCapabilityFPGAInvocationPipeliningAttributesINTEL = 5916, + SpvCapabilityFPGABufferLocationINTEL = 5920, + SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922, + SpvCapabilityUSMStorageClassesINTEL = 5935, + SpvCapabilityRuntimeAlignedAttributeINTEL = 5939, + SpvCapabilityIOPipesINTEL = 5943, + SpvCapabilityBlockingPipesINTEL = 5945, + SpvCapabilityFPGARegINTEL = 5948, + SpvCapabilityDotProductInputAll = 6016, + SpvCapabilityDotProductInputAllKHR = 6016, + SpvCapabilityDotProductInput4x8Bit = 6017, + SpvCapabilityDotProductInput4x8BitKHR = 6017, + SpvCapabilityDotProductInput4x8BitPacked = 6018, + SpvCapabilityDotProductInput4x8BitPackedKHR = 6018, + SpvCapabilityDotProduct = 6019, + SpvCapabilityDotProductKHR = 6019, + SpvCapabilityRayCullMaskKHR = 6020, + SpvCapabilityCooperativeMatrixKHR = 6022, + SpvCapabilityBitInstructions = 6025, + SpvCapabilityGroupNonUniformRotateKHR = 6026, + SpvCapabilityFloatControls2 = 6029, + SpvCapabilityAtomicFloat32AddEXT = 6033, + SpvCapabilityAtomicFloat64AddEXT = 6034, + SpvCapabilityLongCompositesINTEL = 6089, + SpvCapabilityOptNoneINTEL = 6094, + SpvCapabilityAtomicFloat16AddEXT = 6095, + SpvCapabilityDebugInfoModuleINTEL = 6114, + SpvCapabilityBFloat16ConversionINTEL = 6115, + SpvCapabilitySplitBarrierINTEL = 6141, + SpvCapabilityFPGAClusterAttributesV2INTEL = 6150, + SpvCapabilityFPGAKernelAttributesv2INTEL = 6161, + SpvCapabilityFPMaxErrorINTEL = 6169, + SpvCapabilityFPGALatencyControlINTEL = 6171, + SpvCapabilityFPGAArgumentInterfacesINTEL = 6174, + SpvCapabilityGlobalVariableHostAccessINTEL = 6187, + SpvCapabilityGlobalVariableFPGADecorationsINTEL = 6189, + SpvCapabilityGroupUniformArithmeticKHR = 6400, + SpvCapabilityMaskedGatherScatterINTEL = 6427, + SpvCapabilityCacheControlsINTEL = 6441, + SpvCapabilityRegisterLimitsINTEL = 6460, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvRayFlagsShift_ { + SpvRayFlagsOpaqueKHRShift = 0, + SpvRayFlagsNoOpaqueKHRShift = 1, + SpvRayFlagsTerminateOnFirstHitKHRShift = 2, + SpvRayFlagsSkipClosestHitShaderKHRShift = 3, + SpvRayFlagsCullBackFacingTrianglesKHRShift = 4, + SpvRayFlagsCullFrontFacingTrianglesKHRShift = 5, + SpvRayFlagsCullOpaqueKHRShift = 6, + SpvRayFlagsCullNoOpaqueKHRShift = 7, + SpvRayFlagsSkipTrianglesKHRShift = 8, + SpvRayFlagsSkipAABBsKHRShift = 9, + SpvRayFlagsForceOpacityMicromap2StateEXTShift = 10, + SpvRayFlagsMax = 0x7fffffff, +} SpvRayFlagsShift; + +typedef enum SpvRayFlagsMask_ { + SpvRayFlagsMaskNone = 0, + SpvRayFlagsOpaqueKHRMask = 0x00000001, + SpvRayFlagsNoOpaqueKHRMask = 0x00000002, + SpvRayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + SpvRayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + SpvRayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + SpvRayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + SpvRayFlagsCullOpaqueKHRMask = 0x00000040, + SpvRayFlagsCullNoOpaqueKHRMask = 0x00000080, + SpvRayFlagsSkipTrianglesKHRMask = 0x00000100, + SpvRayFlagsSkipAABBsKHRMask = 0x00000200, + SpvRayFlagsForceOpacityMicromap2StateEXTMask = 0x00000400, +} SpvRayFlagsMask; + +typedef enum SpvRayQueryIntersection_ { + SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + SpvRayQueryIntersectionMax = 0x7fffffff, +} SpvRayQueryIntersection; + +typedef enum SpvRayQueryCommittedIntersectionType_ { + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + SpvRayQueryCommittedIntersectionTypeMax = 0x7fffffff, +} SpvRayQueryCommittedIntersectionType; + +typedef enum SpvRayQueryCandidateIntersectionType_ { + SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff, +} SpvRayQueryCandidateIntersectionType; + +typedef enum SpvFragmentShadingRateShift_ { + SpvFragmentShadingRateVertical2PixelsShift = 0, + SpvFragmentShadingRateVertical4PixelsShift = 1, + SpvFragmentShadingRateHorizontal2PixelsShift = 2, + SpvFragmentShadingRateHorizontal4PixelsShift = 3, + SpvFragmentShadingRateMax = 0x7fffffff, +} SpvFragmentShadingRateShift; + +typedef enum SpvFragmentShadingRateMask_ { + SpvFragmentShadingRateMaskNone = 0, + SpvFragmentShadingRateVertical2PixelsMask = 0x00000001, + SpvFragmentShadingRateVertical4PixelsMask = 0x00000002, + SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004, + SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008, +} SpvFragmentShadingRateMask; + +typedef enum SpvFPDenormMode_ { + SpvFPDenormModePreserve = 0, + SpvFPDenormModeFlushToZero = 1, + SpvFPDenormModeMax = 0x7fffffff, +} SpvFPDenormMode; + +typedef enum SpvFPOperationMode_ { + SpvFPOperationModeIEEE = 0, + SpvFPOperationModeALT = 1, + SpvFPOperationModeMax = 0x7fffffff, +} SpvFPOperationMode; + +typedef enum SpvQuantizationModes_ { + SpvQuantizationModesTRN = 0, + SpvQuantizationModesTRN_ZERO = 1, + SpvQuantizationModesRND = 2, + SpvQuantizationModesRND_ZERO = 3, + SpvQuantizationModesRND_INF = 4, + SpvQuantizationModesRND_MIN_INF = 5, + SpvQuantizationModesRND_CONV = 6, + SpvQuantizationModesRND_CONV_ODD = 7, + SpvQuantizationModesMax = 0x7fffffff, +} SpvQuantizationModes; + +typedef enum SpvOverflowModes_ { + SpvOverflowModesWRAP = 0, + SpvOverflowModesSAT = 1, + SpvOverflowModesSAT_ZERO = 2, + SpvOverflowModesSAT_SYM = 3, + SpvOverflowModesMax = 0x7fffffff, +} SpvOverflowModes; + +typedef enum SpvPackedVectorFormat_ { + SpvPackedVectorFormatPackedVectorFormat4x8Bit = 0, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + SpvPackedVectorFormatMax = 0x7fffffff, +} SpvPackedVectorFormat; + +typedef enum SpvCooperativeMatrixOperandsShift_ { + SpvCooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0, + SpvCooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1, + SpvCooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2, + SpvCooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3, + SpvCooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4, + SpvCooperativeMatrixOperandsMax = 0x7fffffff, +} SpvCooperativeMatrixOperandsShift; + +typedef enum SpvCooperativeMatrixOperandsMask_ { + SpvCooperativeMatrixOperandsMaskNone = 0, + SpvCooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001, + SpvCooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002, + SpvCooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004, + SpvCooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008, + SpvCooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010, +} SpvCooperativeMatrixOperandsMask; + +typedef enum SpvCooperativeMatrixLayout_ { + SpvCooperativeMatrixLayoutRowMajorKHR = 0, + SpvCooperativeMatrixLayoutColumnMajorKHR = 1, + SpvCooperativeMatrixLayoutMax = 0x7fffffff, +} SpvCooperativeMatrixLayout; + +typedef enum SpvCooperativeMatrixUse_ { + SpvCooperativeMatrixUseMatrixAKHR = 0, + SpvCooperativeMatrixUseMatrixBKHR = 1, + SpvCooperativeMatrixUseMatrixAccumulatorKHR = 2, + SpvCooperativeMatrixUseMax = 0x7fffffff, +} SpvCooperativeMatrixUse; + +typedef enum SpvInitializationModeQualifier_ { + SpvInitializationModeQualifierInitOnDeviceReprogramINTEL = 0, + SpvInitializationModeQualifierInitOnDeviceResetINTEL = 1, + SpvInitializationModeQualifierMax = 0x7fffffff, +} SpvInitializationModeQualifier; + +typedef enum SpvHostAccessQualifier_ { + SpvHostAccessQualifierNoneINTEL = 0, + SpvHostAccessQualifierReadINTEL = 1, + SpvHostAccessQualifierWriteINTEL = 2, + SpvHostAccessQualifierReadWriteINTEL = 3, + SpvHostAccessQualifierMax = 0x7fffffff, +} SpvHostAccessQualifier; + +typedef enum SpvLoadCacheControl_ { + SpvLoadCacheControlUncachedINTEL = 0, + SpvLoadCacheControlCachedINTEL = 1, + SpvLoadCacheControlStreamingINTEL = 2, + SpvLoadCacheControlInvalidateAfterReadINTEL = 3, + SpvLoadCacheControlConstCachedINTEL = 4, + SpvLoadCacheControlMax = 0x7fffffff, +} SpvLoadCacheControl; + +typedef enum SpvStoreCacheControl_ { + SpvStoreCacheControlUncachedINTEL = 0, + SpvStoreCacheControlWriteThroughINTEL = 1, + SpvStoreCacheControlWriteBackINTEL = 2, + SpvStoreCacheControlStreamingINTEL = 3, + SpvStoreCacheControlMax = 0x7fffffff, +} SpvStoreCacheControl; + +typedef enum SpvNamedMaximumNumberOfRegisters_ { + SpvNamedMaximumNumberOfRegistersAutoINTEL = 0, + SpvNamedMaximumNumberOfRegistersMax = 0x7fffffff, +} SpvNamedMaximumNumberOfRegisters; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpSizeOf = 321, + SpvOpTypePipeStorage = 322, + SpvOpConstantPipeStorage = 323, + SpvOpCreatePipeFromPipeStorage = 324, + SpvOpGetKernelLocalSizeForSubgroupCount = 325, + SpvOpGetKernelMaxNumSubgroups = 326, + SpvOpTypeNamedBarrier = 327, + SpvOpNamedBarrierInitialize = 328, + SpvOpMemoryNamedBarrier = 329, + SpvOpModuleProcessed = 330, + SpvOpExecutionModeId = 331, + SpvOpDecorateId = 332, + SpvOpGroupNonUniformElect = 333, + SpvOpGroupNonUniformAll = 334, + SpvOpGroupNonUniformAny = 335, + SpvOpGroupNonUniformAllEqual = 336, + SpvOpGroupNonUniformBroadcast = 337, + SpvOpGroupNonUniformBroadcastFirst = 338, + SpvOpGroupNonUniformBallot = 339, + SpvOpGroupNonUniformInverseBallot = 340, + SpvOpGroupNonUniformBallotBitExtract = 341, + SpvOpGroupNonUniformBallotBitCount = 342, + SpvOpGroupNonUniformBallotFindLSB = 343, + SpvOpGroupNonUniformBallotFindMSB = 344, + SpvOpGroupNonUniformShuffle = 345, + SpvOpGroupNonUniformShuffleXor = 346, + SpvOpGroupNonUniformShuffleUp = 347, + SpvOpGroupNonUniformShuffleDown = 348, + SpvOpGroupNonUniformIAdd = 349, + SpvOpGroupNonUniformFAdd = 350, + SpvOpGroupNonUniformIMul = 351, + SpvOpGroupNonUniformFMul = 352, + SpvOpGroupNonUniformSMin = 353, + SpvOpGroupNonUniformUMin = 354, + SpvOpGroupNonUniformFMin = 355, + SpvOpGroupNonUniformSMax = 356, + SpvOpGroupNonUniformUMax = 357, + SpvOpGroupNonUniformFMax = 358, + SpvOpGroupNonUniformBitwiseAnd = 359, + SpvOpGroupNonUniformBitwiseOr = 360, + SpvOpGroupNonUniformBitwiseXor = 361, + SpvOpGroupNonUniformLogicalAnd = 362, + SpvOpGroupNonUniformLogicalOr = 363, + SpvOpGroupNonUniformLogicalXor = 364, + SpvOpGroupNonUniformQuadBroadcast = 365, + SpvOpGroupNonUniformQuadSwap = 366, + SpvOpCopyLogical = 400, + SpvOpPtrEqual = 401, + SpvOpPtrNotEqual = 402, + SpvOpPtrDiff = 403, + SpvOpColorAttachmentReadEXT = 4160, + SpvOpDepthAttachmentReadEXT = 4161, + SpvOpStencilAttachmentReadEXT = 4162, + SpvOpTerminateInvocation = 4416, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpGroupNonUniformRotateKHR = 4431, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpTraceRayKHR = 4445, + SpvOpExecuteCallableKHR = 4446, + SpvOpConvertUToAccelerationStructureKHR = 4447, + SpvOpIgnoreIntersectionKHR = 4448, + SpvOpTerminateRayKHR = 4449, + SpvOpSDot = 4450, + SpvOpSDotKHR = 4450, + SpvOpUDot = 4451, + SpvOpUDotKHR = 4451, + SpvOpSUDot = 4452, + SpvOpSUDotKHR = 4452, + SpvOpSDotAccSat = 4453, + SpvOpSDotAccSatKHR = 4453, + SpvOpUDotAccSat = 4454, + SpvOpUDotAccSatKHR = 4454, + SpvOpSUDotAccSat = 4455, + SpvOpSUDotAccSatKHR = 4455, + SpvOpTypeCooperativeMatrixKHR = 4456, + SpvOpCooperativeMatrixLoadKHR = 4457, + SpvOpCooperativeMatrixStoreKHR = 4458, + SpvOpCooperativeMatrixMulAddKHR = 4459, + SpvOpCooperativeMatrixLengthKHR = 4460, + SpvOpTypeRayQueryKHR = 4472, + SpvOpRayQueryInitializeKHR = 4473, + SpvOpRayQueryTerminateKHR = 4474, + SpvOpRayQueryGenerateIntersectionKHR = 4475, + SpvOpRayQueryConfirmIntersectionKHR = 4476, + SpvOpRayQueryProceedKHR = 4477, + SpvOpRayQueryGetIntersectionTypeKHR = 4479, + SpvOpImageSampleWeightedQCOM = 4480, + SpvOpImageBoxFilterQCOM = 4481, + SpvOpImageBlockMatchSSDQCOM = 4482, + SpvOpImageBlockMatchSADQCOM = 4483, + SpvOpImageBlockMatchWindowSSDQCOM = 4500, + SpvOpImageBlockMatchWindowSADQCOM = 4501, + SpvOpImageBlockMatchGatherSSDQCOM = 4502, + SpvOpImageBlockMatchGatherSADQCOM = 4503, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpReadClockKHR = 5056, + SpvOpFinalizeNodePayloadsAMDX = 5075, + SpvOpFinishWritingNodePayloadAMDX = 5078, + SpvOpInitializeNodePayloadsAMDX = 5090, + SpvOpGroupNonUniformQuadAllKHR = 5110, + SpvOpGroupNonUniformQuadAnyKHR = 5111, + SpvOpHitObjectRecordHitMotionNV = 5249, + SpvOpHitObjectRecordHitWithIndexMotionNV = 5250, + SpvOpHitObjectRecordMissMotionNV = 5251, + SpvOpHitObjectGetWorldToObjectNV = 5252, + SpvOpHitObjectGetObjectToWorldNV = 5253, + SpvOpHitObjectGetObjectRayDirectionNV = 5254, + SpvOpHitObjectGetObjectRayOriginNV = 5255, + SpvOpHitObjectTraceRayMotionNV = 5256, + SpvOpHitObjectGetShaderRecordBufferHandleNV = 5257, + SpvOpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + SpvOpHitObjectRecordEmptyNV = 5259, + SpvOpHitObjectTraceRayNV = 5260, + SpvOpHitObjectRecordHitNV = 5261, + SpvOpHitObjectRecordHitWithIndexNV = 5262, + SpvOpHitObjectRecordMissNV = 5263, + SpvOpHitObjectExecuteShaderNV = 5264, + SpvOpHitObjectGetCurrentTimeNV = 5265, + SpvOpHitObjectGetAttributesNV = 5266, + SpvOpHitObjectGetHitKindNV = 5267, + SpvOpHitObjectGetPrimitiveIndexNV = 5268, + SpvOpHitObjectGetGeometryIndexNV = 5269, + SpvOpHitObjectGetInstanceIdNV = 5270, + SpvOpHitObjectGetInstanceCustomIndexNV = 5271, + SpvOpHitObjectGetWorldRayDirectionNV = 5272, + SpvOpHitObjectGetWorldRayOriginNV = 5273, + SpvOpHitObjectGetRayTMaxNV = 5274, + SpvOpHitObjectGetRayTMinNV = 5275, + SpvOpHitObjectIsEmptyNV = 5276, + SpvOpHitObjectIsHitNV = 5277, + SpvOpHitObjectIsMissNV = 5278, + SpvOpReorderThreadWithHitObjectNV = 5279, + SpvOpReorderThreadWithHintNV = 5280, + SpvOpTypeHitObjectNV = 5281, + SpvOpImageSampleFootprintNV = 5283, + SpvOpEmitMeshTasksEXT = 5294, + SpvOpSetMeshOutputsEXT = 5295, + SpvOpGroupNonUniformPartitionNV = 5296, + SpvOpWritePackedPrimitiveIndices4x8NV = 5299, + SpvOpFetchMicroTriangleVertexPositionNV = 5300, + SpvOpFetchMicroTriangleVertexBarycentricNV = 5301, + SpvOpReportIntersectionKHR = 5334, + SpvOpReportIntersectionNV = 5334, + SpvOpIgnoreIntersectionNV = 5335, + SpvOpTerminateRayNV = 5336, + SpvOpTraceNV = 5337, + SpvOpTraceMotionNV = 5338, + SpvOpTraceRayMotionNV = 5339, + SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + SpvOpTypeAccelerationStructureKHR = 5341, + SpvOpTypeAccelerationStructureNV = 5341, + SpvOpExecuteCallableNV = 5344, + SpvOpTypeCooperativeMatrixNV = 5358, + SpvOpCooperativeMatrixLoadNV = 5359, + SpvOpCooperativeMatrixStoreNV = 5360, + SpvOpCooperativeMatrixMulAddNV = 5361, + SpvOpCooperativeMatrixLengthNV = 5362, + SpvOpBeginInvocationInterlockEXT = 5364, + SpvOpEndInvocationInterlockEXT = 5365, + SpvOpDemoteToHelperInvocation = 5380, + SpvOpDemoteToHelperInvocationEXT = 5380, + SpvOpIsHelperInvocationEXT = 5381, + SpvOpConvertUToImageNV = 5391, + SpvOpConvertUToSamplerNV = 5392, + SpvOpConvertImageToUNV = 5393, + SpvOpConvertSamplerToUNV = 5394, + SpvOpConvertUToSampledImageNV = 5395, + SpvOpConvertSampledImageToUNV = 5396, + SpvOpSamplerImageAddressingModeNV = 5397, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpSubgroupImageMediaBlockReadINTEL = 5580, + SpvOpSubgroupImageMediaBlockWriteINTEL = 5581, + SpvOpUCountLeadingZerosINTEL = 5585, + SpvOpUCountTrailingZerosINTEL = 5586, + SpvOpAbsISubINTEL = 5587, + SpvOpAbsUSubINTEL = 5588, + SpvOpIAddSatINTEL = 5589, + SpvOpUAddSatINTEL = 5590, + SpvOpIAverageINTEL = 5591, + SpvOpUAverageINTEL = 5592, + SpvOpIAverageRoundedINTEL = 5593, + SpvOpUAverageRoundedINTEL = 5594, + SpvOpISubSatINTEL = 5595, + SpvOpUSubSatINTEL = 5596, + SpvOpIMul32x16INTEL = 5597, + SpvOpUMul32x16INTEL = 5598, + SpvOpConstantFunctionPointerINTEL = 5600, + SpvOpFunctionPointerCallINTEL = 5601, + SpvOpAsmTargetINTEL = 5609, + SpvOpAsmINTEL = 5610, + SpvOpAsmCallINTEL = 5611, + SpvOpAtomicFMinEXT = 5614, + SpvOpAtomicFMaxEXT = 5615, + SpvOpAssumeTrueKHR = 5630, + SpvOpExpectKHR = 5631, + SpvOpDecorateString = 5632, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateString = 5633, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpVmeImageINTEL = 5699, + SpvOpTypeVmeImageINTEL = 5700, + SpvOpTypeAvcImePayloadINTEL = 5701, + SpvOpTypeAvcRefPayloadINTEL = 5702, + SpvOpTypeAvcSicPayloadINTEL = 5703, + SpvOpTypeAvcMcePayloadINTEL = 5704, + SpvOpTypeAvcMceResultINTEL = 5705, + SpvOpTypeAvcImeResultINTEL = 5706, + SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + SpvOpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + SpvOpTypeAvcImeDualReferenceStreaminINTEL = 5710, + SpvOpTypeAvcRefResultINTEL = 5711, + SpvOpTypeAvcSicResultINTEL = 5712, + SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + SpvOpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + SpvOpSubgroupAvcMceConvertToImeResultINTEL = 5733, + SpvOpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + SpvOpSubgroupAvcMceConvertToRefResultINTEL = 5735, + SpvOpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + SpvOpSubgroupAvcMceConvertToSicResultINTEL = 5737, + SpvOpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + SpvOpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + SpvOpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + SpvOpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + SpvOpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + SpvOpSubgroupAvcImeInitializeINTEL = 5747, + SpvOpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + SpvOpSubgroupAvcImeSetDualReferenceINTEL = 5749, + SpvOpSubgroupAvcImeRefWindowSizeINTEL = 5750, + SpvOpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + SpvOpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + SpvOpSubgroupAvcImeSetWeightedSadINTEL = 5756, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + SpvOpSubgroupAvcImeConvertToMceResultINTEL = 5765, + SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + SpvOpSubgroupAvcImeGetBorderReachedINTEL = 5776, + SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + SpvOpSubgroupAvcFmeInitializeINTEL = 5781, + SpvOpSubgroupAvcBmeInitializeINTEL = 5782, + SpvOpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + SpvOpSubgroupAvcRefConvertToMceResultINTEL = 5790, + SpvOpSubgroupAvcSicInitializeINTEL = 5791, + SpvOpSubgroupAvcSicConfigureSkcINTEL = 5792, + SpvOpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + SpvOpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + SpvOpSubgroupAvcSicEvaluateIpeINTEL = 5803, + SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + SpvOpSubgroupAvcSicConvertToMceResultINTEL = 5808, + SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + SpvOpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + SpvOpVariableLengthArrayINTEL = 5818, + SpvOpSaveMemoryINTEL = 5819, + SpvOpRestoreMemoryINTEL = 5820, + SpvOpArbitraryFloatSinCosPiINTEL = 5840, + SpvOpArbitraryFloatCastINTEL = 5841, + SpvOpArbitraryFloatCastFromIntINTEL = 5842, + SpvOpArbitraryFloatCastToIntINTEL = 5843, + SpvOpArbitraryFloatAddINTEL = 5846, + SpvOpArbitraryFloatSubINTEL = 5847, + SpvOpArbitraryFloatMulINTEL = 5848, + SpvOpArbitraryFloatDivINTEL = 5849, + SpvOpArbitraryFloatGTINTEL = 5850, + SpvOpArbitraryFloatGEINTEL = 5851, + SpvOpArbitraryFloatLTINTEL = 5852, + SpvOpArbitraryFloatLEINTEL = 5853, + SpvOpArbitraryFloatEQINTEL = 5854, + SpvOpArbitraryFloatRecipINTEL = 5855, + SpvOpArbitraryFloatRSqrtINTEL = 5856, + SpvOpArbitraryFloatCbrtINTEL = 5857, + SpvOpArbitraryFloatHypotINTEL = 5858, + SpvOpArbitraryFloatSqrtINTEL = 5859, + SpvOpArbitraryFloatLogINTEL = 5860, + SpvOpArbitraryFloatLog2INTEL = 5861, + SpvOpArbitraryFloatLog10INTEL = 5862, + SpvOpArbitraryFloatLog1pINTEL = 5863, + SpvOpArbitraryFloatExpINTEL = 5864, + SpvOpArbitraryFloatExp2INTEL = 5865, + SpvOpArbitraryFloatExp10INTEL = 5866, + SpvOpArbitraryFloatExpm1INTEL = 5867, + SpvOpArbitraryFloatSinINTEL = 5868, + SpvOpArbitraryFloatCosINTEL = 5869, + SpvOpArbitraryFloatSinCosINTEL = 5870, + SpvOpArbitraryFloatSinPiINTEL = 5871, + SpvOpArbitraryFloatCosPiINTEL = 5872, + SpvOpArbitraryFloatASinINTEL = 5873, + SpvOpArbitraryFloatASinPiINTEL = 5874, + SpvOpArbitraryFloatACosINTEL = 5875, + SpvOpArbitraryFloatACosPiINTEL = 5876, + SpvOpArbitraryFloatATanINTEL = 5877, + SpvOpArbitraryFloatATanPiINTEL = 5878, + SpvOpArbitraryFloatATan2INTEL = 5879, + SpvOpArbitraryFloatPowINTEL = 5880, + SpvOpArbitraryFloatPowRINTEL = 5881, + SpvOpArbitraryFloatPowNINTEL = 5882, + SpvOpLoopControlINTEL = 5887, + SpvOpAliasDomainDeclINTEL = 5911, + SpvOpAliasScopeDeclINTEL = 5912, + SpvOpAliasScopeListDeclINTEL = 5913, + SpvOpFixedSqrtINTEL = 5923, + SpvOpFixedRecipINTEL = 5924, + SpvOpFixedRsqrtINTEL = 5925, + SpvOpFixedSinINTEL = 5926, + SpvOpFixedCosINTEL = 5927, + SpvOpFixedSinCosINTEL = 5928, + SpvOpFixedSinPiINTEL = 5929, + SpvOpFixedCosPiINTEL = 5930, + SpvOpFixedSinCosPiINTEL = 5931, + SpvOpFixedLogINTEL = 5932, + SpvOpFixedExpINTEL = 5933, + SpvOpPtrCastToCrossWorkgroupINTEL = 5934, + SpvOpCrossWorkgroupCastToPtrINTEL = 5938, + SpvOpReadPipeBlockingINTEL = 5946, + SpvOpWritePipeBlockingINTEL = 5947, + SpvOpFPGARegINTEL = 5949, + SpvOpRayQueryGetRayTMinKHR = 6016, + SpvOpRayQueryGetRayFlagsKHR = 6017, + SpvOpRayQueryGetIntersectionTKHR = 6018, + SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + SpvOpRayQueryGetIntersectionInstanceIdKHR = 6020, + SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + SpvOpRayQueryGetIntersectionGeometryIndexKHR = 6022, + SpvOpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + SpvOpRayQueryGetIntersectionBarycentricsKHR = 6024, + SpvOpRayQueryGetIntersectionFrontFaceKHR = 6025, + SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + SpvOpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + SpvOpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + SpvOpRayQueryGetWorldRayDirectionKHR = 6029, + SpvOpRayQueryGetWorldRayOriginKHR = 6030, + SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031, + SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032, + SpvOpAtomicFAddEXT = 6035, + SpvOpTypeBufferSurfaceINTEL = 6086, + SpvOpTypeStructContinuedINTEL = 6090, + SpvOpConstantCompositeContinuedINTEL = 6091, + SpvOpSpecConstantCompositeContinuedINTEL = 6092, + SpvOpCompositeConstructContinuedINTEL = 6096, + SpvOpConvertFToBF16INTEL = 6116, + SpvOpConvertBF16ToFINTEL = 6117, + SpvOpControlBarrierArriveINTEL = 6142, + SpvOpControlBarrierWaitINTEL = 6143, + SpvOpGroupIMulKHR = 6401, + SpvOpGroupFMulKHR = 6402, + SpvOpGroupBitwiseAndKHR = 6403, + SpvOpGroupBitwiseOrKHR = 6404, + SpvOpGroupBitwiseXorKHR = 6405, + SpvOpGroupLogicalAndKHR = 6406, + SpvOpGroupLogicalOrKHR = 6407, + SpvOpGroupLogicalXorKHR = 6408, + SpvOpMaskedGatherINTEL = 6428, + SpvOpMaskedScatterINTEL = 6429, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif +inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case SpvOpNop: *hasResult = false; *hasResultType = false; break; + case SpvOpUndef: *hasResult = true; *hasResultType = true; break; + case SpvOpSourceContinued: *hasResult = false; *hasResultType = false; break; + case SpvOpSource: *hasResult = false; *hasResultType = false; break; + case SpvOpSourceExtension: *hasResult = false; *hasResultType = false; break; + case SpvOpName: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberName: *hasResult = false; *hasResultType = false; break; + case SpvOpString: *hasResult = true; *hasResultType = false; break; + case SpvOpLine: *hasResult = false; *hasResultType = false; break; + case SpvOpExtension: *hasResult = false; *hasResultType = false; break; + case SpvOpExtInstImport: *hasResult = true; *hasResultType = false; break; + case SpvOpExtInst: *hasResult = true; *hasResultType = true; break; + case SpvOpMemoryModel: *hasResult = false; *hasResultType = false; break; + case SpvOpEntryPoint: *hasResult = false; *hasResultType = false; break; + case SpvOpExecutionMode: *hasResult = false; *hasResultType = false; break; + case SpvOpCapability: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeVoid: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeBool: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeInt: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeFloat: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeVector: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeImage: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeSampler: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeArray: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeStruct: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case SpvOpTypePointer: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeFunction: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeEvent: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeQueue: *hasResult = true; *hasResultType = false; break; + case SpvOpTypePipe: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case SpvOpConstantTrue: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantFalse: *hasResult = true; *hasResultType = true; break; + case SpvOpConstant: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantComposite: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantSampler: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantNull: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstant: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case SpvOpFunction: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case SpvOpFunctionCall: *hasResult = true; *hasResultType = true; break; + case SpvOpVariable: *hasResult = true; *hasResultType = true; break; + case SpvOpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case SpvOpLoad: *hasResult = true; *hasResultType = true; break; + case SpvOpStore: *hasResult = false; *hasResultType = false; break; + case SpvOpCopyMemory: *hasResult = false; *hasResultType = false; break; + case SpvOpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case SpvOpAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpArrayLength: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case SpvOpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case SpvOpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case SpvOpCopyObject: *hasResult = true; *hasResultType = true; break; + case SpvOpTranspose: *hasResult = true; *hasResultType = true; break; + case SpvOpSampledImage: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageFetch: *hasResult = true; *hasResultType = true; break; + case SpvOpImageGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageRead: *hasResult = true; *hasResultType = true; break; + case SpvOpImageWrite: *hasResult = false; *hasResultType = false; break; + case SpvOpImage: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToU: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToS: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSToF: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToF: *hasResult = true; *hasResultType = true; break; + case SpvOpUConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpSConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpFConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case SpvOpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case SpvOpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case SpvOpBitcast: *hasResult = true; *hasResultType = true; break; + case SpvOpSNegate: *hasResult = true; *hasResultType = true; break; + case SpvOpFNegate: *hasResult = true; *hasResultType = true; break; + case SpvOpIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpISub: *hasResult = true; *hasResultType = true; break; + case SpvOpFSub: *hasResult = true; *hasResultType = true; break; + case SpvOpIMul: *hasResult = true; *hasResultType = true; break; + case SpvOpFMul: *hasResult = true; *hasResultType = true; break; + case SpvOpUDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpSDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpFDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpUMod: *hasResult = true; *hasResultType = true; break; + case SpvOpSRem: *hasResult = true; *hasResultType = true; break; + case SpvOpSMod: *hasResult = true; *hasResultType = true; break; + case SpvOpFRem: *hasResult = true; *hasResultType = true; break; + case SpvOpFMod: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case SpvOpOuterProduct: *hasResult = true; *hasResultType = true; break; + case SpvOpDot: *hasResult = true; *hasResultType = true; break; + case SpvOpIAddCarry: *hasResult = true; *hasResultType = true; break; + case SpvOpISubBorrow: *hasResult = true; *hasResultType = true; break; + case SpvOpUMulExtended: *hasResult = true; *hasResultType = true; break; + case SpvOpSMulExtended: *hasResult = true; *hasResultType = true; break; + case SpvOpAny: *hasResult = true; *hasResultType = true; break; + case SpvOpAll: *hasResult = true; *hasResultType = true; break; + case SpvOpIsNan: *hasResult = true; *hasResultType = true; break; + case SpvOpIsInf: *hasResult = true; *hasResultType = true; break; + case SpvOpIsFinite: *hasResult = true; *hasResultType = true; break; + case SpvOpIsNormal: *hasResult = true; *hasResultType = true; break; + case SpvOpSignBitSet: *hasResult = true; *hasResultType = true; break; + case SpvOpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case SpvOpOrdered: *hasResult = true; *hasResultType = true; break; + case SpvOpUnordered: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalOr: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalNot: *hasResult = true; *hasResultType = true; break; + case SpvOpSelect: *hasResult = true; *hasResultType = true; break; + case SpvOpIEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpINotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpULessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpSLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpNot: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpBitReverse: *hasResult = true; *hasResultType = true; break; + case SpvOpBitCount: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdx: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdy: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidth: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdxFine: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdyFine: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidthFine: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpEmitVertex: *hasResult = false; *hasResultType = false; break; + case SpvOpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case SpvOpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case SpvOpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicStore: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicISub: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicOr: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicXor: *hasResult = true; *hasResultType = true; break; + case SpvOpPhi: *hasResult = true; *hasResultType = true; break; + case SpvOpLoopMerge: *hasResult = false; *hasResultType = false; break; + case SpvOpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case SpvOpLabel: *hasResult = true; *hasResultType = false; break; + case SpvOpBranch: *hasResult = false; *hasResultType = false; break; + case SpvOpBranchConditional: *hasResult = false; *hasResultType = false; break; + case SpvOpSwitch: *hasResult = false; *hasResultType = false; break; + case SpvOpKill: *hasResult = false; *hasResultType = false; break; + case SpvOpReturn: *hasResult = false; *hasResultType = false; break; + case SpvOpReturnValue: *hasResult = false; *hasResultType = false; break; + case SpvOpUnreachable: *hasResult = false; *hasResultType = false; break; + case SpvOpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case SpvOpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupAll: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupAny: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpReadPipe: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case SpvOpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case SpvOpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case SpvOpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case SpvOpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case SpvOpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case SpvOpRetainEvent: *hasResult = false; *hasResultType = false; break; + case SpvOpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case SpvOpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case SpvOpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case SpvOpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case SpvOpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case SpvOpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case SpvOpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case SpvOpNoLine: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case SpvOpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case SpvOpSizeOf: *hasResult = true; *hasResultType = true; break; + case SpvOpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case SpvOpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case SpvOpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case SpvOpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case SpvOpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case SpvOpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case SpvOpDecorateId: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break; + case SpvOpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpSDot: *hasResult = true; *hasResultType = true; break; + case SpvOpUDot: *hasResult = true; *hasResultType = true; break; + case SpvOpSUDot: *hasResult = true; *hasResultType = true; break; + case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break; + case SpvOpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleWeightedQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case SpvOpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break; + case SpvOpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectGetWorldToObjectNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetObjectToWorldNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetObjectRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetObjectRayOriginNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectGetShaderRecordBufferHandleNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetShaderBindingTableRecordIndexNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectRecordEmptyNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectTraceRayNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordHitNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordHitWithIndexNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectRecordMissNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectExecuteShaderNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectGetCurrentTimeNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetAttributesNV: *hasResult = false; *hasResultType = false; break; + case SpvOpHitObjectGetHitKindNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetPrimitiveIndexNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetGeometryIndexNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetInstanceIdNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetInstanceCustomIndexNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetWorldRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetWorldRayOriginNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetRayTMaxNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectGetRayTMinNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectIsEmptyNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectIsHitNV: *hasResult = true; *hasResultType = true; break; + case SpvOpHitObjectIsMissNV: *hasResult = true; *hasResultType = true; break; + case SpvOpReorderThreadWithHitObjectNV: *hasResult = false; *hasResultType = false; break; + case SpvOpReorderThreadWithHintNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeHitObjectNV: *hasResult = true; *hasResultType = false; break; + case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case SpvOpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case SpvOpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; + case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case SpvOpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpExpectKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +#endif + diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.hpp b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.hpp new file mode 100644 index 000000000000..327000af9a2d --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.hpp @@ -0,0 +1,2924 @@ +// Copyright (c) 2014-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010600; +static const unsigned int Revision = 1; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageCPP_for_OpenCL = 6, + SourceLanguageSYCL = 7, + SourceLanguageHERO_C = 8, + SourceLanguageNZSL = 9, + SourceLanguageWGSL = 10, + SourceLanguageSlang = 11, + SourceLanguageZig = 12, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelTaskNV = 5267, + ExecutionModelMeshNV = 5268, + ExecutionModelRayGenerationKHR = 5313, + ExecutionModelRayGenerationNV = 5313, + ExecutionModelIntersectionKHR = 5314, + ExecutionModelIntersectionNV = 5314, + ExecutionModelAnyHitKHR = 5315, + ExecutionModelAnyHitNV = 5315, + ExecutionModelClosestHitKHR = 5316, + ExecutionModelClosestHitNV = 5316, + ExecutionModelMissKHR = 5317, + ExecutionModelMissNV = 5317, + ExecutionModelCallableKHR = 5318, + ExecutionModelCallableNV = 5318, + ExecutionModelTaskEXT = 5364, + ExecutionModelMeshEXT = 5365, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelPhysicalStorageBuffer64 = 5348, + AddressingModelPhysicalStorageBuffer64EXT = 5348, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelVulkan = 3, + MemoryModelVulkanKHR = 3, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModeInitializer = 33, + ExecutionModeFinalizer = 34, + ExecutionModeSubgroupSize = 35, + ExecutionModeSubgroupsPerWorkgroup = 36, + ExecutionModeSubgroupsPerWorkgroupId = 37, + ExecutionModeLocalSizeId = 38, + ExecutionModeLocalSizeHintId = 39, + ExecutionModeNonCoherentColorAttachmentReadEXT = 4169, + ExecutionModeNonCoherentDepthAttachmentReadEXT = 4170, + ExecutionModeNonCoherentStencilAttachmentReadEXT = 4171, + ExecutionModeSubgroupUniformControlFlowKHR = 4421, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeDenormPreserve = 4459, + ExecutionModeDenormFlushToZero = 4460, + ExecutionModeSignedZeroInfNanPreserve = 4461, + ExecutionModeRoundingModeRTE = 4462, + ExecutionModeRoundingModeRTZ = 4463, + ExecutionModeEarlyAndLateFragmentTestsAMD = 5017, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeCoalescingAMDX = 5069, + ExecutionModeMaxNodeRecursionAMDX = 5071, + ExecutionModeStaticNumWorkgroupsAMDX = 5072, + ExecutionModeShaderIndexAMDX = 5073, + ExecutionModeMaxNumWorkgroupsAMDX = 5077, + ExecutionModeStencilRefUnchangedFrontAMD = 5079, + ExecutionModeStencilRefGreaterFrontAMD = 5080, + ExecutionModeStencilRefLessFrontAMD = 5081, + ExecutionModeStencilRefUnchangedBackAMD = 5082, + ExecutionModeStencilRefGreaterBackAMD = 5083, + ExecutionModeStencilRefLessBackAMD = 5084, + ExecutionModeQuadDerivativesKHR = 5088, + ExecutionModeRequireFullQuadsKHR = 5089, + ExecutionModeOutputLinesEXT = 5269, + ExecutionModeOutputLinesNV = 5269, + ExecutionModeOutputPrimitivesEXT = 5270, + ExecutionModeOutputPrimitivesNV = 5270, + ExecutionModeDerivativeGroupQuadsNV = 5289, + ExecutionModeDerivativeGroupLinearNV = 5290, + ExecutionModeOutputTrianglesEXT = 5298, + ExecutionModeOutputTrianglesNV = 5298, + ExecutionModePixelInterlockOrderedEXT = 5366, + ExecutionModePixelInterlockUnorderedEXT = 5367, + ExecutionModeSampleInterlockOrderedEXT = 5368, + ExecutionModeSampleInterlockUnorderedEXT = 5369, + ExecutionModeShadingRateInterlockOrderedEXT = 5370, + ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeSharedLocalMemorySizeINTEL = 5618, + ExecutionModeRoundingModeRTPINTEL = 5620, + ExecutionModeRoundingModeRTNINTEL = 5621, + ExecutionModeFloatingPointModeALTINTEL = 5622, + ExecutionModeFloatingPointModeIEEEINTEL = 5623, + ExecutionModeMaxWorkgroupSizeINTEL = 5893, + ExecutionModeMaxWorkDimINTEL = 5894, + ExecutionModeNoGlobalOffsetINTEL = 5895, + ExecutionModeNumSIMDWorkitemsINTEL = 5896, + ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + ExecutionModeMaximallyReconvergesKHR = 6023, + ExecutionModeFPFastMathDefault = 6028, + ExecutionModeStreamingInterfaceINTEL = 6154, + ExecutionModeRegisterMapInterfaceINTEL = 6160, + ExecutionModeNamedBarrierCountINTEL = 6417, + ExecutionModeMaximumRegistersINTEL = 6461, + ExecutionModeMaximumRegistersIdINTEL = 6462, + ExecutionModeNamedMaximumRegistersINTEL = 6463, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassTileImageEXT = 4172, + StorageClassNodePayloadAMDX = 5068, + StorageClassNodeOutputPayloadAMDX = 5076, + StorageClassCallableDataKHR = 5328, + StorageClassCallableDataNV = 5328, + StorageClassIncomingCallableDataKHR = 5329, + StorageClassIncomingCallableDataNV = 5329, + StorageClassRayPayloadKHR = 5338, + StorageClassRayPayloadNV = 5338, + StorageClassHitAttributeKHR = 5339, + StorageClassHitAttributeNV = 5339, + StorageClassIncomingRayPayloadKHR = 5342, + StorageClassIncomingRayPayloadNV = 5342, + StorageClassShaderRecordBufferKHR = 5343, + StorageClassShaderRecordBufferNV = 5343, + StorageClassPhysicalStorageBuffer = 5349, + StorageClassPhysicalStorageBufferEXT = 5349, + StorageClassHitObjectAttributeNV = 5385, + StorageClassTaskPayloadWorkgroupEXT = 5402, + StorageClassCodeSectionINTEL = 5605, + StorageClassDeviceOnlyINTEL = 5936, + StorageClassHostOnlyINTEL = 5937, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimTileImageDataEXT = 4173, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatR64ui = 40, + ImageFormatR64i = 41, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeUnsignedIntRaw10EXT = 19, + ImageChannelDataTypeUnsignedIntRaw12EXT = 20, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMakeTexelAvailableShift = 8, + ImageOperandsMakeTexelAvailableKHRShift = 8, + ImageOperandsMakeTexelVisibleShift = 9, + ImageOperandsMakeTexelVisibleKHRShift = 9, + ImageOperandsNonPrivateTexelShift = 10, + ImageOperandsNonPrivateTexelKHRShift = 10, + ImageOperandsVolatileTexelShift = 11, + ImageOperandsVolatileTexelKHRShift = 11, + ImageOperandsSignExtendShift = 12, + ImageOperandsZeroExtendShift = 13, + ImageOperandsNontemporalShift = 14, + ImageOperandsOffsetsShift = 16, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, + ImageOperandsMakeTexelAvailableMask = 0x00000100, + ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + ImageOperandsMakeTexelVisibleMask = 0x00000200, + ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + ImageOperandsNonPrivateTexelMask = 0x00000400, + ImageOperandsNonPrivateTexelKHRMask = 0x00000400, + ImageOperandsVolatileTexelMask = 0x00000800, + ImageOperandsVolatileTexelKHRMask = 0x00000800, + ImageOperandsSignExtendMask = 0x00001000, + ImageOperandsZeroExtendMask = 0x00002000, + ImageOperandsNontemporalMask = 0x00004000, + ImageOperandsOffsetsMask = 0x00010000, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeAllowContractShift = 16, + FPFastMathModeAllowContractFastINTELShift = 16, + FPFastMathModeAllowReassocShift = 17, + FPFastMathModeAllowReassocINTELShift = 17, + FPFastMathModeAllowTransformShift = 18, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, + FPFastMathModeAllowContractMask = 0x00010000, + FPFastMathModeAllowContractFastINTELMask = 0x00010000, + FPFastMathModeAllowReassocMask = 0x00020000, + FPFastMathModeAllowReassocINTELMask = 0x00020000, + FPFastMathModeAllowTransformMask = 0x00040000, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeLinkOnceODR = 2, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeRuntimeAlignedINTEL = 5940, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationUniformId = 27, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationMaxByteOffset = 45, + DecorationAlignmentId = 46, + DecorationMaxByteOffsetId = 47, + DecorationNoSignedWrap = 4469, + DecorationNoUnsignedWrap = 4470, + DecorationWeightTextureQCOM = 4487, + DecorationBlockMatchTextureQCOM = 4488, + DecorationBlockMatchSamplerQCOM = 4499, + DecorationExplicitInterpAMD = 4999, + DecorationNodeSharesPayloadLimitsWithAMDX = 5019, + DecorationNodeMaxPayloadsAMDX = 5020, + DecorationTrackFinishWritingAMDX = 5078, + DecorationPayloadNodeNameAMDX = 5091, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationPerPrimitiveEXT = 5271, + DecorationPerPrimitiveNV = 5271, + DecorationPerViewNV = 5272, + DecorationPerTaskNV = 5273, + DecorationPerVertexKHR = 5285, + DecorationPerVertexNV = 5285, + DecorationNonUniform = 5300, + DecorationNonUniformEXT = 5300, + DecorationRestrictPointer = 5355, + DecorationRestrictPointerEXT = 5355, + DecorationAliasedPointer = 5356, + DecorationAliasedPointerEXT = 5356, + DecorationHitObjectShaderRecordBufferNV = 5386, + DecorationBindlessSamplerNV = 5398, + DecorationBindlessImageNV = 5399, + DecorationBoundSamplerNV = 5400, + DecorationBoundImageNV = 5401, + DecorationSIMTCallINTEL = 5599, + DecorationReferencedIndirectlyINTEL = 5602, + DecorationClobberINTEL = 5607, + DecorationSideEffectsINTEL = 5608, + DecorationVectorComputeVariableINTEL = 5624, + DecorationFuncParamIOKindINTEL = 5625, + DecorationVectorComputeFunctionINTEL = 5626, + DecorationStackCallINTEL = 5627, + DecorationGlobalVariableOffsetINTEL = 5628, + DecorationCounterBuffer = 5634, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationUserSemantic = 5635, + DecorationUserTypeGOOGLE = 5636, + DecorationFunctionRoundingModeINTEL = 5822, + DecorationFunctionDenormModeINTEL = 5823, + DecorationRegisterINTEL = 5825, + DecorationMemoryINTEL = 5826, + DecorationNumbanksINTEL = 5827, + DecorationBankwidthINTEL = 5828, + DecorationMaxPrivateCopiesINTEL = 5829, + DecorationSinglepumpINTEL = 5830, + DecorationDoublepumpINTEL = 5831, + DecorationMaxReplicatesINTEL = 5832, + DecorationSimpleDualPortINTEL = 5833, + DecorationMergeINTEL = 5834, + DecorationBankBitsINTEL = 5835, + DecorationForcePow2DepthINTEL = 5836, + DecorationStridesizeINTEL = 5883, + DecorationWordsizeINTEL = 5884, + DecorationTrueDualPortINTEL = 5885, + DecorationBurstCoalesceINTEL = 5899, + DecorationCacheSizeINTEL = 5900, + DecorationDontStaticallyCoalesceINTEL = 5901, + DecorationPrefetchINTEL = 5902, + DecorationStallEnableINTEL = 5905, + DecorationFuseLoopsInFunctionINTEL = 5907, + DecorationMathOpDSPModeINTEL = 5909, + DecorationAliasScopeINTEL = 5914, + DecorationNoAliasINTEL = 5915, + DecorationInitiationIntervalINTEL = 5917, + DecorationMaxConcurrencyINTEL = 5918, + DecorationPipelineEnableINTEL = 5919, + DecorationBufferLocationINTEL = 5921, + DecorationIOPipeStorageINTEL = 5944, + DecorationFunctionFloatingPointModeINTEL = 6080, + DecorationSingleElementVectorINTEL = 6085, + DecorationVectorComputeCallableFunctionINTEL = 6087, + DecorationMediaBlockIOINTEL = 6140, + DecorationStallFreeINTEL = 6151, + DecorationFPMaxErrorDecorationINTEL = 6170, + DecorationLatencyControlLabelINTEL = 6172, + DecorationLatencyControlConstraintINTEL = 6173, + DecorationConduitKernelArgumentINTEL = 6175, + DecorationRegisterMapKernelArgumentINTEL = 6176, + DecorationMMHostInterfaceAddressWidthINTEL = 6177, + DecorationMMHostInterfaceDataWidthINTEL = 6178, + DecorationMMHostInterfaceLatencyINTEL = 6179, + DecorationMMHostInterfaceReadWriteModeINTEL = 6180, + DecorationMMHostInterfaceMaxBurstINTEL = 6181, + DecorationMMHostInterfaceWaitRequestINTEL = 6182, + DecorationStableKernelArgumentINTEL = 6183, + DecorationHostAccessINTEL = 6188, + DecorationInitModeINTEL = 6190, + DecorationImplementInRegisterMapINTEL = 6191, + DecorationCacheControlLoadINTEL = 6442, + DecorationCacheControlStoreINTEL = 6443, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInCoreIDARM = 4160, + BuiltInCoreCountARM = 4161, + BuiltInCoreMaxIDARM = 4162, + BuiltInWarpIDARM = 4163, + BuiltInWarpMaxIDARM = 4164, + BuiltInSubgroupEqMask = 4416, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMask = 4417, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMask = 4418, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMask = 4419, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMask = 4420, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInPrimitiveShadingRateKHR = 4432, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInShadingRateKHR = 4444, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInCoalescedInputCountAMDX = 5021, + BuiltInShaderIndexAMDX = 5073, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInFullyCoveredEXT = 5264, + BuiltInTaskCountNV = 5274, + BuiltInPrimitiveCountNV = 5275, + BuiltInPrimitiveIndicesNV = 5276, + BuiltInClipDistancePerViewNV = 5277, + BuiltInCullDistancePerViewNV = 5278, + BuiltInLayerPerViewNV = 5279, + BuiltInMeshViewCountNV = 5280, + BuiltInMeshViewIndicesNV = 5281, + BuiltInBaryCoordKHR = 5286, + BuiltInBaryCoordNV = 5286, + BuiltInBaryCoordNoPerspKHR = 5287, + BuiltInBaryCoordNoPerspNV = 5287, + BuiltInFragSizeEXT = 5292, + BuiltInFragmentSizeNV = 5292, + BuiltInFragInvocationCountEXT = 5293, + BuiltInInvocationsPerPixelNV = 5293, + BuiltInPrimitivePointIndicesEXT = 5294, + BuiltInPrimitiveLineIndicesEXT = 5295, + BuiltInPrimitiveTriangleIndicesEXT = 5296, + BuiltInCullPrimitiveEXT = 5299, + BuiltInLaunchIdKHR = 5319, + BuiltInLaunchIdNV = 5319, + BuiltInLaunchSizeKHR = 5320, + BuiltInLaunchSizeNV = 5320, + BuiltInWorldRayOriginKHR = 5321, + BuiltInWorldRayOriginNV = 5321, + BuiltInWorldRayDirectionKHR = 5322, + BuiltInWorldRayDirectionNV = 5322, + BuiltInObjectRayOriginKHR = 5323, + BuiltInObjectRayOriginNV = 5323, + BuiltInObjectRayDirectionKHR = 5324, + BuiltInObjectRayDirectionNV = 5324, + BuiltInRayTminKHR = 5325, + BuiltInRayTminNV = 5325, + BuiltInRayTmaxKHR = 5326, + BuiltInRayTmaxNV = 5326, + BuiltInInstanceCustomIndexKHR = 5327, + BuiltInInstanceCustomIndexNV = 5327, + BuiltInObjectToWorldKHR = 5330, + BuiltInObjectToWorldNV = 5330, + BuiltInWorldToObjectKHR = 5331, + BuiltInWorldToObjectNV = 5331, + BuiltInHitTNV = 5332, + BuiltInHitKindKHR = 5333, + BuiltInHitKindNV = 5333, + BuiltInCurrentRayTimeNV = 5334, + BuiltInHitTriangleVertexPositionsKHR = 5335, + BuiltInHitMicroTriangleVertexPositionsNV = 5337, + BuiltInHitMicroTriangleVertexBarycentricsNV = 5344, + BuiltInIncomingRayFlagsKHR = 5351, + BuiltInIncomingRayFlagsNV = 5351, + BuiltInRayGeometryIndexKHR = 5352, + BuiltInWarpsPerSMNV = 5374, + BuiltInSMCountNV = 5375, + BuiltInWarpIDNV = 5376, + BuiltInSMIDNV = 5377, + BuiltInHitKindFrontFacingMicroTriangleNV = 5405, + BuiltInHitKindBackFacingMicroTriangleNV = 5406, + BuiltInCullMaskKHR = 6021, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlDependencyInfiniteShift = 2, + LoopControlDependencyLengthShift = 3, + LoopControlMinIterationsShift = 4, + LoopControlMaxIterationsShift = 5, + LoopControlIterationMultipleShift = 6, + LoopControlPeelCountShift = 7, + LoopControlPartialCountShift = 8, + LoopControlInitiationIntervalINTELShift = 16, + LoopControlMaxConcurrencyINTELShift = 17, + LoopControlDependencyArrayINTELShift = 18, + LoopControlPipelineEnableINTELShift = 19, + LoopControlLoopCoalesceINTELShift = 20, + LoopControlMaxInterleavingINTELShift = 21, + LoopControlSpeculatedIterationsINTELShift = 22, + LoopControlNoFusionINTELShift = 23, + LoopControlLoopCountINTELShift = 24, + LoopControlMaxReinvocationDelayINTELShift = 25, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, + LoopControlDependencyInfiniteMask = 0x00000004, + LoopControlDependencyLengthMask = 0x00000008, + LoopControlMinIterationsMask = 0x00000010, + LoopControlMaxIterationsMask = 0x00000020, + LoopControlIterationMultipleMask = 0x00000040, + LoopControlPeelCountMask = 0x00000080, + LoopControlPartialCountMask = 0x00000100, + LoopControlInitiationIntervalINTELMask = 0x00010000, + LoopControlMaxConcurrencyINTELMask = 0x00020000, + LoopControlDependencyArrayINTELMask = 0x00040000, + LoopControlPipelineEnableINTELMask = 0x00080000, + LoopControlLoopCoalesceINTELMask = 0x00100000, + LoopControlMaxInterleavingINTELMask = 0x00200000, + LoopControlSpeculatedIterationsINTELMask = 0x00400000, + LoopControlNoFusionINTELMask = 0x00800000, + LoopControlLoopCountINTELMask = 0x01000000, + LoopControlMaxReinvocationDelayINTELMask = 0x02000000, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlOptNoneINTELShift = 16, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, + FunctionControlOptNoneINTELMask = 0x00010000, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsOutputMemoryShift = 12, + MemorySemanticsOutputMemoryKHRShift = 12, + MemorySemanticsMakeAvailableShift = 13, + MemorySemanticsMakeAvailableKHRShift = 13, + MemorySemanticsMakeVisibleShift = 14, + MemorySemanticsMakeVisibleKHRShift = 14, + MemorySemanticsVolatileShift = 15, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, + MemorySemanticsOutputMemoryMask = 0x00001000, + MemorySemanticsOutputMemoryKHRMask = 0x00001000, + MemorySemanticsMakeAvailableMask = 0x00002000, + MemorySemanticsMakeAvailableKHRMask = 0x00002000, + MemorySemanticsMakeVisibleMask = 0x00004000, + MemorySemanticsMakeVisibleKHRMask = 0x00004000, + MemorySemanticsVolatileMask = 0x00008000, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMakePointerAvailableShift = 3, + MemoryAccessMakePointerAvailableKHRShift = 3, + MemoryAccessMakePointerVisibleShift = 4, + MemoryAccessMakePointerVisibleKHRShift = 4, + MemoryAccessNonPrivatePointerShift = 5, + MemoryAccessNonPrivatePointerKHRShift = 5, + MemoryAccessAliasScopeINTELMaskShift = 16, + MemoryAccessNoAliasINTELMaskShift = 17, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, + MemoryAccessMakePointerAvailableMask = 0x00000008, + MemoryAccessMakePointerAvailableKHRMask = 0x00000008, + MemoryAccessMakePointerVisibleMask = 0x00000010, + MemoryAccessMakePointerVisibleKHRMask = 0x00000010, + MemoryAccessNonPrivatePointerMask = 0x00000020, + MemoryAccessNonPrivatePointerKHRMask = 0x00000020, + MemoryAccessAliasScopeINTELMaskMask = 0x00010000, + MemoryAccessNoAliasINTELMaskMask = 0x00020000, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeQueueFamily = 5, + ScopeQueueFamilyKHR = 5, + ScopeShaderCallKHR = 6, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationClusteredReduce = 3, + GroupOperationPartitionedReduceNV = 6, + GroupOperationPartitionedInclusiveScanNV = 7, + GroupOperationPartitionedExclusiveScanNV = 8, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupDispatch = 58, + CapabilityNamedBarrier = 59, + CapabilityPipeStorage = 60, + CapabilityGroupNonUniform = 61, + CapabilityGroupNonUniformVote = 62, + CapabilityGroupNonUniformArithmetic = 63, + CapabilityGroupNonUniformBallot = 64, + CapabilityGroupNonUniformShuffle = 65, + CapabilityGroupNonUniformShuffleRelative = 66, + CapabilityGroupNonUniformClustered = 67, + CapabilityGroupNonUniformQuad = 68, + CapabilityShaderLayer = 69, + CapabilityShaderViewportIndex = 70, + CapabilityUniformDecoration = 71, + CapabilityCoreBuiltinsARM = 4165, + CapabilityTileImageColorReadAccessEXT = 4166, + CapabilityTileImageDepthReadAccessEXT = 4167, + CapabilityTileImageStencilReadAccessEXT = 4168, + CapabilityFragmentShadingRateKHR = 4422, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityStorageBuffer8BitAccess = 4448, + CapabilityUniformAndStorageBuffer8BitAccess = 4449, + CapabilityStoragePushConstant8 = 4450, + CapabilityDenormPreserve = 4464, + CapabilityDenormFlushToZero = 4465, + CapabilitySignedZeroInfNanPreserve = 4466, + CapabilityRoundingModeRTE = 4467, + CapabilityRoundingModeRTZ = 4468, + CapabilityRayQueryProvisionalKHR = 4471, + CapabilityRayQueryKHR = 4472, + CapabilityRayTraversalPrimitiveCullingKHR = 4478, + CapabilityRayTracingKHR = 4479, + CapabilityTextureSampleWeightedQCOM = 4484, + CapabilityTextureBoxFilterQCOM = 4485, + CapabilityTextureBlockMatchQCOM = 4486, + CapabilityTextureBlockMatch2QCOM = 4498, + CapabilityFloat16ImageAMD = 5008, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilityInt64ImageEXT = 5016, + CapabilityShaderClockKHR = 5055, + CapabilityShaderEnqueueAMDX = 5067, + CapabilityQuadControlKHR = 5087, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilityFragmentFullyCoveredEXT = 5265, + CapabilityMeshShadingNV = 5266, + CapabilityImageFootprintNV = 5282, + CapabilityMeshShadingEXT = 5283, + CapabilityFragmentBarycentricKHR = 5284, + CapabilityFragmentBarycentricNV = 5284, + CapabilityComputeDerivativeGroupQuadsNV = 5288, + CapabilityFragmentDensityEXT = 5291, + CapabilityShadingRateNV = 5291, + CapabilityGroupNonUniformPartitionedNV = 5297, + CapabilityShaderNonUniform = 5301, + CapabilityShaderNonUniformEXT = 5301, + CapabilityRuntimeDescriptorArray = 5302, + CapabilityRuntimeDescriptorArrayEXT = 5302, + CapabilityInputAttachmentArrayDynamicIndexing = 5303, + CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, + CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, + CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + CapabilityUniformBufferArrayNonUniformIndexing = 5306, + CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + CapabilitySampledImageArrayNonUniformIndexing = 5307, + CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + CapabilityStorageBufferArrayNonUniformIndexing = 5308, + CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + CapabilityStorageImageArrayNonUniformIndexing = 5309, + CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + CapabilityInputAttachmentArrayNonUniformIndexing = 5310, + CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, + CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, + CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + CapabilityRayTracingPositionFetchKHR = 5336, + CapabilityRayTracingNV = 5340, + CapabilityRayTracingMotionBlurNV = 5341, + CapabilityVulkanMemoryModel = 5345, + CapabilityVulkanMemoryModelKHR = 5345, + CapabilityVulkanMemoryModelDeviceScope = 5346, + CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + CapabilityPhysicalStorageBufferAddresses = 5347, + CapabilityPhysicalStorageBufferAddressesEXT = 5347, + CapabilityComputeDerivativeGroupLinearNV = 5350, + CapabilityRayTracingProvisionalKHR = 5353, + CapabilityCooperativeMatrixNV = 5357, + CapabilityFragmentShaderSampleInterlockEXT = 5363, + CapabilityFragmentShaderShadingRateInterlockEXT = 5372, + CapabilityShaderSMBuiltinsNV = 5373, + CapabilityFragmentShaderPixelInterlockEXT = 5378, + CapabilityDemoteToHelperInvocation = 5379, + CapabilityDemoteToHelperInvocationEXT = 5379, + CapabilityDisplacementMicromapNV = 5380, + CapabilityRayTracingOpacityMicromapEXT = 5381, + CapabilityShaderInvocationReorderNV = 5383, + CapabilityBindlessTextureNV = 5390, + CapabilityRayQueryPositionFetchKHR = 5391, + CapabilityAtomicFloat16VectorNV = 5404, + CapabilityRayTracingDisplacementMicromapNV = 5409, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilitySubgroupImageMediaBlockIOINTEL = 5579, + CapabilityRoundToInfinityINTEL = 5582, + CapabilityFloatingPointModeINTEL = 5583, + CapabilityIntegerFunctions2INTEL = 5584, + CapabilityFunctionPointersINTEL = 5603, + CapabilityIndirectReferencesINTEL = 5604, + CapabilityAsmINTEL = 5606, + CapabilityAtomicFloat32MinMaxEXT = 5612, + CapabilityAtomicFloat64MinMaxEXT = 5613, + CapabilityAtomicFloat16MinMaxEXT = 5616, + CapabilityVectorComputeINTEL = 5617, + CapabilityVectorAnyINTEL = 5619, + CapabilityExpectAssumeKHR = 5629, + CapabilitySubgroupAvcMotionEstimationINTEL = 5696, + CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityVariableLengthArrayINTEL = 5817, + CapabilityFunctionFloatControlINTEL = 5821, + CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityFPFastMathModeINTEL = 5837, + CapabilityArbitraryPrecisionIntegersINTEL = 5844, + CapabilityArbitraryPrecisionFloatingPointINTEL = 5845, + CapabilityUnstructuredLoopControlsINTEL = 5886, + CapabilityFPGALoopControlsINTEL = 5888, + CapabilityKernelAttributesINTEL = 5892, + CapabilityFPGAKernelAttributesINTEL = 5897, + CapabilityFPGAMemoryAccessesINTEL = 5898, + CapabilityFPGAClusterAttributesINTEL = 5904, + CapabilityLoopFuseINTEL = 5906, + CapabilityFPGADSPControlINTEL = 5908, + CapabilityMemoryAccessAliasingINTEL = 5910, + CapabilityFPGAInvocationPipeliningAttributesINTEL = 5916, + CapabilityFPGABufferLocationINTEL = 5920, + CapabilityArbitraryPrecisionFixedPointINTEL = 5922, + CapabilityUSMStorageClassesINTEL = 5935, + CapabilityRuntimeAlignedAttributeINTEL = 5939, + CapabilityIOPipesINTEL = 5943, + CapabilityBlockingPipesINTEL = 5945, + CapabilityFPGARegINTEL = 5948, + CapabilityDotProductInputAll = 6016, + CapabilityDotProductInputAllKHR = 6016, + CapabilityDotProductInput4x8Bit = 6017, + CapabilityDotProductInput4x8BitKHR = 6017, + CapabilityDotProductInput4x8BitPacked = 6018, + CapabilityDotProductInput4x8BitPackedKHR = 6018, + CapabilityDotProduct = 6019, + CapabilityDotProductKHR = 6019, + CapabilityRayCullMaskKHR = 6020, + CapabilityCooperativeMatrixKHR = 6022, + CapabilityBitInstructions = 6025, + CapabilityGroupNonUniformRotateKHR = 6026, + CapabilityFloatControls2 = 6029, + CapabilityAtomicFloat32AddEXT = 6033, + CapabilityAtomicFloat64AddEXT = 6034, + CapabilityLongCompositesINTEL = 6089, + CapabilityOptNoneINTEL = 6094, + CapabilityAtomicFloat16AddEXT = 6095, + CapabilityDebugInfoModuleINTEL = 6114, + CapabilityBFloat16ConversionINTEL = 6115, + CapabilitySplitBarrierINTEL = 6141, + CapabilityFPGAClusterAttributesV2INTEL = 6150, + CapabilityFPGAKernelAttributesv2INTEL = 6161, + CapabilityFPMaxErrorINTEL = 6169, + CapabilityFPGALatencyControlINTEL = 6171, + CapabilityFPGAArgumentInterfacesINTEL = 6174, + CapabilityGlobalVariableHostAccessINTEL = 6187, + CapabilityGlobalVariableFPGADecorationsINTEL = 6189, + CapabilityGroupUniformArithmeticKHR = 6400, + CapabilityMaskedGatherScatterINTEL = 6427, + CapabilityCacheControlsINTEL = 6441, + CapabilityRegisterLimitsINTEL = 6460, + CapabilityMax = 0x7fffffff, +}; + +enum RayFlagsShift { + RayFlagsOpaqueKHRShift = 0, + RayFlagsNoOpaqueKHRShift = 1, + RayFlagsTerminateOnFirstHitKHRShift = 2, + RayFlagsSkipClosestHitShaderKHRShift = 3, + RayFlagsCullBackFacingTrianglesKHRShift = 4, + RayFlagsCullFrontFacingTrianglesKHRShift = 5, + RayFlagsCullOpaqueKHRShift = 6, + RayFlagsCullNoOpaqueKHRShift = 7, + RayFlagsSkipTrianglesKHRShift = 8, + RayFlagsSkipAABBsKHRShift = 9, + RayFlagsForceOpacityMicromap2StateEXTShift = 10, + RayFlagsMax = 0x7fffffff, +}; + +enum RayFlagsMask { + RayFlagsMaskNone = 0, + RayFlagsOpaqueKHRMask = 0x00000001, + RayFlagsNoOpaqueKHRMask = 0x00000002, + RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + RayFlagsCullOpaqueKHRMask = 0x00000040, + RayFlagsCullNoOpaqueKHRMask = 0x00000080, + RayFlagsSkipTrianglesKHRMask = 0x00000100, + RayFlagsSkipAABBsKHRMask = 0x00000200, + RayFlagsForceOpacityMicromap2StateEXTMask = 0x00000400, +}; + +enum RayQueryIntersection { + RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + RayQueryIntersectionMax = 0x7fffffff, +}; + +enum RayQueryCommittedIntersectionType { + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + RayQueryCommittedIntersectionTypeMax = 0x7fffffff, +}; + +enum RayQueryCandidateIntersectionType { + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + RayQueryCandidateIntersectionTypeMax = 0x7fffffff, +}; + +enum FragmentShadingRateShift { + FragmentShadingRateVertical2PixelsShift = 0, + FragmentShadingRateVertical4PixelsShift = 1, + FragmentShadingRateHorizontal2PixelsShift = 2, + FragmentShadingRateHorizontal4PixelsShift = 3, + FragmentShadingRateMax = 0x7fffffff, +}; + +enum FragmentShadingRateMask { + FragmentShadingRateMaskNone = 0, + FragmentShadingRateVertical2PixelsMask = 0x00000001, + FragmentShadingRateVertical4PixelsMask = 0x00000002, + FragmentShadingRateHorizontal2PixelsMask = 0x00000004, + FragmentShadingRateHorizontal4PixelsMask = 0x00000008, +}; + +enum FPDenormMode { + FPDenormModePreserve = 0, + FPDenormModeFlushToZero = 1, + FPDenormModeMax = 0x7fffffff, +}; + +enum FPOperationMode { + FPOperationModeIEEE = 0, + FPOperationModeALT = 1, + FPOperationModeMax = 0x7fffffff, +}; + +enum QuantizationModes { + QuantizationModesTRN = 0, + QuantizationModesTRN_ZERO = 1, + QuantizationModesRND = 2, + QuantizationModesRND_ZERO = 3, + QuantizationModesRND_INF = 4, + QuantizationModesRND_MIN_INF = 5, + QuantizationModesRND_CONV = 6, + QuantizationModesRND_CONV_ODD = 7, + QuantizationModesMax = 0x7fffffff, +}; + +enum OverflowModes { + OverflowModesWRAP = 0, + OverflowModesSAT = 1, + OverflowModesSAT_ZERO = 2, + OverflowModesSAT_SYM = 3, + OverflowModesMax = 0x7fffffff, +}; + +enum PackedVectorFormat { + PackedVectorFormatPackedVectorFormat4x8Bit = 0, + PackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + PackedVectorFormatMax = 0x7fffffff, +}; + +enum CooperativeMatrixOperandsShift { + CooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0, + CooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1, + CooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2, + CooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3, + CooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4, + CooperativeMatrixOperandsMax = 0x7fffffff, +}; + +enum CooperativeMatrixOperandsMask { + CooperativeMatrixOperandsMaskNone = 0, + CooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001, + CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002, + CooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004, + CooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008, + CooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010, +}; + +enum CooperativeMatrixLayout { + CooperativeMatrixLayoutRowMajorKHR = 0, + CooperativeMatrixLayoutColumnMajorKHR = 1, + CooperativeMatrixLayoutMax = 0x7fffffff, +}; + +enum CooperativeMatrixUse { + CooperativeMatrixUseMatrixAKHR = 0, + CooperativeMatrixUseMatrixBKHR = 1, + CooperativeMatrixUseMatrixAccumulatorKHR = 2, + CooperativeMatrixUseMax = 0x7fffffff, +}; + +enum InitializationModeQualifier { + InitializationModeQualifierInitOnDeviceReprogramINTEL = 0, + InitializationModeQualifierInitOnDeviceResetINTEL = 1, + InitializationModeQualifierMax = 0x7fffffff, +}; + +enum HostAccessQualifier { + HostAccessQualifierNoneINTEL = 0, + HostAccessQualifierReadINTEL = 1, + HostAccessQualifierWriteINTEL = 2, + HostAccessQualifierReadWriteINTEL = 3, + HostAccessQualifierMax = 0x7fffffff, +}; + +enum LoadCacheControl { + LoadCacheControlUncachedINTEL = 0, + LoadCacheControlCachedINTEL = 1, + LoadCacheControlStreamingINTEL = 2, + LoadCacheControlInvalidateAfterReadINTEL = 3, + LoadCacheControlConstCachedINTEL = 4, + LoadCacheControlMax = 0x7fffffff, +}; + +enum StoreCacheControl { + StoreCacheControlUncachedINTEL = 0, + StoreCacheControlWriteThroughINTEL = 1, + StoreCacheControlWriteBackINTEL = 2, + StoreCacheControlStreamingINTEL = 3, + StoreCacheControlMax = 0x7fffffff, +}; + +enum NamedMaximumNumberOfRegisters { + NamedMaximumNumberOfRegistersAutoINTEL = 0, + NamedMaximumNumberOfRegistersMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + OpMax = 0x7fffffff, +}; + +#ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif +inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case OpNop: *hasResult = false; *hasResultType = false; break; + case OpUndef: *hasResult = true; *hasResultType = true; break; + case OpSourceContinued: *hasResult = false; *hasResultType = false; break; + case OpSource: *hasResult = false; *hasResultType = false; break; + case OpSourceExtension: *hasResult = false; *hasResultType = false; break; + case OpName: *hasResult = false; *hasResultType = false; break; + case OpMemberName: *hasResult = false; *hasResultType = false; break; + case OpString: *hasResult = true; *hasResultType = false; break; + case OpLine: *hasResult = false; *hasResultType = false; break; + case OpExtension: *hasResult = false; *hasResultType = false; break; + case OpExtInstImport: *hasResult = true; *hasResultType = false; break; + case OpExtInst: *hasResult = true; *hasResultType = true; break; + case OpMemoryModel: *hasResult = false; *hasResultType = false; break; + case OpEntryPoint: *hasResult = false; *hasResultType = false; break; + case OpExecutionMode: *hasResult = false; *hasResultType = false; break; + case OpCapability: *hasResult = false; *hasResultType = false; break; + case OpTypeVoid: *hasResult = true; *hasResultType = false; break; + case OpTypeBool: *hasResult = true; *hasResultType = false; break; + case OpTypeInt: *hasResult = true; *hasResultType = false; break; + case OpTypeFloat: *hasResult = true; *hasResultType = false; break; + case OpTypeVector: *hasResult = true; *hasResultType = false; break; + case OpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case OpTypeImage: *hasResult = true; *hasResultType = false; break; + case OpTypeSampler: *hasResult = true; *hasResultType = false; break; + case OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case OpTypeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeStruct: *hasResult = true; *hasResultType = false; break; + case OpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case OpTypePointer: *hasResult = true; *hasResultType = false; break; + case OpTypeFunction: *hasResult = true; *hasResultType = false; break; + case OpTypeEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case OpTypeQueue: *hasResult = true; *hasResultType = false; break; + case OpTypePipe: *hasResult = true; *hasResultType = false; break; + case OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case OpConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpConstant: *hasResult = true; *hasResultType = true; break; + case OpConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpConstantSampler: *hasResult = true; *hasResultType = true; break; + case OpConstantNull: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpSpecConstant: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case OpFunction: *hasResult = true; *hasResultType = true; break; + case OpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case OpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case OpFunctionCall: *hasResult = true; *hasResultType = true; break; + case OpVariable: *hasResult = true; *hasResultType = true; break; + case OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case OpLoad: *hasResult = true; *hasResultType = true; break; + case OpStore: *hasResult = false; *hasResultType = false; break; + case OpCopyMemory: *hasResult = false; *hasResultType = false; break; + case OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case OpAccessChain: *hasResult = true; *hasResultType = true; break; + case OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpArrayLength: *hasResult = true; *hasResultType = true; break; + case OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpDecorate: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case OpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case OpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case OpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case OpCopyObject: *hasResult = true; *hasResultType = true; break; + case OpTranspose: *hasResult = true; *hasResultType = true; break; + case OpSampledImage: *hasResult = true; *hasResultType = true; break; + case OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageFetch: *hasResult = true; *hasResultType = true; break; + case OpImageGather: *hasResult = true; *hasResultType = true; break; + case OpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageRead: *hasResult = true; *hasResultType = true; break; + case OpImageWrite: *hasResult = false; *hasResultType = false; break; + case OpImage: *hasResult = true; *hasResultType = true; break; + case OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case OpConvertFToU: *hasResult = true; *hasResultType = true; break; + case OpConvertFToS: *hasResult = true; *hasResultType = true; break; + case OpConvertSToF: *hasResult = true; *hasResultType = true; break; + case OpConvertUToF: *hasResult = true; *hasResultType = true; break; + case OpUConvert: *hasResult = true; *hasResultType = true; break; + case OpSConvert: *hasResult = true; *hasResultType = true; break; + case OpFConvert: *hasResult = true; *hasResultType = true; break; + case OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case OpBitcast: *hasResult = true; *hasResultType = true; break; + case OpSNegate: *hasResult = true; *hasResultType = true; break; + case OpFNegate: *hasResult = true; *hasResultType = true; break; + case OpIAdd: *hasResult = true; *hasResultType = true; break; + case OpFAdd: *hasResult = true; *hasResultType = true; break; + case OpISub: *hasResult = true; *hasResultType = true; break; + case OpFSub: *hasResult = true; *hasResultType = true; break; + case OpIMul: *hasResult = true; *hasResultType = true; break; + case OpFMul: *hasResult = true; *hasResultType = true; break; + case OpUDiv: *hasResult = true; *hasResultType = true; break; + case OpSDiv: *hasResult = true; *hasResultType = true; break; + case OpFDiv: *hasResult = true; *hasResultType = true; break; + case OpUMod: *hasResult = true; *hasResultType = true; break; + case OpSRem: *hasResult = true; *hasResultType = true; break; + case OpSMod: *hasResult = true; *hasResultType = true; break; + case OpFRem: *hasResult = true; *hasResultType = true; break; + case OpFMod: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpOuterProduct: *hasResult = true; *hasResultType = true; break; + case OpDot: *hasResult = true; *hasResultType = true; break; + case OpIAddCarry: *hasResult = true; *hasResultType = true; break; + case OpISubBorrow: *hasResult = true; *hasResultType = true; break; + case OpUMulExtended: *hasResult = true; *hasResultType = true; break; + case OpSMulExtended: *hasResult = true; *hasResultType = true; break; + case OpAny: *hasResult = true; *hasResultType = true; break; + case OpAll: *hasResult = true; *hasResultType = true; break; + case OpIsNan: *hasResult = true; *hasResultType = true; break; + case OpIsInf: *hasResult = true; *hasResultType = true; break; + case OpIsFinite: *hasResult = true; *hasResultType = true; break; + case OpIsNormal: *hasResult = true; *hasResultType = true; break; + case OpSignBitSet: *hasResult = true; *hasResultType = true; break; + case OpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case OpOrdered: *hasResult = true; *hasResultType = true; break; + case OpUnordered: *hasResult = true; *hasResultType = true; break; + case OpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpLogicalNot: *hasResult = true; *hasResultType = true; break; + case OpSelect: *hasResult = true; *hasResultType = true; break; + case OpIEqual: *hasResult = true; *hasResultType = true; break; + case OpINotEqual: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpULessThan: *hasResult = true; *hasResultType = true; break; + case OpSLessThan: *hasResult = true; *hasResultType = true; break; + case OpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case OpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpNot: *hasResult = true; *hasResultType = true; break; + case OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case OpBitReverse: *hasResult = true; *hasResultType = true; break; + case OpBitCount: *hasResult = true; *hasResultType = true; break; + case OpDPdx: *hasResult = true; *hasResultType = true; break; + case OpDPdy: *hasResult = true; *hasResultType = true; break; + case OpFwidth: *hasResult = true; *hasResultType = true; break; + case OpDPdxFine: *hasResult = true; *hasResultType = true; break; + case OpDPdyFine: *hasResult = true; *hasResultType = true; break; + case OpFwidthFine: *hasResult = true; *hasResultType = true; break; + case OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case OpEmitVertex: *hasResult = false; *hasResultType = false; break; + case OpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case OpControlBarrier: *hasResult = false; *hasResultType = false; break; + case OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case OpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case OpAtomicStore: *hasResult = false; *hasResultType = false; break; + case OpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case OpAtomicISub: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case OpAtomicOr: *hasResult = true; *hasResultType = true; break; + case OpAtomicXor: *hasResult = true; *hasResultType = true; break; + case OpPhi: *hasResult = true; *hasResultType = true; break; + case OpLoopMerge: *hasResult = false; *hasResultType = false; break; + case OpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case OpLabel: *hasResult = true; *hasResultType = false; break; + case OpBranch: *hasResult = false; *hasResultType = false; break; + case OpBranchConditional: *hasResult = false; *hasResultType = false; break; + case OpSwitch: *hasResult = false; *hasResultType = false; break; + case OpKill: *hasResult = false; *hasResultType = false; break; + case OpReturn: *hasResult = false; *hasResultType = false; break; + case OpReturnValue: *hasResult = false; *hasResultType = false; break; + case OpUnreachable: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case OpGroupAll: *hasResult = true; *hasResultType = true; break; + case OpGroupAny: *hasResult = true; *hasResultType = true; break; + case OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupSMax: *hasResult = true; *hasResultType = true; break; + case OpReadPipe: *hasResult = true; *hasResultType = true; break; + case OpWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case OpRetainEvent: *hasResult = false; *hasResultType = false; break; + case OpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case OpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case OpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case OpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case OpNoLine: *hasResult = false; *hasResultType = false; break; + case OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case OpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case OpSizeOf: *hasResult = true; *hasResultType = true; break; + case OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case OpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case OpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case OpDecorateId: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case OpCopyLogical: *hasResult = true; *hasResultType = true; break; + case OpPtrEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case OpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case OpSDot: *hasResult = true; *hasResultType = true; break; + case OpUDot: *hasResult = true; *hasResultType = true; break; + case OpSUDot: *hasResult = true; *hasResultType = true; break; + case OpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break; + case OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; + case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case OpImageSampleWeightedQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case OpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case OpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break; + case OpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; + case OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetWorldToObjectNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectToWorldNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectRayOriginNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetShaderRecordBufferHandleNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetShaderBindingTableRecordIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectRecordEmptyNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectTraceRayNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitWithIndexNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordMissNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectExecuteShaderNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetCurrentTimeNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetAttributesNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetHitKindNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetPrimitiveIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetGeometryIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetInstanceIdNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetInstanceCustomIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetWorldRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetWorldRayOriginNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetRayTMaxNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetRayTMinNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsEmptyNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsHitNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsMissNV: *hasResult = true; *hasResultType = true; break; + case OpReorderThreadWithHitObjectNV: *hasResult = false; *hasResultType = false; break; + case OpReorderThreadWithHintNV: *hasResult = false; *hasResultType = false; break; + case OpTypeHitObjectNV: *hasResult = true; *hasResultType = false; break; + case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case OpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case OpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; + case OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; + case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case OpTraceNV: *hasResult = false; *hasResultType = false; break; + case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; + case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case OpExpectKHR: *hasResult = true; *hasResultType = true; break; + case OpDecorateString: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break; + case OpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break; + case OpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break; + case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; + case OpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break; + case OpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +// Overload bitwise operators for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline ImageOperandsMask operator&(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) & unsigned(b)); } +inline ImageOperandsMask operator^(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) ^ unsigned(b)); } +inline ImageOperandsMask operator~(ImageOperandsMask a) { return ImageOperandsMask(~unsigned(a)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator&(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) & unsigned(b)); } +inline FPFastMathModeMask operator^(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) ^ unsigned(b)); } +inline FPFastMathModeMask operator~(FPFastMathModeMask a) { return FPFastMathModeMask(~unsigned(a)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator&(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) & unsigned(b)); } +inline SelectionControlMask operator^(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) ^ unsigned(b)); } +inline SelectionControlMask operator~(SelectionControlMask a) { return SelectionControlMask(~unsigned(a)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator&(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) & unsigned(b)); } +inline LoopControlMask operator^(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) ^ unsigned(b)); } +inline LoopControlMask operator~(LoopControlMask a) { return LoopControlMask(~unsigned(a)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator&(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) & unsigned(b)); } +inline FunctionControlMask operator^(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) ^ unsigned(b)); } +inline FunctionControlMask operator~(FunctionControlMask a) { return FunctionControlMask(~unsigned(a)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator&(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) & unsigned(b)); } +inline MemorySemanticsMask operator^(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) ^ unsigned(b)); } +inline MemorySemanticsMask operator~(MemorySemanticsMask a) { return MemorySemanticsMask(~unsigned(a)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator&(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) & unsigned(b)); } +inline MemoryAccessMask operator^(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) ^ unsigned(b)); } +inline MemoryAccessMask operator~(MemoryAccessMask a) { return MemoryAccessMask(~unsigned(a)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator&(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) & unsigned(b)); } +inline KernelProfilingInfoMask operator^(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) ^ unsigned(b)); } +inline KernelProfilingInfoMask operator~(KernelProfilingInfoMask a) { return KernelProfilingInfoMask(~unsigned(a)); } +inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } +inline RayFlagsMask operator&(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) & unsigned(b)); } +inline RayFlagsMask operator^(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) ^ unsigned(b)); } +inline RayFlagsMask operator~(RayFlagsMask a) { return RayFlagsMask(~unsigned(a)); } +inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } +inline FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); } +inline FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); } +inline FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); } +inline CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) | unsigned(b)); } +inline CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); } +inline CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); } +inline CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.hpp11 b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.hpp11 new file mode 100644 index 000000000000..79307fd451d8 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.hpp11 @@ -0,0 +1,2924 @@ +// Copyright (c) 2014-2024 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and/or associated documentation files (the "Materials"), +// to deal in the Materials without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Materials, and to permit persons to whom the +// Materials are furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +// IN THE MATERIALS. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010600; +static const unsigned int Revision = 1; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + NodeOutputPayloadAMDX = 5076, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + LinkOnceODR = 2, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + CoalescedInputCountAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + Max = 0x7fffffff, +}; + +enum class RayFlagsShift : unsigned { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + Max = 0x7fffffff, +}; + +enum class RayFlagsMask : unsigned { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, +}; + +enum class RayQueryIntersection : unsigned { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + Max = 0x7fffffff, +}; + +enum class RayQueryCommittedIntersectionType : unsigned { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + Max = 0x7fffffff, +}; + +enum class RayQueryCandidateIntersectionType : unsigned { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + Max = 0x7fffffff, +}; + +enum class FragmentShadingRateShift : unsigned { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + Max = 0x7fffffff, +}; + +enum class FragmentShadingRateMask : unsigned { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, +}; + +enum class FPDenormMode : unsigned { + Preserve = 0, + FlushToZero = 1, + Max = 0x7fffffff, +}; + +enum class FPOperationMode : unsigned { + IEEE = 0, + ALT = 1, + Max = 0x7fffffff, +}; + +enum class QuantizationModes : unsigned { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + Max = 0x7fffffff, +}; + +enum class OverflowModes : unsigned { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + Max = 0x7fffffff, +}; + +enum class PackedVectorFormat : unsigned { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixOperandsShift : unsigned { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixOperandsMask : unsigned { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, +}; + +enum class CooperativeMatrixLayout : unsigned { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixUse : unsigned { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + Max = 0x7fffffff, +}; + +enum class InitializationModeQualifier : unsigned { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + Max = 0x7fffffff, +}; + +enum class HostAccessQualifier : unsigned { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + Max = 0x7fffffff, +}; + +enum class LoadCacheControl : unsigned { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + Max = 0x7fffffff, +}; + +enum class StoreCacheControl : unsigned { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + Max = 0x7fffffff, +}; + +enum class NamedMaximumNumberOfRegisters : unsigned { + AutoINTEL = 0, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + Max = 0x7fffffff, +}; + +#ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif +inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case Op::OpNop: *hasResult = false; *hasResultType = false; break; + case Op::OpUndef: *hasResult = true; *hasResultType = true; break; + case Op::OpSourceContinued: *hasResult = false; *hasResultType = false; break; + case Op::OpSource: *hasResult = false; *hasResultType = false; break; + case Op::OpSourceExtension: *hasResult = false; *hasResultType = false; break; + case Op::OpName: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberName: *hasResult = false; *hasResultType = false; break; + case Op::OpString: *hasResult = true; *hasResultType = false; break; + case Op::OpLine: *hasResult = false; *hasResultType = false; break; + case Op::OpExtension: *hasResult = false; *hasResultType = false; break; + case Op::OpExtInstImport: *hasResult = true; *hasResultType = false; break; + case Op::OpExtInst: *hasResult = true; *hasResultType = true; break; + case Op::OpMemoryModel: *hasResult = false; *hasResultType = false; break; + case Op::OpEntryPoint: *hasResult = false; *hasResultType = false; break; + case Op::OpExecutionMode: *hasResult = false; *hasResultType = false; break; + case Op::OpCapability: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeVoid: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeBool: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeInt: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeFloat: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeVector: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeImage: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeSampler: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeArray: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeStruct: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case Op::OpTypePointer: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeFunction: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeEvent: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeQueue: *hasResult = true; *hasResultType = false; break; + case Op::OpTypePipe: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case Op::OpConstantTrue: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantFalse: *hasResult = true; *hasResultType = true; break; + case Op::OpConstant: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantComposite: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantSampler: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantNull: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstant: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case Op::OpFunction: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case Op::OpFunctionCall: *hasResult = true; *hasResultType = true; break; + case Op::OpVariable: *hasResult = true; *hasResultType = true; break; + case Op::OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case Op::OpLoad: *hasResult = true; *hasResultType = true; break; + case Op::OpStore: *hasResult = false; *hasResultType = false; break; + case Op::OpCopyMemory: *hasResult = false; *hasResultType = false; break; + case Op::OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case Op::OpAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpArrayLength: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case Op::OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case Op::OpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case Op::OpCopyObject: *hasResult = true; *hasResultType = true; break; + case Op::OpTranspose: *hasResult = true; *hasResultType = true; break; + case Op::OpSampledImage: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageFetch: *hasResult = true; *hasResultType = true; break; + case Op::OpImageGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageRead: *hasResult = true; *hasResultType = true; break; + case Op::OpImageWrite: *hasResult = false; *hasResultType = false; break; + case Op::OpImage: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToU: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToS: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSToF: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToF: *hasResult = true; *hasResultType = true; break; + case Op::OpUConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpSConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpFConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case Op::OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case Op::OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case Op::OpBitcast: *hasResult = true; *hasResultType = true; break; + case Op::OpSNegate: *hasResult = true; *hasResultType = true; break; + case Op::OpFNegate: *hasResult = true; *hasResultType = true; break; + case Op::OpIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpISub: *hasResult = true; *hasResultType = true; break; + case Op::OpFSub: *hasResult = true; *hasResultType = true; break; + case Op::OpIMul: *hasResult = true; *hasResultType = true; break; + case Op::OpFMul: *hasResult = true; *hasResultType = true; break; + case Op::OpUDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpSDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpFDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpUMod: *hasResult = true; *hasResultType = true; break; + case Op::OpSRem: *hasResult = true; *hasResultType = true; break; + case Op::OpSMod: *hasResult = true; *hasResultType = true; break; + case Op::OpFRem: *hasResult = true; *hasResultType = true; break; + case Op::OpFMod: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case Op::OpOuterProduct: *hasResult = true; *hasResultType = true; break; + case Op::OpDot: *hasResult = true; *hasResultType = true; break; + case Op::OpIAddCarry: *hasResult = true; *hasResultType = true; break; + case Op::OpISubBorrow: *hasResult = true; *hasResultType = true; break; + case Op::OpUMulExtended: *hasResult = true; *hasResultType = true; break; + case Op::OpSMulExtended: *hasResult = true; *hasResultType = true; break; + case Op::OpAny: *hasResult = true; *hasResultType = true; break; + case Op::OpAll: *hasResult = true; *hasResultType = true; break; + case Op::OpIsNan: *hasResult = true; *hasResultType = true; break; + case Op::OpIsInf: *hasResult = true; *hasResultType = true; break; + case Op::OpIsFinite: *hasResult = true; *hasResultType = true; break; + case Op::OpIsNormal: *hasResult = true; *hasResultType = true; break; + case Op::OpSignBitSet: *hasResult = true; *hasResultType = true; break; + case Op::OpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case Op::OpOrdered: *hasResult = true; *hasResultType = true; break; + case Op::OpUnordered: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalOr: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalNot: *hasResult = true; *hasResultType = true; break; + case Op::OpSelect: *hasResult = true; *hasResultType = true; break; + case Op::OpIEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpINotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpULessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpSLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpNot: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpBitReverse: *hasResult = true; *hasResultType = true; break; + case Op::OpBitCount: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdx: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdy: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidth: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdxFine: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdyFine: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidthFine: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpEmitVertex: *hasResult = false; *hasResultType = false; break; + case Op::OpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case Op::OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case Op::OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case Op::OpControlBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicStore: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicISub: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicOr: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicXor: *hasResult = true; *hasResultType = true; break; + case Op::OpPhi: *hasResult = true; *hasResultType = true; break; + case Op::OpLoopMerge: *hasResult = false; *hasResultType = false; break; + case Op::OpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case Op::OpLabel: *hasResult = true; *hasResultType = false; break; + case Op::OpBranch: *hasResult = false; *hasResultType = false; break; + case Op::OpBranchConditional: *hasResult = false; *hasResultType = false; break; + case Op::OpSwitch: *hasResult = false; *hasResultType = false; break; + case Op::OpKill: *hasResult = false; *hasResultType = false; break; + case Op::OpReturn: *hasResult = false; *hasResultType = false; break; + case Op::OpReturnValue: *hasResult = false; *hasResultType = false; break; + case Op::OpUnreachable: *hasResult = false; *hasResultType = false; break; + case Op::OpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case Op::OpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupAll: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupAny: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpReadPipe: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case Op::OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case Op::OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case Op::OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case Op::OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case Op::OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case Op::OpRetainEvent: *hasResult = false; *hasResultType = false; break; + case Op::OpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case Op::OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case Op::OpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case Op::OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case Op::OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case Op::OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case Op::OpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case Op::OpNoLine: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case Op::OpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case Op::OpSizeOf: *hasResult = true; *hasResultType = true; break; + case Op::OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case Op::OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case Op::OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case Op::OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case Op::OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case Op::OpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case Op::OpDecorateId: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case Op::OpCopyLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case Op::OpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpSDot: *hasResult = true; *hasResultType = true; break; + case Op::OpUDot: *hasResult = true; *hasResultType = true; break; + case Op::OpSUDot: *hasResult = true; *hasResultType = true; break; + case Op::OpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break; + case Op::OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case Op::OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleWeightedQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case Op::OpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break; + case Op::OpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetWorldToObjectNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectToWorldNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectRayOriginNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetShaderRecordBufferHandleNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetShaderBindingTableRecordIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectRecordEmptyNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectTraceRayNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitWithIndexNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordMissNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectExecuteShaderNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetCurrentTimeNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetAttributesNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetHitKindNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetPrimitiveIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetGeometryIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetInstanceIdNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetInstanceCustomIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetWorldRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetWorldRayOriginNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetRayTMaxNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetRayTMinNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsEmptyNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsHitNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsMissNV: *hasResult = true; *hasResultType = true; break; + case Op::OpReorderThreadWithHitObjectNV: *hasResult = false; *hasResultType = false; break; + case Op::OpReorderThreadWithHintNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeHitObjectNV: *hasResult = true; *hasResultType = false; break; + case Op::OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case Op::OpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case Op::OpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; + case Op::OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case Op::OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case Op::OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case Op::OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case Op::OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpExpectKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpDecorateString: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case Op::OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +// Overload bitwise operators for mask bit combining + +constexpr ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +constexpr ImageOperandsMask operator&(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) & unsigned(b)); } +constexpr ImageOperandsMask operator^(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr ImageOperandsMask operator~(ImageOperandsMask a) { return ImageOperandsMask(~unsigned(a)); } +constexpr FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +constexpr FPFastMathModeMask operator&(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) & unsigned(b)); } +constexpr FPFastMathModeMask operator^(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) ^ unsigned(b)); } +constexpr FPFastMathModeMask operator~(FPFastMathModeMask a) { return FPFastMathModeMask(~unsigned(a)); } +constexpr SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +constexpr SelectionControlMask operator&(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) & unsigned(b)); } +constexpr SelectionControlMask operator^(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) ^ unsigned(b)); } +constexpr SelectionControlMask operator~(SelectionControlMask a) { return SelectionControlMask(~unsigned(a)); } +constexpr LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +constexpr LoopControlMask operator&(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) & unsigned(b)); } +constexpr LoopControlMask operator^(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) ^ unsigned(b)); } +constexpr LoopControlMask operator~(LoopControlMask a) { return LoopControlMask(~unsigned(a)); } +constexpr FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +constexpr FunctionControlMask operator&(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) & unsigned(b)); } +constexpr FunctionControlMask operator^(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) ^ unsigned(b)); } +constexpr FunctionControlMask operator~(FunctionControlMask a) { return FunctionControlMask(~unsigned(a)); } +constexpr MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +constexpr MemorySemanticsMask operator&(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) & unsigned(b)); } +constexpr MemorySemanticsMask operator^(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) ^ unsigned(b)); } +constexpr MemorySemanticsMask operator~(MemorySemanticsMask a) { return MemorySemanticsMask(~unsigned(a)); } +constexpr MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +constexpr MemoryAccessMask operator&(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) & unsigned(b)); } +constexpr MemoryAccessMask operator^(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) ^ unsigned(b)); } +constexpr MemoryAccessMask operator~(MemoryAccessMask a) { return MemoryAccessMask(~unsigned(a)); } +constexpr KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +constexpr KernelProfilingInfoMask operator&(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) & unsigned(b)); } +constexpr KernelProfilingInfoMask operator^(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) ^ unsigned(b)); } +constexpr KernelProfilingInfoMask operator~(KernelProfilingInfoMask a) { return KernelProfilingInfoMask(~unsigned(a)); } +constexpr RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } +constexpr RayFlagsMask operator&(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) & unsigned(b)); } +constexpr RayFlagsMask operator^(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) ^ unsigned(b)); } +constexpr RayFlagsMask operator~(RayFlagsMask a) { return RayFlagsMask(~unsigned(a)); } +constexpr FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } +constexpr FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); } +constexpr FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); } +constexpr FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); } +constexpr CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) | unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.json b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.json new file mode 100644 index 000000000000..c329090aa238 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.json @@ -0,0 +1,2145 @@ +{ + "spv": + { + "meta": + { + "Comment": + [ + [ + "Copyright (c) 2014-2024 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + [ + "This header is automatically generated by the same tool that creates", + "the Binary Section of the SPIR-V specification." + ], + [ + "Enumeration tokens for SPIR-V, in various styles:", + " C, C++, C++11, JSON, Lua, Python, C#, D, Beef", + "", + "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", + "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", + "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", + "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", + "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "- C# will use enum classes in the Specification class located in the \"Spv\" namespace,", + " e.g.: Spv.Specification.SourceLanguage.GLSL", + "- D will have tokens under the \"spv\" module, e.g: spv.SourceLanguage.GLSL", + "- Beef will use enum classes in the Specification class located in the \"Spv\" namespace,", + " e.g.: Spv.Specification.SourceLanguage.GLSL", + "", + "Some tokens act like mask values, which can be OR'd together,", + "while others are mutually exclusive. The mask-like ones have", + "\"Mask\" in their name, and a parallel enum that has the shift", + "amount (1 << x) for each corresponding enumerant." + ] + ], + "MagicNumber": 119734787, + "Version": 67072, + "Revision": 1, + "OpCodeMask": 65535, + "WordCountShift": 16 + }, + "enum": + [ + { + "Name": "SourceLanguage", + "Type": "Value", + "Values": + { + "Unknown": 0, + "ESSL": 1, + "GLSL": 2, + "OpenCL_C": 3, + "OpenCL_CPP": 4, + "HLSL": 5, + "CPP_for_OpenCL": 6, + "SYCL": 7, + "HERO_C": 8, + "NZSL": 9, + "WGSL": 10, + "Slang": 11, + "Zig": 12 + } + }, + { + "Name": "ExecutionModel", + "Type": "Value", + "Values": + { + "Vertex": 0, + "TessellationControl": 1, + "TessellationEvaluation": 2, + "Geometry": 3, + "Fragment": 4, + "GLCompute": 5, + "Kernel": 6, + "TaskNV": 5267, + "MeshNV": 5268, + "RayGenerationKHR": 5313, + "RayGenerationNV": 5313, + "IntersectionKHR": 5314, + "IntersectionNV": 5314, + "AnyHitKHR": 5315, + "AnyHitNV": 5315, + "ClosestHitKHR": 5316, + "ClosestHitNV": 5316, + "MissKHR": 5317, + "MissNV": 5317, + "CallableKHR": 5318, + "CallableNV": 5318, + "TaskEXT": 5364, + "MeshEXT": 5365 + } + }, + { + "Name": "AddressingModel", + "Type": "Value", + "Values": + { + "Logical": 0, + "Physical32": 1, + "Physical64": 2, + "PhysicalStorageBuffer64": 5348, + "PhysicalStorageBuffer64EXT": 5348 + } + }, + { + "Name": "MemoryModel", + "Type": "Value", + "Values": + { + "Simple": 0, + "GLSL450": 1, + "OpenCL": 2, + "Vulkan": 3, + "VulkanKHR": 3 + } + }, + { + "Name": "ExecutionMode", + "Type": "Value", + "Values": + { + "Invocations": 0, + "SpacingEqual": 1, + "SpacingFractionalEven": 2, + "SpacingFractionalOdd": 3, + "VertexOrderCw": 4, + "VertexOrderCcw": 5, + "PixelCenterInteger": 6, + "OriginUpperLeft": 7, + "OriginLowerLeft": 8, + "EarlyFragmentTests": 9, + "PointMode": 10, + "Xfb": 11, + "DepthReplacing": 12, + "DepthGreater": 14, + "DepthLess": 15, + "DepthUnchanged": 16, + "LocalSize": 17, + "LocalSizeHint": 18, + "InputPoints": 19, + "InputLines": 20, + "InputLinesAdjacency": 21, + "Triangles": 22, + "InputTrianglesAdjacency": 23, + "Quads": 24, + "Isolines": 25, + "OutputVertices": 26, + "OutputPoints": 27, + "OutputLineStrip": 28, + "OutputTriangleStrip": 29, + "VecTypeHint": 30, + "ContractionOff": 31, + "Initializer": 33, + "Finalizer": 34, + "SubgroupSize": 35, + "SubgroupsPerWorkgroup": 36, + "SubgroupsPerWorkgroupId": 37, + "LocalSizeId": 38, + "LocalSizeHintId": 39, + "NonCoherentColorAttachmentReadEXT": 4169, + "NonCoherentDepthAttachmentReadEXT": 4170, + "NonCoherentStencilAttachmentReadEXT": 4171, + "SubgroupUniformControlFlowKHR": 4421, + "PostDepthCoverage": 4446, + "DenormPreserve": 4459, + "DenormFlushToZero": 4460, + "SignedZeroInfNanPreserve": 4461, + "RoundingModeRTE": 4462, + "RoundingModeRTZ": 4463, + "EarlyAndLateFragmentTestsAMD": 5017, + "StencilRefReplacingEXT": 5027, + "CoalescingAMDX": 5069, + "MaxNodeRecursionAMDX": 5071, + "StaticNumWorkgroupsAMDX": 5072, + "ShaderIndexAMDX": 5073, + "MaxNumWorkgroupsAMDX": 5077, + "StencilRefUnchangedFrontAMD": 5079, + "StencilRefGreaterFrontAMD": 5080, + "StencilRefLessFrontAMD": 5081, + "StencilRefUnchangedBackAMD": 5082, + "StencilRefGreaterBackAMD": 5083, + "StencilRefLessBackAMD": 5084, + "QuadDerivativesKHR": 5088, + "RequireFullQuadsKHR": 5089, + "OutputLinesEXT": 5269, + "OutputLinesNV": 5269, + "OutputPrimitivesEXT": 5270, + "OutputPrimitivesNV": 5270, + "DerivativeGroupQuadsNV": 5289, + "DerivativeGroupLinearNV": 5290, + "OutputTrianglesEXT": 5298, + "OutputTrianglesNV": 5298, + "PixelInterlockOrderedEXT": 5366, + "PixelInterlockUnorderedEXT": 5367, + "SampleInterlockOrderedEXT": 5368, + "SampleInterlockUnorderedEXT": 5369, + "ShadingRateInterlockOrderedEXT": 5370, + "ShadingRateInterlockUnorderedEXT": 5371, + "SharedLocalMemorySizeINTEL": 5618, + "RoundingModeRTPINTEL": 5620, + "RoundingModeRTNINTEL": 5621, + "FloatingPointModeALTINTEL": 5622, + "FloatingPointModeIEEEINTEL": 5623, + "MaxWorkgroupSizeINTEL": 5893, + "MaxWorkDimINTEL": 5894, + "NoGlobalOffsetINTEL": 5895, + "NumSIMDWorkitemsINTEL": 5896, + "SchedulerTargetFmaxMhzINTEL": 5903, + "MaximallyReconvergesKHR": 6023, + "FPFastMathDefault": 6028, + "StreamingInterfaceINTEL": 6154, + "RegisterMapInterfaceINTEL": 6160, + "NamedBarrierCountINTEL": 6417, + "MaximumRegistersINTEL": 6461, + "MaximumRegistersIdINTEL": 6462, + "NamedMaximumRegistersINTEL": 6463 + } + }, + { + "Name": "StorageClass", + "Type": "Value", + "Values": + { + "UniformConstant": 0, + "Input": 1, + "Uniform": 2, + "Output": 3, + "Workgroup": 4, + "CrossWorkgroup": 5, + "Private": 6, + "Function": 7, + "Generic": 8, + "PushConstant": 9, + "AtomicCounter": 10, + "Image": 11, + "StorageBuffer": 12, + "TileImageEXT": 4172, + "NodePayloadAMDX": 5068, + "NodeOutputPayloadAMDX": 5076, + "CallableDataKHR": 5328, + "CallableDataNV": 5328, + "IncomingCallableDataKHR": 5329, + "IncomingCallableDataNV": 5329, + "RayPayloadKHR": 5338, + "RayPayloadNV": 5338, + "HitAttributeKHR": 5339, + "HitAttributeNV": 5339, + "IncomingRayPayloadKHR": 5342, + "IncomingRayPayloadNV": 5342, + "ShaderRecordBufferKHR": 5343, + "ShaderRecordBufferNV": 5343, + "PhysicalStorageBuffer": 5349, + "PhysicalStorageBufferEXT": 5349, + "HitObjectAttributeNV": 5385, + "TaskPayloadWorkgroupEXT": 5402, + "CodeSectionINTEL": 5605, + "DeviceOnlyINTEL": 5936, + "HostOnlyINTEL": 5937 + } + }, + { + "Name": "Dim", + "Type": "Value", + "Values": + { + "Dim1D": 0, + "Dim2D": 1, + "Dim3D": 2, + "Cube": 3, + "Rect": 4, + "Buffer": 5, + "SubpassData": 6, + "TileImageDataEXT": 4173 + } + }, + { + "Name": "SamplerAddressingMode", + "Type": "Value", + "Values": + { + "None": 0, + "ClampToEdge": 1, + "Clamp": 2, + "Repeat": 3, + "RepeatMirrored": 4 + } + }, + { + "Name": "SamplerFilterMode", + "Type": "Value", + "Values": + { + "Nearest": 0, + "Linear": 1 + } + }, + { + "Name": "ImageFormat", + "Type": "Value", + "Values": + { + "Unknown": 0, + "Rgba32f": 1, + "Rgba16f": 2, + "R32f": 3, + "Rgba8": 4, + "Rgba8Snorm": 5, + "Rg32f": 6, + "Rg16f": 7, + "R11fG11fB10f": 8, + "R16f": 9, + "Rgba16": 10, + "Rgb10A2": 11, + "Rg16": 12, + "Rg8": 13, + "R16": 14, + "R8": 15, + "Rgba16Snorm": 16, + "Rg16Snorm": 17, + "Rg8Snorm": 18, + "R16Snorm": 19, + "R8Snorm": 20, + "Rgba32i": 21, + "Rgba16i": 22, + "Rgba8i": 23, + "R32i": 24, + "Rg32i": 25, + "Rg16i": 26, + "Rg8i": 27, + "R16i": 28, + "R8i": 29, + "Rgba32ui": 30, + "Rgba16ui": 31, + "Rgba8ui": 32, + "R32ui": 33, + "Rgb10a2ui": 34, + "Rg32ui": 35, + "Rg16ui": 36, + "Rg8ui": 37, + "R16ui": 38, + "R8ui": 39, + "R64ui": 40, + "R64i": 41 + } + }, + { + "Name": "ImageChannelOrder", + "Type": "Value", + "Values": + { + "R": 0, + "A": 1, + "RG": 2, + "RA": 3, + "RGB": 4, + "RGBA": 5, + "BGRA": 6, + "ARGB": 7, + "Intensity": 8, + "Luminance": 9, + "Rx": 10, + "RGx": 11, + "RGBx": 12, + "Depth": 13, + "DepthStencil": 14, + "sRGB": 15, + "sRGBx": 16, + "sRGBA": 17, + "sBGRA": 18, + "ABGR": 19 + } + }, + { + "Name": "ImageChannelDataType", + "Type": "Value", + "Values": + { + "SnormInt8": 0, + "SnormInt16": 1, + "UnormInt8": 2, + "UnormInt16": 3, + "UnormShort565": 4, + "UnormShort555": 5, + "UnormInt101010": 6, + "SignedInt8": 7, + "SignedInt16": 8, + "SignedInt32": 9, + "UnsignedInt8": 10, + "UnsignedInt16": 11, + "UnsignedInt32": 12, + "HalfFloat": 13, + "Float": 14, + "UnormInt24": 15, + "UnormInt101010_2": 16, + "UnsignedIntRaw10EXT": 19, + "UnsignedIntRaw12EXT": 20 + } + }, + { + "Name": "ImageOperands", + "Type": "Bit", + "Values": + { + "Bias": 0, + "Lod": 1, + "Grad": 2, + "ConstOffset": 3, + "Offset": 4, + "ConstOffsets": 5, + "Sample": 6, + "MinLod": 7, + "MakeTexelAvailable": 8, + "MakeTexelAvailableKHR": 8, + "MakeTexelVisible": 9, + "MakeTexelVisibleKHR": 9, + "NonPrivateTexel": 10, + "NonPrivateTexelKHR": 10, + "VolatileTexel": 11, + "VolatileTexelKHR": 11, + "SignExtend": 12, + "ZeroExtend": 13, + "Nontemporal": 14, + "Offsets": 16 + } + }, + { + "Name": "FPFastMathMode", + "Type": "Bit", + "Values": + { + "NotNaN": 0, + "NotInf": 1, + "NSZ": 2, + "AllowRecip": 3, + "Fast": 4, + "AllowContract": 16, + "AllowContractFastINTEL": 16, + "AllowReassoc": 17, + "AllowReassocINTEL": 17, + "AllowTransform": 18 + } + }, + { + "Name": "FPRoundingMode", + "Type": "Value", + "Values": + { + "RTE": 0, + "RTZ": 1, + "RTP": 2, + "RTN": 3 + } + }, + { + "Name": "LinkageType", + "Type": "Value", + "Values": + { + "Export": 0, + "Import": 1, + "LinkOnceODR": 2 + } + }, + { + "Name": "AccessQualifier", + "Type": "Value", + "Values": + { + "ReadOnly": 0, + "WriteOnly": 1, + "ReadWrite": 2 + } + }, + { + "Name": "FunctionParameterAttribute", + "Type": "Value", + "Values": + { + "Zext": 0, + "Sext": 1, + "ByVal": 2, + "Sret": 3, + "NoAlias": 4, + "NoCapture": 5, + "NoWrite": 6, + "NoReadWrite": 7, + "RuntimeAlignedINTEL": 5940 + } + }, + { + "Name": "Decoration", + "Type": "Value", + "Values": + { + "RelaxedPrecision": 0, + "SpecId": 1, + "Block": 2, + "BufferBlock": 3, + "RowMajor": 4, + "ColMajor": 5, + "ArrayStride": 6, + "MatrixStride": 7, + "GLSLShared": 8, + "GLSLPacked": 9, + "CPacked": 10, + "BuiltIn": 11, + "NoPerspective": 13, + "Flat": 14, + "Patch": 15, + "Centroid": 16, + "Sample": 17, + "Invariant": 18, + "Restrict": 19, + "Aliased": 20, + "Volatile": 21, + "Constant": 22, + "Coherent": 23, + "NonWritable": 24, + "NonReadable": 25, + "Uniform": 26, + "UniformId": 27, + "SaturatedConversion": 28, + "Stream": 29, + "Location": 30, + "Component": 31, + "Index": 32, + "Binding": 33, + "DescriptorSet": 34, + "Offset": 35, + "XfbBuffer": 36, + "XfbStride": 37, + "FuncParamAttr": 38, + "FPRoundingMode": 39, + "FPFastMathMode": 40, + "LinkageAttributes": 41, + "NoContraction": 42, + "InputAttachmentIndex": 43, + "Alignment": 44, + "MaxByteOffset": 45, + "AlignmentId": 46, + "MaxByteOffsetId": 47, + "NoSignedWrap": 4469, + "NoUnsignedWrap": 4470, + "WeightTextureQCOM": 4487, + "BlockMatchTextureQCOM": 4488, + "BlockMatchSamplerQCOM": 4499, + "ExplicitInterpAMD": 4999, + "NodeSharesPayloadLimitsWithAMDX": 5019, + "NodeMaxPayloadsAMDX": 5020, + "TrackFinishWritingAMDX": 5078, + "PayloadNodeNameAMDX": 5091, + "OverrideCoverageNV": 5248, + "PassthroughNV": 5250, + "ViewportRelativeNV": 5252, + "SecondaryViewportRelativeNV": 5256, + "PerPrimitiveEXT": 5271, + "PerPrimitiveNV": 5271, + "PerViewNV": 5272, + "PerTaskNV": 5273, + "PerVertexKHR": 5285, + "PerVertexNV": 5285, + "NonUniform": 5300, + "NonUniformEXT": 5300, + "RestrictPointer": 5355, + "RestrictPointerEXT": 5355, + "AliasedPointer": 5356, + "AliasedPointerEXT": 5356, + "HitObjectShaderRecordBufferNV": 5386, + "BindlessSamplerNV": 5398, + "BindlessImageNV": 5399, + "BoundSamplerNV": 5400, + "BoundImageNV": 5401, + "SIMTCallINTEL": 5599, + "ReferencedIndirectlyINTEL": 5602, + "ClobberINTEL": 5607, + "SideEffectsINTEL": 5608, + "VectorComputeVariableINTEL": 5624, + "FuncParamIOKindINTEL": 5625, + "VectorComputeFunctionINTEL": 5626, + "StackCallINTEL": 5627, + "GlobalVariableOffsetINTEL": 5628, + "CounterBuffer": 5634, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635, + "UserSemantic": 5635, + "UserTypeGOOGLE": 5636, + "FunctionRoundingModeINTEL": 5822, + "FunctionDenormModeINTEL": 5823, + "RegisterINTEL": 5825, + "MemoryINTEL": 5826, + "NumbanksINTEL": 5827, + "BankwidthINTEL": 5828, + "MaxPrivateCopiesINTEL": 5829, + "SinglepumpINTEL": 5830, + "DoublepumpINTEL": 5831, + "MaxReplicatesINTEL": 5832, + "SimpleDualPortINTEL": 5833, + "MergeINTEL": 5834, + "BankBitsINTEL": 5835, + "ForcePow2DepthINTEL": 5836, + "StridesizeINTEL": 5883, + "WordsizeINTEL": 5884, + "TrueDualPortINTEL": 5885, + "BurstCoalesceINTEL": 5899, + "CacheSizeINTEL": 5900, + "DontStaticallyCoalesceINTEL": 5901, + "PrefetchINTEL": 5902, + "StallEnableINTEL": 5905, + "FuseLoopsInFunctionINTEL": 5907, + "MathOpDSPModeINTEL": 5909, + "AliasScopeINTEL": 5914, + "NoAliasINTEL": 5915, + "InitiationIntervalINTEL": 5917, + "MaxConcurrencyINTEL": 5918, + "PipelineEnableINTEL": 5919, + "BufferLocationINTEL": 5921, + "IOPipeStorageINTEL": 5944, + "FunctionFloatingPointModeINTEL": 6080, + "SingleElementVectorINTEL": 6085, + "VectorComputeCallableFunctionINTEL": 6087, + "MediaBlockIOINTEL": 6140, + "StallFreeINTEL": 6151, + "FPMaxErrorDecorationINTEL": 6170, + "LatencyControlLabelINTEL": 6172, + "LatencyControlConstraintINTEL": 6173, + "ConduitKernelArgumentINTEL": 6175, + "RegisterMapKernelArgumentINTEL": 6176, + "MMHostInterfaceAddressWidthINTEL": 6177, + "MMHostInterfaceDataWidthINTEL": 6178, + "MMHostInterfaceLatencyINTEL": 6179, + "MMHostInterfaceReadWriteModeINTEL": 6180, + "MMHostInterfaceMaxBurstINTEL": 6181, + "MMHostInterfaceWaitRequestINTEL": 6182, + "StableKernelArgumentINTEL": 6183, + "HostAccessINTEL": 6188, + "InitModeINTEL": 6190, + "ImplementInRegisterMapINTEL": 6191, + "CacheControlLoadINTEL": 6442, + "CacheControlStoreINTEL": 6443 + } + }, + { + "Name": "BuiltIn", + "Type": "Value", + "Values": + { + "Position": 0, + "PointSize": 1, + "ClipDistance": 3, + "CullDistance": 4, + "VertexId": 5, + "InstanceId": 6, + "PrimitiveId": 7, + "InvocationId": 8, + "Layer": 9, + "ViewportIndex": 10, + "TessLevelOuter": 11, + "TessLevelInner": 12, + "TessCoord": 13, + "PatchVertices": 14, + "FragCoord": 15, + "PointCoord": 16, + "FrontFacing": 17, + "SampleId": 18, + "SamplePosition": 19, + "SampleMask": 20, + "FragDepth": 22, + "HelperInvocation": 23, + "NumWorkgroups": 24, + "WorkgroupSize": 25, + "WorkgroupId": 26, + "LocalInvocationId": 27, + "GlobalInvocationId": 28, + "LocalInvocationIndex": 29, + "WorkDim": 30, + "GlobalSize": 31, + "EnqueuedWorkgroupSize": 32, + "GlobalOffset": 33, + "GlobalLinearId": 34, + "SubgroupSize": 36, + "SubgroupMaxSize": 37, + "NumSubgroups": 38, + "NumEnqueuedSubgroups": 39, + "SubgroupId": 40, + "SubgroupLocalInvocationId": 41, + "VertexIndex": 42, + "InstanceIndex": 43, + "CoreIDARM": 4160, + "CoreCountARM": 4161, + "CoreMaxIDARM": 4162, + "WarpIDARM": 4163, + "WarpMaxIDARM": 4164, + "SubgroupEqMask": 4416, + "SubgroupEqMaskKHR": 4416, + "SubgroupGeMask": 4417, + "SubgroupGeMaskKHR": 4417, + "SubgroupGtMask": 4418, + "SubgroupGtMaskKHR": 4418, + "SubgroupLeMask": 4419, + "SubgroupLeMaskKHR": 4419, + "SubgroupLtMask": 4420, + "SubgroupLtMaskKHR": 4420, + "BaseVertex": 4424, + "BaseInstance": 4425, + "DrawIndex": 4426, + "PrimitiveShadingRateKHR": 4432, + "DeviceIndex": 4438, + "ViewIndex": 4440, + "ShadingRateKHR": 4444, + "BaryCoordNoPerspAMD": 4992, + "BaryCoordNoPerspCentroidAMD": 4993, + "BaryCoordNoPerspSampleAMD": 4994, + "BaryCoordSmoothAMD": 4995, + "BaryCoordSmoothCentroidAMD": 4996, + "BaryCoordSmoothSampleAMD": 4997, + "BaryCoordPullModelAMD": 4998, + "FragStencilRefEXT": 5014, + "CoalescedInputCountAMDX": 5021, + "ShaderIndexAMDX": 5073, + "ViewportMaskNV": 5253, + "SecondaryPositionNV": 5257, + "SecondaryViewportMaskNV": 5258, + "PositionPerViewNV": 5261, + "ViewportMaskPerViewNV": 5262, + "FullyCoveredEXT": 5264, + "TaskCountNV": 5274, + "PrimitiveCountNV": 5275, + "PrimitiveIndicesNV": 5276, + "ClipDistancePerViewNV": 5277, + "CullDistancePerViewNV": 5278, + "LayerPerViewNV": 5279, + "MeshViewCountNV": 5280, + "MeshViewIndicesNV": 5281, + "BaryCoordKHR": 5286, + "BaryCoordNV": 5286, + "BaryCoordNoPerspKHR": 5287, + "BaryCoordNoPerspNV": 5287, + "FragSizeEXT": 5292, + "FragmentSizeNV": 5292, + "FragInvocationCountEXT": 5293, + "InvocationsPerPixelNV": 5293, + "PrimitivePointIndicesEXT": 5294, + "PrimitiveLineIndicesEXT": 5295, + "PrimitiveTriangleIndicesEXT": 5296, + "CullPrimitiveEXT": 5299, + "LaunchIdKHR": 5319, + "LaunchIdNV": 5319, + "LaunchSizeKHR": 5320, + "LaunchSizeNV": 5320, + "WorldRayOriginKHR": 5321, + "WorldRayOriginNV": 5321, + "WorldRayDirectionKHR": 5322, + "WorldRayDirectionNV": 5322, + "ObjectRayOriginKHR": 5323, + "ObjectRayOriginNV": 5323, + "ObjectRayDirectionKHR": 5324, + "ObjectRayDirectionNV": 5324, + "RayTminKHR": 5325, + "RayTminNV": 5325, + "RayTmaxKHR": 5326, + "RayTmaxNV": 5326, + "InstanceCustomIndexKHR": 5327, + "InstanceCustomIndexNV": 5327, + "ObjectToWorldKHR": 5330, + "ObjectToWorldNV": 5330, + "WorldToObjectKHR": 5331, + "WorldToObjectNV": 5331, + "HitTNV": 5332, + "HitKindKHR": 5333, + "HitKindNV": 5333, + "CurrentRayTimeNV": 5334, + "HitTriangleVertexPositionsKHR": 5335, + "HitMicroTriangleVertexPositionsNV": 5337, + "HitMicroTriangleVertexBarycentricsNV": 5344, + "IncomingRayFlagsKHR": 5351, + "IncomingRayFlagsNV": 5351, + "RayGeometryIndexKHR": 5352, + "WarpsPerSMNV": 5374, + "SMCountNV": 5375, + "WarpIDNV": 5376, + "SMIDNV": 5377, + "HitKindFrontFacingMicroTriangleNV": 5405, + "HitKindBackFacingMicroTriangleNV": 5406, + "CullMaskKHR": 6021 + } + }, + { + "Name": "SelectionControl", + "Type": "Bit", + "Values": + { + "Flatten": 0, + "DontFlatten": 1 + } + }, + { + "Name": "LoopControl", + "Type": "Bit", + "Values": + { + "Unroll": 0, + "DontUnroll": 1, + "DependencyInfinite": 2, + "DependencyLength": 3, + "MinIterations": 4, + "MaxIterations": 5, + "IterationMultiple": 6, + "PeelCount": 7, + "PartialCount": 8, + "InitiationIntervalINTEL": 16, + "MaxConcurrencyINTEL": 17, + "DependencyArrayINTEL": 18, + "PipelineEnableINTEL": 19, + "LoopCoalesceINTEL": 20, + "MaxInterleavingINTEL": 21, + "SpeculatedIterationsINTEL": 22, + "NoFusionINTEL": 23, + "LoopCountINTEL": 24, + "MaxReinvocationDelayINTEL": 25 + } + }, + { + "Name": "FunctionControl", + "Type": "Bit", + "Values": + { + "Inline": 0, + "DontInline": 1, + "Pure": 2, + "Const": 3, + "OptNoneINTEL": 16 + } + }, + { + "Name": "MemorySemantics", + "Type": "Bit", + "Values": + { + "Acquire": 1, + "Release": 2, + "AcquireRelease": 3, + "SequentiallyConsistent": 4, + "UniformMemory": 6, + "SubgroupMemory": 7, + "WorkgroupMemory": 8, + "CrossWorkgroupMemory": 9, + "AtomicCounterMemory": 10, + "ImageMemory": 11, + "OutputMemory": 12, + "OutputMemoryKHR": 12, + "MakeAvailable": 13, + "MakeAvailableKHR": 13, + "MakeVisible": 14, + "MakeVisibleKHR": 14, + "Volatile": 15 + } + }, + { + "Name": "MemoryAccess", + "Type": "Bit", + "Values": + { + "Volatile": 0, + "Aligned": 1, + "Nontemporal": 2, + "MakePointerAvailable": 3, + "MakePointerAvailableKHR": 3, + "MakePointerVisible": 4, + "MakePointerVisibleKHR": 4, + "NonPrivatePointer": 5, + "NonPrivatePointerKHR": 5, + "AliasScopeINTELMask": 16, + "NoAliasINTELMask": 17 + } + }, + { + "Name": "Scope", + "Type": "Value", + "Values": + { + "CrossDevice": 0, + "Device": 1, + "Workgroup": 2, + "Subgroup": 3, + "Invocation": 4, + "QueueFamily": 5, + "QueueFamilyKHR": 5, + "ShaderCallKHR": 6 + } + }, + { + "Name": "GroupOperation", + "Type": "Value", + "Values": + { + "Reduce": 0, + "InclusiveScan": 1, + "ExclusiveScan": 2, + "ClusteredReduce": 3, + "PartitionedReduceNV": 6, + "PartitionedInclusiveScanNV": 7, + "PartitionedExclusiveScanNV": 8 + } + }, + { + "Name": "KernelEnqueueFlags", + "Type": "Value", + "Values": + { + "NoWait": 0, + "WaitKernel": 1, + "WaitWorkGroup": 2 + } + }, + { + "Name": "KernelProfilingInfo", + "Type": "Bit", + "Values": + { + "CmdExecTime": 0 + } + }, + { + "Name": "Capability", + "Type": "Value", + "Values": + { + "Matrix": 0, + "Shader": 1, + "Geometry": 2, + "Tessellation": 3, + "Addresses": 4, + "Linkage": 5, + "Kernel": 6, + "Vector16": 7, + "Float16Buffer": 8, + "Float16": 9, + "Float64": 10, + "Int64": 11, + "Int64Atomics": 12, + "ImageBasic": 13, + "ImageReadWrite": 14, + "ImageMipmap": 15, + "Pipes": 17, + "Groups": 18, + "DeviceEnqueue": 19, + "LiteralSampler": 20, + "AtomicStorage": 21, + "Int16": 22, + "TessellationPointSize": 23, + "GeometryPointSize": 24, + "ImageGatherExtended": 25, + "StorageImageMultisample": 27, + "UniformBufferArrayDynamicIndexing": 28, + "SampledImageArrayDynamicIndexing": 29, + "StorageBufferArrayDynamicIndexing": 30, + "StorageImageArrayDynamicIndexing": 31, + "ClipDistance": 32, + "CullDistance": 33, + "ImageCubeArray": 34, + "SampleRateShading": 35, + "ImageRect": 36, + "SampledRect": 37, + "GenericPointer": 38, + "Int8": 39, + "InputAttachment": 40, + "SparseResidency": 41, + "MinLod": 42, + "Sampled1D": 43, + "Image1D": 44, + "SampledCubeArray": 45, + "SampledBuffer": 46, + "ImageBuffer": 47, + "ImageMSArray": 48, + "StorageImageExtendedFormats": 49, + "ImageQuery": 50, + "DerivativeControl": 51, + "InterpolationFunction": 52, + "TransformFeedback": 53, + "GeometryStreams": 54, + "StorageImageReadWithoutFormat": 55, + "StorageImageWriteWithoutFormat": 56, + "MultiViewport": 57, + "SubgroupDispatch": 58, + "NamedBarrier": 59, + "PipeStorage": 60, + "GroupNonUniform": 61, + "GroupNonUniformVote": 62, + "GroupNonUniformArithmetic": 63, + "GroupNonUniformBallot": 64, + "GroupNonUniformShuffle": 65, + "GroupNonUniformShuffleRelative": 66, + "GroupNonUniformClustered": 67, + "GroupNonUniformQuad": 68, + "ShaderLayer": 69, + "ShaderViewportIndex": 70, + "UniformDecoration": 71, + "CoreBuiltinsARM": 4165, + "TileImageColorReadAccessEXT": 4166, + "TileImageDepthReadAccessEXT": 4167, + "TileImageStencilReadAccessEXT": 4168, + "FragmentShadingRateKHR": 4422, + "SubgroupBallotKHR": 4423, + "DrawParameters": 4427, + "WorkgroupMemoryExplicitLayoutKHR": 4428, + "WorkgroupMemoryExplicitLayout8BitAccessKHR": 4429, + "WorkgroupMemoryExplicitLayout16BitAccessKHR": 4430, + "SubgroupVoteKHR": 4431, + "StorageBuffer16BitAccess": 4433, + "StorageUniformBufferBlock16": 4433, + "StorageUniform16": 4434, + "UniformAndStorageBuffer16BitAccess": 4434, + "StoragePushConstant16": 4435, + "StorageInputOutput16": 4436, + "DeviceGroup": 4437, + "MultiView": 4439, + "VariablePointersStorageBuffer": 4441, + "VariablePointers": 4442, + "AtomicStorageOps": 4445, + "SampleMaskPostDepthCoverage": 4447, + "StorageBuffer8BitAccess": 4448, + "UniformAndStorageBuffer8BitAccess": 4449, + "StoragePushConstant8": 4450, + "DenormPreserve": 4464, + "DenormFlushToZero": 4465, + "SignedZeroInfNanPreserve": 4466, + "RoundingModeRTE": 4467, + "RoundingModeRTZ": 4468, + "RayQueryProvisionalKHR": 4471, + "RayQueryKHR": 4472, + "RayTraversalPrimitiveCullingKHR": 4478, + "RayTracingKHR": 4479, + "TextureSampleWeightedQCOM": 4484, + "TextureBoxFilterQCOM": 4485, + "TextureBlockMatchQCOM": 4486, + "TextureBlockMatch2QCOM": 4498, + "Float16ImageAMD": 5008, + "ImageGatherBiasLodAMD": 5009, + "FragmentMaskAMD": 5010, + "StencilExportEXT": 5013, + "ImageReadWriteLodAMD": 5015, + "Int64ImageEXT": 5016, + "ShaderClockKHR": 5055, + "ShaderEnqueueAMDX": 5067, + "QuadControlKHR": 5087, + "SampleMaskOverrideCoverageNV": 5249, + "GeometryShaderPassthroughNV": 5251, + "ShaderViewportIndexLayerEXT": 5254, + "ShaderViewportIndexLayerNV": 5254, + "ShaderViewportMaskNV": 5255, + "ShaderStereoViewNV": 5259, + "PerViewAttributesNV": 5260, + "FragmentFullyCoveredEXT": 5265, + "MeshShadingNV": 5266, + "ImageFootprintNV": 5282, + "MeshShadingEXT": 5283, + "FragmentBarycentricKHR": 5284, + "FragmentBarycentricNV": 5284, + "ComputeDerivativeGroupQuadsNV": 5288, + "FragmentDensityEXT": 5291, + "ShadingRateNV": 5291, + "GroupNonUniformPartitionedNV": 5297, + "ShaderNonUniform": 5301, + "ShaderNonUniformEXT": 5301, + "RuntimeDescriptorArray": 5302, + "RuntimeDescriptorArrayEXT": 5302, + "InputAttachmentArrayDynamicIndexing": 5303, + "InputAttachmentArrayDynamicIndexingEXT": 5303, + "UniformTexelBufferArrayDynamicIndexing": 5304, + "UniformTexelBufferArrayDynamicIndexingEXT": 5304, + "StorageTexelBufferArrayDynamicIndexing": 5305, + "StorageTexelBufferArrayDynamicIndexingEXT": 5305, + "UniformBufferArrayNonUniformIndexing": 5306, + "UniformBufferArrayNonUniformIndexingEXT": 5306, + "SampledImageArrayNonUniformIndexing": 5307, + "SampledImageArrayNonUniformIndexingEXT": 5307, + "StorageBufferArrayNonUniformIndexing": 5308, + "StorageBufferArrayNonUniformIndexingEXT": 5308, + "StorageImageArrayNonUniformIndexing": 5309, + "StorageImageArrayNonUniformIndexingEXT": 5309, + "InputAttachmentArrayNonUniformIndexing": 5310, + "InputAttachmentArrayNonUniformIndexingEXT": 5310, + "UniformTexelBufferArrayNonUniformIndexing": 5311, + "UniformTexelBufferArrayNonUniformIndexingEXT": 5311, + "StorageTexelBufferArrayNonUniformIndexing": 5312, + "StorageTexelBufferArrayNonUniformIndexingEXT": 5312, + "RayTracingPositionFetchKHR": 5336, + "RayTracingNV": 5340, + "RayTracingMotionBlurNV": 5341, + "VulkanMemoryModel": 5345, + "VulkanMemoryModelKHR": 5345, + "VulkanMemoryModelDeviceScope": 5346, + "VulkanMemoryModelDeviceScopeKHR": 5346, + "PhysicalStorageBufferAddresses": 5347, + "PhysicalStorageBufferAddressesEXT": 5347, + "ComputeDerivativeGroupLinearNV": 5350, + "RayTracingProvisionalKHR": 5353, + "CooperativeMatrixNV": 5357, + "FragmentShaderSampleInterlockEXT": 5363, + "FragmentShaderShadingRateInterlockEXT": 5372, + "ShaderSMBuiltinsNV": 5373, + "FragmentShaderPixelInterlockEXT": 5378, + "DemoteToHelperInvocation": 5379, + "DemoteToHelperInvocationEXT": 5379, + "DisplacementMicromapNV": 5380, + "RayTracingOpacityMicromapEXT": 5381, + "ShaderInvocationReorderNV": 5383, + "BindlessTextureNV": 5390, + "RayQueryPositionFetchKHR": 5391, + "AtomicFloat16VectorNV": 5404, + "RayTracingDisplacementMicromapNV": 5409, + "SubgroupShuffleINTEL": 5568, + "SubgroupBufferBlockIOINTEL": 5569, + "SubgroupImageBlockIOINTEL": 5570, + "SubgroupImageMediaBlockIOINTEL": 5579, + "RoundToInfinityINTEL": 5582, + "FloatingPointModeINTEL": 5583, + "IntegerFunctions2INTEL": 5584, + "FunctionPointersINTEL": 5603, + "IndirectReferencesINTEL": 5604, + "AsmINTEL": 5606, + "AtomicFloat32MinMaxEXT": 5612, + "AtomicFloat64MinMaxEXT": 5613, + "AtomicFloat16MinMaxEXT": 5616, + "VectorComputeINTEL": 5617, + "VectorAnyINTEL": 5619, + "ExpectAssumeKHR": 5629, + "SubgroupAvcMotionEstimationINTEL": 5696, + "SubgroupAvcMotionEstimationIntraINTEL": 5697, + "SubgroupAvcMotionEstimationChromaINTEL": 5698, + "VariableLengthArrayINTEL": 5817, + "FunctionFloatControlINTEL": 5821, + "FPGAMemoryAttributesINTEL": 5824, + "FPFastMathModeINTEL": 5837, + "ArbitraryPrecisionIntegersINTEL": 5844, + "ArbitraryPrecisionFloatingPointINTEL": 5845, + "UnstructuredLoopControlsINTEL": 5886, + "FPGALoopControlsINTEL": 5888, + "KernelAttributesINTEL": 5892, + "FPGAKernelAttributesINTEL": 5897, + "FPGAMemoryAccessesINTEL": 5898, + "FPGAClusterAttributesINTEL": 5904, + "LoopFuseINTEL": 5906, + "FPGADSPControlINTEL": 5908, + "MemoryAccessAliasingINTEL": 5910, + "FPGAInvocationPipeliningAttributesINTEL": 5916, + "FPGABufferLocationINTEL": 5920, + "ArbitraryPrecisionFixedPointINTEL": 5922, + "USMStorageClassesINTEL": 5935, + "RuntimeAlignedAttributeINTEL": 5939, + "IOPipesINTEL": 5943, + "BlockingPipesINTEL": 5945, + "FPGARegINTEL": 5948, + "DotProductInputAll": 6016, + "DotProductInputAllKHR": 6016, + "DotProductInput4x8Bit": 6017, + "DotProductInput4x8BitKHR": 6017, + "DotProductInput4x8BitPacked": 6018, + "DotProductInput4x8BitPackedKHR": 6018, + "DotProduct": 6019, + "DotProductKHR": 6019, + "RayCullMaskKHR": 6020, + "CooperativeMatrixKHR": 6022, + "BitInstructions": 6025, + "GroupNonUniformRotateKHR": 6026, + "FloatControls2": 6029, + "AtomicFloat32AddEXT": 6033, + "AtomicFloat64AddEXT": 6034, + "LongCompositesINTEL": 6089, + "OptNoneINTEL": 6094, + "AtomicFloat16AddEXT": 6095, + "DebugInfoModuleINTEL": 6114, + "BFloat16ConversionINTEL": 6115, + "SplitBarrierINTEL": 6141, + "FPGAClusterAttributesV2INTEL": 6150, + "FPGAKernelAttributesv2INTEL": 6161, + "FPMaxErrorINTEL": 6169, + "FPGALatencyControlINTEL": 6171, + "FPGAArgumentInterfacesINTEL": 6174, + "GlobalVariableHostAccessINTEL": 6187, + "GlobalVariableFPGADecorationsINTEL": 6189, + "GroupUniformArithmeticKHR": 6400, + "MaskedGatherScatterINTEL": 6427, + "CacheControlsINTEL": 6441, + "RegisterLimitsINTEL": 6460 + } + }, + { + "Name": "RayFlags", + "Type": "Bit", + "Values": + { + "OpaqueKHR": 0, + "NoOpaqueKHR": 1, + "TerminateOnFirstHitKHR": 2, + "SkipClosestHitShaderKHR": 3, + "CullBackFacingTrianglesKHR": 4, + "CullFrontFacingTrianglesKHR": 5, + "CullOpaqueKHR": 6, + "CullNoOpaqueKHR": 7, + "SkipTrianglesKHR": 8, + "SkipAABBsKHR": 9, + "ForceOpacityMicromap2StateEXT": 10 + } + }, + { + "Name": "RayQueryIntersection", + "Type": "Value", + "Values": + { + "RayQueryCandidateIntersectionKHR": 0, + "RayQueryCommittedIntersectionKHR": 1 + } + }, + { + "Name": "RayQueryCommittedIntersectionType", + "Type": "Value", + "Values": + { + "RayQueryCommittedIntersectionNoneKHR": 0, + "RayQueryCommittedIntersectionTriangleKHR": 1, + "RayQueryCommittedIntersectionGeneratedKHR": 2 + } + }, + { + "Name": "RayQueryCandidateIntersectionType", + "Type": "Value", + "Values": + { + "RayQueryCandidateIntersectionTriangleKHR": 0, + "RayQueryCandidateIntersectionAABBKHR": 1 + } + }, + { + "Name": "FragmentShadingRate", + "Type": "Bit", + "Values": + { + "Vertical2Pixels": 0, + "Vertical4Pixels": 1, + "Horizontal2Pixels": 2, + "Horizontal4Pixels": 3 + } + }, + { + "Name": "FPDenormMode", + "Type": "Value", + "Values": + { + "Preserve": 0, + "FlushToZero": 1 + } + }, + { + "Name": "FPOperationMode", + "Type": "Value", + "Values": + { + "IEEE": 0, + "ALT": 1 + } + }, + { + "Name": "QuantizationModes", + "Type": "Value", + "Values": + { + "TRN": 0, + "TRN_ZERO": 1, + "RND": 2, + "RND_ZERO": 3, + "RND_INF": 4, + "RND_MIN_INF": 5, + "RND_CONV": 6, + "RND_CONV_ODD": 7 + } + }, + { + "Name": "OverflowModes", + "Type": "Value", + "Values": + { + "WRAP": 0, + "SAT": 1, + "SAT_ZERO": 2, + "SAT_SYM": 3 + } + }, + { + "Name": "PackedVectorFormat", + "Type": "Value", + "Values": + { + "PackedVectorFormat4x8Bit": 0, + "PackedVectorFormat4x8BitKHR": 0 + } + }, + { + "Name": "CooperativeMatrixOperands", + "Type": "Bit", + "Values": + { + "MatrixASignedComponentsKHR": 0, + "MatrixBSignedComponentsKHR": 1, + "MatrixCSignedComponentsKHR": 2, + "MatrixResultSignedComponentsKHR": 3, + "SaturatingAccumulationKHR": 4 + } + }, + { + "Name": "CooperativeMatrixLayout", + "Type": "Value", + "Values": + { + "RowMajorKHR": 0, + "ColumnMajorKHR": 1 + } + }, + { + "Name": "CooperativeMatrixUse", + "Type": "Value", + "Values": + { + "MatrixAKHR": 0, + "MatrixBKHR": 1, + "MatrixAccumulatorKHR": 2 + } + }, + { + "Name": "InitializationModeQualifier", + "Type": "Value", + "Values": + { + "InitOnDeviceReprogramINTEL": 0, + "InitOnDeviceResetINTEL": 1 + } + }, + { + "Name": "HostAccessQualifier", + "Type": "Value", + "Values": + { + "NoneINTEL": 0, + "ReadINTEL": 1, + "WriteINTEL": 2, + "ReadWriteINTEL": 3 + } + }, + { + "Name": "LoadCacheControl", + "Type": "Value", + "Values": + { + "UncachedINTEL": 0, + "CachedINTEL": 1, + "StreamingINTEL": 2, + "InvalidateAfterReadINTEL": 3, + "ConstCachedINTEL": 4 + } + }, + { + "Name": "StoreCacheControl", + "Type": "Value", + "Values": + { + "UncachedINTEL": 0, + "WriteThroughINTEL": 1, + "WriteBackINTEL": 2, + "StreamingINTEL": 3 + } + }, + { + "Name": "NamedMaximumNumberOfRegisters", + "Type": "Value", + "Values": + { + "AutoINTEL": 0 + } + }, + { + "Name": "Op", + "Type": "Value", + "Values": + { + "OpNop": 0, + "OpUndef": 1, + "OpSourceContinued": 2, + "OpSource": 3, + "OpSourceExtension": 4, + "OpName": 5, + "OpMemberName": 6, + "OpString": 7, + "OpLine": 8, + "OpExtension": 10, + "OpExtInstImport": 11, + "OpExtInst": 12, + "OpMemoryModel": 14, + "OpEntryPoint": 15, + "OpExecutionMode": 16, + "OpCapability": 17, + "OpTypeVoid": 19, + "OpTypeBool": 20, + "OpTypeInt": 21, + "OpTypeFloat": 22, + "OpTypeVector": 23, + "OpTypeMatrix": 24, + "OpTypeImage": 25, + "OpTypeSampler": 26, + "OpTypeSampledImage": 27, + "OpTypeArray": 28, + "OpTypeRuntimeArray": 29, + "OpTypeStruct": 30, + "OpTypeOpaque": 31, + "OpTypePointer": 32, + "OpTypeFunction": 33, + "OpTypeEvent": 34, + "OpTypeDeviceEvent": 35, + "OpTypeReserveId": 36, + "OpTypeQueue": 37, + "OpTypePipe": 38, + "OpTypeForwardPointer": 39, + "OpConstantTrue": 41, + "OpConstantFalse": 42, + "OpConstant": 43, + "OpConstantComposite": 44, + "OpConstantSampler": 45, + "OpConstantNull": 46, + "OpSpecConstantTrue": 48, + "OpSpecConstantFalse": 49, + "OpSpecConstant": 50, + "OpSpecConstantComposite": 51, + "OpSpecConstantOp": 52, + "OpFunction": 54, + "OpFunctionParameter": 55, + "OpFunctionEnd": 56, + "OpFunctionCall": 57, + "OpVariable": 59, + "OpImageTexelPointer": 60, + "OpLoad": 61, + "OpStore": 62, + "OpCopyMemory": 63, + "OpCopyMemorySized": 64, + "OpAccessChain": 65, + "OpInBoundsAccessChain": 66, + "OpPtrAccessChain": 67, + "OpArrayLength": 68, + "OpGenericPtrMemSemantics": 69, + "OpInBoundsPtrAccessChain": 70, + "OpDecorate": 71, + "OpMemberDecorate": 72, + "OpDecorationGroup": 73, + "OpGroupDecorate": 74, + "OpGroupMemberDecorate": 75, + "OpVectorExtractDynamic": 77, + "OpVectorInsertDynamic": 78, + "OpVectorShuffle": 79, + "OpCompositeConstruct": 80, + "OpCompositeExtract": 81, + "OpCompositeInsert": 82, + "OpCopyObject": 83, + "OpTranspose": 84, + "OpSampledImage": 86, + "OpImageSampleImplicitLod": 87, + "OpImageSampleExplicitLod": 88, + "OpImageSampleDrefImplicitLod": 89, + "OpImageSampleDrefExplicitLod": 90, + "OpImageSampleProjImplicitLod": 91, + "OpImageSampleProjExplicitLod": 92, + "OpImageSampleProjDrefImplicitLod": 93, + "OpImageSampleProjDrefExplicitLod": 94, + "OpImageFetch": 95, + "OpImageGather": 96, + "OpImageDrefGather": 97, + "OpImageRead": 98, + "OpImageWrite": 99, + "OpImage": 100, + "OpImageQueryFormat": 101, + "OpImageQueryOrder": 102, + "OpImageQuerySizeLod": 103, + "OpImageQuerySize": 104, + "OpImageQueryLod": 105, + "OpImageQueryLevels": 106, + "OpImageQuerySamples": 107, + "OpConvertFToU": 109, + "OpConvertFToS": 110, + "OpConvertSToF": 111, + "OpConvertUToF": 112, + "OpUConvert": 113, + "OpSConvert": 114, + "OpFConvert": 115, + "OpQuantizeToF16": 116, + "OpConvertPtrToU": 117, + "OpSatConvertSToU": 118, + "OpSatConvertUToS": 119, + "OpConvertUToPtr": 120, + "OpPtrCastToGeneric": 121, + "OpGenericCastToPtr": 122, + "OpGenericCastToPtrExplicit": 123, + "OpBitcast": 124, + "OpSNegate": 126, + "OpFNegate": 127, + "OpIAdd": 128, + "OpFAdd": 129, + "OpISub": 130, + "OpFSub": 131, + "OpIMul": 132, + "OpFMul": 133, + "OpUDiv": 134, + "OpSDiv": 135, + "OpFDiv": 136, + "OpUMod": 137, + "OpSRem": 138, + "OpSMod": 139, + "OpFRem": 140, + "OpFMod": 141, + "OpVectorTimesScalar": 142, + "OpMatrixTimesScalar": 143, + "OpVectorTimesMatrix": 144, + "OpMatrixTimesVector": 145, + "OpMatrixTimesMatrix": 146, + "OpOuterProduct": 147, + "OpDot": 148, + "OpIAddCarry": 149, + "OpISubBorrow": 150, + "OpUMulExtended": 151, + "OpSMulExtended": 152, + "OpAny": 154, + "OpAll": 155, + "OpIsNan": 156, + "OpIsInf": 157, + "OpIsFinite": 158, + "OpIsNormal": 159, + "OpSignBitSet": 160, + "OpLessOrGreater": 161, + "OpOrdered": 162, + "OpUnordered": 163, + "OpLogicalEqual": 164, + "OpLogicalNotEqual": 165, + "OpLogicalOr": 166, + "OpLogicalAnd": 167, + "OpLogicalNot": 168, + "OpSelect": 169, + "OpIEqual": 170, + "OpINotEqual": 171, + "OpUGreaterThan": 172, + "OpSGreaterThan": 173, + "OpUGreaterThanEqual": 174, + "OpSGreaterThanEqual": 175, + "OpULessThan": 176, + "OpSLessThan": 177, + "OpULessThanEqual": 178, + "OpSLessThanEqual": 179, + "OpFOrdEqual": 180, + "OpFUnordEqual": 181, + "OpFOrdNotEqual": 182, + "OpFUnordNotEqual": 183, + "OpFOrdLessThan": 184, + "OpFUnordLessThan": 185, + "OpFOrdGreaterThan": 186, + "OpFUnordGreaterThan": 187, + "OpFOrdLessThanEqual": 188, + "OpFUnordLessThanEqual": 189, + "OpFOrdGreaterThanEqual": 190, + "OpFUnordGreaterThanEqual": 191, + "OpShiftRightLogical": 194, + "OpShiftRightArithmetic": 195, + "OpShiftLeftLogical": 196, + "OpBitwiseOr": 197, + "OpBitwiseXor": 198, + "OpBitwiseAnd": 199, + "OpNot": 200, + "OpBitFieldInsert": 201, + "OpBitFieldSExtract": 202, + "OpBitFieldUExtract": 203, + "OpBitReverse": 204, + "OpBitCount": 205, + "OpDPdx": 207, + "OpDPdy": 208, + "OpFwidth": 209, + "OpDPdxFine": 210, + "OpDPdyFine": 211, + "OpFwidthFine": 212, + "OpDPdxCoarse": 213, + "OpDPdyCoarse": 214, + "OpFwidthCoarse": 215, + "OpEmitVertex": 218, + "OpEndPrimitive": 219, + "OpEmitStreamVertex": 220, + "OpEndStreamPrimitive": 221, + "OpControlBarrier": 224, + "OpMemoryBarrier": 225, + "OpAtomicLoad": 227, + "OpAtomicStore": 228, + "OpAtomicExchange": 229, + "OpAtomicCompareExchange": 230, + "OpAtomicCompareExchangeWeak": 231, + "OpAtomicIIncrement": 232, + "OpAtomicIDecrement": 233, + "OpAtomicIAdd": 234, + "OpAtomicISub": 235, + "OpAtomicSMin": 236, + "OpAtomicUMin": 237, + "OpAtomicSMax": 238, + "OpAtomicUMax": 239, + "OpAtomicAnd": 240, + "OpAtomicOr": 241, + "OpAtomicXor": 242, + "OpPhi": 245, + "OpLoopMerge": 246, + "OpSelectionMerge": 247, + "OpLabel": 248, + "OpBranch": 249, + "OpBranchConditional": 250, + "OpSwitch": 251, + "OpKill": 252, + "OpReturn": 253, + "OpReturnValue": 254, + "OpUnreachable": 255, + "OpLifetimeStart": 256, + "OpLifetimeStop": 257, + "OpGroupAsyncCopy": 259, + "OpGroupWaitEvents": 260, + "OpGroupAll": 261, + "OpGroupAny": 262, + "OpGroupBroadcast": 263, + "OpGroupIAdd": 264, + "OpGroupFAdd": 265, + "OpGroupFMin": 266, + "OpGroupUMin": 267, + "OpGroupSMin": 268, + "OpGroupFMax": 269, + "OpGroupUMax": 270, + "OpGroupSMax": 271, + "OpReadPipe": 274, + "OpWritePipe": 275, + "OpReservedReadPipe": 276, + "OpReservedWritePipe": 277, + "OpReserveReadPipePackets": 278, + "OpReserveWritePipePackets": 279, + "OpCommitReadPipe": 280, + "OpCommitWritePipe": 281, + "OpIsValidReserveId": 282, + "OpGetNumPipePackets": 283, + "OpGetMaxPipePackets": 284, + "OpGroupReserveReadPipePackets": 285, + "OpGroupReserveWritePipePackets": 286, + "OpGroupCommitReadPipe": 287, + "OpGroupCommitWritePipe": 288, + "OpEnqueueMarker": 291, + "OpEnqueueKernel": 292, + "OpGetKernelNDrangeSubGroupCount": 293, + "OpGetKernelNDrangeMaxSubGroupSize": 294, + "OpGetKernelWorkGroupSize": 295, + "OpGetKernelPreferredWorkGroupSizeMultiple": 296, + "OpRetainEvent": 297, + "OpReleaseEvent": 298, + "OpCreateUserEvent": 299, + "OpIsValidEvent": 300, + "OpSetUserEventStatus": 301, + "OpCaptureEventProfilingInfo": 302, + "OpGetDefaultQueue": 303, + "OpBuildNDRange": 304, + "OpImageSparseSampleImplicitLod": 305, + "OpImageSparseSampleExplicitLod": 306, + "OpImageSparseSampleDrefImplicitLod": 307, + "OpImageSparseSampleDrefExplicitLod": 308, + "OpImageSparseSampleProjImplicitLod": 309, + "OpImageSparseSampleProjExplicitLod": 310, + "OpImageSparseSampleProjDrefImplicitLod": 311, + "OpImageSparseSampleProjDrefExplicitLod": 312, + "OpImageSparseFetch": 313, + "OpImageSparseGather": 314, + "OpImageSparseDrefGather": 315, + "OpImageSparseTexelsResident": 316, + "OpNoLine": 317, + "OpAtomicFlagTestAndSet": 318, + "OpAtomicFlagClear": 319, + "OpImageSparseRead": 320, + "OpSizeOf": 321, + "OpTypePipeStorage": 322, + "OpConstantPipeStorage": 323, + "OpCreatePipeFromPipeStorage": 324, + "OpGetKernelLocalSizeForSubgroupCount": 325, + "OpGetKernelMaxNumSubgroups": 326, + "OpTypeNamedBarrier": 327, + "OpNamedBarrierInitialize": 328, + "OpMemoryNamedBarrier": 329, + "OpModuleProcessed": 330, + "OpExecutionModeId": 331, + "OpDecorateId": 332, + "OpGroupNonUniformElect": 333, + "OpGroupNonUniformAll": 334, + "OpGroupNonUniformAny": 335, + "OpGroupNonUniformAllEqual": 336, + "OpGroupNonUniformBroadcast": 337, + "OpGroupNonUniformBroadcastFirst": 338, + "OpGroupNonUniformBallot": 339, + "OpGroupNonUniformInverseBallot": 340, + "OpGroupNonUniformBallotBitExtract": 341, + "OpGroupNonUniformBallotBitCount": 342, + "OpGroupNonUniformBallotFindLSB": 343, + "OpGroupNonUniformBallotFindMSB": 344, + "OpGroupNonUniformShuffle": 345, + "OpGroupNonUniformShuffleXor": 346, + "OpGroupNonUniformShuffleUp": 347, + "OpGroupNonUniformShuffleDown": 348, + "OpGroupNonUniformIAdd": 349, + "OpGroupNonUniformFAdd": 350, + "OpGroupNonUniformIMul": 351, + "OpGroupNonUniformFMul": 352, + "OpGroupNonUniformSMin": 353, + "OpGroupNonUniformUMin": 354, + "OpGroupNonUniformFMin": 355, + "OpGroupNonUniformSMax": 356, + "OpGroupNonUniformUMax": 357, + "OpGroupNonUniformFMax": 358, + "OpGroupNonUniformBitwiseAnd": 359, + "OpGroupNonUniformBitwiseOr": 360, + "OpGroupNonUniformBitwiseXor": 361, + "OpGroupNonUniformLogicalAnd": 362, + "OpGroupNonUniformLogicalOr": 363, + "OpGroupNonUniformLogicalXor": 364, + "OpGroupNonUniformQuadBroadcast": 365, + "OpGroupNonUniformQuadSwap": 366, + "OpCopyLogical": 400, + "OpPtrEqual": 401, + "OpPtrNotEqual": 402, + "OpPtrDiff": 403, + "OpColorAttachmentReadEXT": 4160, + "OpDepthAttachmentReadEXT": 4161, + "OpStencilAttachmentReadEXT": 4162, + "OpTerminateInvocation": 4416, + "OpSubgroupBallotKHR": 4421, + "OpSubgroupFirstInvocationKHR": 4422, + "OpSubgroupAllKHR": 4428, + "OpSubgroupAnyKHR": 4429, + "OpSubgroupAllEqualKHR": 4430, + "OpGroupNonUniformRotateKHR": 4431, + "OpSubgroupReadInvocationKHR": 4432, + "OpTraceRayKHR": 4445, + "OpExecuteCallableKHR": 4446, + "OpConvertUToAccelerationStructureKHR": 4447, + "OpIgnoreIntersectionKHR": 4448, + "OpTerminateRayKHR": 4449, + "OpSDot": 4450, + "OpSDotKHR": 4450, + "OpUDot": 4451, + "OpUDotKHR": 4451, + "OpSUDot": 4452, + "OpSUDotKHR": 4452, + "OpSDotAccSat": 4453, + "OpSDotAccSatKHR": 4453, + "OpUDotAccSat": 4454, + "OpUDotAccSatKHR": 4454, + "OpSUDotAccSat": 4455, + "OpSUDotAccSatKHR": 4455, + "OpTypeCooperativeMatrixKHR": 4456, + "OpCooperativeMatrixLoadKHR": 4457, + "OpCooperativeMatrixStoreKHR": 4458, + "OpCooperativeMatrixMulAddKHR": 4459, + "OpCooperativeMatrixLengthKHR": 4460, + "OpTypeRayQueryKHR": 4472, + "OpRayQueryInitializeKHR": 4473, + "OpRayQueryTerminateKHR": 4474, + "OpRayQueryGenerateIntersectionKHR": 4475, + "OpRayQueryConfirmIntersectionKHR": 4476, + "OpRayQueryProceedKHR": 4477, + "OpRayQueryGetIntersectionTypeKHR": 4479, + "OpImageSampleWeightedQCOM": 4480, + "OpImageBoxFilterQCOM": 4481, + "OpImageBlockMatchSSDQCOM": 4482, + "OpImageBlockMatchSADQCOM": 4483, + "OpImageBlockMatchWindowSSDQCOM": 4500, + "OpImageBlockMatchWindowSADQCOM": 4501, + "OpImageBlockMatchGatherSSDQCOM": 4502, + "OpImageBlockMatchGatherSADQCOM": 4503, + "OpGroupIAddNonUniformAMD": 5000, + "OpGroupFAddNonUniformAMD": 5001, + "OpGroupFMinNonUniformAMD": 5002, + "OpGroupUMinNonUniformAMD": 5003, + "OpGroupSMinNonUniformAMD": 5004, + "OpGroupFMaxNonUniformAMD": 5005, + "OpGroupUMaxNonUniformAMD": 5006, + "OpGroupSMaxNonUniformAMD": 5007, + "OpFragmentMaskFetchAMD": 5011, + "OpFragmentFetchAMD": 5012, + "OpReadClockKHR": 5056, + "OpFinalizeNodePayloadsAMDX": 5075, + "OpFinishWritingNodePayloadAMDX": 5078, + "OpInitializeNodePayloadsAMDX": 5090, + "OpGroupNonUniformQuadAllKHR": 5110, + "OpGroupNonUniformQuadAnyKHR": 5111, + "OpHitObjectRecordHitMotionNV": 5249, + "OpHitObjectRecordHitWithIndexMotionNV": 5250, + "OpHitObjectRecordMissMotionNV": 5251, + "OpHitObjectGetWorldToObjectNV": 5252, + "OpHitObjectGetObjectToWorldNV": 5253, + "OpHitObjectGetObjectRayDirectionNV": 5254, + "OpHitObjectGetObjectRayOriginNV": 5255, + "OpHitObjectTraceRayMotionNV": 5256, + "OpHitObjectGetShaderRecordBufferHandleNV": 5257, + "OpHitObjectGetShaderBindingTableRecordIndexNV": 5258, + "OpHitObjectRecordEmptyNV": 5259, + "OpHitObjectTraceRayNV": 5260, + "OpHitObjectRecordHitNV": 5261, + "OpHitObjectRecordHitWithIndexNV": 5262, + "OpHitObjectRecordMissNV": 5263, + "OpHitObjectExecuteShaderNV": 5264, + "OpHitObjectGetCurrentTimeNV": 5265, + "OpHitObjectGetAttributesNV": 5266, + "OpHitObjectGetHitKindNV": 5267, + "OpHitObjectGetPrimitiveIndexNV": 5268, + "OpHitObjectGetGeometryIndexNV": 5269, + "OpHitObjectGetInstanceIdNV": 5270, + "OpHitObjectGetInstanceCustomIndexNV": 5271, + "OpHitObjectGetWorldRayDirectionNV": 5272, + "OpHitObjectGetWorldRayOriginNV": 5273, + "OpHitObjectGetRayTMaxNV": 5274, + "OpHitObjectGetRayTMinNV": 5275, + "OpHitObjectIsEmptyNV": 5276, + "OpHitObjectIsHitNV": 5277, + "OpHitObjectIsMissNV": 5278, + "OpReorderThreadWithHitObjectNV": 5279, + "OpReorderThreadWithHintNV": 5280, + "OpTypeHitObjectNV": 5281, + "OpImageSampleFootprintNV": 5283, + "OpEmitMeshTasksEXT": 5294, + "OpSetMeshOutputsEXT": 5295, + "OpGroupNonUniformPartitionNV": 5296, + "OpWritePackedPrimitiveIndices4x8NV": 5299, + "OpFetchMicroTriangleVertexPositionNV": 5300, + "OpFetchMicroTriangleVertexBarycentricNV": 5301, + "OpReportIntersectionKHR": 5334, + "OpReportIntersectionNV": 5334, + "OpIgnoreIntersectionNV": 5335, + "OpTerminateRayNV": 5336, + "OpTraceNV": 5337, + "OpTraceMotionNV": 5338, + "OpTraceRayMotionNV": 5339, + "OpRayQueryGetIntersectionTriangleVertexPositionsKHR": 5340, + "OpTypeAccelerationStructureKHR": 5341, + "OpTypeAccelerationStructureNV": 5341, + "OpExecuteCallableNV": 5344, + "OpTypeCooperativeMatrixNV": 5358, + "OpCooperativeMatrixLoadNV": 5359, + "OpCooperativeMatrixStoreNV": 5360, + "OpCooperativeMatrixMulAddNV": 5361, + "OpCooperativeMatrixLengthNV": 5362, + "OpBeginInvocationInterlockEXT": 5364, + "OpEndInvocationInterlockEXT": 5365, + "OpDemoteToHelperInvocation": 5380, + "OpDemoteToHelperInvocationEXT": 5380, + "OpIsHelperInvocationEXT": 5381, + "OpConvertUToImageNV": 5391, + "OpConvertUToSamplerNV": 5392, + "OpConvertImageToUNV": 5393, + "OpConvertSamplerToUNV": 5394, + "OpConvertUToSampledImageNV": 5395, + "OpConvertSampledImageToUNV": 5396, + "OpSamplerImageAddressingModeNV": 5397, + "OpSubgroupShuffleINTEL": 5571, + "OpSubgroupShuffleDownINTEL": 5572, + "OpSubgroupShuffleUpINTEL": 5573, + "OpSubgroupShuffleXorINTEL": 5574, + "OpSubgroupBlockReadINTEL": 5575, + "OpSubgroupBlockWriteINTEL": 5576, + "OpSubgroupImageBlockReadINTEL": 5577, + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpSubgroupImageMediaBlockReadINTEL": 5580, + "OpSubgroupImageMediaBlockWriteINTEL": 5581, + "OpUCountLeadingZerosINTEL": 5585, + "OpUCountTrailingZerosINTEL": 5586, + "OpAbsISubINTEL": 5587, + "OpAbsUSubINTEL": 5588, + "OpIAddSatINTEL": 5589, + "OpUAddSatINTEL": 5590, + "OpIAverageINTEL": 5591, + "OpUAverageINTEL": 5592, + "OpIAverageRoundedINTEL": 5593, + "OpUAverageRoundedINTEL": 5594, + "OpISubSatINTEL": 5595, + "OpUSubSatINTEL": 5596, + "OpIMul32x16INTEL": 5597, + "OpUMul32x16INTEL": 5598, + "OpConstantFunctionPointerINTEL": 5600, + "OpFunctionPointerCallINTEL": 5601, + "OpAsmTargetINTEL": 5609, + "OpAsmINTEL": 5610, + "OpAsmCallINTEL": 5611, + "OpAtomicFMinEXT": 5614, + "OpAtomicFMaxEXT": 5615, + "OpAssumeTrueKHR": 5630, + "OpExpectKHR": 5631, + "OpDecorateString": 5632, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateString": 5633, + "OpMemberDecorateStringGOOGLE": 5633, + "OpVmeImageINTEL": 5699, + "OpTypeVmeImageINTEL": 5700, + "OpTypeAvcImePayloadINTEL": 5701, + "OpTypeAvcRefPayloadINTEL": 5702, + "OpTypeAvcSicPayloadINTEL": 5703, + "OpTypeAvcMcePayloadINTEL": 5704, + "OpTypeAvcMceResultINTEL": 5705, + "OpTypeAvcImeResultINTEL": 5706, + "OpTypeAvcImeResultSingleReferenceStreamoutINTEL": 5707, + "OpTypeAvcImeResultDualReferenceStreamoutINTEL": 5708, + "OpTypeAvcImeSingleReferenceStreaminINTEL": 5709, + "OpTypeAvcImeDualReferenceStreaminINTEL": 5710, + "OpTypeAvcRefResultINTEL": 5711, + "OpTypeAvcSicResultINTEL": 5712, + "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL": 5713, + "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL": 5714, + "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL": 5715, + "OpSubgroupAvcMceSetInterShapePenaltyINTEL": 5716, + "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL": 5717, + "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL": 5718, + "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL": 5719, + "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL": 5720, + "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL": 5721, + "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL": 5722, + "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL": 5723, + "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL": 5724, + "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL": 5725, + "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL": 5726, + "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL": 5727, + "OpSubgroupAvcMceSetAcOnlyHaarINTEL": 5728, + "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL": 5729, + "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL": 5730, + "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL": 5731, + "OpSubgroupAvcMceConvertToImePayloadINTEL": 5732, + "OpSubgroupAvcMceConvertToImeResultINTEL": 5733, + "OpSubgroupAvcMceConvertToRefPayloadINTEL": 5734, + "OpSubgroupAvcMceConvertToRefResultINTEL": 5735, + "OpSubgroupAvcMceConvertToSicPayloadINTEL": 5736, + "OpSubgroupAvcMceConvertToSicResultINTEL": 5737, + "OpSubgroupAvcMceGetMotionVectorsINTEL": 5738, + "OpSubgroupAvcMceGetInterDistortionsINTEL": 5739, + "OpSubgroupAvcMceGetBestInterDistortionsINTEL": 5740, + "OpSubgroupAvcMceGetInterMajorShapeINTEL": 5741, + "OpSubgroupAvcMceGetInterMinorShapeINTEL": 5742, + "OpSubgroupAvcMceGetInterDirectionsINTEL": 5743, + "OpSubgroupAvcMceGetInterMotionVectorCountINTEL": 5744, + "OpSubgroupAvcMceGetInterReferenceIdsINTEL": 5745, + "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL": 5746, + "OpSubgroupAvcImeInitializeINTEL": 5747, + "OpSubgroupAvcImeSetSingleReferenceINTEL": 5748, + "OpSubgroupAvcImeSetDualReferenceINTEL": 5749, + "OpSubgroupAvcImeRefWindowSizeINTEL": 5750, + "OpSubgroupAvcImeAdjustRefOffsetINTEL": 5751, + "OpSubgroupAvcImeConvertToMcePayloadINTEL": 5752, + "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL": 5753, + "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL": 5754, + "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL": 5755, + "OpSubgroupAvcImeSetWeightedSadINTEL": 5756, + "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL": 5757, + "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL": 5758, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL": 5759, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL": 5760, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL": 5761, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL": 5762, + "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL": 5763, + "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL": 5764, + "OpSubgroupAvcImeConvertToMceResultINTEL": 5765, + "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL": 5766, + "OpSubgroupAvcImeGetDualReferenceStreaminINTEL": 5767, + "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL": 5768, + "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL": 5769, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL": 5770, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL": 5771, + "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL": 5772, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL": 5773, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL": 5774, + "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL": 5775, + "OpSubgroupAvcImeGetBorderReachedINTEL": 5776, + "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL": 5777, + "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL": 5778, + "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL": 5779, + "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL": 5780, + "OpSubgroupAvcFmeInitializeINTEL": 5781, + "OpSubgroupAvcBmeInitializeINTEL": 5782, + "OpSubgroupAvcRefConvertToMcePayloadINTEL": 5783, + "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL": 5784, + "OpSubgroupAvcRefSetBilinearFilterEnableINTEL": 5785, + "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL": 5786, + "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL": 5787, + "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL": 5788, + "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL": 5789, + "OpSubgroupAvcRefConvertToMceResultINTEL": 5790, + "OpSubgroupAvcSicInitializeINTEL": 5791, + "OpSubgroupAvcSicConfigureSkcINTEL": 5792, + "OpSubgroupAvcSicConfigureIpeLumaINTEL": 5793, + "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL": 5794, + "OpSubgroupAvcSicGetMotionVectorMaskINTEL": 5795, + "OpSubgroupAvcSicConvertToMcePayloadINTEL": 5796, + "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL": 5797, + "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL": 5798, + "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL": 5799, + "OpSubgroupAvcSicSetBilinearFilterEnableINTEL": 5800, + "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL": 5801, + "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL": 5802, + "OpSubgroupAvcSicEvaluateIpeINTEL": 5803, + "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL": 5804, + "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL": 5805, + "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL": 5806, + "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL": 5807, + "OpSubgroupAvcSicConvertToMceResultINTEL": 5808, + "OpSubgroupAvcSicGetIpeLumaShapeINTEL": 5809, + "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL": 5810, + "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL": 5811, + "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL": 5812, + "OpSubgroupAvcSicGetIpeChromaModeINTEL": 5813, + "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL": 5814, + "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL": 5815, + "OpSubgroupAvcSicGetInterRawSadsINTEL": 5816, + "OpVariableLengthArrayINTEL": 5818, + "OpSaveMemoryINTEL": 5819, + "OpRestoreMemoryINTEL": 5820, + "OpArbitraryFloatSinCosPiINTEL": 5840, + "OpArbitraryFloatCastINTEL": 5841, + "OpArbitraryFloatCastFromIntINTEL": 5842, + "OpArbitraryFloatCastToIntINTEL": 5843, + "OpArbitraryFloatAddINTEL": 5846, + "OpArbitraryFloatSubINTEL": 5847, + "OpArbitraryFloatMulINTEL": 5848, + "OpArbitraryFloatDivINTEL": 5849, + "OpArbitraryFloatGTINTEL": 5850, + "OpArbitraryFloatGEINTEL": 5851, + "OpArbitraryFloatLTINTEL": 5852, + "OpArbitraryFloatLEINTEL": 5853, + "OpArbitraryFloatEQINTEL": 5854, + "OpArbitraryFloatRecipINTEL": 5855, + "OpArbitraryFloatRSqrtINTEL": 5856, + "OpArbitraryFloatCbrtINTEL": 5857, + "OpArbitraryFloatHypotINTEL": 5858, + "OpArbitraryFloatSqrtINTEL": 5859, + "OpArbitraryFloatLogINTEL": 5860, + "OpArbitraryFloatLog2INTEL": 5861, + "OpArbitraryFloatLog10INTEL": 5862, + "OpArbitraryFloatLog1pINTEL": 5863, + "OpArbitraryFloatExpINTEL": 5864, + "OpArbitraryFloatExp2INTEL": 5865, + "OpArbitraryFloatExp10INTEL": 5866, + "OpArbitraryFloatExpm1INTEL": 5867, + "OpArbitraryFloatSinINTEL": 5868, + "OpArbitraryFloatCosINTEL": 5869, + "OpArbitraryFloatSinCosINTEL": 5870, + "OpArbitraryFloatSinPiINTEL": 5871, + "OpArbitraryFloatCosPiINTEL": 5872, + "OpArbitraryFloatASinINTEL": 5873, + "OpArbitraryFloatASinPiINTEL": 5874, + "OpArbitraryFloatACosINTEL": 5875, + "OpArbitraryFloatACosPiINTEL": 5876, + "OpArbitraryFloatATanINTEL": 5877, + "OpArbitraryFloatATanPiINTEL": 5878, + "OpArbitraryFloatATan2INTEL": 5879, + "OpArbitraryFloatPowINTEL": 5880, + "OpArbitraryFloatPowRINTEL": 5881, + "OpArbitraryFloatPowNINTEL": 5882, + "OpLoopControlINTEL": 5887, + "OpAliasDomainDeclINTEL": 5911, + "OpAliasScopeDeclINTEL": 5912, + "OpAliasScopeListDeclINTEL": 5913, + "OpFixedSqrtINTEL": 5923, + "OpFixedRecipINTEL": 5924, + "OpFixedRsqrtINTEL": 5925, + "OpFixedSinINTEL": 5926, + "OpFixedCosINTEL": 5927, + "OpFixedSinCosINTEL": 5928, + "OpFixedSinPiINTEL": 5929, + "OpFixedCosPiINTEL": 5930, + "OpFixedSinCosPiINTEL": 5931, + "OpFixedLogINTEL": 5932, + "OpFixedExpINTEL": 5933, + "OpPtrCastToCrossWorkgroupINTEL": 5934, + "OpCrossWorkgroupCastToPtrINTEL": 5938, + "OpReadPipeBlockingINTEL": 5946, + "OpWritePipeBlockingINTEL": 5947, + "OpFPGARegINTEL": 5949, + "OpRayQueryGetRayTMinKHR": 6016, + "OpRayQueryGetRayFlagsKHR": 6017, + "OpRayQueryGetIntersectionTKHR": 6018, + "OpRayQueryGetIntersectionInstanceCustomIndexKHR": 6019, + "OpRayQueryGetIntersectionInstanceIdKHR": 6020, + "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR": 6021, + "OpRayQueryGetIntersectionGeometryIndexKHR": 6022, + "OpRayQueryGetIntersectionPrimitiveIndexKHR": 6023, + "OpRayQueryGetIntersectionBarycentricsKHR": 6024, + "OpRayQueryGetIntersectionFrontFaceKHR": 6025, + "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR": 6026, + "OpRayQueryGetIntersectionObjectRayDirectionKHR": 6027, + "OpRayQueryGetIntersectionObjectRayOriginKHR": 6028, + "OpRayQueryGetWorldRayDirectionKHR": 6029, + "OpRayQueryGetWorldRayOriginKHR": 6030, + "OpRayQueryGetIntersectionObjectToWorldKHR": 6031, + "OpRayQueryGetIntersectionWorldToObjectKHR": 6032, + "OpAtomicFAddEXT": 6035, + "OpTypeBufferSurfaceINTEL": 6086, + "OpTypeStructContinuedINTEL": 6090, + "OpConstantCompositeContinuedINTEL": 6091, + "OpSpecConstantCompositeContinuedINTEL": 6092, + "OpCompositeConstructContinuedINTEL": 6096, + "OpConvertFToBF16INTEL": 6116, + "OpConvertBF16ToFINTEL": 6117, + "OpControlBarrierArriveINTEL": 6142, + "OpControlBarrierWaitINTEL": 6143, + "OpGroupIMulKHR": 6401, + "OpGroupFMulKHR": 6402, + "OpGroupBitwiseAndKHR": 6403, + "OpGroupBitwiseOrKHR": 6404, + "OpGroupBitwiseXorKHR": 6405, + "OpGroupLogicalAndKHR": 6406, + "OpGroupLogicalOrKHR": 6407, + "OpGroupLogicalXorKHR": 6408, + "OpMaskedGatherINTEL": 6428, + "OpMaskedScatterINTEL": 6429 + } + } + ] + } +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.lua b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.lua new file mode 100644 index 000000000000..0be8e9119bf8 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.lua @@ -0,0 +1,2084 @@ +-- Copyright (c) 2014-2024 The Khronos Group Inc. +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and/or associated documentation files (the "Materials"), +-- to deal in the Materials without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Materials, and to permit persons to whom the +-- Materials are furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Materials. +-- +-- MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +-- STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +-- HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +-- +-- THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +-- IN THE MATERIALS. + +-- This header is automatically generated by the same tool that creates +-- the Binary Section of the SPIR-V specification. + +-- Enumeration tokens for SPIR-V, in various styles: +-- C, C++, C++11, JSON, Lua, Python, C#, D, Beef +-- +-- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +-- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +-- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +-- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +-- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- - C# will use enum classes in the Specification class located in the "Spv" namespace, +-- e.g.: Spv.Specification.SourceLanguage.GLSL +-- - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +-- - Beef will use enum classes in the Specification class located in the "Spv" namespace, +-- e.g.: Spv.Specification.SourceLanguage.GLSL +-- +-- Some tokens act like mask values, which can be OR'd together, +-- while others are mutually exclusive. The mask-like ones have +-- "Mask" in their name, and a parallel enum that has the shift +-- amount (1 << x) for each corresponding enumerant. + +spv = { + MagicNumber = 0x07230203, + Version = 0x00010600, + Revision = 1, + OpCodeMask = 0xffff, + WordCountShift = 16, + + SourceLanguage = { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + }, + + ExecutionModel = { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + }, + + AddressingModel = { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + }, + + MemoryModel = { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + }, + + ExecutionMode = { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + }, + + StorageClass = { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + NodeOutputPayloadAMDX = 5076, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + }, + + Dim = { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + }, + + SamplerAddressingMode = { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + }, + + SamplerFilterMode = { + Nearest = 0, + Linear = 1, + }, + + ImageFormat = { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + }, + + ImageChannelOrder = { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + }, + + ImageChannelDataType = { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + }, + + ImageOperandsShift = { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + }, + + ImageOperandsMask = { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, + }, + + FPFastMathModeShift = { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + }, + + FPFastMathModeMask = { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, + }, + + FPRoundingMode = { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + }, + + LinkageType = { + Export = 0, + Import = 1, + LinkOnceODR = 2, + }, + + AccessQualifier = { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + }, + + FunctionParameterAttribute = { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + }, + + Decoration = { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + }, + + BuiltIn = { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + CoalescedInputCountAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + }, + + SelectionControlShift = { + Flatten = 0, + DontFlatten = 1, + }, + + SelectionControlMask = { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, + }, + + LoopControlShift = { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + }, + + LoopControlMask = { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, + }, + + FunctionControlShift = { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, + }, + + FunctionControlMask = { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, + }, + + MemorySemanticsShift = { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + }, + + MemorySemanticsMask = { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, + }, + + MemoryAccessShift = { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + }, + + MemoryAccessMask = { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, + }, + + Scope = { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + }, + + GroupOperation = { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + }, + + KernelEnqueueFlags = { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + }, + + KernelProfilingInfoShift = { + CmdExecTime = 0, + }, + + KernelProfilingInfoMask = { + MaskNone = 0, + CmdExecTime = 0x00000001, + }, + + Capability = { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + }, + + RayFlagsShift = { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + }, + + RayFlagsMask = { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, + }, + + RayQueryIntersection = { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + }, + + RayQueryCommittedIntersectionType = { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + }, + + RayQueryCandidateIntersectionType = { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + }, + + FragmentShadingRateShift = { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + }, + + FragmentShadingRateMask = { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, + }, + + FPDenormMode = { + Preserve = 0, + FlushToZero = 1, + }, + + FPOperationMode = { + IEEE = 0, + ALT = 1, + }, + + QuantizationModes = { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + }, + + OverflowModes = { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + }, + + PackedVectorFormat = { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + }, + + CooperativeMatrixOperandsShift = { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + }, + + CooperativeMatrixOperandsMask = { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, + }, + + CooperativeMatrixLayout = { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + }, + + CooperativeMatrixUse = { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + }, + + InitializationModeQualifier = { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + }, + + HostAccessQualifier = { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + }, + + LoadCacheControl = { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + }, + + StoreCacheControl = { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + }, + + NamedMaximumNumberOfRegisters = { + AutoINTEL = 0, + }, + + Op = { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpFinalizeNodePayloadsAMDX = 5075, + OpFinishWritingNodePayloadAMDX = 5078, + OpInitializeNodePayloadsAMDX = 5090, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + }, + +} + diff --git a/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.py b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.py new file mode 100644 index 000000000000..a507f19e9b37 --- /dev/null +++ b/thirdparty/glslang/glslang/Include/spirv/unified1/spirv.py @@ -0,0 +1,2084 @@ +# Copyright (c) 2014-2024 The Khronos Group Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and/or associated documentation files (the "Materials"), +# to deal in the Materials without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Materials, and to permit persons to whom the +# Materials are furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Materials. +# +# MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +# STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +# HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +# +# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +# IN THE MATERIALS. + +# This header is automatically generated by the same tool that creates +# the Binary Section of the SPIR-V specification. + +# Enumeration tokens for SPIR-V, in various styles: +# C, C++, C++11, JSON, Lua, Python, C#, D, Beef +# +# - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +# - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +# - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +# - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +# - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# - C# will use enum classes in the Specification class located in the "Spv" namespace, +# e.g.: Spv.Specification.SourceLanguage.GLSL +# - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +# - Beef will use enum classes in the Specification class located in the "Spv" namespace, +# e.g.: Spv.Specification.SourceLanguage.GLSL +# +# Some tokens act like mask values, which can be OR'd together, +# while others are mutually exclusive. The mask-like ones have +# "Mask" in their name, and a parallel enum that has the shift +# amount (1 << x) for each corresponding enumerant. + +spv = { + 'MagicNumber' : 0x07230203, + 'Version' : 0x00010600, + 'Revision' : 1, + 'OpCodeMask' : 0xffff, + 'WordCountShift' : 16, + + 'SourceLanguage' : { + 'Unknown' : 0, + 'ESSL' : 1, + 'GLSL' : 2, + 'OpenCL_C' : 3, + 'OpenCL_CPP' : 4, + 'HLSL' : 5, + 'CPP_for_OpenCL' : 6, + 'SYCL' : 7, + 'HERO_C' : 8, + 'NZSL' : 9, + 'WGSL' : 10, + 'Slang' : 11, + 'Zig' : 12, + }, + + 'ExecutionModel' : { + 'Vertex' : 0, + 'TessellationControl' : 1, + 'TessellationEvaluation' : 2, + 'Geometry' : 3, + 'Fragment' : 4, + 'GLCompute' : 5, + 'Kernel' : 6, + 'TaskNV' : 5267, + 'MeshNV' : 5268, + 'RayGenerationKHR' : 5313, + 'RayGenerationNV' : 5313, + 'IntersectionKHR' : 5314, + 'IntersectionNV' : 5314, + 'AnyHitKHR' : 5315, + 'AnyHitNV' : 5315, + 'ClosestHitKHR' : 5316, + 'ClosestHitNV' : 5316, + 'MissKHR' : 5317, + 'MissNV' : 5317, + 'CallableKHR' : 5318, + 'CallableNV' : 5318, + 'TaskEXT' : 5364, + 'MeshEXT' : 5365, + }, + + 'AddressingModel' : { + 'Logical' : 0, + 'Physical32' : 1, + 'Physical64' : 2, + 'PhysicalStorageBuffer64' : 5348, + 'PhysicalStorageBuffer64EXT' : 5348, + }, + + 'MemoryModel' : { + 'Simple' : 0, + 'GLSL450' : 1, + 'OpenCL' : 2, + 'Vulkan' : 3, + 'VulkanKHR' : 3, + }, + + 'ExecutionMode' : { + 'Invocations' : 0, + 'SpacingEqual' : 1, + 'SpacingFractionalEven' : 2, + 'SpacingFractionalOdd' : 3, + 'VertexOrderCw' : 4, + 'VertexOrderCcw' : 5, + 'PixelCenterInteger' : 6, + 'OriginUpperLeft' : 7, + 'OriginLowerLeft' : 8, + 'EarlyFragmentTests' : 9, + 'PointMode' : 10, + 'Xfb' : 11, + 'DepthReplacing' : 12, + 'DepthGreater' : 14, + 'DepthLess' : 15, + 'DepthUnchanged' : 16, + 'LocalSize' : 17, + 'LocalSizeHint' : 18, + 'InputPoints' : 19, + 'InputLines' : 20, + 'InputLinesAdjacency' : 21, + 'Triangles' : 22, + 'InputTrianglesAdjacency' : 23, + 'Quads' : 24, + 'Isolines' : 25, + 'OutputVertices' : 26, + 'OutputPoints' : 27, + 'OutputLineStrip' : 28, + 'OutputTriangleStrip' : 29, + 'VecTypeHint' : 30, + 'ContractionOff' : 31, + 'Initializer' : 33, + 'Finalizer' : 34, + 'SubgroupSize' : 35, + 'SubgroupsPerWorkgroup' : 36, + 'SubgroupsPerWorkgroupId' : 37, + 'LocalSizeId' : 38, + 'LocalSizeHintId' : 39, + 'NonCoherentColorAttachmentReadEXT' : 4169, + 'NonCoherentDepthAttachmentReadEXT' : 4170, + 'NonCoherentStencilAttachmentReadEXT' : 4171, + 'SubgroupUniformControlFlowKHR' : 4421, + 'PostDepthCoverage' : 4446, + 'DenormPreserve' : 4459, + 'DenormFlushToZero' : 4460, + 'SignedZeroInfNanPreserve' : 4461, + 'RoundingModeRTE' : 4462, + 'RoundingModeRTZ' : 4463, + 'EarlyAndLateFragmentTestsAMD' : 5017, + 'StencilRefReplacingEXT' : 5027, + 'CoalescingAMDX' : 5069, + 'MaxNodeRecursionAMDX' : 5071, + 'StaticNumWorkgroupsAMDX' : 5072, + 'ShaderIndexAMDX' : 5073, + 'MaxNumWorkgroupsAMDX' : 5077, + 'StencilRefUnchangedFrontAMD' : 5079, + 'StencilRefGreaterFrontAMD' : 5080, + 'StencilRefLessFrontAMD' : 5081, + 'StencilRefUnchangedBackAMD' : 5082, + 'StencilRefGreaterBackAMD' : 5083, + 'StencilRefLessBackAMD' : 5084, + 'QuadDerivativesKHR' : 5088, + 'RequireFullQuadsKHR' : 5089, + 'OutputLinesEXT' : 5269, + 'OutputLinesNV' : 5269, + 'OutputPrimitivesEXT' : 5270, + 'OutputPrimitivesNV' : 5270, + 'DerivativeGroupQuadsNV' : 5289, + 'DerivativeGroupLinearNV' : 5290, + 'OutputTrianglesEXT' : 5298, + 'OutputTrianglesNV' : 5298, + 'PixelInterlockOrderedEXT' : 5366, + 'PixelInterlockUnorderedEXT' : 5367, + 'SampleInterlockOrderedEXT' : 5368, + 'SampleInterlockUnorderedEXT' : 5369, + 'ShadingRateInterlockOrderedEXT' : 5370, + 'ShadingRateInterlockUnorderedEXT' : 5371, + 'SharedLocalMemorySizeINTEL' : 5618, + 'RoundingModeRTPINTEL' : 5620, + 'RoundingModeRTNINTEL' : 5621, + 'FloatingPointModeALTINTEL' : 5622, + 'FloatingPointModeIEEEINTEL' : 5623, + 'MaxWorkgroupSizeINTEL' : 5893, + 'MaxWorkDimINTEL' : 5894, + 'NoGlobalOffsetINTEL' : 5895, + 'NumSIMDWorkitemsINTEL' : 5896, + 'SchedulerTargetFmaxMhzINTEL' : 5903, + 'MaximallyReconvergesKHR' : 6023, + 'FPFastMathDefault' : 6028, + 'StreamingInterfaceINTEL' : 6154, + 'RegisterMapInterfaceINTEL' : 6160, + 'NamedBarrierCountINTEL' : 6417, + 'MaximumRegistersINTEL' : 6461, + 'MaximumRegistersIdINTEL' : 6462, + 'NamedMaximumRegistersINTEL' : 6463, + }, + + 'StorageClass' : { + 'UniformConstant' : 0, + 'Input' : 1, + 'Uniform' : 2, + 'Output' : 3, + 'Workgroup' : 4, + 'CrossWorkgroup' : 5, + 'Private' : 6, + 'Function' : 7, + 'Generic' : 8, + 'PushConstant' : 9, + 'AtomicCounter' : 10, + 'Image' : 11, + 'StorageBuffer' : 12, + 'TileImageEXT' : 4172, + 'NodePayloadAMDX' : 5068, + 'NodeOutputPayloadAMDX' : 5076, + 'CallableDataKHR' : 5328, + 'CallableDataNV' : 5328, + 'IncomingCallableDataKHR' : 5329, + 'IncomingCallableDataNV' : 5329, + 'RayPayloadKHR' : 5338, + 'RayPayloadNV' : 5338, + 'HitAttributeKHR' : 5339, + 'HitAttributeNV' : 5339, + 'IncomingRayPayloadKHR' : 5342, + 'IncomingRayPayloadNV' : 5342, + 'ShaderRecordBufferKHR' : 5343, + 'ShaderRecordBufferNV' : 5343, + 'PhysicalStorageBuffer' : 5349, + 'PhysicalStorageBufferEXT' : 5349, + 'HitObjectAttributeNV' : 5385, + 'TaskPayloadWorkgroupEXT' : 5402, + 'CodeSectionINTEL' : 5605, + 'DeviceOnlyINTEL' : 5936, + 'HostOnlyINTEL' : 5937, + }, + + 'Dim' : { + 'Dim1D' : 0, + 'Dim2D' : 1, + 'Dim3D' : 2, + 'Cube' : 3, + 'Rect' : 4, + 'Buffer' : 5, + 'SubpassData' : 6, + 'TileImageDataEXT' : 4173, + }, + + 'SamplerAddressingMode' : { + 'None' : 0, + 'ClampToEdge' : 1, + 'Clamp' : 2, + 'Repeat' : 3, + 'RepeatMirrored' : 4, + }, + + 'SamplerFilterMode' : { + 'Nearest' : 0, + 'Linear' : 1, + }, + + 'ImageFormat' : { + 'Unknown' : 0, + 'Rgba32f' : 1, + 'Rgba16f' : 2, + 'R32f' : 3, + 'Rgba8' : 4, + 'Rgba8Snorm' : 5, + 'Rg32f' : 6, + 'Rg16f' : 7, + 'R11fG11fB10f' : 8, + 'R16f' : 9, + 'Rgba16' : 10, + 'Rgb10A2' : 11, + 'Rg16' : 12, + 'Rg8' : 13, + 'R16' : 14, + 'R8' : 15, + 'Rgba16Snorm' : 16, + 'Rg16Snorm' : 17, + 'Rg8Snorm' : 18, + 'R16Snorm' : 19, + 'R8Snorm' : 20, + 'Rgba32i' : 21, + 'Rgba16i' : 22, + 'Rgba8i' : 23, + 'R32i' : 24, + 'Rg32i' : 25, + 'Rg16i' : 26, + 'Rg8i' : 27, + 'R16i' : 28, + 'R8i' : 29, + 'Rgba32ui' : 30, + 'Rgba16ui' : 31, + 'Rgba8ui' : 32, + 'R32ui' : 33, + 'Rgb10a2ui' : 34, + 'Rg32ui' : 35, + 'Rg16ui' : 36, + 'Rg8ui' : 37, + 'R16ui' : 38, + 'R8ui' : 39, + 'R64ui' : 40, + 'R64i' : 41, + }, + + 'ImageChannelOrder' : { + 'R' : 0, + 'A' : 1, + 'RG' : 2, + 'RA' : 3, + 'RGB' : 4, + 'RGBA' : 5, + 'BGRA' : 6, + 'ARGB' : 7, + 'Intensity' : 8, + 'Luminance' : 9, + 'Rx' : 10, + 'RGx' : 11, + 'RGBx' : 12, + 'Depth' : 13, + 'DepthStencil' : 14, + 'sRGB' : 15, + 'sRGBx' : 16, + 'sRGBA' : 17, + 'sBGRA' : 18, + 'ABGR' : 19, + }, + + 'ImageChannelDataType' : { + 'SnormInt8' : 0, + 'SnormInt16' : 1, + 'UnormInt8' : 2, + 'UnormInt16' : 3, + 'UnormShort565' : 4, + 'UnormShort555' : 5, + 'UnormInt101010' : 6, + 'SignedInt8' : 7, + 'SignedInt16' : 8, + 'SignedInt32' : 9, + 'UnsignedInt8' : 10, + 'UnsignedInt16' : 11, + 'UnsignedInt32' : 12, + 'HalfFloat' : 13, + 'Float' : 14, + 'UnormInt24' : 15, + 'UnormInt101010_2' : 16, + 'UnsignedIntRaw10EXT' : 19, + 'UnsignedIntRaw12EXT' : 20, + }, + + 'ImageOperandsShift' : { + 'Bias' : 0, + 'Lod' : 1, + 'Grad' : 2, + 'ConstOffset' : 3, + 'Offset' : 4, + 'ConstOffsets' : 5, + 'Sample' : 6, + 'MinLod' : 7, + 'MakeTexelAvailable' : 8, + 'MakeTexelAvailableKHR' : 8, + 'MakeTexelVisible' : 9, + 'MakeTexelVisibleKHR' : 9, + 'NonPrivateTexel' : 10, + 'NonPrivateTexelKHR' : 10, + 'VolatileTexel' : 11, + 'VolatileTexelKHR' : 11, + 'SignExtend' : 12, + 'ZeroExtend' : 13, + 'Nontemporal' : 14, + 'Offsets' : 16, + }, + + 'ImageOperandsMask' : { + 'MaskNone' : 0, + 'Bias' : 0x00000001, + 'Lod' : 0x00000002, + 'Grad' : 0x00000004, + 'ConstOffset' : 0x00000008, + 'Offset' : 0x00000010, + 'ConstOffsets' : 0x00000020, + 'Sample' : 0x00000040, + 'MinLod' : 0x00000080, + 'MakeTexelAvailable' : 0x00000100, + 'MakeTexelAvailableKHR' : 0x00000100, + 'MakeTexelVisible' : 0x00000200, + 'MakeTexelVisibleKHR' : 0x00000200, + 'NonPrivateTexel' : 0x00000400, + 'NonPrivateTexelKHR' : 0x00000400, + 'VolatileTexel' : 0x00000800, + 'VolatileTexelKHR' : 0x00000800, + 'SignExtend' : 0x00001000, + 'ZeroExtend' : 0x00002000, + 'Nontemporal' : 0x00004000, + 'Offsets' : 0x00010000, + }, + + 'FPFastMathModeShift' : { + 'NotNaN' : 0, + 'NotInf' : 1, + 'NSZ' : 2, + 'AllowRecip' : 3, + 'Fast' : 4, + 'AllowContract' : 16, + 'AllowContractFastINTEL' : 16, + 'AllowReassoc' : 17, + 'AllowReassocINTEL' : 17, + 'AllowTransform' : 18, + }, + + 'FPFastMathModeMask' : { + 'MaskNone' : 0, + 'NotNaN' : 0x00000001, + 'NotInf' : 0x00000002, + 'NSZ' : 0x00000004, + 'AllowRecip' : 0x00000008, + 'Fast' : 0x00000010, + 'AllowContract' : 0x00010000, + 'AllowContractFastINTEL' : 0x00010000, + 'AllowReassoc' : 0x00020000, + 'AllowReassocINTEL' : 0x00020000, + 'AllowTransform' : 0x00040000, + }, + + 'FPRoundingMode' : { + 'RTE' : 0, + 'RTZ' : 1, + 'RTP' : 2, + 'RTN' : 3, + }, + + 'LinkageType' : { + 'Export' : 0, + 'Import' : 1, + 'LinkOnceODR' : 2, + }, + + 'AccessQualifier' : { + 'ReadOnly' : 0, + 'WriteOnly' : 1, + 'ReadWrite' : 2, + }, + + 'FunctionParameterAttribute' : { + 'Zext' : 0, + 'Sext' : 1, + 'ByVal' : 2, + 'Sret' : 3, + 'NoAlias' : 4, + 'NoCapture' : 5, + 'NoWrite' : 6, + 'NoReadWrite' : 7, + 'RuntimeAlignedINTEL' : 5940, + }, + + 'Decoration' : { + 'RelaxedPrecision' : 0, + 'SpecId' : 1, + 'Block' : 2, + 'BufferBlock' : 3, + 'RowMajor' : 4, + 'ColMajor' : 5, + 'ArrayStride' : 6, + 'MatrixStride' : 7, + 'GLSLShared' : 8, + 'GLSLPacked' : 9, + 'CPacked' : 10, + 'BuiltIn' : 11, + 'NoPerspective' : 13, + 'Flat' : 14, + 'Patch' : 15, + 'Centroid' : 16, + 'Sample' : 17, + 'Invariant' : 18, + 'Restrict' : 19, + 'Aliased' : 20, + 'Volatile' : 21, + 'Constant' : 22, + 'Coherent' : 23, + 'NonWritable' : 24, + 'NonReadable' : 25, + 'Uniform' : 26, + 'UniformId' : 27, + 'SaturatedConversion' : 28, + 'Stream' : 29, + 'Location' : 30, + 'Component' : 31, + 'Index' : 32, + 'Binding' : 33, + 'DescriptorSet' : 34, + 'Offset' : 35, + 'XfbBuffer' : 36, + 'XfbStride' : 37, + 'FuncParamAttr' : 38, + 'FPRoundingMode' : 39, + 'FPFastMathMode' : 40, + 'LinkageAttributes' : 41, + 'NoContraction' : 42, + 'InputAttachmentIndex' : 43, + 'Alignment' : 44, + 'MaxByteOffset' : 45, + 'AlignmentId' : 46, + 'MaxByteOffsetId' : 47, + 'NoSignedWrap' : 4469, + 'NoUnsignedWrap' : 4470, + 'WeightTextureQCOM' : 4487, + 'BlockMatchTextureQCOM' : 4488, + 'BlockMatchSamplerQCOM' : 4499, + 'ExplicitInterpAMD' : 4999, + 'NodeSharesPayloadLimitsWithAMDX' : 5019, + 'NodeMaxPayloadsAMDX' : 5020, + 'TrackFinishWritingAMDX' : 5078, + 'PayloadNodeNameAMDX' : 5091, + 'OverrideCoverageNV' : 5248, + 'PassthroughNV' : 5250, + 'ViewportRelativeNV' : 5252, + 'SecondaryViewportRelativeNV' : 5256, + 'PerPrimitiveEXT' : 5271, + 'PerPrimitiveNV' : 5271, + 'PerViewNV' : 5272, + 'PerTaskNV' : 5273, + 'PerVertexKHR' : 5285, + 'PerVertexNV' : 5285, + 'NonUniform' : 5300, + 'NonUniformEXT' : 5300, + 'RestrictPointer' : 5355, + 'RestrictPointerEXT' : 5355, + 'AliasedPointer' : 5356, + 'AliasedPointerEXT' : 5356, + 'HitObjectShaderRecordBufferNV' : 5386, + 'BindlessSamplerNV' : 5398, + 'BindlessImageNV' : 5399, + 'BoundSamplerNV' : 5400, + 'BoundImageNV' : 5401, + 'SIMTCallINTEL' : 5599, + 'ReferencedIndirectlyINTEL' : 5602, + 'ClobberINTEL' : 5607, + 'SideEffectsINTEL' : 5608, + 'VectorComputeVariableINTEL' : 5624, + 'FuncParamIOKindINTEL' : 5625, + 'VectorComputeFunctionINTEL' : 5626, + 'StackCallINTEL' : 5627, + 'GlobalVariableOffsetINTEL' : 5628, + 'CounterBuffer' : 5634, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, + 'UserSemantic' : 5635, + 'UserTypeGOOGLE' : 5636, + 'FunctionRoundingModeINTEL' : 5822, + 'FunctionDenormModeINTEL' : 5823, + 'RegisterINTEL' : 5825, + 'MemoryINTEL' : 5826, + 'NumbanksINTEL' : 5827, + 'BankwidthINTEL' : 5828, + 'MaxPrivateCopiesINTEL' : 5829, + 'SinglepumpINTEL' : 5830, + 'DoublepumpINTEL' : 5831, + 'MaxReplicatesINTEL' : 5832, + 'SimpleDualPortINTEL' : 5833, + 'MergeINTEL' : 5834, + 'BankBitsINTEL' : 5835, + 'ForcePow2DepthINTEL' : 5836, + 'StridesizeINTEL' : 5883, + 'WordsizeINTEL' : 5884, + 'TrueDualPortINTEL' : 5885, + 'BurstCoalesceINTEL' : 5899, + 'CacheSizeINTEL' : 5900, + 'DontStaticallyCoalesceINTEL' : 5901, + 'PrefetchINTEL' : 5902, + 'StallEnableINTEL' : 5905, + 'FuseLoopsInFunctionINTEL' : 5907, + 'MathOpDSPModeINTEL' : 5909, + 'AliasScopeINTEL' : 5914, + 'NoAliasINTEL' : 5915, + 'InitiationIntervalINTEL' : 5917, + 'MaxConcurrencyINTEL' : 5918, + 'PipelineEnableINTEL' : 5919, + 'BufferLocationINTEL' : 5921, + 'IOPipeStorageINTEL' : 5944, + 'FunctionFloatingPointModeINTEL' : 6080, + 'SingleElementVectorINTEL' : 6085, + 'VectorComputeCallableFunctionINTEL' : 6087, + 'MediaBlockIOINTEL' : 6140, + 'StallFreeINTEL' : 6151, + 'FPMaxErrorDecorationINTEL' : 6170, + 'LatencyControlLabelINTEL' : 6172, + 'LatencyControlConstraintINTEL' : 6173, + 'ConduitKernelArgumentINTEL' : 6175, + 'RegisterMapKernelArgumentINTEL' : 6176, + 'MMHostInterfaceAddressWidthINTEL' : 6177, + 'MMHostInterfaceDataWidthINTEL' : 6178, + 'MMHostInterfaceLatencyINTEL' : 6179, + 'MMHostInterfaceReadWriteModeINTEL' : 6180, + 'MMHostInterfaceMaxBurstINTEL' : 6181, + 'MMHostInterfaceWaitRequestINTEL' : 6182, + 'StableKernelArgumentINTEL' : 6183, + 'HostAccessINTEL' : 6188, + 'InitModeINTEL' : 6190, + 'ImplementInRegisterMapINTEL' : 6191, + 'CacheControlLoadINTEL' : 6442, + 'CacheControlStoreINTEL' : 6443, + }, + + 'BuiltIn' : { + 'Position' : 0, + 'PointSize' : 1, + 'ClipDistance' : 3, + 'CullDistance' : 4, + 'VertexId' : 5, + 'InstanceId' : 6, + 'PrimitiveId' : 7, + 'InvocationId' : 8, + 'Layer' : 9, + 'ViewportIndex' : 10, + 'TessLevelOuter' : 11, + 'TessLevelInner' : 12, + 'TessCoord' : 13, + 'PatchVertices' : 14, + 'FragCoord' : 15, + 'PointCoord' : 16, + 'FrontFacing' : 17, + 'SampleId' : 18, + 'SamplePosition' : 19, + 'SampleMask' : 20, + 'FragDepth' : 22, + 'HelperInvocation' : 23, + 'NumWorkgroups' : 24, + 'WorkgroupSize' : 25, + 'WorkgroupId' : 26, + 'LocalInvocationId' : 27, + 'GlobalInvocationId' : 28, + 'LocalInvocationIndex' : 29, + 'WorkDim' : 30, + 'GlobalSize' : 31, + 'EnqueuedWorkgroupSize' : 32, + 'GlobalOffset' : 33, + 'GlobalLinearId' : 34, + 'SubgroupSize' : 36, + 'SubgroupMaxSize' : 37, + 'NumSubgroups' : 38, + 'NumEnqueuedSubgroups' : 39, + 'SubgroupId' : 40, + 'SubgroupLocalInvocationId' : 41, + 'VertexIndex' : 42, + 'InstanceIndex' : 43, + 'CoreIDARM' : 4160, + 'CoreCountARM' : 4161, + 'CoreMaxIDARM' : 4162, + 'WarpIDARM' : 4163, + 'WarpMaxIDARM' : 4164, + 'SubgroupEqMask' : 4416, + 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMask' : 4417, + 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMask' : 4418, + 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMask' : 4419, + 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMask' : 4420, + 'SubgroupLtMaskKHR' : 4420, + 'BaseVertex' : 4424, + 'BaseInstance' : 4425, + 'DrawIndex' : 4426, + 'PrimitiveShadingRateKHR' : 4432, + 'DeviceIndex' : 4438, + 'ViewIndex' : 4440, + 'ShadingRateKHR' : 4444, + 'BaryCoordNoPerspAMD' : 4992, + 'BaryCoordNoPerspCentroidAMD' : 4993, + 'BaryCoordNoPerspSampleAMD' : 4994, + 'BaryCoordSmoothAMD' : 4995, + 'BaryCoordSmoothCentroidAMD' : 4996, + 'BaryCoordSmoothSampleAMD' : 4997, + 'BaryCoordPullModelAMD' : 4998, + 'FragStencilRefEXT' : 5014, + 'CoalescedInputCountAMDX' : 5021, + 'ShaderIndexAMDX' : 5073, + 'ViewportMaskNV' : 5253, + 'SecondaryPositionNV' : 5257, + 'SecondaryViewportMaskNV' : 5258, + 'PositionPerViewNV' : 5261, + 'ViewportMaskPerViewNV' : 5262, + 'FullyCoveredEXT' : 5264, + 'TaskCountNV' : 5274, + 'PrimitiveCountNV' : 5275, + 'PrimitiveIndicesNV' : 5276, + 'ClipDistancePerViewNV' : 5277, + 'CullDistancePerViewNV' : 5278, + 'LayerPerViewNV' : 5279, + 'MeshViewCountNV' : 5280, + 'MeshViewIndicesNV' : 5281, + 'BaryCoordKHR' : 5286, + 'BaryCoordNV' : 5286, + 'BaryCoordNoPerspKHR' : 5287, + 'BaryCoordNoPerspNV' : 5287, + 'FragSizeEXT' : 5292, + 'FragmentSizeNV' : 5292, + 'FragInvocationCountEXT' : 5293, + 'InvocationsPerPixelNV' : 5293, + 'PrimitivePointIndicesEXT' : 5294, + 'PrimitiveLineIndicesEXT' : 5295, + 'PrimitiveTriangleIndicesEXT' : 5296, + 'CullPrimitiveEXT' : 5299, + 'LaunchIdKHR' : 5319, + 'LaunchIdNV' : 5319, + 'LaunchSizeKHR' : 5320, + 'LaunchSizeNV' : 5320, + 'WorldRayOriginKHR' : 5321, + 'WorldRayOriginNV' : 5321, + 'WorldRayDirectionKHR' : 5322, + 'WorldRayDirectionNV' : 5322, + 'ObjectRayOriginKHR' : 5323, + 'ObjectRayOriginNV' : 5323, + 'ObjectRayDirectionKHR' : 5324, + 'ObjectRayDirectionNV' : 5324, + 'RayTminKHR' : 5325, + 'RayTminNV' : 5325, + 'RayTmaxKHR' : 5326, + 'RayTmaxNV' : 5326, + 'InstanceCustomIndexKHR' : 5327, + 'InstanceCustomIndexNV' : 5327, + 'ObjectToWorldKHR' : 5330, + 'ObjectToWorldNV' : 5330, + 'WorldToObjectKHR' : 5331, + 'WorldToObjectNV' : 5331, + 'HitTNV' : 5332, + 'HitKindKHR' : 5333, + 'HitKindNV' : 5333, + 'CurrentRayTimeNV' : 5334, + 'HitTriangleVertexPositionsKHR' : 5335, + 'HitMicroTriangleVertexPositionsNV' : 5337, + 'HitMicroTriangleVertexBarycentricsNV' : 5344, + 'IncomingRayFlagsKHR' : 5351, + 'IncomingRayFlagsNV' : 5351, + 'RayGeometryIndexKHR' : 5352, + 'WarpsPerSMNV' : 5374, + 'SMCountNV' : 5375, + 'WarpIDNV' : 5376, + 'SMIDNV' : 5377, + 'HitKindFrontFacingMicroTriangleNV' : 5405, + 'HitKindBackFacingMicroTriangleNV' : 5406, + 'CullMaskKHR' : 6021, + }, + + 'SelectionControlShift' : { + 'Flatten' : 0, + 'DontFlatten' : 1, + }, + + 'SelectionControlMask' : { + 'MaskNone' : 0, + 'Flatten' : 0x00000001, + 'DontFlatten' : 0x00000002, + }, + + 'LoopControlShift' : { + 'Unroll' : 0, + 'DontUnroll' : 1, + 'DependencyInfinite' : 2, + 'DependencyLength' : 3, + 'MinIterations' : 4, + 'MaxIterations' : 5, + 'IterationMultiple' : 6, + 'PeelCount' : 7, + 'PartialCount' : 8, + 'InitiationIntervalINTEL' : 16, + 'MaxConcurrencyINTEL' : 17, + 'DependencyArrayINTEL' : 18, + 'PipelineEnableINTEL' : 19, + 'LoopCoalesceINTEL' : 20, + 'MaxInterleavingINTEL' : 21, + 'SpeculatedIterationsINTEL' : 22, + 'NoFusionINTEL' : 23, + 'LoopCountINTEL' : 24, + 'MaxReinvocationDelayINTEL' : 25, + }, + + 'LoopControlMask' : { + 'MaskNone' : 0, + 'Unroll' : 0x00000001, + 'DontUnroll' : 0x00000002, + 'DependencyInfinite' : 0x00000004, + 'DependencyLength' : 0x00000008, + 'MinIterations' : 0x00000010, + 'MaxIterations' : 0x00000020, + 'IterationMultiple' : 0x00000040, + 'PeelCount' : 0x00000080, + 'PartialCount' : 0x00000100, + 'InitiationIntervalINTEL' : 0x00010000, + 'MaxConcurrencyINTEL' : 0x00020000, + 'DependencyArrayINTEL' : 0x00040000, + 'PipelineEnableINTEL' : 0x00080000, + 'LoopCoalesceINTEL' : 0x00100000, + 'MaxInterleavingINTEL' : 0x00200000, + 'SpeculatedIterationsINTEL' : 0x00400000, + 'NoFusionINTEL' : 0x00800000, + 'LoopCountINTEL' : 0x01000000, + 'MaxReinvocationDelayINTEL' : 0x02000000, + }, + + 'FunctionControlShift' : { + 'Inline' : 0, + 'DontInline' : 1, + 'Pure' : 2, + 'Const' : 3, + 'OptNoneINTEL' : 16, + }, + + 'FunctionControlMask' : { + 'MaskNone' : 0, + 'Inline' : 0x00000001, + 'DontInline' : 0x00000002, + 'Pure' : 0x00000004, + 'Const' : 0x00000008, + 'OptNoneINTEL' : 0x00010000, + }, + + 'MemorySemanticsShift' : { + 'Acquire' : 1, + 'Release' : 2, + 'AcquireRelease' : 3, + 'SequentiallyConsistent' : 4, + 'UniformMemory' : 6, + 'SubgroupMemory' : 7, + 'WorkgroupMemory' : 8, + 'CrossWorkgroupMemory' : 9, + 'AtomicCounterMemory' : 10, + 'ImageMemory' : 11, + 'OutputMemory' : 12, + 'OutputMemoryKHR' : 12, + 'MakeAvailable' : 13, + 'MakeAvailableKHR' : 13, + 'MakeVisible' : 14, + 'MakeVisibleKHR' : 14, + 'Volatile' : 15, + }, + + 'MemorySemanticsMask' : { + 'MaskNone' : 0, + 'Acquire' : 0x00000002, + 'Release' : 0x00000004, + 'AcquireRelease' : 0x00000008, + 'SequentiallyConsistent' : 0x00000010, + 'UniformMemory' : 0x00000040, + 'SubgroupMemory' : 0x00000080, + 'WorkgroupMemory' : 0x00000100, + 'CrossWorkgroupMemory' : 0x00000200, + 'AtomicCounterMemory' : 0x00000400, + 'ImageMemory' : 0x00000800, + 'OutputMemory' : 0x00001000, + 'OutputMemoryKHR' : 0x00001000, + 'MakeAvailable' : 0x00002000, + 'MakeAvailableKHR' : 0x00002000, + 'MakeVisible' : 0x00004000, + 'MakeVisibleKHR' : 0x00004000, + 'Volatile' : 0x00008000, + }, + + 'MemoryAccessShift' : { + 'Volatile' : 0, + 'Aligned' : 1, + 'Nontemporal' : 2, + 'MakePointerAvailable' : 3, + 'MakePointerAvailableKHR' : 3, + 'MakePointerVisible' : 4, + 'MakePointerVisibleKHR' : 4, + 'NonPrivatePointer' : 5, + 'NonPrivatePointerKHR' : 5, + 'AliasScopeINTELMask' : 16, + 'NoAliasINTELMask' : 17, + }, + + 'MemoryAccessMask' : { + 'MaskNone' : 0, + 'Volatile' : 0x00000001, + 'Aligned' : 0x00000002, + 'Nontemporal' : 0x00000004, + 'MakePointerAvailable' : 0x00000008, + 'MakePointerAvailableKHR' : 0x00000008, + 'MakePointerVisible' : 0x00000010, + 'MakePointerVisibleKHR' : 0x00000010, + 'NonPrivatePointer' : 0x00000020, + 'NonPrivatePointerKHR' : 0x00000020, + 'AliasScopeINTELMask' : 0x00010000, + 'NoAliasINTELMask' : 0x00020000, + }, + + 'Scope' : { + 'CrossDevice' : 0, + 'Device' : 1, + 'Workgroup' : 2, + 'Subgroup' : 3, + 'Invocation' : 4, + 'QueueFamily' : 5, + 'QueueFamilyKHR' : 5, + 'ShaderCallKHR' : 6, + }, + + 'GroupOperation' : { + 'Reduce' : 0, + 'InclusiveScan' : 1, + 'ExclusiveScan' : 2, + 'ClusteredReduce' : 3, + 'PartitionedReduceNV' : 6, + 'PartitionedInclusiveScanNV' : 7, + 'PartitionedExclusiveScanNV' : 8, + }, + + 'KernelEnqueueFlags' : { + 'NoWait' : 0, + 'WaitKernel' : 1, + 'WaitWorkGroup' : 2, + }, + + 'KernelProfilingInfoShift' : { + 'CmdExecTime' : 0, + }, + + 'KernelProfilingInfoMask' : { + 'MaskNone' : 0, + 'CmdExecTime' : 0x00000001, + }, + + 'Capability' : { + 'Matrix' : 0, + 'Shader' : 1, + 'Geometry' : 2, + 'Tessellation' : 3, + 'Addresses' : 4, + 'Linkage' : 5, + 'Kernel' : 6, + 'Vector16' : 7, + 'Float16Buffer' : 8, + 'Float16' : 9, + 'Float64' : 10, + 'Int64' : 11, + 'Int64Atomics' : 12, + 'ImageBasic' : 13, + 'ImageReadWrite' : 14, + 'ImageMipmap' : 15, + 'Pipes' : 17, + 'Groups' : 18, + 'DeviceEnqueue' : 19, + 'LiteralSampler' : 20, + 'AtomicStorage' : 21, + 'Int16' : 22, + 'TessellationPointSize' : 23, + 'GeometryPointSize' : 24, + 'ImageGatherExtended' : 25, + 'StorageImageMultisample' : 27, + 'UniformBufferArrayDynamicIndexing' : 28, + 'SampledImageArrayDynamicIndexing' : 29, + 'StorageBufferArrayDynamicIndexing' : 30, + 'StorageImageArrayDynamicIndexing' : 31, + 'ClipDistance' : 32, + 'CullDistance' : 33, + 'ImageCubeArray' : 34, + 'SampleRateShading' : 35, + 'ImageRect' : 36, + 'SampledRect' : 37, + 'GenericPointer' : 38, + 'Int8' : 39, + 'InputAttachment' : 40, + 'SparseResidency' : 41, + 'MinLod' : 42, + 'Sampled1D' : 43, + 'Image1D' : 44, + 'SampledCubeArray' : 45, + 'SampledBuffer' : 46, + 'ImageBuffer' : 47, + 'ImageMSArray' : 48, + 'StorageImageExtendedFormats' : 49, + 'ImageQuery' : 50, + 'DerivativeControl' : 51, + 'InterpolationFunction' : 52, + 'TransformFeedback' : 53, + 'GeometryStreams' : 54, + 'StorageImageReadWithoutFormat' : 55, + 'StorageImageWriteWithoutFormat' : 56, + 'MultiViewport' : 57, + 'SubgroupDispatch' : 58, + 'NamedBarrier' : 59, + 'PipeStorage' : 60, + 'GroupNonUniform' : 61, + 'GroupNonUniformVote' : 62, + 'GroupNonUniformArithmetic' : 63, + 'GroupNonUniformBallot' : 64, + 'GroupNonUniformShuffle' : 65, + 'GroupNonUniformShuffleRelative' : 66, + 'GroupNonUniformClustered' : 67, + 'GroupNonUniformQuad' : 68, + 'ShaderLayer' : 69, + 'ShaderViewportIndex' : 70, + 'UniformDecoration' : 71, + 'CoreBuiltinsARM' : 4165, + 'TileImageColorReadAccessEXT' : 4166, + 'TileImageDepthReadAccessEXT' : 4167, + 'TileImageStencilReadAccessEXT' : 4168, + 'FragmentShadingRateKHR' : 4422, + 'SubgroupBallotKHR' : 4423, + 'DrawParameters' : 4427, + 'WorkgroupMemoryExplicitLayoutKHR' : 4428, + 'WorkgroupMemoryExplicitLayout8BitAccessKHR' : 4429, + 'WorkgroupMemoryExplicitLayout16BitAccessKHR' : 4430, + 'SubgroupVoteKHR' : 4431, + 'StorageBuffer16BitAccess' : 4433, + 'StorageUniformBufferBlock16' : 4433, + 'StorageUniform16' : 4434, + 'UniformAndStorageBuffer16BitAccess' : 4434, + 'StoragePushConstant16' : 4435, + 'StorageInputOutput16' : 4436, + 'DeviceGroup' : 4437, + 'MultiView' : 4439, + 'VariablePointersStorageBuffer' : 4441, + 'VariablePointers' : 4442, + 'AtomicStorageOps' : 4445, + 'SampleMaskPostDepthCoverage' : 4447, + 'StorageBuffer8BitAccess' : 4448, + 'UniformAndStorageBuffer8BitAccess' : 4449, + 'StoragePushConstant8' : 4450, + 'DenormPreserve' : 4464, + 'DenormFlushToZero' : 4465, + 'SignedZeroInfNanPreserve' : 4466, + 'RoundingModeRTE' : 4467, + 'RoundingModeRTZ' : 4468, + 'RayQueryProvisionalKHR' : 4471, + 'RayQueryKHR' : 4472, + 'RayTraversalPrimitiveCullingKHR' : 4478, + 'RayTracingKHR' : 4479, + 'TextureSampleWeightedQCOM' : 4484, + 'TextureBoxFilterQCOM' : 4485, + 'TextureBlockMatchQCOM' : 4486, + 'TextureBlockMatch2QCOM' : 4498, + 'Float16ImageAMD' : 5008, + 'ImageGatherBiasLodAMD' : 5009, + 'FragmentMaskAMD' : 5010, + 'StencilExportEXT' : 5013, + 'ImageReadWriteLodAMD' : 5015, + 'Int64ImageEXT' : 5016, + 'ShaderClockKHR' : 5055, + 'ShaderEnqueueAMDX' : 5067, + 'QuadControlKHR' : 5087, + 'SampleMaskOverrideCoverageNV' : 5249, + 'GeometryShaderPassthroughNV' : 5251, + 'ShaderViewportIndexLayerEXT' : 5254, + 'ShaderViewportIndexLayerNV' : 5254, + 'ShaderViewportMaskNV' : 5255, + 'ShaderStereoViewNV' : 5259, + 'PerViewAttributesNV' : 5260, + 'FragmentFullyCoveredEXT' : 5265, + 'MeshShadingNV' : 5266, + 'ImageFootprintNV' : 5282, + 'MeshShadingEXT' : 5283, + 'FragmentBarycentricKHR' : 5284, + 'FragmentBarycentricNV' : 5284, + 'ComputeDerivativeGroupQuadsNV' : 5288, + 'FragmentDensityEXT' : 5291, + 'ShadingRateNV' : 5291, + 'GroupNonUniformPartitionedNV' : 5297, + 'ShaderNonUniform' : 5301, + 'ShaderNonUniformEXT' : 5301, + 'RuntimeDescriptorArray' : 5302, + 'RuntimeDescriptorArrayEXT' : 5302, + 'InputAttachmentArrayDynamicIndexing' : 5303, + 'InputAttachmentArrayDynamicIndexingEXT' : 5303, + 'UniformTexelBufferArrayDynamicIndexing' : 5304, + 'UniformTexelBufferArrayDynamicIndexingEXT' : 5304, + 'StorageTexelBufferArrayDynamicIndexing' : 5305, + 'StorageTexelBufferArrayDynamicIndexingEXT' : 5305, + 'UniformBufferArrayNonUniformIndexing' : 5306, + 'UniformBufferArrayNonUniformIndexingEXT' : 5306, + 'SampledImageArrayNonUniformIndexing' : 5307, + 'SampledImageArrayNonUniformIndexingEXT' : 5307, + 'StorageBufferArrayNonUniformIndexing' : 5308, + 'StorageBufferArrayNonUniformIndexingEXT' : 5308, + 'StorageImageArrayNonUniformIndexing' : 5309, + 'StorageImageArrayNonUniformIndexingEXT' : 5309, + 'InputAttachmentArrayNonUniformIndexing' : 5310, + 'InputAttachmentArrayNonUniformIndexingEXT' : 5310, + 'UniformTexelBufferArrayNonUniformIndexing' : 5311, + 'UniformTexelBufferArrayNonUniformIndexingEXT' : 5311, + 'StorageTexelBufferArrayNonUniformIndexing' : 5312, + 'StorageTexelBufferArrayNonUniformIndexingEXT' : 5312, + 'RayTracingPositionFetchKHR' : 5336, + 'RayTracingNV' : 5340, + 'RayTracingMotionBlurNV' : 5341, + 'VulkanMemoryModel' : 5345, + 'VulkanMemoryModelKHR' : 5345, + 'VulkanMemoryModelDeviceScope' : 5346, + 'VulkanMemoryModelDeviceScopeKHR' : 5346, + 'PhysicalStorageBufferAddresses' : 5347, + 'PhysicalStorageBufferAddressesEXT' : 5347, + 'ComputeDerivativeGroupLinearNV' : 5350, + 'RayTracingProvisionalKHR' : 5353, + 'CooperativeMatrixNV' : 5357, + 'FragmentShaderSampleInterlockEXT' : 5363, + 'FragmentShaderShadingRateInterlockEXT' : 5372, + 'ShaderSMBuiltinsNV' : 5373, + 'FragmentShaderPixelInterlockEXT' : 5378, + 'DemoteToHelperInvocation' : 5379, + 'DemoteToHelperInvocationEXT' : 5379, + 'DisplacementMicromapNV' : 5380, + 'RayTracingOpacityMicromapEXT' : 5381, + 'ShaderInvocationReorderNV' : 5383, + 'BindlessTextureNV' : 5390, + 'RayQueryPositionFetchKHR' : 5391, + 'AtomicFloat16VectorNV' : 5404, + 'RayTracingDisplacementMicromapNV' : 5409, + 'SubgroupShuffleINTEL' : 5568, + 'SubgroupBufferBlockIOINTEL' : 5569, + 'SubgroupImageBlockIOINTEL' : 5570, + 'SubgroupImageMediaBlockIOINTEL' : 5579, + 'RoundToInfinityINTEL' : 5582, + 'FloatingPointModeINTEL' : 5583, + 'IntegerFunctions2INTEL' : 5584, + 'FunctionPointersINTEL' : 5603, + 'IndirectReferencesINTEL' : 5604, + 'AsmINTEL' : 5606, + 'AtomicFloat32MinMaxEXT' : 5612, + 'AtomicFloat64MinMaxEXT' : 5613, + 'AtomicFloat16MinMaxEXT' : 5616, + 'VectorComputeINTEL' : 5617, + 'VectorAnyINTEL' : 5619, + 'ExpectAssumeKHR' : 5629, + 'SubgroupAvcMotionEstimationINTEL' : 5696, + 'SubgroupAvcMotionEstimationIntraINTEL' : 5697, + 'SubgroupAvcMotionEstimationChromaINTEL' : 5698, + 'VariableLengthArrayINTEL' : 5817, + 'FunctionFloatControlINTEL' : 5821, + 'FPGAMemoryAttributesINTEL' : 5824, + 'FPFastMathModeINTEL' : 5837, + 'ArbitraryPrecisionIntegersINTEL' : 5844, + 'ArbitraryPrecisionFloatingPointINTEL' : 5845, + 'UnstructuredLoopControlsINTEL' : 5886, + 'FPGALoopControlsINTEL' : 5888, + 'KernelAttributesINTEL' : 5892, + 'FPGAKernelAttributesINTEL' : 5897, + 'FPGAMemoryAccessesINTEL' : 5898, + 'FPGAClusterAttributesINTEL' : 5904, + 'LoopFuseINTEL' : 5906, + 'FPGADSPControlINTEL' : 5908, + 'MemoryAccessAliasingINTEL' : 5910, + 'FPGAInvocationPipeliningAttributesINTEL' : 5916, + 'FPGABufferLocationINTEL' : 5920, + 'ArbitraryPrecisionFixedPointINTEL' : 5922, + 'USMStorageClassesINTEL' : 5935, + 'RuntimeAlignedAttributeINTEL' : 5939, + 'IOPipesINTEL' : 5943, + 'BlockingPipesINTEL' : 5945, + 'FPGARegINTEL' : 5948, + 'DotProductInputAll' : 6016, + 'DotProductInputAllKHR' : 6016, + 'DotProductInput4x8Bit' : 6017, + 'DotProductInput4x8BitKHR' : 6017, + 'DotProductInput4x8BitPacked' : 6018, + 'DotProductInput4x8BitPackedKHR' : 6018, + 'DotProduct' : 6019, + 'DotProductKHR' : 6019, + 'RayCullMaskKHR' : 6020, + 'CooperativeMatrixKHR' : 6022, + 'BitInstructions' : 6025, + 'GroupNonUniformRotateKHR' : 6026, + 'FloatControls2' : 6029, + 'AtomicFloat32AddEXT' : 6033, + 'AtomicFloat64AddEXT' : 6034, + 'LongCompositesINTEL' : 6089, + 'OptNoneINTEL' : 6094, + 'AtomicFloat16AddEXT' : 6095, + 'DebugInfoModuleINTEL' : 6114, + 'BFloat16ConversionINTEL' : 6115, + 'SplitBarrierINTEL' : 6141, + 'FPGAClusterAttributesV2INTEL' : 6150, + 'FPGAKernelAttributesv2INTEL' : 6161, + 'FPMaxErrorINTEL' : 6169, + 'FPGALatencyControlINTEL' : 6171, + 'FPGAArgumentInterfacesINTEL' : 6174, + 'GlobalVariableHostAccessINTEL' : 6187, + 'GlobalVariableFPGADecorationsINTEL' : 6189, + 'GroupUniformArithmeticKHR' : 6400, + 'MaskedGatherScatterINTEL' : 6427, + 'CacheControlsINTEL' : 6441, + 'RegisterLimitsINTEL' : 6460, + }, + + 'RayFlagsShift' : { + 'OpaqueKHR' : 0, + 'NoOpaqueKHR' : 1, + 'TerminateOnFirstHitKHR' : 2, + 'SkipClosestHitShaderKHR' : 3, + 'CullBackFacingTrianglesKHR' : 4, + 'CullFrontFacingTrianglesKHR' : 5, + 'CullOpaqueKHR' : 6, + 'CullNoOpaqueKHR' : 7, + 'SkipTrianglesKHR' : 8, + 'SkipAABBsKHR' : 9, + 'ForceOpacityMicromap2StateEXT' : 10, + }, + + 'RayFlagsMask' : { + 'MaskNone' : 0, + 'OpaqueKHR' : 0x00000001, + 'NoOpaqueKHR' : 0x00000002, + 'TerminateOnFirstHitKHR' : 0x00000004, + 'SkipClosestHitShaderKHR' : 0x00000008, + 'CullBackFacingTrianglesKHR' : 0x00000010, + 'CullFrontFacingTrianglesKHR' : 0x00000020, + 'CullOpaqueKHR' : 0x00000040, + 'CullNoOpaqueKHR' : 0x00000080, + 'SkipTrianglesKHR' : 0x00000100, + 'SkipAABBsKHR' : 0x00000200, + 'ForceOpacityMicromap2StateEXT' : 0x00000400, + }, + + 'RayQueryIntersection' : { + 'RayQueryCandidateIntersectionKHR' : 0, + 'RayQueryCommittedIntersectionKHR' : 1, + }, + + 'RayQueryCommittedIntersectionType' : { + 'RayQueryCommittedIntersectionNoneKHR' : 0, + 'RayQueryCommittedIntersectionTriangleKHR' : 1, + 'RayQueryCommittedIntersectionGeneratedKHR' : 2, + }, + + 'RayQueryCandidateIntersectionType' : { + 'RayQueryCandidateIntersectionTriangleKHR' : 0, + 'RayQueryCandidateIntersectionAABBKHR' : 1, + }, + + 'FragmentShadingRateShift' : { + 'Vertical2Pixels' : 0, + 'Vertical4Pixels' : 1, + 'Horizontal2Pixels' : 2, + 'Horizontal4Pixels' : 3, + }, + + 'FragmentShadingRateMask' : { + 'MaskNone' : 0, + 'Vertical2Pixels' : 0x00000001, + 'Vertical4Pixels' : 0x00000002, + 'Horizontal2Pixels' : 0x00000004, + 'Horizontal4Pixels' : 0x00000008, + }, + + 'FPDenormMode' : { + 'Preserve' : 0, + 'FlushToZero' : 1, + }, + + 'FPOperationMode' : { + 'IEEE' : 0, + 'ALT' : 1, + }, + + 'QuantizationModes' : { + 'TRN' : 0, + 'TRN_ZERO' : 1, + 'RND' : 2, + 'RND_ZERO' : 3, + 'RND_INF' : 4, + 'RND_MIN_INF' : 5, + 'RND_CONV' : 6, + 'RND_CONV_ODD' : 7, + }, + + 'OverflowModes' : { + 'WRAP' : 0, + 'SAT' : 1, + 'SAT_ZERO' : 2, + 'SAT_SYM' : 3, + }, + + 'PackedVectorFormat' : { + 'PackedVectorFormat4x8Bit' : 0, + 'PackedVectorFormat4x8BitKHR' : 0, + }, + + 'CooperativeMatrixOperandsShift' : { + 'MatrixASignedComponentsKHR' : 0, + 'MatrixBSignedComponentsKHR' : 1, + 'MatrixCSignedComponentsKHR' : 2, + 'MatrixResultSignedComponentsKHR' : 3, + 'SaturatingAccumulationKHR' : 4, + }, + + 'CooperativeMatrixOperandsMask' : { + 'MaskNone' : 0, + 'MatrixASignedComponentsKHR' : 0x00000001, + 'MatrixBSignedComponentsKHR' : 0x00000002, + 'MatrixCSignedComponentsKHR' : 0x00000004, + 'MatrixResultSignedComponentsKHR' : 0x00000008, + 'SaturatingAccumulationKHR' : 0x00000010, + }, + + 'CooperativeMatrixLayout' : { + 'RowMajorKHR' : 0, + 'ColumnMajorKHR' : 1, + }, + + 'CooperativeMatrixUse' : { + 'MatrixAKHR' : 0, + 'MatrixBKHR' : 1, + 'MatrixAccumulatorKHR' : 2, + }, + + 'InitializationModeQualifier' : { + 'InitOnDeviceReprogramINTEL' : 0, + 'InitOnDeviceResetINTEL' : 1, + }, + + 'HostAccessQualifier' : { + 'NoneINTEL' : 0, + 'ReadINTEL' : 1, + 'WriteINTEL' : 2, + 'ReadWriteINTEL' : 3, + }, + + 'LoadCacheControl' : { + 'UncachedINTEL' : 0, + 'CachedINTEL' : 1, + 'StreamingINTEL' : 2, + 'InvalidateAfterReadINTEL' : 3, + 'ConstCachedINTEL' : 4, + }, + + 'StoreCacheControl' : { + 'UncachedINTEL' : 0, + 'WriteThroughINTEL' : 1, + 'WriteBackINTEL' : 2, + 'StreamingINTEL' : 3, + }, + + 'NamedMaximumNumberOfRegisters' : { + 'AutoINTEL' : 0, + }, + + 'Op' : { + 'OpNop' : 0, + 'OpUndef' : 1, + 'OpSourceContinued' : 2, + 'OpSource' : 3, + 'OpSourceExtension' : 4, + 'OpName' : 5, + 'OpMemberName' : 6, + 'OpString' : 7, + 'OpLine' : 8, + 'OpExtension' : 10, + 'OpExtInstImport' : 11, + 'OpExtInst' : 12, + 'OpMemoryModel' : 14, + 'OpEntryPoint' : 15, + 'OpExecutionMode' : 16, + 'OpCapability' : 17, + 'OpTypeVoid' : 19, + 'OpTypeBool' : 20, + 'OpTypeInt' : 21, + 'OpTypeFloat' : 22, + 'OpTypeVector' : 23, + 'OpTypeMatrix' : 24, + 'OpTypeImage' : 25, + 'OpTypeSampler' : 26, + 'OpTypeSampledImage' : 27, + 'OpTypeArray' : 28, + 'OpTypeRuntimeArray' : 29, + 'OpTypeStruct' : 30, + 'OpTypeOpaque' : 31, + 'OpTypePointer' : 32, + 'OpTypeFunction' : 33, + 'OpTypeEvent' : 34, + 'OpTypeDeviceEvent' : 35, + 'OpTypeReserveId' : 36, + 'OpTypeQueue' : 37, + 'OpTypePipe' : 38, + 'OpTypeForwardPointer' : 39, + 'OpConstantTrue' : 41, + 'OpConstantFalse' : 42, + 'OpConstant' : 43, + 'OpConstantComposite' : 44, + 'OpConstantSampler' : 45, + 'OpConstantNull' : 46, + 'OpSpecConstantTrue' : 48, + 'OpSpecConstantFalse' : 49, + 'OpSpecConstant' : 50, + 'OpSpecConstantComposite' : 51, + 'OpSpecConstantOp' : 52, + 'OpFunction' : 54, + 'OpFunctionParameter' : 55, + 'OpFunctionEnd' : 56, + 'OpFunctionCall' : 57, + 'OpVariable' : 59, + 'OpImageTexelPointer' : 60, + 'OpLoad' : 61, + 'OpStore' : 62, + 'OpCopyMemory' : 63, + 'OpCopyMemorySized' : 64, + 'OpAccessChain' : 65, + 'OpInBoundsAccessChain' : 66, + 'OpPtrAccessChain' : 67, + 'OpArrayLength' : 68, + 'OpGenericPtrMemSemantics' : 69, + 'OpInBoundsPtrAccessChain' : 70, + 'OpDecorate' : 71, + 'OpMemberDecorate' : 72, + 'OpDecorationGroup' : 73, + 'OpGroupDecorate' : 74, + 'OpGroupMemberDecorate' : 75, + 'OpVectorExtractDynamic' : 77, + 'OpVectorInsertDynamic' : 78, + 'OpVectorShuffle' : 79, + 'OpCompositeConstruct' : 80, + 'OpCompositeExtract' : 81, + 'OpCompositeInsert' : 82, + 'OpCopyObject' : 83, + 'OpTranspose' : 84, + 'OpSampledImage' : 86, + 'OpImageSampleImplicitLod' : 87, + 'OpImageSampleExplicitLod' : 88, + 'OpImageSampleDrefImplicitLod' : 89, + 'OpImageSampleDrefExplicitLod' : 90, + 'OpImageSampleProjImplicitLod' : 91, + 'OpImageSampleProjExplicitLod' : 92, + 'OpImageSampleProjDrefImplicitLod' : 93, + 'OpImageSampleProjDrefExplicitLod' : 94, + 'OpImageFetch' : 95, + 'OpImageGather' : 96, + 'OpImageDrefGather' : 97, + 'OpImageRead' : 98, + 'OpImageWrite' : 99, + 'OpImage' : 100, + 'OpImageQueryFormat' : 101, + 'OpImageQueryOrder' : 102, + 'OpImageQuerySizeLod' : 103, + 'OpImageQuerySize' : 104, + 'OpImageQueryLod' : 105, + 'OpImageQueryLevels' : 106, + 'OpImageQuerySamples' : 107, + 'OpConvertFToU' : 109, + 'OpConvertFToS' : 110, + 'OpConvertSToF' : 111, + 'OpConvertUToF' : 112, + 'OpUConvert' : 113, + 'OpSConvert' : 114, + 'OpFConvert' : 115, + 'OpQuantizeToF16' : 116, + 'OpConvertPtrToU' : 117, + 'OpSatConvertSToU' : 118, + 'OpSatConvertUToS' : 119, + 'OpConvertUToPtr' : 120, + 'OpPtrCastToGeneric' : 121, + 'OpGenericCastToPtr' : 122, + 'OpGenericCastToPtrExplicit' : 123, + 'OpBitcast' : 124, + 'OpSNegate' : 126, + 'OpFNegate' : 127, + 'OpIAdd' : 128, + 'OpFAdd' : 129, + 'OpISub' : 130, + 'OpFSub' : 131, + 'OpIMul' : 132, + 'OpFMul' : 133, + 'OpUDiv' : 134, + 'OpSDiv' : 135, + 'OpFDiv' : 136, + 'OpUMod' : 137, + 'OpSRem' : 138, + 'OpSMod' : 139, + 'OpFRem' : 140, + 'OpFMod' : 141, + 'OpVectorTimesScalar' : 142, + 'OpMatrixTimesScalar' : 143, + 'OpVectorTimesMatrix' : 144, + 'OpMatrixTimesVector' : 145, + 'OpMatrixTimesMatrix' : 146, + 'OpOuterProduct' : 147, + 'OpDot' : 148, + 'OpIAddCarry' : 149, + 'OpISubBorrow' : 150, + 'OpUMulExtended' : 151, + 'OpSMulExtended' : 152, + 'OpAny' : 154, + 'OpAll' : 155, + 'OpIsNan' : 156, + 'OpIsInf' : 157, + 'OpIsFinite' : 158, + 'OpIsNormal' : 159, + 'OpSignBitSet' : 160, + 'OpLessOrGreater' : 161, + 'OpOrdered' : 162, + 'OpUnordered' : 163, + 'OpLogicalEqual' : 164, + 'OpLogicalNotEqual' : 165, + 'OpLogicalOr' : 166, + 'OpLogicalAnd' : 167, + 'OpLogicalNot' : 168, + 'OpSelect' : 169, + 'OpIEqual' : 170, + 'OpINotEqual' : 171, + 'OpUGreaterThan' : 172, + 'OpSGreaterThan' : 173, + 'OpUGreaterThanEqual' : 174, + 'OpSGreaterThanEqual' : 175, + 'OpULessThan' : 176, + 'OpSLessThan' : 177, + 'OpULessThanEqual' : 178, + 'OpSLessThanEqual' : 179, + 'OpFOrdEqual' : 180, + 'OpFUnordEqual' : 181, + 'OpFOrdNotEqual' : 182, + 'OpFUnordNotEqual' : 183, + 'OpFOrdLessThan' : 184, + 'OpFUnordLessThan' : 185, + 'OpFOrdGreaterThan' : 186, + 'OpFUnordGreaterThan' : 187, + 'OpFOrdLessThanEqual' : 188, + 'OpFUnordLessThanEqual' : 189, + 'OpFOrdGreaterThanEqual' : 190, + 'OpFUnordGreaterThanEqual' : 191, + 'OpShiftRightLogical' : 194, + 'OpShiftRightArithmetic' : 195, + 'OpShiftLeftLogical' : 196, + 'OpBitwiseOr' : 197, + 'OpBitwiseXor' : 198, + 'OpBitwiseAnd' : 199, + 'OpNot' : 200, + 'OpBitFieldInsert' : 201, + 'OpBitFieldSExtract' : 202, + 'OpBitFieldUExtract' : 203, + 'OpBitReverse' : 204, + 'OpBitCount' : 205, + 'OpDPdx' : 207, + 'OpDPdy' : 208, + 'OpFwidth' : 209, + 'OpDPdxFine' : 210, + 'OpDPdyFine' : 211, + 'OpFwidthFine' : 212, + 'OpDPdxCoarse' : 213, + 'OpDPdyCoarse' : 214, + 'OpFwidthCoarse' : 215, + 'OpEmitVertex' : 218, + 'OpEndPrimitive' : 219, + 'OpEmitStreamVertex' : 220, + 'OpEndStreamPrimitive' : 221, + 'OpControlBarrier' : 224, + 'OpMemoryBarrier' : 225, + 'OpAtomicLoad' : 227, + 'OpAtomicStore' : 228, + 'OpAtomicExchange' : 229, + 'OpAtomicCompareExchange' : 230, + 'OpAtomicCompareExchangeWeak' : 231, + 'OpAtomicIIncrement' : 232, + 'OpAtomicIDecrement' : 233, + 'OpAtomicIAdd' : 234, + 'OpAtomicISub' : 235, + 'OpAtomicSMin' : 236, + 'OpAtomicUMin' : 237, + 'OpAtomicSMax' : 238, + 'OpAtomicUMax' : 239, + 'OpAtomicAnd' : 240, + 'OpAtomicOr' : 241, + 'OpAtomicXor' : 242, + 'OpPhi' : 245, + 'OpLoopMerge' : 246, + 'OpSelectionMerge' : 247, + 'OpLabel' : 248, + 'OpBranch' : 249, + 'OpBranchConditional' : 250, + 'OpSwitch' : 251, + 'OpKill' : 252, + 'OpReturn' : 253, + 'OpReturnValue' : 254, + 'OpUnreachable' : 255, + 'OpLifetimeStart' : 256, + 'OpLifetimeStop' : 257, + 'OpGroupAsyncCopy' : 259, + 'OpGroupWaitEvents' : 260, + 'OpGroupAll' : 261, + 'OpGroupAny' : 262, + 'OpGroupBroadcast' : 263, + 'OpGroupIAdd' : 264, + 'OpGroupFAdd' : 265, + 'OpGroupFMin' : 266, + 'OpGroupUMin' : 267, + 'OpGroupSMin' : 268, + 'OpGroupFMax' : 269, + 'OpGroupUMax' : 270, + 'OpGroupSMax' : 271, + 'OpReadPipe' : 274, + 'OpWritePipe' : 275, + 'OpReservedReadPipe' : 276, + 'OpReservedWritePipe' : 277, + 'OpReserveReadPipePackets' : 278, + 'OpReserveWritePipePackets' : 279, + 'OpCommitReadPipe' : 280, + 'OpCommitWritePipe' : 281, + 'OpIsValidReserveId' : 282, + 'OpGetNumPipePackets' : 283, + 'OpGetMaxPipePackets' : 284, + 'OpGroupReserveReadPipePackets' : 285, + 'OpGroupReserveWritePipePackets' : 286, + 'OpGroupCommitReadPipe' : 287, + 'OpGroupCommitWritePipe' : 288, + 'OpEnqueueMarker' : 291, + 'OpEnqueueKernel' : 292, + 'OpGetKernelNDrangeSubGroupCount' : 293, + 'OpGetKernelNDrangeMaxSubGroupSize' : 294, + 'OpGetKernelWorkGroupSize' : 295, + 'OpGetKernelPreferredWorkGroupSizeMultiple' : 296, + 'OpRetainEvent' : 297, + 'OpReleaseEvent' : 298, + 'OpCreateUserEvent' : 299, + 'OpIsValidEvent' : 300, + 'OpSetUserEventStatus' : 301, + 'OpCaptureEventProfilingInfo' : 302, + 'OpGetDefaultQueue' : 303, + 'OpBuildNDRange' : 304, + 'OpImageSparseSampleImplicitLod' : 305, + 'OpImageSparseSampleExplicitLod' : 306, + 'OpImageSparseSampleDrefImplicitLod' : 307, + 'OpImageSparseSampleDrefExplicitLod' : 308, + 'OpImageSparseSampleProjImplicitLod' : 309, + 'OpImageSparseSampleProjExplicitLod' : 310, + 'OpImageSparseSampleProjDrefImplicitLod' : 311, + 'OpImageSparseSampleProjDrefExplicitLod' : 312, + 'OpImageSparseFetch' : 313, + 'OpImageSparseGather' : 314, + 'OpImageSparseDrefGather' : 315, + 'OpImageSparseTexelsResident' : 316, + 'OpNoLine' : 317, + 'OpAtomicFlagTestAndSet' : 318, + 'OpAtomicFlagClear' : 319, + 'OpImageSparseRead' : 320, + 'OpSizeOf' : 321, + 'OpTypePipeStorage' : 322, + 'OpConstantPipeStorage' : 323, + 'OpCreatePipeFromPipeStorage' : 324, + 'OpGetKernelLocalSizeForSubgroupCount' : 325, + 'OpGetKernelMaxNumSubgroups' : 326, + 'OpTypeNamedBarrier' : 327, + 'OpNamedBarrierInitialize' : 328, + 'OpMemoryNamedBarrier' : 329, + 'OpModuleProcessed' : 330, + 'OpExecutionModeId' : 331, + 'OpDecorateId' : 332, + 'OpGroupNonUniformElect' : 333, + 'OpGroupNonUniformAll' : 334, + 'OpGroupNonUniformAny' : 335, + 'OpGroupNonUniformAllEqual' : 336, + 'OpGroupNonUniformBroadcast' : 337, + 'OpGroupNonUniformBroadcastFirst' : 338, + 'OpGroupNonUniformBallot' : 339, + 'OpGroupNonUniformInverseBallot' : 340, + 'OpGroupNonUniformBallotBitExtract' : 341, + 'OpGroupNonUniformBallotBitCount' : 342, + 'OpGroupNonUniformBallotFindLSB' : 343, + 'OpGroupNonUniformBallotFindMSB' : 344, + 'OpGroupNonUniformShuffle' : 345, + 'OpGroupNonUniformShuffleXor' : 346, + 'OpGroupNonUniformShuffleUp' : 347, + 'OpGroupNonUniformShuffleDown' : 348, + 'OpGroupNonUniformIAdd' : 349, + 'OpGroupNonUniformFAdd' : 350, + 'OpGroupNonUniformIMul' : 351, + 'OpGroupNonUniformFMul' : 352, + 'OpGroupNonUniformSMin' : 353, + 'OpGroupNonUniformUMin' : 354, + 'OpGroupNonUniformFMin' : 355, + 'OpGroupNonUniformSMax' : 356, + 'OpGroupNonUniformUMax' : 357, + 'OpGroupNonUniformFMax' : 358, + 'OpGroupNonUniformBitwiseAnd' : 359, + 'OpGroupNonUniformBitwiseOr' : 360, + 'OpGroupNonUniformBitwiseXor' : 361, + 'OpGroupNonUniformLogicalAnd' : 362, + 'OpGroupNonUniformLogicalOr' : 363, + 'OpGroupNonUniformLogicalXor' : 364, + 'OpGroupNonUniformQuadBroadcast' : 365, + 'OpGroupNonUniformQuadSwap' : 366, + 'OpCopyLogical' : 400, + 'OpPtrEqual' : 401, + 'OpPtrNotEqual' : 402, + 'OpPtrDiff' : 403, + 'OpColorAttachmentReadEXT' : 4160, + 'OpDepthAttachmentReadEXT' : 4161, + 'OpStencilAttachmentReadEXT' : 4162, + 'OpTerminateInvocation' : 4416, + 'OpSubgroupBallotKHR' : 4421, + 'OpSubgroupFirstInvocationKHR' : 4422, + 'OpSubgroupAllKHR' : 4428, + 'OpSubgroupAnyKHR' : 4429, + 'OpSubgroupAllEqualKHR' : 4430, + 'OpGroupNonUniformRotateKHR' : 4431, + 'OpSubgroupReadInvocationKHR' : 4432, + 'OpTraceRayKHR' : 4445, + 'OpExecuteCallableKHR' : 4446, + 'OpConvertUToAccelerationStructureKHR' : 4447, + 'OpIgnoreIntersectionKHR' : 4448, + 'OpTerminateRayKHR' : 4449, + 'OpSDot' : 4450, + 'OpSDotKHR' : 4450, + 'OpUDot' : 4451, + 'OpUDotKHR' : 4451, + 'OpSUDot' : 4452, + 'OpSUDotKHR' : 4452, + 'OpSDotAccSat' : 4453, + 'OpSDotAccSatKHR' : 4453, + 'OpUDotAccSat' : 4454, + 'OpUDotAccSatKHR' : 4454, + 'OpSUDotAccSat' : 4455, + 'OpSUDotAccSatKHR' : 4455, + 'OpTypeCooperativeMatrixKHR' : 4456, + 'OpCooperativeMatrixLoadKHR' : 4457, + 'OpCooperativeMatrixStoreKHR' : 4458, + 'OpCooperativeMatrixMulAddKHR' : 4459, + 'OpCooperativeMatrixLengthKHR' : 4460, + 'OpTypeRayQueryKHR' : 4472, + 'OpRayQueryInitializeKHR' : 4473, + 'OpRayQueryTerminateKHR' : 4474, + 'OpRayQueryGenerateIntersectionKHR' : 4475, + 'OpRayQueryConfirmIntersectionKHR' : 4476, + 'OpRayQueryProceedKHR' : 4477, + 'OpRayQueryGetIntersectionTypeKHR' : 4479, + 'OpImageSampleWeightedQCOM' : 4480, + 'OpImageBoxFilterQCOM' : 4481, + 'OpImageBlockMatchSSDQCOM' : 4482, + 'OpImageBlockMatchSADQCOM' : 4483, + 'OpImageBlockMatchWindowSSDQCOM' : 4500, + 'OpImageBlockMatchWindowSADQCOM' : 4501, + 'OpImageBlockMatchGatherSSDQCOM' : 4502, + 'OpImageBlockMatchGatherSADQCOM' : 4503, + 'OpGroupIAddNonUniformAMD' : 5000, + 'OpGroupFAddNonUniformAMD' : 5001, + 'OpGroupFMinNonUniformAMD' : 5002, + 'OpGroupUMinNonUniformAMD' : 5003, + 'OpGroupSMinNonUniformAMD' : 5004, + 'OpGroupFMaxNonUniformAMD' : 5005, + 'OpGroupUMaxNonUniformAMD' : 5006, + 'OpGroupSMaxNonUniformAMD' : 5007, + 'OpFragmentMaskFetchAMD' : 5011, + 'OpFragmentFetchAMD' : 5012, + 'OpReadClockKHR' : 5056, + 'OpFinalizeNodePayloadsAMDX' : 5075, + 'OpFinishWritingNodePayloadAMDX' : 5078, + 'OpInitializeNodePayloadsAMDX' : 5090, + 'OpGroupNonUniformQuadAllKHR' : 5110, + 'OpGroupNonUniformQuadAnyKHR' : 5111, + 'OpHitObjectRecordHitMotionNV' : 5249, + 'OpHitObjectRecordHitWithIndexMotionNV' : 5250, + 'OpHitObjectRecordMissMotionNV' : 5251, + 'OpHitObjectGetWorldToObjectNV' : 5252, + 'OpHitObjectGetObjectToWorldNV' : 5253, + 'OpHitObjectGetObjectRayDirectionNV' : 5254, + 'OpHitObjectGetObjectRayOriginNV' : 5255, + 'OpHitObjectTraceRayMotionNV' : 5256, + 'OpHitObjectGetShaderRecordBufferHandleNV' : 5257, + 'OpHitObjectGetShaderBindingTableRecordIndexNV' : 5258, + 'OpHitObjectRecordEmptyNV' : 5259, + 'OpHitObjectTraceRayNV' : 5260, + 'OpHitObjectRecordHitNV' : 5261, + 'OpHitObjectRecordHitWithIndexNV' : 5262, + 'OpHitObjectRecordMissNV' : 5263, + 'OpHitObjectExecuteShaderNV' : 5264, + 'OpHitObjectGetCurrentTimeNV' : 5265, + 'OpHitObjectGetAttributesNV' : 5266, + 'OpHitObjectGetHitKindNV' : 5267, + 'OpHitObjectGetPrimitiveIndexNV' : 5268, + 'OpHitObjectGetGeometryIndexNV' : 5269, + 'OpHitObjectGetInstanceIdNV' : 5270, + 'OpHitObjectGetInstanceCustomIndexNV' : 5271, + 'OpHitObjectGetWorldRayDirectionNV' : 5272, + 'OpHitObjectGetWorldRayOriginNV' : 5273, + 'OpHitObjectGetRayTMaxNV' : 5274, + 'OpHitObjectGetRayTMinNV' : 5275, + 'OpHitObjectIsEmptyNV' : 5276, + 'OpHitObjectIsHitNV' : 5277, + 'OpHitObjectIsMissNV' : 5278, + 'OpReorderThreadWithHitObjectNV' : 5279, + 'OpReorderThreadWithHintNV' : 5280, + 'OpTypeHitObjectNV' : 5281, + 'OpImageSampleFootprintNV' : 5283, + 'OpEmitMeshTasksEXT' : 5294, + 'OpSetMeshOutputsEXT' : 5295, + 'OpGroupNonUniformPartitionNV' : 5296, + 'OpWritePackedPrimitiveIndices4x8NV' : 5299, + 'OpFetchMicroTriangleVertexPositionNV' : 5300, + 'OpFetchMicroTriangleVertexBarycentricNV' : 5301, + 'OpReportIntersectionKHR' : 5334, + 'OpReportIntersectionNV' : 5334, + 'OpIgnoreIntersectionNV' : 5335, + 'OpTerminateRayNV' : 5336, + 'OpTraceNV' : 5337, + 'OpTraceMotionNV' : 5338, + 'OpTraceRayMotionNV' : 5339, + 'OpRayQueryGetIntersectionTriangleVertexPositionsKHR' : 5340, + 'OpTypeAccelerationStructureKHR' : 5341, + 'OpTypeAccelerationStructureNV' : 5341, + 'OpExecuteCallableNV' : 5344, + 'OpTypeCooperativeMatrixNV' : 5358, + 'OpCooperativeMatrixLoadNV' : 5359, + 'OpCooperativeMatrixStoreNV' : 5360, + 'OpCooperativeMatrixMulAddNV' : 5361, + 'OpCooperativeMatrixLengthNV' : 5362, + 'OpBeginInvocationInterlockEXT' : 5364, + 'OpEndInvocationInterlockEXT' : 5365, + 'OpDemoteToHelperInvocation' : 5380, + 'OpDemoteToHelperInvocationEXT' : 5380, + 'OpIsHelperInvocationEXT' : 5381, + 'OpConvertUToImageNV' : 5391, + 'OpConvertUToSamplerNV' : 5392, + 'OpConvertImageToUNV' : 5393, + 'OpConvertSamplerToUNV' : 5394, + 'OpConvertUToSampledImageNV' : 5395, + 'OpConvertSampledImageToUNV' : 5396, + 'OpSamplerImageAddressingModeNV' : 5397, + 'OpSubgroupShuffleINTEL' : 5571, + 'OpSubgroupShuffleDownINTEL' : 5572, + 'OpSubgroupShuffleUpINTEL' : 5573, + 'OpSubgroupShuffleXorINTEL' : 5574, + 'OpSubgroupBlockReadINTEL' : 5575, + 'OpSubgroupBlockWriteINTEL' : 5576, + 'OpSubgroupImageBlockReadINTEL' : 5577, + 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpSubgroupImageMediaBlockReadINTEL' : 5580, + 'OpSubgroupImageMediaBlockWriteINTEL' : 5581, + 'OpUCountLeadingZerosINTEL' : 5585, + 'OpUCountTrailingZerosINTEL' : 5586, + 'OpAbsISubINTEL' : 5587, + 'OpAbsUSubINTEL' : 5588, + 'OpIAddSatINTEL' : 5589, + 'OpUAddSatINTEL' : 5590, + 'OpIAverageINTEL' : 5591, + 'OpUAverageINTEL' : 5592, + 'OpIAverageRoundedINTEL' : 5593, + 'OpUAverageRoundedINTEL' : 5594, + 'OpISubSatINTEL' : 5595, + 'OpUSubSatINTEL' : 5596, + 'OpIMul32x16INTEL' : 5597, + 'OpUMul32x16INTEL' : 5598, + 'OpConstantFunctionPointerINTEL' : 5600, + 'OpFunctionPointerCallINTEL' : 5601, + 'OpAsmTargetINTEL' : 5609, + 'OpAsmINTEL' : 5610, + 'OpAsmCallINTEL' : 5611, + 'OpAtomicFMinEXT' : 5614, + 'OpAtomicFMaxEXT' : 5615, + 'OpAssumeTrueKHR' : 5630, + 'OpExpectKHR' : 5631, + 'OpDecorateString' : 5632, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateString' : 5633, + 'OpMemberDecorateStringGOOGLE' : 5633, + 'OpVmeImageINTEL' : 5699, + 'OpTypeVmeImageINTEL' : 5700, + 'OpTypeAvcImePayloadINTEL' : 5701, + 'OpTypeAvcRefPayloadINTEL' : 5702, + 'OpTypeAvcSicPayloadINTEL' : 5703, + 'OpTypeAvcMcePayloadINTEL' : 5704, + 'OpTypeAvcMceResultINTEL' : 5705, + 'OpTypeAvcImeResultINTEL' : 5706, + 'OpTypeAvcImeResultSingleReferenceStreamoutINTEL' : 5707, + 'OpTypeAvcImeResultDualReferenceStreamoutINTEL' : 5708, + 'OpTypeAvcImeSingleReferenceStreaminINTEL' : 5709, + 'OpTypeAvcImeDualReferenceStreaminINTEL' : 5710, + 'OpTypeAvcRefResultINTEL' : 5711, + 'OpTypeAvcSicResultINTEL' : 5712, + 'OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL' : 5713, + 'OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL' : 5714, + 'OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL' : 5715, + 'OpSubgroupAvcMceSetInterShapePenaltyINTEL' : 5716, + 'OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL' : 5717, + 'OpSubgroupAvcMceSetInterDirectionPenaltyINTEL' : 5718, + 'OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL' : 5719, + 'OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL' : 5720, + 'OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL' : 5721, + 'OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL' : 5722, + 'OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL' : 5723, + 'OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL' : 5724, + 'OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL' : 5725, + 'OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL' : 5726, + 'OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL' : 5727, + 'OpSubgroupAvcMceSetAcOnlyHaarINTEL' : 5728, + 'OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL' : 5729, + 'OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL' : 5730, + 'OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL' : 5731, + 'OpSubgroupAvcMceConvertToImePayloadINTEL' : 5732, + 'OpSubgroupAvcMceConvertToImeResultINTEL' : 5733, + 'OpSubgroupAvcMceConvertToRefPayloadINTEL' : 5734, + 'OpSubgroupAvcMceConvertToRefResultINTEL' : 5735, + 'OpSubgroupAvcMceConvertToSicPayloadINTEL' : 5736, + 'OpSubgroupAvcMceConvertToSicResultINTEL' : 5737, + 'OpSubgroupAvcMceGetMotionVectorsINTEL' : 5738, + 'OpSubgroupAvcMceGetInterDistortionsINTEL' : 5739, + 'OpSubgroupAvcMceGetBestInterDistortionsINTEL' : 5740, + 'OpSubgroupAvcMceGetInterMajorShapeINTEL' : 5741, + 'OpSubgroupAvcMceGetInterMinorShapeINTEL' : 5742, + 'OpSubgroupAvcMceGetInterDirectionsINTEL' : 5743, + 'OpSubgroupAvcMceGetInterMotionVectorCountINTEL' : 5744, + 'OpSubgroupAvcMceGetInterReferenceIdsINTEL' : 5745, + 'OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL' : 5746, + 'OpSubgroupAvcImeInitializeINTEL' : 5747, + 'OpSubgroupAvcImeSetSingleReferenceINTEL' : 5748, + 'OpSubgroupAvcImeSetDualReferenceINTEL' : 5749, + 'OpSubgroupAvcImeRefWindowSizeINTEL' : 5750, + 'OpSubgroupAvcImeAdjustRefOffsetINTEL' : 5751, + 'OpSubgroupAvcImeConvertToMcePayloadINTEL' : 5752, + 'OpSubgroupAvcImeSetMaxMotionVectorCountINTEL' : 5753, + 'OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL' : 5754, + 'OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL' : 5755, + 'OpSubgroupAvcImeSetWeightedSadINTEL' : 5756, + 'OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL' : 5757, + 'OpSubgroupAvcImeEvaluateWithDualReferenceINTEL' : 5758, + 'OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL' : 5759, + 'OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL' : 5760, + 'OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL' : 5761, + 'OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL' : 5762, + 'OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL' : 5763, + 'OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL' : 5764, + 'OpSubgroupAvcImeConvertToMceResultINTEL' : 5765, + 'OpSubgroupAvcImeGetSingleReferenceStreaminINTEL' : 5766, + 'OpSubgroupAvcImeGetDualReferenceStreaminINTEL' : 5767, + 'OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL' : 5768, + 'OpSubgroupAvcImeStripDualReferenceStreamoutINTEL' : 5769, + 'OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL' : 5770, + 'OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL' : 5771, + 'OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL' : 5772, + 'OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL' : 5773, + 'OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL' : 5774, + 'OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL' : 5775, + 'OpSubgroupAvcImeGetBorderReachedINTEL' : 5776, + 'OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL' : 5777, + 'OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL' : 5778, + 'OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL' : 5779, + 'OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL' : 5780, + 'OpSubgroupAvcFmeInitializeINTEL' : 5781, + 'OpSubgroupAvcBmeInitializeINTEL' : 5782, + 'OpSubgroupAvcRefConvertToMcePayloadINTEL' : 5783, + 'OpSubgroupAvcRefSetBidirectionalMixDisableINTEL' : 5784, + 'OpSubgroupAvcRefSetBilinearFilterEnableINTEL' : 5785, + 'OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL' : 5786, + 'OpSubgroupAvcRefEvaluateWithDualReferenceINTEL' : 5787, + 'OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL' : 5788, + 'OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL' : 5789, + 'OpSubgroupAvcRefConvertToMceResultINTEL' : 5790, + 'OpSubgroupAvcSicInitializeINTEL' : 5791, + 'OpSubgroupAvcSicConfigureSkcINTEL' : 5792, + 'OpSubgroupAvcSicConfigureIpeLumaINTEL' : 5793, + 'OpSubgroupAvcSicConfigureIpeLumaChromaINTEL' : 5794, + 'OpSubgroupAvcSicGetMotionVectorMaskINTEL' : 5795, + 'OpSubgroupAvcSicConvertToMcePayloadINTEL' : 5796, + 'OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL' : 5797, + 'OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL' : 5798, + 'OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL' : 5799, + 'OpSubgroupAvcSicSetBilinearFilterEnableINTEL' : 5800, + 'OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL' : 5801, + 'OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL' : 5802, + 'OpSubgroupAvcSicEvaluateIpeINTEL' : 5803, + 'OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL' : 5804, + 'OpSubgroupAvcSicEvaluateWithDualReferenceINTEL' : 5805, + 'OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL' : 5806, + 'OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL' : 5807, + 'OpSubgroupAvcSicConvertToMceResultINTEL' : 5808, + 'OpSubgroupAvcSicGetIpeLumaShapeINTEL' : 5809, + 'OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL' : 5810, + 'OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL' : 5811, + 'OpSubgroupAvcSicGetPackedIpeLumaModesINTEL' : 5812, + 'OpSubgroupAvcSicGetIpeChromaModeINTEL' : 5813, + 'OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL' : 5814, + 'OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL' : 5815, + 'OpSubgroupAvcSicGetInterRawSadsINTEL' : 5816, + 'OpVariableLengthArrayINTEL' : 5818, + 'OpSaveMemoryINTEL' : 5819, + 'OpRestoreMemoryINTEL' : 5820, + 'OpArbitraryFloatSinCosPiINTEL' : 5840, + 'OpArbitraryFloatCastINTEL' : 5841, + 'OpArbitraryFloatCastFromIntINTEL' : 5842, + 'OpArbitraryFloatCastToIntINTEL' : 5843, + 'OpArbitraryFloatAddINTEL' : 5846, + 'OpArbitraryFloatSubINTEL' : 5847, + 'OpArbitraryFloatMulINTEL' : 5848, + 'OpArbitraryFloatDivINTEL' : 5849, + 'OpArbitraryFloatGTINTEL' : 5850, + 'OpArbitraryFloatGEINTEL' : 5851, + 'OpArbitraryFloatLTINTEL' : 5852, + 'OpArbitraryFloatLEINTEL' : 5853, + 'OpArbitraryFloatEQINTEL' : 5854, + 'OpArbitraryFloatRecipINTEL' : 5855, + 'OpArbitraryFloatRSqrtINTEL' : 5856, + 'OpArbitraryFloatCbrtINTEL' : 5857, + 'OpArbitraryFloatHypotINTEL' : 5858, + 'OpArbitraryFloatSqrtINTEL' : 5859, + 'OpArbitraryFloatLogINTEL' : 5860, + 'OpArbitraryFloatLog2INTEL' : 5861, + 'OpArbitraryFloatLog10INTEL' : 5862, + 'OpArbitraryFloatLog1pINTEL' : 5863, + 'OpArbitraryFloatExpINTEL' : 5864, + 'OpArbitraryFloatExp2INTEL' : 5865, + 'OpArbitraryFloatExp10INTEL' : 5866, + 'OpArbitraryFloatExpm1INTEL' : 5867, + 'OpArbitraryFloatSinINTEL' : 5868, + 'OpArbitraryFloatCosINTEL' : 5869, + 'OpArbitraryFloatSinCosINTEL' : 5870, + 'OpArbitraryFloatSinPiINTEL' : 5871, + 'OpArbitraryFloatCosPiINTEL' : 5872, + 'OpArbitraryFloatASinINTEL' : 5873, + 'OpArbitraryFloatASinPiINTEL' : 5874, + 'OpArbitraryFloatACosINTEL' : 5875, + 'OpArbitraryFloatACosPiINTEL' : 5876, + 'OpArbitraryFloatATanINTEL' : 5877, + 'OpArbitraryFloatATanPiINTEL' : 5878, + 'OpArbitraryFloatATan2INTEL' : 5879, + 'OpArbitraryFloatPowINTEL' : 5880, + 'OpArbitraryFloatPowRINTEL' : 5881, + 'OpArbitraryFloatPowNINTEL' : 5882, + 'OpLoopControlINTEL' : 5887, + 'OpAliasDomainDeclINTEL' : 5911, + 'OpAliasScopeDeclINTEL' : 5912, + 'OpAliasScopeListDeclINTEL' : 5913, + 'OpFixedSqrtINTEL' : 5923, + 'OpFixedRecipINTEL' : 5924, + 'OpFixedRsqrtINTEL' : 5925, + 'OpFixedSinINTEL' : 5926, + 'OpFixedCosINTEL' : 5927, + 'OpFixedSinCosINTEL' : 5928, + 'OpFixedSinPiINTEL' : 5929, + 'OpFixedCosPiINTEL' : 5930, + 'OpFixedSinCosPiINTEL' : 5931, + 'OpFixedLogINTEL' : 5932, + 'OpFixedExpINTEL' : 5933, + 'OpPtrCastToCrossWorkgroupINTEL' : 5934, + 'OpCrossWorkgroupCastToPtrINTEL' : 5938, + 'OpReadPipeBlockingINTEL' : 5946, + 'OpWritePipeBlockingINTEL' : 5947, + 'OpFPGARegINTEL' : 5949, + 'OpRayQueryGetRayTMinKHR' : 6016, + 'OpRayQueryGetRayFlagsKHR' : 6017, + 'OpRayQueryGetIntersectionTKHR' : 6018, + 'OpRayQueryGetIntersectionInstanceCustomIndexKHR' : 6019, + 'OpRayQueryGetIntersectionInstanceIdKHR' : 6020, + 'OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR' : 6021, + 'OpRayQueryGetIntersectionGeometryIndexKHR' : 6022, + 'OpRayQueryGetIntersectionPrimitiveIndexKHR' : 6023, + 'OpRayQueryGetIntersectionBarycentricsKHR' : 6024, + 'OpRayQueryGetIntersectionFrontFaceKHR' : 6025, + 'OpRayQueryGetIntersectionCandidateAABBOpaqueKHR' : 6026, + 'OpRayQueryGetIntersectionObjectRayDirectionKHR' : 6027, + 'OpRayQueryGetIntersectionObjectRayOriginKHR' : 6028, + 'OpRayQueryGetWorldRayDirectionKHR' : 6029, + 'OpRayQueryGetWorldRayOriginKHR' : 6030, + 'OpRayQueryGetIntersectionObjectToWorldKHR' : 6031, + 'OpRayQueryGetIntersectionWorldToObjectKHR' : 6032, + 'OpAtomicFAddEXT' : 6035, + 'OpTypeBufferSurfaceINTEL' : 6086, + 'OpTypeStructContinuedINTEL' : 6090, + 'OpConstantCompositeContinuedINTEL' : 6091, + 'OpSpecConstantCompositeContinuedINTEL' : 6092, + 'OpCompositeConstructContinuedINTEL' : 6096, + 'OpConvertFToBF16INTEL' : 6116, + 'OpConvertBF16ToFINTEL' : 6117, + 'OpControlBarrierArriveINTEL' : 6142, + 'OpControlBarrierWaitINTEL' : 6143, + 'OpGroupIMulKHR' : 6401, + 'OpGroupFMulKHR' : 6402, + 'OpGroupBitwiseAndKHR' : 6403, + 'OpGroupBitwiseOrKHR' : 6404, + 'OpGroupBitwiseXorKHR' : 6405, + 'OpGroupLogicalAndKHR' : 6406, + 'OpGroupLogicalOrKHR' : 6407, + 'OpGroupLogicalXorKHR' : 6408, + 'OpMaskedGatherINTEL' : 6428, + 'OpMaskedScatterINTEL' : 6429, + }, + +} + diff --git a/thirdparty/swappy-frame-pacing/arm64-v8a/libswappy_static.a b/thirdparty/swappy-frame-pacing/arm64-v8a/libswappy_static.a new file mode 100644 index 000000000000..3bd342b8479f Binary files /dev/null and b/thirdparty/swappy-frame-pacing/arm64-v8a/libswappy_static.a differ diff --git a/thirdparty/swappy-frame-pacing/armeabi-v7a/libswappy_static.a b/thirdparty/swappy-frame-pacing/armeabi-v7a/libswappy_static.a new file mode 100644 index 000000000000..bfe01acbb034 Binary files /dev/null and b/thirdparty/swappy-frame-pacing/armeabi-v7a/libswappy_static.a differ diff --git a/thirdparty/swappy-frame-pacing/common/gamesdk_common.h b/thirdparty/swappy-frame-pacing/common/gamesdk_common.h new file mode 100644 index 000000000000..d29ac01af384 --- /dev/null +++ b/thirdparty/swappy-frame-pacing/common/gamesdk_common.h @@ -0,0 +1,41 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This is the main interface to the Android Performance Tuner library, also + * known as Tuning Fork. + * + * It is part of the Android Games SDK and produces best results when integrated + * with the Swappy Frame Pacing Library. + * + * See the documentation at + * https://developer.android.com/games/sdk/performance-tuner/custom-engine for + * more information on using this library in a native Android game. + * + */ + +#pragma once + +// There are separate versions for each GameSDK component that use this format: +#define ANDROID_GAMESDK_PACKED_VERSION(MAJOR, MINOR, BUGFIX) \ + ((MAJOR << 16) | (MINOR << 8) | (BUGFIX)) +// Accessors +#define ANDROID_GAMESDK_MAJOR_VERSION(PACKED) ((PACKED) >> 16) +#define ANDROID_GAMESDK_MINOR_VERSION(PACKED) (((PACKED) >> 8) & 0xff) +#define ANDROID_GAMESDK_BUGFIX_VERSION(PACKED) ((PACKED) & 0xff) + +#define AGDK_STRING_VERSION(MAJOR, MINOR, BUGFIX, GIT) \ +#MAJOR "." #MINOR "." #BUGFIX "." #GIT diff --git a/thirdparty/swappy-frame-pacing/swappyVk.h b/thirdparty/swappy-frame-pacing/swappyVk.h new file mode 100644 index 000000000000..020683cbc43c --- /dev/null +++ b/thirdparty/swappy-frame-pacing/swappyVk.h @@ -0,0 +1,420 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @defgroup swappyVk Swappy for Vulkan + * Vulkan part of Swappy. + * @{ + */ + +#pragma once + +#include "jni.h" +#include "swappy_common.h" + +#ifndef VK_NO_PROTOTYPES +#define VK_NO_PROTOTYPES 1 +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Determine any Vulkan device extensions that must be enabled for a new + * VkDevice. + * + * Swappy-for-Vulkan (SwappyVk) benefits from certain Vulkan device extensions + * (e.g. VK_GOOGLE_display_timing). Before the application calls + * vkCreateDevice, SwappyVk needs to look at the list of available extensions + * (returned by vkEnumerateDeviceExtensionProperties) and potentially identify + * one or more extensions that the application must add to: + * + * - VkDeviceCreateInfo::enabledExtensionCount + * - VkDeviceCreateInfo::ppEnabledExtensionNames + * + * before the application calls vkCreateDevice. For each VkPhysicalDevice that + * the application will call vkCreateDevice for, the application must call this + * function, and then must add the identified extension(s) to the list that are + * enabled for the VkDevice. Similar to many Vulkan functions, this function + * can be called twice, once to identify the number of required extensions, and + * again with application-allocated memory that the function can write into. + * + * @param[in] physicalDevice - The VkPhysicalDevice associated with + * the available extensions. + * @param[in] availableExtensionCount - This is the returned value of + * pPropertyCount from vkEnumerateDeviceExtensionProperties. + * @param[in] pAvailableExtensions - This is the returned value of + * pProperties from vkEnumerateDeviceExtensionProperties. + * @param[inout] pRequiredExtensionCount - If pRequiredExtensions is nullptr, + * the function sets this to the number of extensions that are required. If + * pRequiredExtensions is non-nullptr, this is the number of required extensions + * that the function should write into pRequiredExtensions. + * @param[inout] pRequiredExtensions - If non-nullptr, this is + * application-allocated memory into which the function will write the names of + * required extensions. It is a pointer to an array of + * char* strings (i.e. the same as + * VkDeviceCreateInfo::ppEnabledExtensionNames). + */ +void SwappyVk_determineDeviceExtensions( + VkPhysicalDevice physicalDevice, uint32_t availableExtensionCount, + VkExtensionProperties* pAvailableExtensions, + uint32_t* pRequiredExtensionCount, char** pRequiredExtensions); + +/** + * @brief Tell Swappy the queueFamilyIndex used to create a specific VkQueue + * + * Swappy needs to know the queueFamilyIndex used for creating a specific + * VkQueue so it can use it when presenting. + * + * @param[in] device - The VkDevice associated with the queue + * @param[in] queue - A device queue. + * @param[in] queueFamilyIndex - The queue family index used to create the + * VkQueue. + * + */ +void SwappyVk_setQueueFamilyIndex(VkDevice device, VkQueue queue, + uint32_t queueFamilyIndex); + +// TBD: For now, SwappyVk assumes only one VkSwapchainKHR per VkDevice, and that +// applications don't re-create swapchains. Is this long-term sufficient? + +/** + * Internal init function. Do not call directly. + * See SwappyVk_initAndGetRefreshCycleDuration instead. + * @private + */ +bool SwappyVk_initAndGetRefreshCycleDuration_internal( + JNIEnv* env, jobject jactivity, VkPhysicalDevice physicalDevice, + VkDevice device, VkSwapchainKHR swapchain, uint64_t* pRefreshDuration); + +/** + * @brief Initialize SwappyVk for a given device and swapchain, and obtain the + * approximate time duration between vertical-blanking periods. + * + * Uses JNI to query AppVsyncOffset and PresentationDeadline. + * + * If your application presents to more than one swapchain at a time, you must + * call this for each swapchain before calling swappyVkSetSwapInterval() for it. + * + * The duration between vertical-blanking periods (an interval) is expressed as + * the approximate number of nanoseconds between vertical-blanking periods of + * the swapchain’s physical display. + * + * If the application converts this number to a fraction (e.g. 16,666,666 nsec + * to 0.016666666) and divides one by that fraction, it will be the approximate + * refresh rate of the display (e.g. 16,666,666 nanoseconds corresponds to a + * 60Hz display, 11,111,111 nsec corresponds to a 90Hz display). + * + * @param[in] env - JNIEnv that is assumed to be from AttachCurrentThread + * function + * @param[in] jactivity - NativeActivity object handle, used for JNI + * @param[in] physicalDevice - The VkPhysicalDevice associated with the + * swapchain + * @param[in] device - The VkDevice associated with the swapchain + * @param[in] swapchain - The VkSwapchainKHR the application wants Swappy to + * swap + * @param[out] pRefreshDuration - The returned refresh cycle duration + * + * @return bool - true if the value returned by pRefreshDuration is + * valid, otherwise false if an error. + */ +bool SwappyVk_initAndGetRefreshCycleDuration(JNIEnv* env, jobject jactivity, + VkPhysicalDevice physicalDevice, + VkDevice device, + VkSwapchainKHR swapchain, + uint64_t* pRefreshDuration); + +/** + * @brief Tell Swappy which ANativeWindow to use when calling to ANativeWindow_* + * API. + * @param[in] device - The VkDevice associated with the swapchain + * @param[in] swapchain - The VkSwapchainKHR the application wants Swappy to + * swap + * @param[in] window - The ANativeWindow that was used to create the + * VkSwapchainKHR + */ +void SwappyVk_setWindow(VkDevice device, VkSwapchainKHR swapchain, + ANativeWindow* window); + +/** + * @brief Tell Swappy the duration of that each presented image should be + * visible. + * + * If your application presents to more than one swapchain at a time, you must + * call this for each swapchain before presenting to it. + * + * @param[in] device - The VkDevice associated with the swapchain + * @param[in] swapchain - The VkSwapchainKHR the application wants Swappy to + * swap + * @param[in] swap_ns - The duration of that each presented image should be + * visible in nanoseconds + */ +void SwappyVk_setSwapIntervalNS(VkDevice device, VkSwapchainKHR swapchain, + uint64_t swap_ns); + +/** + * @brief Tell Swappy to present one or more images to corresponding swapchains. + * + * Swappy will call vkQueuePresentKHR for your application. Swappy may insert a + * struct to the pNext-chain of VkPresentInfoKHR, or it may insert other Vulkan + * commands in order to attempt to honor the desired swap interval. + * + * @note If your application presents to more than one swapchain at a time, and + * if you use a different swap interval for each swapchain, Swappy will attempt + * to honor the swap interval for each swapchain (being more successful on + * devices that support an underlying presentation-timing extension, such as + * VK_GOOGLE_display_timing). + * + * @param[in] queue - The VkQueue associated with the device and swapchain + * @param[in] pPresentInfo - A pointer to the VkPresentInfoKHR containing the + * information about what image(s) to present on which + * swapchain(s). + */ +VkResult SwappyVk_queuePresent(VkQueue queue, + const VkPresentInfoKHR* pPresentInfo); + +/** + * @brief Destroy the SwappyVk instance associated with a swapchain. + * + * This API is expected to be called before calling vkDestroySwapchainKHR() + * so Swappy can cleanup its internal state. + * + * @param[in] device - The VkDevice associated with SwappyVk + * @param[in] swapchain - The VkSwapchainKHR the application wants Swappy to + * destroy + */ +void SwappyVk_destroySwapchain(VkDevice device, VkSwapchainKHR swapchain); + +/** + * @brief Destroy any swapchains associated with the device and clean up the + * device's resources + * + * This function should be called after SwappyVk_destroySwapchain if you no + * longer need the device. + * + * @param[in] device - The VkDevice associated with SwappyVk + */ +void SwappyVk_destroyDevice(VkDevice device); + +/** + * @brief Enables Auto-Swap-Interval feature for all instances. + * + * By default this feature is enabled. Changing it is completely + * optional for fine-tuning swappy behaviour. + * + * @param[in] enabled - True means enable, false means disable + */ +void SwappyVk_setAutoSwapInterval(bool enabled); + +/** + * @brief Enables Auto-Pipeline-Mode feature for all instances. + * + * By default this feature is enabled. Changing it is completely + * optional for fine-tuning swappy behaviour. + * + * @param[in] enabled - True means enable, false means disable + */ +void SwappyVk_setAutoPipelineMode(bool enabled); + +/** + * @brief Sets the maximal swap duration for all instances. + * + * Sets the maximal duration for Auto-Swap-Interval in milliseconds. + * If SwappyVk is operating in Auto-Swap-Interval and the frame duration is + * longer than the provided duration, SwappyVk will not do any pacing and just + * submit the frame as soon as possible. + * + * @param[in] max_swap_ns - maximal swap duration in milliseconds. + */ +void SwappyVk_setMaxAutoSwapIntervalNS(uint64_t max_swap_ns); + +/** + * @brief The fence timeout parameter can be set for devices with faulty + * drivers. Its default value is 50,000,000. + */ +void SwappyVk_setFenceTimeoutNS(uint64_t fence_timeout_ns); + +/** + * @brief Get the fence timeout parameter, for devices with faulty + * drivers. Its default value is 50,000,000. + */ +uint64_t SwappyVk_getFenceTimeoutNS(); + +/** + * @brief Inject callback functions to be called each frame. + * + * @param[in] tracer - Collection of callback functions + */ +void SwappyVk_injectTracer(const SwappyTracer* tracer); + +/** + * @brief Remove callbacks that were previously added using + * SwappyVk_injectTracer. + * + * Only removes callbacks that were previously added using + * SwappyVK_injectTracer. If SwappyVK_injectTracker was not called with the + * tracer, then there is no effect. + * + * @param[in] tracer - Collection of callback functions + */ +void SwappyVk_uninjectTracer(const SwappyTracer* tracer); + +/** + * @brief A structure enabling you to provide your own Vulkan function wrappers + * by calling ::SwappyVk_setFunctionProvider. + * + * Usage of this functionality is optional. + */ +typedef struct SwappyVkFunctionProvider { + /** + * @brief Callback to initialize the function provider. + * + * This function is called by Swappy before any functions are requested. + * E.g. so you can call dlopen on the Vulkan library. + */ + bool (*init)(); + + /** + * @brief Callback to get the address of a function. + * + * This function is called by Swappy to get the address of a Vulkan + * function. + * @param name The null-terminated name of the function. + */ + void* (*getProcAddr)(const char* name); + + /** + * @brief Callback to close any resources owned by the function provider. + * + * This function is called by Swappy when no more functions will be + * requested, e.g. so you can call dlclose on the Vulkan library. + */ + void (*close)(); +} SwappyVkFunctionProvider; + +/** + * @brief Set the Vulkan function provider. + * + * This enables you to provide an object that will be used to look up Vulkan + * functions, e.g. to hook usage of these functions. + * + * To use this functionality, you *must* call this function before any others. + * + * Usage of this function is entirely optional. If you do not use it, the Vulkan + * functions required by Swappy will be dynamically loaded from libvulkan.so. + * + * @param[in] provider - provider object + */ +void SwappyVk_setFunctionProvider( + const SwappyVkFunctionProvider* pSwappyVkFunctionProvider); + +/** + * @brief Get the swap interval value, in nanoseconds, for a given swapchain. + * + * @param[in] swapchain - the swapchain to query + */ +uint64_t SwappyVk_getSwapIntervalNS(VkSwapchainKHR swapchain); + +/** + * @brief Get the supported refresh periods of this device. Call once with + * out_refreshrates set to nullptr to get the number of supported refresh + * periods, then call again passing that number as allocated_entries and + * an array of size equal to allocated_entries that will be filled with the + * refresh periods. + */ +int SwappyVk_getSupportedRefreshPeriodsNS(uint64_t* out_refreshrates, + int allocated_entries, + VkSwapchainKHR swapchain); +/** + * @brief Check if Swappy is enabled for the specified swapchain. + * + * @return false if SwappyVk_initAndGetRefreshCycleDuration was not + * called for the specified swapchain, true otherwise. + */ +bool SwappyVk_isEnabled(VkSwapchainKHR swapchain, bool* isEnabled); + +/** + * @brief Toggle statistics collection on/off + * + * By default, stats collection is off and there is no overhead related to + * stats. An app can turn on stats collection by calling + * `SwappyVk_enableStats(swapchain, true)`. Then, the app is expected to call + * ::SwappyVk_recordFrameStart for each frame before starting to do any CPU + * related work. Stats will be logged to logcat with a 'FrameStatistics' tag. An + * app can get the stats by calling ::SwappyVk_getStats. + * + * SwappyVk_initAndGetRefreshCycleDuration must have been called successfully + * before for this swapchain, otherwise there is no effect in this call. Frame + * stats are only available if the platform supports VK_GOOGLE_display_timing + * extension. + * + * @param[in] swapchain - The swapchain for which frame stat collection is + * configured. + * @param enabled - Whether to enable/disable frame stat collection. + */ +void SwappyVk_enableStats(VkSwapchainKHR swapchain, bool enabled); + +/** + * @brief Should be called if stats have been enabled with SwappyVk_enableStats. + * + * When stats collection is enabled with SwappyVk_enableStats, the app is + * expected to call this function for each frame before starting to do any CPU + * related work. It is assumed that this function will be called after a + * successful call to vkAcquireNextImageKHR. See ::SwappyVk_enableStats for more + * conditions. + * + * @param[in] queue - The VkQueue associated with the device and swapchain + * @param[in] swapchain - The swapchain where the frame is presented to. + * @param[in] image - The image in swapchain that corresponds to the frame. + + * @see SwappyVk_enableStats. + */ +void SwappyVk_recordFrameStart(VkQueue queue, VkSwapchainKHR swapchain, uint32_t image); + +/** + * @brief Returns the stats collected, if statistics collection was toggled on. + * + * Given that this API uses VkSwapchainKHR and the potential for this call to be + * done on different threads, all calls to ::SwappyVk_getStats + * must be externally synchronized with other SwappyVk calls. Unsynchronized + * calls may lead to undefined behavior. See ::SwappyVk_enableStats for more + * conditions. + * + * @param[in] swapchain - The swapchain for which stats are being queried. + * @param swappyStats - Pointer to a SwappyStats that will be populated with + * the collected stats. Cannot be NULL. + * @see SwappyStats + */ +void SwappyVk_getStats(VkSwapchainKHR swapchain, SwappyStats *swappyStats); + +/** + * @brief Clears the frame statistics collected so far. + * + * All the frame statistics collected are reset to 0, frame statistics are + * collected normally after this call. See ::SwappyVk_enableStats for more + * conditions. + * + * @param[in] swapchain - The swapchain for which stats are being cleared. + */ +void SwappyVk_clearStats(VkSwapchainKHR swapchain); + +#ifdef __cplusplus +} // extern "C" +#endif + +/** @} */ diff --git a/thirdparty/swappy-frame-pacing/swappy_common.h b/thirdparty/swappy-frame-pacing/swappy_common.h new file mode 100644 index 000000000000..b711ca910fb3 --- /dev/null +++ b/thirdparty/swappy-frame-pacing/swappy_common.h @@ -0,0 +1,278 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @defgroup swappy_common Swappy common tools + * Tools to be used with Swappy for OpenGL or Swappy for Vulkan. + * @{ + */ + +#pragma once + +#include +#include + +#include "common/gamesdk_common.h" + +/** @brief Swap interval for 60fps, in nanoseconds. */ +#define SWAPPY_SWAP_60FPS (16666667L) + +/** @brief Swap interval for 30fps, in nanoseconds. */ +#define SWAPPY_SWAP_30FPS (33333333L) + +/** @brief Swap interval for 20fps, in nanoseconds. */ +#define SWAPPY_SWAP_20FPS (50000000L) + +/** + * The longest duration, in refresh periods, represented by the statistics. + * @see SwappyStats + */ +#define MAX_FRAME_BUCKETS 6 + +/** @cond INTERNAL */ + +#define SWAPPY_SYSTEM_PROP_KEY_DISABLE "swappy.disable" + +// Internal macros to track Swappy version, do not use directly. +#define SWAPPY_MAJOR_VERSION 2 +#define SWAPPY_MINOR_VERSION 0 +#define SWAPPY_BUGFIX_VERSION 0 +#define SWAPPY_PACKED_VERSION \ + ANDROID_GAMESDK_PACKED_VERSION(SWAPPY_MAJOR_VERSION, SWAPPY_MINOR_VERSION, \ + SWAPPY_BUGFIX_VERSION) + +// Internal macros to generate a symbol to track Swappy version, do not use +// directly. +#define SWAPPY_VERSION_CONCAT_NX(PREFIX, MAJOR, MINOR, BUGFIX, GITCOMMIT) \ + PREFIX##_##MAJOR##_##MINOR##_##BUGFIX##_##GITCOMMIT +#define SWAPPY_VERSION_CONCAT(PREFIX, MAJOR, MINOR, BUGFIX, GITCOMMIT) \ + SWAPPY_VERSION_CONCAT_NX(PREFIX, MAJOR, MINOR, BUGFIX, GITCOMMIT) +#define SWAPPY_VERSION_SYMBOL \ + SWAPPY_VERSION_CONCAT(Swappy_version, SWAPPY_MAJOR_VERSION, \ + SWAPPY_MINOR_VERSION, SWAPPY_BUGFIX_VERSION, \ + AGDK_GIT_COMMIT) + +// Define this to 1 to enable all logging from Swappy, by default it is +// disabled in a release build and enabled in a debug build. +#ifndef ENABLE_SWAPPY_LOGGING +#define ENABLE_SWAPPY_LOGGING 0 +#endif +/** @endcond */ + +/** @brief Id of a thread returned by an external thread manager. */ +typedef uint64_t SwappyThreadId; + +/** + * @brief A structure enabling you to set how Swappy starts and joins threads by + * calling + * ::Swappy_setThreadFunctions. + * + * Usage of this functionality is optional. + */ +typedef struct SwappyThreadFunctions { + /** @brief Thread start callback. + * + * This function is called by Swappy to start thread_func on a new thread. + * @param user_data A value to be passed the thread function. + * If the thread was started, this function should set the thread_id and + * return 0. If the thread was not started, this function should return a + * non-zero value. + */ + int (*start)(SwappyThreadId* thread_id, void* (*thread_func)(void*), + void* user_data); + + /** @brief Thread join callback. + * + * This function is called by Swappy to join the thread with given id. + */ + void (*join)(SwappyThreadId thread_id); + + /** @brief Thread joinable callback. + * + * This function is called by Swappy to discover whether the thread with the + * given id is joinable. + */ + bool (*joinable)(SwappyThreadId thread_id); +} SwappyThreadFunctions; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Return the version of the Swappy library at runtime. + */ +uint32_t Swappy_version(); + +/** + * @brief Call this before any other functions in order to use a custom thread + * manager. + * + * Usage of this function is entirely optional. Swappy uses std::thread by + * default. + * + */ +void Swappy_setThreadFunctions(const SwappyThreadFunctions* thread_functions); + +/** + * @brief Return the full version of the Swappy library at runtime, e.g. + * "1.9.0_8a85ab7c46" + */ +const char* Swappy_versionString(); + +/** + * @brief Swappy frame statistics, collected if toggled on with + * ::SwappyGL_enableStats or ::SwappyVk_enableStats. + */ +typedef struct SwappyStats { + /** @brief Total frames swapped by swappy */ + uint64_t totalFrames; + + /** @brief Histogram of the number of screen refreshes a frame waited in the + * compositor queue after rendering was completed. + * + * For example: + * if a frame waited 2 refresh periods in the compositor queue after + * rendering was done, the frame will be counted in idleFrames[2] + */ + uint64_t idleFrames[MAX_FRAME_BUCKETS]; + + /** @brief Histogram of the number of screen refreshes passed between the + * requested presentation time and the actual present time. + * + * For example: + * if a frame was presented 2 refresh periods after the requested + * timestamp swappy set, the frame will be counted in lateFrames[2] + */ + uint64_t lateFrames[MAX_FRAME_BUCKETS]; + + /** @brief Histogram of the number of screen refreshes passed between two + * consecutive frames + * + * For example: + * if frame N was presented 2 refresh periods after frame N-1 + * frame N will be counted in offsetFromPreviousFrame[2] + */ + uint64_t offsetFromPreviousFrame[MAX_FRAME_BUCKETS]; + + /** @brief Histogram of the number of screen refreshes passed between the + * call to Swappy_recordFrameStart and the actual present time. + * + * For example: + * if a frame was presented 2 refresh periods after the call to + * `Swappy_recordFrameStart` the frame will be counted in latencyFrames[2] + */ + uint64_t latencyFrames[MAX_FRAME_BUCKETS]; +} SwappyStats; + + +#ifdef __cplusplus +} // extern "C" +#endif + +/** + * Pointer to a function that can be attached to SwappyTracer::preWait + * @param userData Pointer to arbitrary data, see SwappyTracer::userData. + */ +typedef void (*SwappyPreWaitCallback)(void*); + +/** + * Pointer to a function that can be attached to SwappyTracer::postWait. + * @param userData Pointer to arbitrary data, see SwappyTracer::userData. + * @param cpu_time_ns Time for CPU processing of this frame in nanoseconds. + * @param gpu_time_ns Time for GPU processing of previous frame in nanoseconds. + */ +typedef void (*SwappyPostWaitCallback)(void*, int64_t cpu_time_ns, + int64_t gpu_time_ns); + +/** + * Pointer to a function that can be attached to SwappyTracer::preSwapBuffers. + * @param userData Pointer to arbitrary data, see SwappyTracer::userData. + */ +typedef void (*SwappyPreSwapBuffersCallback)(void*); + +/** + * Pointer to a function that can be attached to SwappyTracer::postSwapBuffers. + * @param userData Pointer to arbitrary data, see SwappyTracer::userData. + * @param desiredPresentationTimeMillis The target time, in milliseconds, at + * which the frame would be presented on screen. + */ +typedef void (*SwappyPostSwapBuffersCallback)( + void*, int64_t desiredPresentationTimeMillis); + +/** + * Pointer to a function that can be attached to SwappyTracer::startFrame. + * @param userData Pointer to arbitrary data, see SwappyTracer::userData. + * @param desiredPresentationTimeMillis The time, in milliseconds, at which the + * frame is scheduled to be presented. + */ +typedef void (*SwappyStartFrameCallback)(void*, int currentFrame, + int64_t desiredPresentationTimeMillis); + +/** + * Pointer to a function that can be attached to + * SwappyTracer::swapIntervalChanged. Call ::SwappyGL_getSwapIntervalNS or + * ::SwappyVk_getSwapIntervalNS to get the latest swapInterval. + * @param userData Pointer to arbitrary data, see SwappyTracer::userData. + */ +typedef void (*SwappySwapIntervalChangedCallback)(void*); + +/** + * @brief Collection of callbacks to be called each frame to trace execution. + * + * Injection of these is optional. + */ +typedef struct SwappyTracer { + /** + * Callback called before waiting to queue the frame to the composer. + */ + SwappyPreWaitCallback preWait; + + /** + * Callback called after wait to queue the frame to the composer is done. + */ + SwappyPostWaitCallback postWait; + + /** + * Callback called before calling the function to queue the frame to the + * composer. + */ + SwappyPreSwapBuffersCallback preSwapBuffers; + + /** + * Callback called after calling the function to queue the frame to the + * composer. + */ + SwappyPostSwapBuffersCallback postSwapBuffers; + + /** + * Callback called at the start of a frame. + */ + SwappyStartFrameCallback startFrame; + + /** + * Pointer to some arbitrary data that will be passed as the first argument + * of callbacks. + */ + void* userData; + + /** + * Callback called when the swap interval was changed. + */ + SwappySwapIntervalChangedCallback swapIntervalChanged; +} SwappyTracer; + +/** @} */ diff --git a/thirdparty/swappy-frame-pacing/x86-64/libswappy_static.a b/thirdparty/swappy-frame-pacing/x86-64/libswappy_static.a new file mode 100644 index 000000000000..56ab344d7393 Binary files /dev/null and b/thirdparty/swappy-frame-pacing/x86-64/libswappy_static.a differ diff --git a/thirdparty/swappy-frame-pacing/x86/libswappy_static.a b/thirdparty/swappy-frame-pacing/x86/libswappy_static.a new file mode 100644 index 000000000000..d21e0f09a38d Binary files /dev/null and b/thirdparty/swappy-frame-pacing/x86/libswappy_static.a differ diff --git a/thirdparty/vulkan/vk_mem_alloc.h b/thirdparty/vulkan/vk_mem_alloc.h index 1963b0852cb1..807d7f72f6b6 100644 --- a/thirdparty/vulkan/vk_mem_alloc.h +++ b/thirdparty/vulkan/vk_mem_alloc.h @@ -1699,6 +1699,24 @@ VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStatistics( VmaAllocator VMA_NOT_NULL allocator, VmaTotalStatistics* VMA_NOT_NULL pStats); +// +// @ShadyTF lazily allocated memory +// adding extra method because vma includes lazily allocated memory in the total bytes +/** \brief Retrieves lazily allocated bytes + +This function is called "calculate" not "get" because it has to traverse all +internal data structures, so it may be quite slow. Use it for debugging purposes. +For faster but more brief statistics suitable to be called every frame or every allocation, +use vmaGetHeapBudgets(). + +Note that when using allocator from multiple threads, returned information may immediately +become outdated. +*/ +VMA_CALL_PRE uint64_t VMA_CALL_POST vmaCalculateLazilyAllocatedBytes( + VmaAllocator VMA_NOT_NULL allocator); + +// + /** \brief Retrieves information about current memory usage and budget for all memory heaps. \param allocator @@ -14807,6 +14825,31 @@ VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStatistics( allocator->CalculateStatistics(pStats); } +// +// @ShadyTF lazily allocated memory +// adding extra method because vma includes lazily allocated memory in the total bytes +VMA_CALL_PRE uint64_t VMA_CALL_POST vmaCalculateLazilyAllocatedBytes( + VmaAllocator allocator) +{ + VMA_ASSERT(allocator); + VMA_DEBUG_GLOBAL_MUTEX_LOCK + VmaTotalStatistics stats; + allocator->CalculateStatistics(&stats); + uint64_t total_lazilily_allocated_bytes = 0; + for (uint32_t heapIndex = 0; heapIndex < allocator->GetMemoryHeapCount(); ++heapIndex) { + for (uint32_t typeIndex = 0; typeIndex < allocator->GetMemoryTypeCount(); ++typeIndex) { + if (allocator->MemoryTypeIndexToHeapIndex(typeIndex) == heapIndex) { + VkMemoryPropertyFlags flags = allocator->m_MemProps.memoryTypes[typeIndex].propertyFlags; + if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) + total_lazilily_allocated_bytes += stats.memoryType[typeIndex].statistics.allocationBytes; + } + } + } + return total_lazilily_allocated_bytes; +} +// + + VMA_CALL_PRE void VMA_CALL_POST vmaGetHeapBudgets( VmaAllocator allocator, VmaBudget* pBudgets)